diff --git a/backend/src/routes/admin.ts b/backend/src/routes/admin.ts index c4e4fc6..c2e2037 100644 --- a/backend/src/routes/admin.ts +++ b/backend/src/routes/admin.ts @@ -5,7 +5,7 @@ import { eq, desc } from 'drizzle-orm'; import { v4 as uuid } from 'uuid'; import bcrypt from 'bcrypt'; import { db } from '../db/index'; -import { users, authorMappings, syncLogs, projects, projectRepos, gitCommits, gitPRs, userProjectPermissions } from '../db/schema'; +import { users, authorMappings, syncLogs, projects, projectRepos, gitCommits, gitPRs, userProjectPermissions, objectives, keyResults, krLogs } from '../db/schema'; import { requireRole } from '../middleware/role'; import { AppError } from '../middleware/error-handler'; @@ -178,6 +178,17 @@ adminRoutes.patch('/admin/projects/:id', zValidator('json', updateProjectSchema) adminRoutes.delete('/admin/projects/:id', async (c) => { const id = c.req.param('id'); + await db.delete(userProjectPermissions).where(eq(userProjectPermissions.projectId, id)); + await db.delete(projectRepos).where(eq(projectRepos.projectId, id)); + const objs = await db.select().from(objectives).where(eq(objectives.projectId, id)); + for (const obj of objs) { + const krs = await db.select().from(keyResults).where(eq(keyResults.objectiveId, obj.id)); + for (const kr of krs) { + await db.delete(krLogs).where(eq(krLogs.krId, kr.id)); + } + await db.delete(keyResults).where(eq(keyResults.objectiveId, obj.id)); + } + await db.delete(objectives).where(eq(objectives.projectId, id)); await db.delete(projects).where(eq(projects.id, id)); return c.json({ code: 0, data: null, message: 'success' }); }); diff --git a/backend/src/routes/projects.ts b/backend/src/routes/projects.ts index 4f456fb..6a164d7 100644 --- a/backend/src/routes/projects.ts +++ b/backend/src/routes/projects.ts @@ -76,6 +76,19 @@ projectRoutes.delete('/projects/:id', requireRole('admin'), async (c) => { const id = c.req.param('id'); + // 先清理关联数据(外键约束) + await db.delete(userProjectPermissions).where(eq(userProjectPermissions.projectId, id)); + await db.delete(projectRepos).where(eq(projectRepos.projectId, id)); + // 清理 OKR:KR logs → KR → Objectives + const objs = await db.select().from(objectives).where(eq(objectives.projectId, id)); + for (const obj of objs) { + const krs = await db.select().from(keyResults).where(eq(keyResults.objectiveId, obj.id)); + for (const kr of krs) { + await db.delete(krLogs).where(eq(krLogs.krId, kr.id)); + } + await db.delete(keyResults).where(eq(keyResults.objectiveId, obj.id)); + } + await db.delete(objectives).where(eq(objectives.projectId, id)); await db.delete(projects).where(eq(projects.id, id)); return c.json({ code: 0, data: null, message: 'success' }); }