Centralize structural command transactions
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import type { SerializedProjectCommand } from "../../domain/models/project-command.model.js";
|
||||
import type {
|
||||
AppendedProjectRevision,
|
||||
ProjectRevisionSource,
|
||||
} from "../../domain/ports/project-revision.store.js";
|
||||
import type { AppDatabase } from "../database-context.js";
|
||||
import { applyProjectHistoryTransition } from "./project-history.persistence.js";
|
||||
import { appendProjectRevision } from "./project-revision.persistence.js";
|
||||
|
||||
export interface ProjectCommandTransactionInput<
|
||||
Command extends SerializedProjectCommand<unknown>,
|
||||
> {
|
||||
projectId: string;
|
||||
expectedRevision: number;
|
||||
source: ProjectRevisionSource;
|
||||
description?: string;
|
||||
actorId?: string;
|
||||
historyTargetChangeSetId?: string;
|
||||
command: Command;
|
||||
}
|
||||
|
||||
export function executeProjectCommandTransaction<
|
||||
Command extends SerializedProjectCommand<unknown>,
|
||||
Inverse extends SerializedProjectCommand<unknown>,
|
||||
>(
|
||||
database: AppDatabase,
|
||||
input: ProjectCommandTransactionInput<Command>,
|
||||
applyCommand: (transaction: AppDatabase) => Inverse
|
||||
): { revision: AppendedProjectRevision; inverse: Inverse } {
|
||||
return database.transaction((tx) => {
|
||||
const inverse = applyCommand(tx);
|
||||
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 };
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user