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, }, }; } }