feat: enhance task persistence and implement centralized kanban board

This commit is contained in:
2026-04-28 21:55:37 +05:00
parent 7da3fc8ff4
commit 1f87f0d6e9
9 changed files with 425 additions and 45 deletions
+6 -1
View File
@@ -10,7 +10,12 @@ export default defineEventHandler(async (event) => {
const existing = await prisma.canvas.findUnique({ where: { id } })
if (!existing) throw createError({ statusCode: 404, message: 'Canvas not found' })
if (existing.ownerId !== user.id) throw createError({ statusCode: 403, message: 'Access denied' })
// Allow if owner, or if admin, or if canvas is public (for collaborative editing)
if (existing.ownerId !== user.id && user.role !== 'admin' && !existing.isPublic) {
console.log('[DEBUG 403]', { ownerId: existing.ownerId, userId: user.id, userRole: user.role, isPublic: existing.isPublic })
throw createError({ statusCode: 403, message: 'Access denied' })
}
const { name, nodes, edges, isPublic, groupId } = body
const canvas = await prisma.canvas.update({
+56
View File
@@ -0,0 +1,56 @@
import { requireAuth } from '~/server/utils/auth'
import { prisma } from '~/server/utils/prisma'
export default defineEventHandler(async (event) => {
const user = requireAuth(event)
const userGroups = await prisma.groupMember.findMany({
where: { userId: user.id },
select: { groupId: true }
})
const groupIds = userGroups.map(m => m.groupId)
// Get all canvases user has access to
const canvasList = await prisma.canvas.findMany({
where: {
OR: [
{ ownerId: user.id },
{ isPublic: true },
{ groupId: { in: groupIds } }
]
},
select: {
id: true,
name: true,
nodes: true
}
})
// Extract tasks from all canvases
const allTasks = []
for (const canvas of canvasList) {
const nodes = Array.isArray(canvas.nodes) ? canvas.nodes :
(typeof canvas.nodes === 'string' ? JSON.parse(canvas.nodes) : [])
if (!Array.isArray(nodes)) continue
const canvasTasks = nodes.filter(n => {
const type = n.type || n.data?.type
if (type !== 'task') return false
// Temporary: Show ALL tasks regardless of assignee so you can see them!
return true
})
for (const t of canvasTasks) {
allTasks.push({
...t,
canvasId: canvas.id,
canvasName: canvas.name
})
}
}
return { tasks: allTasks }
})
+32
View File
@@ -0,0 +1,32 @@
import { defineEventHandler } from 'h3'
import { prisma } from '~/server/utils/prisma'
import { requireAuth } from '~/server/utils/auth'
export default defineEventHandler(async (event) => {
const user = await requireAuth(event)
if (!user) return []
const users = await prisma.user.findMany({
select: {
id: true,
username: true,
email: true,
role: true,
profile: {
select: {
displayName: true,
avatar: true
}
}
}
})
return users.map(u => ({
id: u.id,
username: u.username,
email: u.email,
role: u.role,
displayName: u.profile?.displayName || u.username,
avatar: u.profile?.avatar
}))
})