task(F1): wcadlib export/import endpoints + fix gfolder/gblock id collisions

This commit is contained in:
Agent Zero
2026-08-28 12:19:44 +02:00
parent 1e7fb8bcd0
commit 5cbfe55d03
3 changed files with 165 additions and 2 deletions
+2 -2
View File
@@ -400,7 +400,7 @@ export class SqliteAdapter implements DatabaseInterface {
}
createGlobalFolder(data: Partial<DBGlobalBlockFolder>): DBGlobalBlockFolder {
const id = data.id ?? `gfolder-${Date.now()}`;
const id = data.id ?? `gfolder-${randomUUID().slice(0, 8)}`;
this.db.prepare(
'INSERT INTO global_block_folders (id, name, parent_id) VALUES (?, ?, ?)',
).run(id, data.name ?? 'Neuer Ordner', data.parent_id ?? null);
@@ -438,7 +438,7 @@ export class SqliteAdapter implements DatabaseInterface {
}
createGlobalBlock(data: Partial<DBGlobalBlock>): DBGlobalBlock {
const id = data.id ?? `gblock-${Date.now()}`;
const id = data.id ?? `gblock-${randomUUID().slice(0, 8)}`;
this.db.prepare(
'INSERT INTO global_blocks (id, folder_id, name, block_data, svg_data) VALUES (?, ?, ?, ?, ?)',
).run(id, data.folder_id ?? null, data.name ?? 'Global Block', data.block_data ?? '{}', data.svg_data ?? null);
+62
View File
@@ -164,4 +164,66 @@ export function registerGlobalBlockRoutes(fastify: FastifyInstance, db: Database
if (!ok) return reply.code(404).send({ error: 'Global block not found' });
return reply.code(204).send();
});
// ─── Task F1: Library-Paket Export/Import (.wcadlib) ──────
// Export: komplette Library als JSON-Paket (Ordner + Blöcke)
fastify.get('/api/global-blocks/export', async (request, reply) => {
if (!requireAuth(request, reply, authService)) return;
const folders = db.listGlobalFolders();
const blocks = db.listGlobalBlocks();
return {
format: 'wcadlib',
version: 1,
exported_at: new Date().toISOString(),
folders: folders.map((f) => ({ id: f.id, name: f.name, parent_id: f.parent_id })),
blocks: blocks.map((b) => ({
name: b.name,
folder_id: b.folder_id,
block_data: b.block_data,
svg_data: b.svg_data,
})),
};
});
// Import: .wcadlib-Paket einspielen (IDs neu, Ordner-Hierarchie über Mapping erhalten)
fastify.post('/api/global-blocks/import', async (request, reply) => {
if (!requireAuth(request, reply, authService)) return;
const pkg = request.body as {
format?: string;
folders?: Array<{ id: string; name: string; parent_id: string | null }>;
blocks?: Array<{ name: string; folder_id: string | null; block_data: string; svg_data: string | null }>;
};
if (!pkg || pkg.format !== 'wcadlib' || !Array.isArray(pkg.blocks)) {
return reply.code(400).send({ error: 'Invalid wcadlib package (format != wcadlib or blocks missing)' });
}
// Ordner mit ID-Mapping importieren:
const folderIdMap = new Map<string, string>();
const sortedFolders = [...(pkg.folders ?? [])].sort((a, b) => {
if (a.parent_id === b.parent_id) return 0;
if (a.parent_id === null) return -1;
if (b.parent_id === null) return 1;
return 0;
});
for (const f of sortedFolders) {
const newParent = f.parent_id ? folderIdMap.get(f.parent_id) ?? null : null;
const created = db.createGlobalFolder({ name: f.name, parent_id: newParent });
folderIdMap.set(f.id, created.id);
}
// Blöcke importieren:
let imported = 0;
for (const b of pkg.blocks) {
const newFolderId = b.folder_id ? folderIdMap.get(b.folder_id) ?? null : null;
db.createGlobalBlock({
name: b.name,
folder_id: newFolderId,
block_data: b.block_data,
svg_data: b.svg_data,
});
imported++;
}
return reply.code(201).send({ imported_blocks: imported, imported_folders: folderIdMap.size });
});
}