feat: prisma schema, groups API, deploy workflow
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
import { requireAuth } from '~/server/utils/auth'
|
||||
import { saveCanvasToGitea } from '~/server/utils/giteaApi'
|
||||
import { canvases } from '~/server/utils/db'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = requireAuth(event)
|
||||
const body = await readBody(event)
|
||||
const { canvasId, autoSync = true } = body
|
||||
|
||||
if (!canvasId) {
|
||||
throw createError({ statusCode: 400, message: 'Canvas ID is required' })
|
||||
}
|
||||
|
||||
// Check if canvas exists and user has access
|
||||
const canvas = canvases.get(canvasId)
|
||||
if (!canvas) {
|
||||
throw createError({ statusCode: 404, message: 'Canvas not found' })
|
||||
}
|
||||
|
||||
// Check permissions
|
||||
if (canvas.ownerId !== user.id && !canvas.isPublic) {
|
||||
throw createError({ statusCode: 403, message: 'Access denied' })
|
||||
}
|
||||
|
||||
try {
|
||||
const ok = await saveCanvasToGitea(canvasId, canvas, `Auto-sync: ${canvas.name}`)
|
||||
return {
|
||||
success: ok,
|
||||
message: ok ? 'Canvas synchronized with Gitea' : 'Gitea sync failed',
|
||||
autoSyncEnabled: autoSync
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to sync canvas to Gitea:', error)
|
||||
throw createError({ statusCode: 500, message: 'Failed to sync canvas to Gitea' })
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,56 @@
|
||||
import { requireAuth } from '~/server/utils/auth'
|
||||
import { saveCanvasToGitea, loadCanvasFromGitea } from '~/server/utils/giteaApi'
|
||||
import { canvases } from '~/server/utils/db'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = requireAuth(event)
|
||||
const body = await readBody(event)
|
||||
const { canvasId, action, commitMessage } = body
|
||||
|
||||
if (!canvasId || !action) {
|
||||
throw createError({ statusCode: 400, message: 'Canvas ID and action are required' })
|
||||
}
|
||||
|
||||
try {
|
||||
switch (action) {
|
||||
case 'init':
|
||||
case 'sync': {
|
||||
const canvas = canvases.get(canvasId)
|
||||
if (!canvas) {
|
||||
throw createError({ statusCode: 404, message: 'Canvas not found' })
|
||||
}
|
||||
if (canvas.ownerId !== user.id && !canvas.isPublic) {
|
||||
throw createError({ statusCode: 403, message: 'Access denied' })
|
||||
}
|
||||
|
||||
const ok = await saveCanvasToGitea(canvasId, canvas, commitMessage)
|
||||
return {
|
||||
success: ok,
|
||||
message: ok
|
||||
? `Canvas ${canvasId} saved to Gitea`
|
||||
: `Failed to save canvas ${canvasId} to Gitea`
|
||||
}
|
||||
}
|
||||
|
||||
case 'load': {
|
||||
const gitCanvas = await loadCanvasFromGitea(canvasId)
|
||||
if (!gitCanvas) {
|
||||
return { success: false, message: 'Canvas not found in Gitea', needsInit: true }
|
||||
}
|
||||
|
||||
const existing = canvases.get(canvasId)
|
||||
if (existing) {
|
||||
canvases.set(canvasId, { ...existing, nodes: gitCanvas.nodes || [], edges: gitCanvas.edges || [] })
|
||||
}
|
||||
|
||||
return { success: true, canvas: gitCanvas, message: `Canvas ${canvasId} loaded from Gitea` }
|
||||
}
|
||||
|
||||
default:
|
||||
throw createError({ statusCode: 400, message: 'Invalid action' })
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('Gitea sync error:', error)
|
||||
throw createError({ statusCode: 500, message: error?.message || 'Gitea operation failed' })
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,47 @@
|
||||
import { requireAuth } from '~/server/utils/auth'
|
||||
import { saveCanvasToGitea } from '~/server/utils/giteaApi'
|
||||
import { canvases, userGroups } from '~/server/utils/db'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = requireAuth(event)
|
||||
const body = await readBody(event)
|
||||
const { canvasId, type } = body
|
||||
|
||||
if (!canvasId || !type) {
|
||||
throw createError({ statusCode: 400, message: 'Canvas ID and repository type are required' })
|
||||
}
|
||||
|
||||
// Check if canvas exists and user has access
|
||||
const canvas = canvases.get(canvasId)
|
||||
if (!canvas) {
|
||||
throw createError({ statusCode: 404, message: 'Canvas not found' })
|
||||
}
|
||||
|
||||
if (canvas.ownerId !== user.id && !canvas.isPublic) {
|
||||
// Check group access
|
||||
if (canvas.groupId) {
|
||||
const membership = Array.from(userGroups.values()).find(
|
||||
m => m.userId === user.id && m.groupId === canvas.groupId
|
||||
)
|
||||
if (!membership) {
|
||||
throw createError({ statusCode: 403, message: 'Access denied' })
|
||||
}
|
||||
} else {
|
||||
throw createError({ statusCode: 403, message: 'Access denied' })
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Initial save to Gitea creates the canvas file in the repo
|
||||
const ok = await saveCanvasToGitea(canvasId, canvas, `Init canvas ${canvasId}`)
|
||||
return {
|
||||
success: ok,
|
||||
message: ok
|
||||
? `Canvas ${canvasId} initialized in Gitea`
|
||||
: `Failed to initialize canvas ${canvasId} in Gitea`
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to initialize canvas in Gitea:', error)
|
||||
throw createError({ statusCode: 500, message: 'Failed to initialize canvas in Gitea' })
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,23 @@
|
||||
import { requireAuth } from '~/server/utils/auth'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = requireAuth(event)
|
||||
const body = await readBody(event)
|
||||
const { canvasId, action, commitMessage } = body
|
||||
|
||||
if (!canvasId || !action) {
|
||||
throw createError({ statusCode: 400, message: 'Canvas ID and action are required' })
|
||||
}
|
||||
|
||||
try {
|
||||
// Git sync logic will be implemented here
|
||||
// For now, return success response
|
||||
return {
|
||||
success: true,
|
||||
message: `Git ${action} completed for canvas ${canvasId}`,
|
||||
commitMessage: commitMessage || `Auto-sync canvas ${canvasId}`
|
||||
}
|
||||
} catch (error) {
|
||||
throw createError({ statusCode: 500, message: 'Git sync failed' })
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,45 @@
|
||||
// Test endpoint: GET /api/git/test
|
||||
// Verifies Gitea connection and repo access
|
||||
export default defineEventHandler(async (event) => {
|
||||
const config = useRuntimeConfig()
|
||||
|
||||
const { giteaUrl, giteaToken, giteaOrg, giteaMindmapRepo } = config
|
||||
|
||||
if (!giteaUrl || !giteaToken) {
|
||||
return { success: false, message: 'GITEA_URL or GITEA_TOKEN not set in .env' }
|
||||
}
|
||||
|
||||
try {
|
||||
// Test 1: check repo exists
|
||||
const repo = await $fetch<any>(`${giteaUrl}/api/v1/repos/${giteaOrg}/${giteaMindmapRepo}`, {
|
||||
headers: { 'Authorization': `token ${giteaToken}` }
|
||||
})
|
||||
|
||||
// Test 2: check/create canvases folder by listing contents
|
||||
let folderExists = false
|
||||
try {
|
||||
await $fetch(`${giteaUrl}/api/v1/repos/${giteaOrg}/${giteaMindmapRepo}/contents/canvases`, {
|
||||
headers: { 'Authorization': `token ${giteaToken}` }
|
||||
})
|
||||
folderExists = true
|
||||
} catch {
|
||||
folderExists = false
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
repo: repo.full_name,
|
||||
private: repo.private,
|
||||
folderExists,
|
||||
message: folderExists
|
||||
? '✅ Gitea connected, canvases/ folder exists'
|
||||
: '✅ Gitea connected, canvases/ folder will be created on first save'
|
||||
}
|
||||
} catch (e: any) {
|
||||
return {
|
||||
success: false,
|
||||
message: `❌ Gitea connection failed: ${e?.message || e}`,
|
||||
hint: 'Check GITEA_URL, GITEA_TOKEN, GITEA_ORG, GITEA_MINDMAP_REPO in .env'
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user