leistungsbilanz-ts/src/domain/services/project-command.service.ts
Grovy311 37a70b6b36 Add the rough power balance module for early design phases
In LPH 2/3 there are no circuits yet, but the office needs a power
balance by DIN 276 cost group, as in the Excel template "Leistungsbilanz -
KG400": each trade enters consumers by piece or by area (W/m²) with GLF
and cos phi; the balance sums AV and SV per cost group, adds a reserve and
derives the maximum current.

The module is separate from the circuit structure: own tables
(migration 0010), own folder src/estimate-balance and an import-free
shared calculation used by API and UI. Writes go through project commands
(estimate-balance.insert/.update/.delete with complete documents), so
revision checks and Undo/Redo apply; it is not part of project snapshots
or transfer yet. A comparison endpoint sums the device rows of all circuit
lists by cost group (longest prefix) against the estimate.

The UI adds a sidebar entry, a list of Stände (template KG 400, empty or
copy) and a spreadsheet-like editor with autosave, AMEV picker for the
GLF, totals, reserve, maximum current, comparison table and print layout.
The tests reproduce the template example exactly (143.24 kW, 148.48 kVA,
157.56 kW / 163.33 kVA with 10 % reserve, 235.75 A). See
docs/estimate-balance.md and issue #7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 17:39:28 +02:00

709 lines
29 KiB
TypeScript

