import { eq } from "drizzle-orm"; import { assertProjectSettingsUpdateProjectCommand, createProjectSettingsUpdateProjectCommand, } from "../../domain/models/project-settings-project-command.model.js"; import type { ExecuteProjectSettingsUpdateCommandInput, ProjectSettingsProjectCommandStore, } from "../../domain/ports/project-settings-project-command.store.js"; import type { AppDatabase } from "../database-context.js"; import { projects } from "../schema/projects.js"; import { applyProjectHistoryTransition } from "./project-history.persistence.js"; import { appendProjectRevision } from "./project-revision.persistence.js"; export class ProjectSettingsProjectCommandRepository implements ProjectSettingsProjectCommandStore { constructor(private readonly database: AppDatabase) {} executeUpdate(input: ExecuteProjectSettingsUpdateCommandInput) { assertProjectSettingsUpdateProjectCommand(input.command); return this.database.transaction((tx) => { const current = tx .select() .from(projects) .where(eq(projects.id, input.projectId)) .get(); if (!current) { throw new Error("Project not found."); } if ( current.singlePhaseVoltageV === input.command.payload.singlePhaseVoltageV && current.threePhaseVoltageV === input.command.payload.threePhaseVoltageV ) { throw new Error("Project settings did not change."); } const inverse = createProjectSettingsUpdateProjectCommand({ singlePhaseVoltageV: current.singlePhaseVoltageV, threePhaseVoltageV: current.threePhaseVoltageV, }); const updated = tx .update(projects) .set(input.command.payload) .where(eq(projects.id, input.projectId)) .run(); if (updated.changes !== 1) { throw new Error("Project changed before settings update."); } const revision = appendProjectRevision(tx, { projectId: input.projectId, expectedRevision: input.expectedRevision, source: input.source, description: input.description, actorId: input.actorId, forward: input.command, inverse, }); applyProjectHistoryTransition(tx, { projectId: input.projectId, source: input.source, recordedChangeSetId: revision.changeSetId, targetChangeSetId: input.historyTargetChangeSetId, }); return { revision, inverse }; }); } }