/
ncit
/
c4panelmodel
Обзор
Документация
Войти
/
ncit
/
c4panelmodel
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
src/lib/server/services/draft.ts
126 строк
3 KB
ncit
feat: implement full IcePanel feature clone (Phases 1-8)
09 июн 2026, 11:13
09 июн 2026, 11:13
858c15a
Код
Авторство
О чём код?
import { db } from '$lib/server/db'; /** * Draft system: fork the current model into a draft, edit independently, * then review and merge back. */ export async function listDrafts(projectId: string) { return db.draft.findMany({ where: { projectId }, orderBy: { updatedAt: 'desc' } }); } export async function createDraft(projectId: string, name: string, description: string | null) { // Capture current model state as the draft's base. const [objects, connections] = await Promise.all([ db.modelObject.findMany({ where: { projectId } }), db.connection.findMany({ where: { projectId } }) ]); // Find the latest version as base. const latestVersion = await db.version.findFirst({ where: { projectId }, orderBy: { createdAt: 'desc' }, select: { id: true } }); const changes = { objects: objects.map((o) => ({ ...o, _action: 'unchanged' as const })), connections: connections.map((c) => ({ ...c, _action: 'unchanged' as const })), addedObjects: [] as any[], removedObjects: [] as string[], addedConnections: [] as any[], removedConnections: [] as string[] }; return db.draft.create({ data: { projectId, name, description, baseVersionId: latestVersion?.id ?? null, changes } }); } export async function getDraft(projectId: string, draftId: string) { return db.draft.findFirst({ where: { id: draftId, projectId } }); } export async function deleteDraft(projectId: string, draftId: string) { await db.draft.deleteMany({ where: { id: draftId, projectId } }); } /** * Update draft changes (add/remove/modify objects and connections). */ export async function updateDraftChanges(projectId: string, draftId: string, patch: Record<string, unknown>) { const draft = await getDraft(projectId, draftId); if (!draft) throw new Error('Draft not found'); const currentChanges = draft.changes as any; const updated = { ...currentChanges, ...patch }; return db.draft.update({ where: { id: draftId }, data: { changes: updated } }); } /** * Merge draft changes back into the main model. */ export async function mergeDraft(projectId: string, draftId: string) { const draft = await getDraft(projectId, draftId); if (!draft) throw new Error('Draft not found'); const changes = draft.changes as any; await db.$transaction(async (tx) => { // Remove objects marked for removal. for (const id of changes.removedObjects ?? []) { await tx.modelObject.deleteMany({ where: { id, projectId } }); } // Add new objects. for (const obj of changes.addedObjects ?? []) { await tx.modelObject.create({ data: { projectId, type: obj.type, name: obj.name, parentId: obj.parentId ?? null, displayDescription: obj.displayDescription ?? null, status: obj.status ?? 'LIVE', isExternal: obj.isExternal ?? false } }); } // Remove connections marked for removal. for (const id of changes.removedConnections ?? []) { await tx.connection.deleteMany({ where: { id, projectId } }); } // Add new connections. for (const conn of changes.addedConnections ?? []) { await tx.connection.create({ data: { projectId, sourceId: conn.sourceId, targetId: conn.targetId, label: conn.label ?? null, direction: conn.direction ?? 'OUTGOING', lineStyle: conn.lineStyle ?? 'SOLID', technology: conn.technology ?? null } }); } }); // Archive the draft after merge. await db.draft.update({ where: { id: draftId }, data: { description: `${draft.description ?? ''} (merged)` } }); }