70 lines
2.0 KiB
TypeScript
70 lines
2.0 KiB
TypeScript
import { requireAuth } from '~/server/utils/auth'
|
|
import { prisma } from '~/server/utils/prisma'
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const user = requireAuth(event)
|
|
const body = await readBody(event)
|
|
const { canvasId, title, priority, state } = body
|
|
|
|
if (!canvasId || !title) {
|
|
throw createError({ statusCode: 400, message: 'Canvas ID and Title are required' })
|
|
}
|
|
|
|
// 1. Получаем канвас
|
|
const canvas = await prisma.canvas.findUnique({
|
|
where: { id: canvasId }
|
|
})
|
|
|
|
if (!canvas) {
|
|
throw createError({ statusCode: 404, message: 'Canvas not found' })
|
|
}
|
|
|
|
// 2. Проверяем права
|
|
const isOwner = canvas.ownerId === user.id
|
|
let isMember = false
|
|
if (canvas.groupId) {
|
|
const membership = await prisma.groupMember.findFirst({
|
|
where: { userId: user.id, groupId: canvas.groupId }
|
|
})
|
|
isMember = !!membership
|
|
}
|
|
|
|
if (!isOwner && !isMember && user.role !== 'admin') {
|
|
throw createError({ statusCode: 403, message: 'No permission to add tasks to this canvas' })
|
|
}
|
|
|
|
// 3. Создаем новый узел задачи
|
|
const nodes = (canvas.nodes as any[]) || []
|
|
|
|
// Генерируем позицию (просто в центре или скраю)
|
|
const lastNode = nodes[nodes.length - 1]
|
|
const x = lastNode?.position?.x || 100
|
|
const y = (lastNode?.position?.y || 100) + 100
|
|
|
|
const newTaskNode = {
|
|
id: `task-${Date.now()}`,
|
|
type: 'task',
|
|
position: { x, y },
|
|
data: {
|
|
text: `# ${title}`,
|
|
priority: priority || 'medium',
|
|
state: state || 'todo',
|
|
createdAt: new Date().toISOString()
|
|
},
|
|
// Дублируем поля для удобства фильтрации на бэкенде
|
|
priority: priority || 'medium',
|
|
state: state || 'todo',
|
|
label: title
|
|
}
|
|
|
|
nodes.push(newTaskNode)
|
|
|
|
// 4. Сохраняем в БД
|
|
await prisma.canvas.update({
|
|
where: { id: canvasId },
|
|
data: { nodes }
|
|
})
|
|
|
|
return { success: true, task: newTaskNode }
|
|
})
|