Add external model persistence foundation

This commit is contained in:
2026-08-02 17:18:24 +02:00
parent d0fc1a7caf
commit 76493b573e
15 changed files with 3207 additions and 8 deletions
@@ -0,0 +1,74 @@
import { asc, eq } from "drizzle-orm";
import type { ExternalModelStateReader } from "../../domain/ports/external-model-state.reader.js";
import type { ExternalModelStateSnapshot } from "../../external-model/domain/external-model-contracts.js";
import type { AppDatabase } from "../database-context.js";
import { externalImportBatches } from "../schema/external-import-batches.js";
import { externalModelObjects } from "../schema/external-model-objects.js";
import { externalModelSources } from "../schema/external-model-sources.js";
import { externalRoomMappings } from "../schema/external-room-mappings.js";
import { projects } from "../schema/projects.js";
const emptyState = (): ExternalModelStateSnapshot => ({
source: null,
importBatches: [],
roomMappings: [],
objects: [],
});
export class ExternalModelStateRepository implements ExternalModelStateReader {
constructor(private readonly database: AppDatabase) {}
getByProject(projectId: string) {
const project = this.database
.select({ id: projects.id })
.from(projects)
.where(eq(projects.id, projectId))
.get();
if (!project) return { projectExists: false, state: emptyState() };
const source = this.database
.select()
.from(externalModelSources)
.where(eq(externalModelSources.projectId, projectId))
.get() ?? null;
if (!source) return { projectExists: true, state: emptyState() };
const batches = this.database
.select()
.from(externalImportBatches)
.where(eq(externalImportBatches.sourceId, source.id))
.orderBy(
asc(externalImportBatches.appliedProjectRevision),
asc(externalImportBatches.id)
)
.all();
const roomMappings = this.database
.select()
.from(externalRoomMappings)
.where(eq(externalRoomMappings.sourceId, source.id))
.orderBy(
asc(externalRoomMappings.normalizedSourceRoomKey),
asc(externalRoomMappings.id)
)
.all();
const objects = this.database
.select()
.from(externalModelObjects)
.where(eq(externalModelObjects.sourceId, source.id))
.orderBy(asc(externalModelObjects.ifcGuid), asc(externalModelObjects.id))
.all();
return {
projectExists: true,
state: {
source,
importBatches: batches.map(({ originalBytes, ...batch }) => ({
...batch,
originalContentBase64: Buffer.from(originalBytes).toString("base64"),
})),
roomMappings,
objects,
},
};
}
}