import { ProjectHistoryOperationUnavailableError } from "../errors/project-history-operation-unavailable.error.js";
import {
assertCircuitDeviceRowMoveProjectCommand,
assertCircuitDeviceRowMoveWithNewCircuitProjectCommand,
circuitDeviceRowMoveCommandType,
circuitDeviceRowMoveWithNewCircuitCommandType,
} from "../models/circuit-device-row-move-project-command.model.js";
import {
assertCircuitDeviceRowUpdateProjectCommand,
circuitDeviceRowUpdateCommandType,
} from "../models/circuit-device-row-project-command.model.js";
import {
assertCircuitDeviceRowDeleteProjectCommand,
assertCircuitDeviceRowInsertProjectCommand,
circuitDeviceRowDeleteCommandType,
circuitDeviceRowInsertCommandType,
} from "../models/circuit-device-row-structure-project-command.model.js";
import {
assertCircuitUpdateProjectCommand,
circuitUpdateCommandType,
} from "../models/circuit-project-command.model.js";
import {
assertCircuitProtectionUpdateProjectCommand,
circuitProtectionUpdateCommandType,
} from "../models/circuit-protection-project-command.model.js";
import {
assertCircuitSectionReorderProjectCommand,
circuitSectionReorderCommandType,
} from "../models/circuit-section-reorder-project-command.model.js";
import {
assertCircuitSectionsReorderProjectCommand,
circuitSectionsReorderCommandType,
} from "../models/circuit-sections-reorder-project-command.model.js";
import {
assertCircuitSectionRenumberProjectCommand,
circuitSectionRenumberCommandType,
} from "../models/circuit-section-renumber-project-command.model.js";
import {
assertCircuitDeleteProjectCommand,
assertCircuitInsertProjectCommand,
circuitDeleteCommandType,
circuitInsertCommandType,
} from "../models/circuit-structure-project-command.model.js";
import {
assertDistributionBoardUpdateProjectCommand,
distributionBoardUpdateCommandType,
} from "../models/distribution-board-project-command.model.js";
import {
assertDistributionBoardComponentDeleteProjectCommand,
assertDistributionBoardComponentInsertProjectCommand,
assertDistributionBoardComponentUpdateProjectCommand,
distributionBoardComponentDeleteCommandType,
distributionBoardComponentInsertCommandType,
distributionBoardComponentUpdateCommandType,
} from "../models/distribution-board-component-structure-project-command.model.js";
import {
assertDistributionBoardDeleteProjectCommand,
assertDistributionBoardInsertProjectCommand,
distributionBoardDeleteCommandType,
distributionBoardInsertCommandType,
} from "../models/distribution-board-structure-project-command.model.js";
import {
assertDistributionBoardDeleteSubtreeProjectCommand,
assertDistributionBoardInsertSubtreeProjectCommand,
distributionBoardDeleteSubtreeCommandType,
distributionBoardInsertSubtreeCommandType,
} from "../models/distribution-board-subtree-project-command.model.js";
import {
assertSerializedProjectCommand,
type SerializedProjectCommand,
} from "../models/project-command.model.js";
import {
assertProjectBuildingDeleteProjectCommand,
assertProjectBuildingInsertProjectCommand,
assertProjectBuildingUpdateProjectCommand,
assertProjectFloorDeleteProjectCommand,
assertProjectFloorInsertProjectCommand,
assertProjectFloorUpdateProjectCommand,
assertProjectRoomDeleteProjectCommand,
assertProjectRoomInsertProjectCommand,
assertProjectRoomUpdateProjectCommand,
projectBuildingDeleteCommandType,
projectBuildingInsertCommandType,
projectBuildingUpdateCommandType,
projectFloorDeleteCommandType,
projectFloorInsertCommandType,
projectFloorUpdateCommandType,
projectRoomDeleteCommandType,
projectRoomInsertCommandType,
projectRoomUpdateCommandType,
} from "../models/project-location-structure-project-command.model.js";
import {
assertProjectStateRestoreCommand,
projectStateRestoreCommandType,
} from "../models/project-state-restore-command.model.js";
import {
assertProjectSettingsUpdateProjectCommand,
projectSettingsUpdateCommandType,
} from "../models/project-settings-project-command.model.js";
import {
assertProjectDeviceRowSyncProjectCommand,
projectDeviceRowSyncCommandType,
} from "../models/project-device-row-sync-project-command.model.js";
import {
assertProjectDeviceUpdateProjectCommand,
projectDeviceUpdateCommandType,
} from "../models/project-device-project-command.model.js";
import {
assertProjectDeviceDeleteProjectCommand,
assertProjectDeviceInsertProjectCommand,
projectDeviceDeleteCommandType,
projectDeviceInsertCommandType,
} from "../models/project-device-structure-project-command.model.js";
import type { CircuitDeviceRowProjectCommandStore } from "../ports/circuit-device-row-project-command.store.js";
import type { CircuitDeviceRowMoveProjectCommandStore } from "../ports/circuit-device-row-move-project-command.store.js";
import type { CircuitDeviceRowStructureProjectCommandStore } from "../ports/circuit-device-row-structure-project-command.store.js";
import type { CircuitProjectCommandStore } from "../ports/circuit-project-command.store.js";
import type { CircuitProtectionProjectCommandStore } from "../ports/circuit-protection-project-command.store.js";
import type { CircuitSectionReorderProjectCommandStore } from "../ports/circuit-section-reorder-project-command.store.js";
import type { CircuitSectionRenumberProjectCommandStore } from "../ports/circuit-section-renumber-project-command.store.js";
import type { CircuitStructureProjectCommandStore } from "../ports/circuit-structure-project-command.store.js";
import type { CircuitGroupStructureProjectCommandStore } from "../ports/circuit-group-structure-project-command.store.js";
import type { CircuitGroupRenumberProjectCommandStore } from "../ports/circuit-group-renumber-project-command.store.js";
import type { CircuitGroupMoveProjectCommandStore } from "../ports/circuit-group-move-project-command.store.js";
import type { CircuitGroupSubtreeProjectCommandStore } from "../ports/circuit-group-subtree-project-command.store.js";
import type { DistributionBoardStructureProjectCommandStore } from "../ports/distribution-board-structure-project-command.store.js";
import type { DistributionBoardSubtreeProjectCommandStore } from "../ports/distribution-board-subtree-project-command.store.js";
import type { DistributionBoardComponentStructureProjectCommandStore } from "../ports/distribution-board-component-structure-project-command.store.js";
import type {
ExecuteProjectHistoryCommandInput,
ExecutedProjectCommand,
ExecuteUserProjectCommandInput,
ProjectCommandExecutor,
} from "../ports/project-command.executor.js";
import type {
ProjectHistoryDirection,
ProjectHistoryStore,
} from "../ports/project-history.store.js";
import {
assertCircuitGroupDeleteProjectCommand,
assertCircuitGroupInsertProjectCommand,
assertCircuitGroupReorderProjectCommand,
assertCircuitGroupUpdateProjectCommand,
circuitGroupDeleteCommandType,
circuitGroupInsertCommandType,
circuitGroupReorderCommandType,
circuitGroupUpdateCommandType,
} from "../models/circuit-group-structure-project-command.model.js";
import {
assertCircuitGroupRenumberProjectCommand,
circuitGroupRenumberCommandType,
} from "../models/circuit-group-renumber-project-command.model.js";
import {
assertCircuitGroupMoveProjectCommand,
circuitGroupMoveCommandType,
} from "../models/circuit-group-move-project-command.model.js";
import {
assertCircuitGroupDeleteSubtreeProjectCommand,
assertCircuitGroupRestoreSubtreeProjectCommand,
circuitGroupDeleteSubtreeCommandType,
circuitGroupRestoreSubtreeCommandType,
} from "../models/circuit-group-subtree-project-command.model.js";
import type { ProjectLocationStructureProjectCommandStore } from "../ports/project-location-structure-project-command.store.js";
import type { ProjectDeviceProjectCommandStore } from "../ports/project-device-project-command.store.js";
import type { ProjectDeviceRowSyncProjectCommandStore } from "../ports/project-device-row-sync-project-command.store.js";
import type { ProjectDeviceStructureProjectCommandStore } from "../ports/project-device-structure-project-command.store.js";
import type { ProjectRevisionSource } from "../ports/project-revision.store.js";
import type { ProjectSettingsProjectCommandStore } from "../ports/project-settings-project-command.store.js";
import type { ProjectStateRestoreCommandStore } from "../ports/project-state-restore-command.store.js";
import {
assertExternalCsvConfigurationUpdateProjectCommand,
externalCsvConfigurationUpdateCommandType,
} from "../models/external-csv-configuration-project-command.model.js";
import type { ExternalCsvConfigurationProjectCommandStore } from "../ports/external-csv-configuration-project-command.store.js";
import {
assertExternalInitialImportProjectCommand,
externalInitialImportCommandType,
} from "../models/external-initial-import-project-command.model.js";
import type { ExternalInitialImportProjectCommandStore } from "../ports/external-initial-import-project-command.store.js";
import {
assertExternalObjectRowAssignmentProjectCommand,
externalObjectRowAssignmentCommandType,
} from "../models/external-object-row-assignment-project-command.model.js";
import type { ExternalObjectRowAssignmentProjectCommandStore } from "../ports/external-object-row-assignment-project-command.store.js";
import {
assertExternalObjectNewRowProjectCommand,
externalObjectAssignToNewRowCommandType,
externalObjectDeleteCreatedRowCommandType,
} from "../models/external-object-new-row-project-command.model.js";
import type { ExternalObjectNewRowProjectCommandStore } from "../ports/external-object-new-row-project-command.store.js";
import {
assertExternalObjectNewCircuitProjectCommand,
externalObjectAssignToNewCircuitCommandType,
externalObjectDeleteCreatedCircuitCommandType,
} from "../models/external-object-new-circuit-project-command.model.js";
import type { ExternalObjectNewCircuitProjectCommandStore } from "../ports/external-object-new-circuit-project-command.store.js";
import {
assertEstimateBalanceDeleteProjectCommand,
assertEstimateBalanceInsertProjectCommand,
assertEstimateBalanceUpdateProjectCommand,
estimateBalanceDeleteCommandType,
estimateBalanceInsertCommandType,
estimateBalanceUpdateCommandType,
} from "../../estimate-balance/domain/estimate-balance-command.model.js";
import type { EstimateBalanceProjectCommandStore } from "../../estimate-balance/domain/estimate-balance-project-command.store.js";
interface DispatchProjectCommandInput {
projectId: string;
expectedRevision: number;
source: ProjectRevisionSource;
description?: string;
actorId?: string;
historyTargetChangeSetId?: string;
command: SerializedProjectCommand<unknown>;
}
export class ProjectCommandService implements ProjectCommandExecutor {
constructor(
private readonly circuitStore: CircuitProjectCommandStore,
private readonly deviceRowStore: CircuitDeviceRowProjectCommandStore,
private readonly deviceRowStructureStore: CircuitDeviceRowStructureProjectCommandStore,
private readonly deviceRowMoveStore: CircuitDeviceRowMoveProjectCommandStore,
private readonly circuitStructureStore: CircuitStructureProjectCommandStore,
private readonly distributionBoardStructureStore: DistributionBoardStructureProjectCommandStore,
private readonly distributionBoardSubtreeStore: DistributionBoardSubtreeProjectCommandStore,
private readonly projectLocationStructureStore: ProjectLocationStructureProjectCommandStore,
private readonly circuitSectionReorderStore: CircuitSectionReorderProjectCommandStore,
private readonly circuitSectionRenumberStore: CircuitSectionRenumberProjectCommandStore,
private readonly projectDeviceStructureStore: ProjectDeviceStructureProjectCommandStore,
private readonly projectDeviceStore: ProjectDeviceProjectCommandStore,
private readonly projectDeviceRowSyncStore: ProjectDeviceRowSyncProjectCommandStore,
private readonly projectSettingsStore: ProjectSettingsProjectCommandStore,
private readonly projectStateRestoreStore: ProjectStateRestoreCommandStore,
private readonly distributionBoardComponentStructureStore: DistributionBoardComponentStructureProjectCommandStore,
private readonly circuitGroupStructureStore: CircuitGroupStructureProjectCommandStore,
private readonly circuitGroupRenumberStore: CircuitGroupRenumberProjectCommandStore,
private readonly circuitGroupMoveStore: CircuitGroupMoveProjectCommandStore,
private readonly circuitGroupSubtreeStore: CircuitGroupSubtreeProjectCommandStore,
private readonly circuitProtectionStore: CircuitProtectionProjectCommandStore,
private readonly historyStore: ProjectHistoryStore,
private readonly externalCsvConfigurationStore?: ExternalCsvConfigurationProjectCommandStore,
private readonly externalInitialImportStore?: ExternalInitialImportProjectCommandStore,
private readonly externalObjectRowAssignmentStore?: ExternalObjectRowAssignmentProjectCommandStore,
private readonly externalObjectNewRowStore?: ExternalObjectNewRowProjectCommandStore,
private readonly externalObjectNewCircuitStore?: ExternalObjectNewCircuitProjectCommandStore,
private readonly estimateBalanceStore?: EstimateBalanceProjectCommandStore
) {}
executeUser(
input: ExecuteUserProjectCommandInput
): ExecutedProjectCommand {
assertExpectedRevision(input.expectedRevision);
assertSerializedProjectCommand(input.command);
if (input.command.type === projectStateRestoreCommandType) {
throw new Error(
"Project state restore commands require a stored server snapshot."
);
}
return this.dispatch({
...input,
source: "user",
command: input.command,
});
}
executeRestore(
input: ExecuteUserProjectCommandInput
): ExecutedProjectCommand {
assertExpectedRevision(input.expectedRevision);
assertProjectStateRestoreCommand(input.command);
return this.dispatch({
...input,
source: "restore",
command: input.command,
});
}
undo(
input: ExecuteProjectHistoryCommandInput
): ExecutedProjectCommand {
return this.executeHistory(input, "undo");
}
redo(
input: ExecuteProjectHistoryCommandInput
): ExecutedProjectCommand {
return this.executeHistory(input, "redo");
}
private executeHistory(
input: ExecuteProjectHistoryCommandInput,
direction: ProjectHistoryDirection
) {
assertExpectedRevision(input.expectedRevision);
const step = this.historyStore.getNextCommand(
input.projectId,
direction
);
if (!step) {
throw new ProjectHistoryOperationUnavailableError(
input.projectId,
direction
);
}
return this.dispatch({
...input,
source: direction,
description: `${direction === "undo" ? "Undo" : "Redo"} ${step.command.type}`,
historyTargetChangeSetId: step.changeSetId,
command: step.command,
});
}
private dispatch(
input: DispatchProjectCommandInput
): ExecutedProjectCommand {
const revision = this.executeTypedCommand(input);
const history = this.historyStore.getState(input.projectId);
if (!history) {
throw new Error("Project history disappeared after command execution.");
}
return { revision, history };
}
private executeTypedCommand(input: DispatchProjectCommandInput) {
switch (input.command.type) {
case circuitUpdateCommandType: {
assertCircuitUpdateProjectCommand(input.command);
return this.circuitStore.executeUpdate({
...input,
command: input.command,
}).revision;
}
case circuitDeviceRowUpdateCommandType: {
assertCircuitDeviceRowUpdateProjectCommand(input.command);
return this.deviceRowStore.executeUpdate({
...input,
command: input.command,
}).revision;
}
case circuitDeviceRowInsertCommandType: {
assertCircuitDeviceRowInsertProjectCommand(input.command);
return this.deviceRowStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitDeviceRowDeleteCommandType: {
assertCircuitDeviceRowDeleteProjectCommand(input.command);
return this.deviceRowStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitDeviceRowMoveCommandType: {
assertCircuitDeviceRowMoveProjectCommand(input.command);
return this.deviceRowMoveStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitDeviceRowMoveWithNewCircuitCommandType: {
assertCircuitDeviceRowMoveWithNewCircuitProjectCommand(
input.command
);
return this.deviceRowMoveStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitInsertCommandType: {
assertCircuitInsertProjectCommand(input.command);
return this.circuitStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitDeleteCommandType: {
assertCircuitDeleteProjectCommand(input.command);
return this.circuitStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case distributionBoardInsertCommandType: {
assertDistributionBoardInsertProjectCommand(input.command);
return this.distributionBoardStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case distributionBoardDeleteCommandType: {
assertDistributionBoardDeleteProjectCommand(input.command);
return this.distributionBoardStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case distributionBoardInsertSubtreeCommandType: {
assertDistributionBoardInsertSubtreeProjectCommand(input.command);
return this.distributionBoardSubtreeStore.execute({
...input,
command: input.command,
}).revision;
}
case distributionBoardDeleteSubtreeCommandType: {
assertDistributionBoardDeleteSubtreeProjectCommand(input.command);
return this.distributionBoardSubtreeStore.execute({
...input,
command: input.command,
}).revision;
}
case distributionBoardUpdateCommandType: {
assertDistributionBoardUpdateProjectCommand(input.command);
return this.distributionBoardStructureStore.executeUpdate({
...input,
command: input.command,
}).revision;
}
case distributionBoardComponentInsertCommandType: {
assertDistributionBoardComponentInsertProjectCommand(
input.command
);
return this.distributionBoardComponentStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case distributionBoardComponentDeleteCommandType: {
assertDistributionBoardComponentDeleteProjectCommand(
input.command
);
return this.distributionBoardComponentStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case distributionBoardComponentUpdateCommandType: {
assertDistributionBoardComponentUpdateProjectCommand(
input.command
);
return this.distributionBoardComponentStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitGroupInsertCommandType: {
assertCircuitGroupInsertProjectCommand(input.command);
return this.circuitGroupStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitGroupDeleteCommandType: {
assertCircuitGroupDeleteProjectCommand(input.command);
return this.circuitGroupStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitGroupUpdateCommandType: {
assertCircuitGroupUpdateProjectCommand(input.command);
return this.circuitGroupStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitGroupReorderCommandType: {
assertCircuitGroupReorderProjectCommand(input.command);
return this.circuitGroupStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitGroupRenumberCommandType: {
assertCircuitGroupRenumberProjectCommand(input.command);
return this.circuitGroupRenumberStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitGroupMoveCommandType: {
assertCircuitGroupMoveProjectCommand(input.command);
return this.circuitGroupMoveStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitGroupDeleteSubtreeCommandType: {
assertCircuitGroupDeleteSubtreeProjectCommand(input.command);
return this.circuitGroupSubtreeStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitGroupRestoreSubtreeCommandType: {
assertCircuitGroupRestoreSubtreeProjectCommand(input.command);
return this.circuitGroupSubtreeStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitProtectionUpdateCommandType: {
assertCircuitProtectionUpdateProjectCommand(input.command);
return this.circuitProtectionStore.execute({
...input,
command: input.command,
}).revision;
}
case projectBuildingInsertCommandType: {
assertProjectBuildingInsertProjectCommand(input.command);
return this.projectLocationStructureStore.execute({ ...input, command: input.command }).revision;
}
case projectBuildingDeleteCommandType: {
assertProjectBuildingDeleteProjectCommand(input.command);
return this.projectLocationStructureStore.execute({ ...input, command: input.command }).revision;
}
case projectBuildingUpdateCommandType: {
assertProjectBuildingUpdateProjectCommand(input.command);
return this.projectLocationStructureStore.execute({ ...input, command: input.command }).revision;
}
case projectFloorInsertCommandType: {
assertProjectFloorInsertProjectCommand(input.command);
return this.projectLocationStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case projectFloorDeleteCommandType: {
assertProjectFloorDeleteProjectCommand(input.command);
return this.projectLocationStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case projectFloorUpdateCommandType: {
assertProjectFloorUpdateProjectCommand(input.command);
return this.projectLocationStructureStore.execute({ ...input, command: input.command }).revision;
}
case projectRoomInsertCommandType: {
assertProjectRoomInsertProjectCommand(input.command);
return this.projectLocationStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case projectRoomDeleteCommandType: {
assertProjectRoomDeleteProjectCommand(input.command);
return this.projectLocationStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case projectRoomUpdateCommandType: {
assertProjectRoomUpdateProjectCommand(input.command);
return this.projectLocationStructureStore.execute({ ...input, command: input.command }).revision;
}
case circuitSectionReorderCommandType: {
assertCircuitSectionReorderProjectCommand(input.command);
return this.circuitSectionReorderStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitSectionsReorderCommandType: {
assertCircuitSectionsReorderProjectCommand(input.command);
return this.circuitSectionReorderStore.execute({
...input,
command: input.command,
}).revision;
}
case circuitSectionRenumberCommandType: {
assertCircuitSectionRenumberProjectCommand(input.command);
return this.circuitSectionRenumberStore.execute({
...input,
command: input.command,
}).revision;
}
case projectDeviceRowSyncCommandType: {
assertProjectDeviceRowSyncProjectCommand(input.command);
return this.projectDeviceRowSyncStore.execute({
...input,
command: input.command,
}).revision;
}
case projectDeviceUpdateCommandType: {
assertProjectDeviceUpdateProjectCommand(input.command);
return this.projectDeviceStore.executeUpdate({
...input,
command: input.command,
}).revision;
}
case projectDeviceInsertCommandType: {
assertProjectDeviceInsertProjectCommand(input.command);
return this.projectDeviceStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case projectDeviceDeleteCommandType: {
assertProjectDeviceDeleteProjectCommand(input.command);
return this.projectDeviceStructureStore.execute({
...input,
command: input.command,
}).revision;
}
case projectSettingsUpdateCommandType: {
assertProjectSettingsUpdateProjectCommand(input.command);
return this.projectSettingsStore.executeUpdate({
...input,
command: input.command,
}).revision;
}
case externalCsvConfigurationUpdateCommandType: {
assertExternalCsvConfigurationUpdateProjectCommand(input.command);
if (!this.externalCsvConfigurationStore) {
throw new Error("External CSV configuration store is not available.");
}
return this.externalCsvConfigurationStore.execute({
...input,
command: input.command,
}).revision;
}
case externalInitialImportCommandType: {
assertExternalInitialImportProjectCommand(input.command);
if (!this.externalInitialImportStore) {
throw new Error("External initial import store is not available.");
}
return this.externalInitialImportStore.execute({
...input,
command: input.command,
}).revision;
}
case externalObjectRowAssignmentCommandType: {
assertExternalObjectRowAssignmentProjectCommand(input.command);
if (!this.externalObjectRowAssignmentStore) {
throw new Error("External object row-assignment store is not available.");
}
return this.externalObjectRowAssignmentStore.execute({
...input,
command: input.command,
}).revision;
}
case externalObjectAssignToNewRowCommandType:
case externalObjectDeleteCreatedRowCommandType: {
assertExternalObjectNewRowProjectCommand(input.command);
if (!this.externalObjectNewRowStore) {
throw new Error("External object new-row store is not available.");
}
return this.externalObjectNewRowStore.execute({
...input,
command: input.command,
}).revision;
}
case externalObjectAssignToNewCircuitCommandType:
case externalObjectDeleteCreatedCircuitCommandType: {
assertExternalObjectNewCircuitProjectCommand(input.command);
if (!this.externalObjectNewCircuitStore) {
throw new Error("External object new-circuit store is not available.");
}
return this.externalObjectNewCircuitStore.execute({
...input,
command: input.command,
}).revision;
}
case estimateBalanceInsertCommandType:
case estimateBalanceDeleteCommandType:
case estimateBalanceUpdateCommandType: {
if (input.command.type === estimateBalanceInsertCommandType) {
assertEstimateBalanceInsertProjectCommand(input.command);
} else if (input.command.type === estimateBalanceDeleteCommandType) {
assertEstimateBalanceDeleteProjectCommand(input.command);
} else {
assertEstimateBalanceUpdateProjectCommand(input.command);
}
if (!this.estimateBalanceStore) {
throw new Error("Estimate-balance store is not available.");
}
return this.estimateBalanceStore.execute({
...input,
command: input.command,
}).revision;
}
case projectStateRestoreCommandType: {
assertProjectStateRestoreCommand(input.command);
return this.projectStateRestoreStore.execute({
...input,
command: input.command,
}).revision;
}
default:
throw new Error(
`Unsupported project command type: ${input.command.type}.`
);
}
}
}
function assertExpectedRevision(expectedRevision: number) {
if (
!Number.isSafeInteger(expectedRevision) ||
expectedRevision < 0
) {
throw new Error(
"Expected project revision must be a non-negative integer."
);
}
}