Inject application database contexts
This commit is contained in:
@@ -30,6 +30,9 @@ It must support circuits, device rows, project devices, drag-and-drop restructur
|
|||||||
directly; do not reintroduce a standalone runtime revision repository.
|
directly; do not reintroduce a standalone runtime revision repository.
|
||||||
- Runtime domain services receive narrow reader/store dependencies explicitly;
|
- Runtime domain services receive narrow reader/store dependencies explicitly;
|
||||||
concrete SQLite repositories are instantiated only under `src/server/composition`.
|
concrete SQLite repositories are instantiated only under `src/server/composition`.
|
||||||
|
- General application repositories also require an explicit `AppDatabase`;
|
||||||
|
`src/server/composition/application-repositories.ts` owns their runtime
|
||||||
|
instances, and controllers never import the global SQLite client.
|
||||||
- The upgrade-only legacy migration service follows the same dependency rule;
|
- The upgrade-only legacy migration service follows the same dependency rule;
|
||||||
its concrete repositories are instantiated only in
|
its concrete repositories are instantiated only in
|
||||||
`scripts/db-migrate-legacy-consumers.ts`.
|
`scripts/db-migrate-legacy-consumers.ts`.
|
||||||
|
|||||||
@@ -102,6 +102,11 @@ Ein eigenständiges Runtime-Revisions-Repository existiert nicht.
|
|||||||
`ProjectDeviceSyncService` und `CircuitNumberingService` kennen nur schmale,
|
`ProjectDeviceSyncService` und `CircuitNumberingService` kennen nur schmale,
|
||||||
fachlich benannte Reader-Interfaces. Ihre SQLite-Repositories werden
|
fachlich benannte Reader-Interfaces. Ihre SQLite-Repositories werden
|
||||||
ausschließlich in `src/server/composition/` erzeugt und injiziert.
|
ausschließlich in `src/server/composition/` erzeugt und injiziert.
|
||||||
|
Auch die allgemeinen Projekt-, Geräte-, Raum-, Geschoss- und Circuit-
|
||||||
|
Repositories verlangen einen expliziten `AppDatabase`-Kontext. Ihre
|
||||||
|
Anwendungsinstanzen werden zentral in
|
||||||
|
`src/server/composition/application-repositories.ts` erzeugt; Controller
|
||||||
|
importieren weder den globalen SQLite-Client noch konkrete Repository-Klassen.
|
||||||
`circuit-device-row.insert` und `circuit-device-row.delete` sind atomare
|
`circuit-device-row.insert` und `circuit-device-row.delete` sind atomare
|
||||||
Strukturkommandos. Beim Löschen wird die vollständige Zeile im inversen
|
Strukturkommandos. Beim Löschen wird die vollständige Zeile im inversen
|
||||||
Kommando gesichert, sodass Undo dieselbe UUID und alle Fachwerte wiederherstellt.
|
Kommando gesichert, sodass Undo dieselbe UUID und alle Fachwerte wiederherstellt.
|
||||||
|
|||||||
@@ -355,6 +355,9 @@ Implemented foundation:
|
|||||||
standalone runtime revision repository and store interface are removed
|
standalone runtime revision repository and store interface are removed
|
||||||
- runtime project-device synchronization and circuit-numbering services depend
|
- runtime project-device synchronization and circuit-numbering services depend
|
||||||
on narrow domain readers; server composition injects the SQLite repositories
|
on narrow domain readers; server composition injects the SQLite repositories
|
||||||
|
- all general application repositories require an explicit database context;
|
||||||
|
server composition owns their runtime instances and controllers contain no
|
||||||
|
direct global SQLite access
|
||||||
- the legacy consumer UI and application read/write endpoints are removed after verified data cutover
|
- the legacy consumer UI and application read/write endpoints are removed after verified data cutover
|
||||||
- retained legacy rows are accessible only through explicit database upgrade tooling
|
- retained legacy rows are accessible only through explicit database upgrade tooling
|
||||||
- project devices no longer persist duplicate legacy power, phase, cosPhi or remark fields
|
- project devices no longer persist duplicate legacy power, phase, cosPhi or remark fields
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
|
import { db } from "../src/db/client.js";
|
||||||
import { CircuitListRepository } from "../src/db/repositories/circuit-list.repository.js";
|
import { CircuitListRepository } from "../src/db/repositories/circuit-list.repository.js";
|
||||||
import { CircuitSectionRepository } from "../src/db/repositories/circuit-section.repository.js";
|
import { CircuitSectionRepository } from "../src/db/repositories/circuit-section.repository.js";
|
||||||
import { ProjectRepository } from "../src/db/repositories/project.repository.js";
|
import { ProjectRepository } from "../src/db/repositories/project.repository.js";
|
||||||
|
|
||||||
const projectRepository = new ProjectRepository();
|
const projectRepository = new ProjectRepository(db);
|
||||||
const circuitListRepository = new CircuitListRepository();
|
const circuitListRepository = new CircuitListRepository(db);
|
||||||
const circuitSectionRepository = new CircuitSectionRepository();
|
const circuitSectionRepository = new CircuitSectionRepository(db);
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
const projects = await projectRepository.list();
|
const projects = await projectRepository.list();
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ import { ProjectRepository } from "../src/db/repositories/project.repository.js"
|
|||||||
import { RoomRepository } from "../src/db/repositories/room.repository.js";
|
import { RoomRepository } from "../src/db/repositories/room.repository.js";
|
||||||
import { LegacyConsumerMigrationService } from "../src/domain/services/legacy-consumer-migration.service.js";
|
import { LegacyConsumerMigrationService } from "../src/domain/services/legacy-consumer-migration.service.js";
|
||||||
|
|
||||||
const projectRepository = new ProjectRepository();
|
const projectRepository = new ProjectRepository(db);
|
||||||
const circuitListRepository = new CircuitListRepository();
|
const circuitListRepository = new CircuitListRepository(db);
|
||||||
const migrationRepository = new LegacyConsumerMigrationRepository(db);
|
const migrationRepository = new LegacyConsumerMigrationRepository(db);
|
||||||
const migrationService = new LegacyConsumerMigrationService({
|
const migrationService = new LegacyConsumerMigrationService({
|
||||||
circuitListReader: circuitListRepository,
|
circuitListReader: circuitListRepository,
|
||||||
sectionStore: new CircuitSectionRepository(),
|
sectionStore: new CircuitSectionRepository(db),
|
||||||
circuitReader: new CircuitRepository(),
|
circuitReader: new CircuitRepository(db),
|
||||||
roomReader: new RoomRepository(),
|
roomReader: new RoomRepository(db),
|
||||||
migrationStore: migrationRepository,
|
migrationStore: migrationRepository,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import { and, asc, eq, inArray } from "drizzle-orm";
|
import { and, asc, eq, inArray } from "drizzle-orm";
|
||||||
import { db } from "../client.js";
|
import type { AppDatabase } from "../database-context.js";
|
||||||
import { circuitDeviceRows } from "../schema/circuit-device-rows.js";
|
import { circuitDeviceRows } from "../schema/circuit-device-rows.js";
|
||||||
import { circuitLists } from "../schema/circuit-lists.js";
|
import { circuitLists } from "../schema/circuit-lists.js";
|
||||||
import { circuits } from "../schema/circuits.js";
|
import { circuits } from "../schema/circuits.js";
|
||||||
import { distributionBoards } from "../schema/distribution-boards.js";
|
import { distributionBoards } from "../schema/distribution-boards.js";
|
||||||
|
|
||||||
export class CircuitDeviceRowRepository {
|
export class CircuitDeviceRowRepository {
|
||||||
|
constructor(private readonly database: AppDatabase) {}
|
||||||
|
|
||||||
async listByCircuitList(circuitIds: string[]) {
|
async listByCircuitList(circuitIds: string[]) {
|
||||||
if (!circuitIds.length) {
|
if (!circuitIds.length) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return db
|
return this.database
|
||||||
.select()
|
.select()
|
||||||
.from(circuitDeviceRows)
|
.from(circuitDeviceRows)
|
||||||
.where(inArray(circuitDeviceRows.circuitId, circuitIds))
|
.where(inArray(circuitDeviceRows.circuitId, circuitIds))
|
||||||
@@ -18,7 +20,7 @@ export class CircuitDeviceRowRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async listLinkedByProjectDevice(projectId: string, projectDeviceId: string) {
|
async listLinkedByProjectDevice(projectId: string, projectDeviceId: string) {
|
||||||
return db
|
return this.database
|
||||||
.select({
|
.select({
|
||||||
id: circuitDeviceRows.id,
|
id: circuitDeviceRows.id,
|
||||||
circuitId: circuitDeviceRows.circuitId,
|
circuitId: circuitDeviceRows.circuitId,
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
import { and, eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import { db } from "../client.js";
|
import type { AppDatabase } from "../database-context.js";
|
||||||
import { circuitLists } from "../schema/circuit-lists.js";
|
import { circuitLists } from "../schema/circuit-lists.js";
|
||||||
|
|
||||||
export class CircuitListRepository {
|
export class CircuitListRepository {
|
||||||
|
constructor(private readonly database: AppDatabase) {}
|
||||||
|
|
||||||
async listByProject(projectId: string) {
|
async listByProject(projectId: string) {
|
||||||
|
const db = this.database;
|
||||||
return db.select().from(circuitLists).where(eq(circuitLists.projectId, projectId));
|
return db.select().from(circuitLists).where(eq(circuitLists.projectId, projectId));
|
||||||
}
|
}
|
||||||
|
|
||||||
async findById(projectId: string, circuitListId: string) {
|
async findById(projectId: string, circuitListId: string) {
|
||||||
|
const db = this.database;
|
||||||
const [row] = await db
|
const [row] = await db
|
||||||
.select()
|
.select()
|
||||||
.from(circuitLists)
|
.from(circuitLists)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import crypto from "node:crypto";
|
import crypto from "node:crypto";
|
||||||
import { and, asc, eq } from "drizzle-orm";
|
import { and, asc, eq } from "drizzle-orm";
|
||||||
import { defaultCircuitSectionDefinitions } from "../../domain/models/distribution-board-structure-project-command.model.js";
|
import { defaultCircuitSectionDefinitions } from "../../domain/models/distribution-board-structure-project-command.model.js";
|
||||||
import { db } from "../client.js";
|
import type { AppDatabase } from "../database-context.js";
|
||||||
import { circuitSections } from "../schema/circuit-sections.js";
|
import { circuitSections } from "../schema/circuit-sections.js";
|
||||||
|
|
||||||
export function createDefaultCircuitSectionValues(circuitListId: string) {
|
export function createDefaultCircuitSectionValues(circuitListId: string) {
|
||||||
@@ -13,12 +13,16 @@ export function createDefaultCircuitSectionValues(circuitListId: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class CircuitSectionRepository {
|
export class CircuitSectionRepository {
|
||||||
|
constructor(private readonly database: AppDatabase) {}
|
||||||
|
|
||||||
async findById(sectionId: string) {
|
async findById(sectionId: string) {
|
||||||
|
const db = this.database;
|
||||||
const [row] = await db.select().from(circuitSections).where(eq(circuitSections.id, sectionId)).limit(1);
|
const [row] = await db.select().from(circuitSections).where(eq(circuitSections.id, sectionId)).limit(1);
|
||||||
return row ?? null;
|
return row ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async listByCircuitList(circuitListId: string) {
|
async listByCircuitList(circuitListId: string) {
|
||||||
|
const db = this.database;
|
||||||
return db
|
return db
|
||||||
.select()
|
.select()
|
||||||
.from(circuitSections)
|
.from(circuitSections)
|
||||||
@@ -27,6 +31,7 @@ export class CircuitSectionRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async createDefaults(circuitListId: string) {
|
async createDefaults(circuitListId: string) {
|
||||||
|
const db = this.database;
|
||||||
for (const entry of createDefaultCircuitSectionValues(circuitListId)) {
|
for (const entry of createDefaultCircuitSectionValues(circuitListId)) {
|
||||||
const existing = await db
|
const existing = await db
|
||||||
.select({ id: circuitSections.id })
|
.select({ id: circuitSections.id })
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import { asc, eq } from "drizzle-orm";
|
import { asc, eq } from "drizzle-orm";
|
||||||
import { db } from "../client.js";
|
import type { AppDatabase } from "../database-context.js";
|
||||||
import { circuits } from "../schema/circuits.js";
|
import { circuits } from "../schema/circuits.js";
|
||||||
|
|
||||||
export class CircuitRepository {
|
export class CircuitRepository {
|
||||||
|
constructor(private readonly database: AppDatabase) {}
|
||||||
|
|
||||||
async listByCircuitList(circuitListId: string) {
|
async listByCircuitList(circuitListId: string) {
|
||||||
|
const db = this.database;
|
||||||
return db
|
return db
|
||||||
.select()
|
.select()
|
||||||
.from(circuits)
|
.from(circuits)
|
||||||
@@ -12,6 +15,7 @@ export class CircuitRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async listBySection(sectionId: string) {
|
async listBySection(sectionId: string) {
|
||||||
|
const db = this.database;
|
||||||
return db
|
return db
|
||||||
.select()
|
.select()
|
||||||
.from(circuits)
|
.from(circuits)
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import { asc, eq } from "drizzle-orm";
|
import { asc, eq } from "drizzle-orm";
|
||||||
import { db } from "../client.js";
|
import type { AppDatabase } from "../database-context.js";
|
||||||
import { floors } from "../schema/floors.js";
|
import { floors } from "../schema/floors.js";
|
||||||
|
|
||||||
export class FloorRepository {
|
export class FloorRepository {
|
||||||
|
constructor(private readonly database: AppDatabase) {}
|
||||||
|
|
||||||
async listByProject(projectId: string) {
|
async listByProject(projectId: string) {
|
||||||
|
const db = this.database;
|
||||||
return db
|
return db
|
||||||
.select()
|
.select()
|
||||||
.from(floors)
|
.from(floors)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import crypto from "node:crypto";
|
import crypto from "node:crypto";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import { db } from "../client.js";
|
import type { AppDatabase } from "../database-context.js";
|
||||||
import { globalDevices } from "../schema/global-devices.js";
|
import { globalDevices } from "../schema/global-devices.js";
|
||||||
import type {
|
import type {
|
||||||
CreateGlobalDeviceInput,
|
CreateGlobalDeviceInput,
|
||||||
@@ -8,11 +8,15 @@ import type {
|
|||||||
} from "../../shared/validation/global-device.schemas.js";
|
} from "../../shared/validation/global-device.schemas.js";
|
||||||
|
|
||||||
export class GlobalDeviceRepository {
|
export class GlobalDeviceRepository {
|
||||||
|
constructor(private readonly database: AppDatabase) {}
|
||||||
|
|
||||||
async list() {
|
async list() {
|
||||||
|
const db = this.database;
|
||||||
return db.select().from(globalDevices);
|
return db.select().from(globalDevices);
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(input: CreateGlobalDeviceInput) {
|
async create(input: CreateGlobalDeviceInput) {
|
||||||
|
const db = this.database;
|
||||||
const id = crypto.randomUUID();
|
const id = crypto.randomUUID();
|
||||||
await db.insert(globalDevices).values({
|
await db.insert(globalDevices).values({
|
||||||
id,
|
id,
|
||||||
@@ -31,6 +35,7 @@ export class GlobalDeviceRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async update(globalDeviceId: string, input: UpdateGlobalDeviceInput) {
|
async update(globalDeviceId: string, input: UpdateGlobalDeviceInput) {
|
||||||
|
const db = this.database;
|
||||||
await db
|
await db
|
||||||
.update(globalDevices)
|
.update(globalDevices)
|
||||||
.set({
|
.set({
|
||||||
@@ -49,11 +54,13 @@ export class GlobalDeviceRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findById(globalDeviceId: string) {
|
async findById(globalDeviceId: string) {
|
||||||
|
const db = this.database;
|
||||||
const [row] = await db.select().from(globalDevices).where(eq(globalDevices.id, globalDeviceId)).limit(1);
|
const [row] = await db.select().from(globalDevices).where(eq(globalDevices.id, globalDeviceId)).limit(1);
|
||||||
return row ?? null;
|
return row ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(globalDeviceId: string) {
|
async delete(globalDeviceId: string) {
|
||||||
|
const db = this.database;
|
||||||
await db.delete(globalDevices).where(eq(globalDevices.id, globalDeviceId));
|
await db.delete(globalDevices).where(eq(globalDevices.id, globalDeviceId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { and, eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import { db } from "../client.js";
|
import type { AppDatabase } from "../database-context.js";
|
||||||
import { projectDevices } from "../schema/project-devices.js";
|
import { projectDevices } from "../schema/project-devices.js";
|
||||||
import { calculateRowTotalPower } from "../../domain/calculations/circuit-power-calculation.js";
|
import { calculateRowTotalPower } from "../../domain/calculations/circuit-power-calculation.js";
|
||||||
|
|
||||||
@@ -11,12 +11,16 @@ function withTotalPower(row: typeof projectDevices.$inferSelect) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ProjectDeviceRepository {
|
export class ProjectDeviceRepository {
|
||||||
|
constructor(private readonly database: AppDatabase) {}
|
||||||
|
|
||||||
async listByProject(projectId: string) {
|
async listByProject(projectId: string) {
|
||||||
|
const db = this.database;
|
||||||
const rows = await db.select().from(projectDevices).where(eq(projectDevices.projectId, projectId));
|
const rows = await db.select().from(projectDevices).where(eq(projectDevices.projectId, projectId));
|
||||||
return rows.map(withTotalPower);
|
return rows.map(withTotalPower);
|
||||||
}
|
}
|
||||||
|
|
||||||
async findById(projectId: string, projectDeviceId: string) {
|
async findById(projectId: string, projectDeviceId: string) {
|
||||||
|
const db = this.database;
|
||||||
const [row] = await db
|
const [row] = await db
|
||||||
.select()
|
.select()
|
||||||
.from(projectDevices)
|
.from(projectDevices)
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
import crypto from "node:crypto";
|
import crypto from "node:crypto";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import { db } from "../client.js";
|
import type { AppDatabase } from "../database-context.js";
|
||||||
import { projects } from "../schema/projects.js";
|
import { projects } from "../schema/projects.js";
|
||||||
import type {
|
import type {
|
||||||
CreateProjectInput,
|
CreateProjectInput,
|
||||||
} from "../../shared/validation/project-structure.schemas.js";
|
} from "../../shared/validation/project-structure.schemas.js";
|
||||||
|
|
||||||
export class ProjectRepository {
|
export class ProjectRepository {
|
||||||
|
constructor(private readonly database: AppDatabase) {}
|
||||||
|
|
||||||
async list() {
|
async list() {
|
||||||
|
const db = this.database;
|
||||||
return db.select().from(projects);
|
return db.select().from(projects);
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(input: CreateProjectInput) {
|
async create(input: CreateProjectInput) {
|
||||||
|
const db = this.database;
|
||||||
const id = crypto.randomUUID();
|
const id = crypto.randomUUID();
|
||||||
const project = {
|
const project = {
|
||||||
id,
|
id,
|
||||||
@@ -25,6 +29,7 @@ export class ProjectRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findById(projectId: string) {
|
async findById(projectId: string) {
|
||||||
|
const db = this.database;
|
||||||
const [row] = await db.select().from(projects).where(eq(projects.id, projectId)).limit(1);
|
const [row] = await db.select().from(projects).where(eq(projects.id, projectId)).limit(1);
|
||||||
return row ?? null;
|
return row ?? null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import { asc, eq } from "drizzle-orm";
|
import { asc, eq } from "drizzle-orm";
|
||||||
import { db } from "../client.js";
|
import type { AppDatabase } from "../database-context.js";
|
||||||
import { rooms } from "../schema/rooms.js";
|
import { rooms } from "../schema/rooms.js";
|
||||||
|
|
||||||
export class RoomRepository {
|
export class RoomRepository {
|
||||||
|
constructor(private readonly database: AppDatabase) {}
|
||||||
|
|
||||||
async listByProject(projectId: string) {
|
async listByProject(projectId: string) {
|
||||||
|
const db = this.database;
|
||||||
return db
|
return db
|
||||||
.select()
|
.select()
|
||||||
.from(rooms)
|
.from(rooms)
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { db } from "../../db/client.js";
|
||||||
|
import { CircuitDeviceRowRepository } from "../../db/repositories/circuit-device-row.repository.js";
|
||||||
|
import { CircuitListRepository } from "../../db/repositories/circuit-list.repository.js";
|
||||||
|
import { CircuitSectionRepository } from "../../db/repositories/circuit-section.repository.js";
|
||||||
|
import { CircuitRepository } from "../../db/repositories/circuit.repository.js";
|
||||||
|
import { DistributionBoardRepository } from "../../db/repositories/distribution-board.repository.js";
|
||||||
|
import { FloorRepository } from "../../db/repositories/floor.repository.js";
|
||||||
|
import { GlobalDeviceRepository } from "../../db/repositories/global-device.repository.js";
|
||||||
|
import { ProjectDeviceRepository } from "../../db/repositories/project-device.repository.js";
|
||||||
|
import { ProjectRepository } from "../../db/repositories/project.repository.js";
|
||||||
|
import { RoomRepository } from "../../db/repositories/room.repository.js";
|
||||||
|
|
||||||
|
export const circuitDeviceRowRepository =
|
||||||
|
new CircuitDeviceRowRepository(db);
|
||||||
|
export const circuitListRepository = new CircuitListRepository(db);
|
||||||
|
export const circuitSectionRepository = new CircuitSectionRepository(db);
|
||||||
|
export const circuitRepository = new CircuitRepository(db);
|
||||||
|
export const distributionBoardRepository =
|
||||||
|
new DistributionBoardRepository(db);
|
||||||
|
export const floorRepository = new FloorRepository(db);
|
||||||
|
export const globalDeviceRepository = new GlobalDeviceRepository(db);
|
||||||
|
export const projectDeviceRepository = new ProjectDeviceRepository(db);
|
||||||
|
export const projectRepository = new ProjectRepository(db);
|
||||||
|
export const roomRepository = new RoomRepository(db);
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
import { CircuitRepository } from "../../db/repositories/circuit.repository.js";
|
|
||||||
import { CircuitSectionRepository } from "../../db/repositories/circuit-section.repository.js";
|
|
||||||
import { CircuitNumberingService } from "../../domain/services/circuit-numbering.service.js";
|
import { CircuitNumberingService } from "../../domain/services/circuit-numbering.service.js";
|
||||||
|
import {
|
||||||
|
circuitRepository,
|
||||||
|
circuitSectionRepository,
|
||||||
|
} from "./application-repositories.js";
|
||||||
|
|
||||||
export const circuitNumberingService = new CircuitNumberingService({
|
export const circuitNumberingService = new CircuitNumberingService({
|
||||||
sectionRepository: new CircuitSectionRepository(),
|
sectionRepository: circuitSectionRepository,
|
||||||
circuitRepository: new CircuitRepository(),
|
circuitRepository,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { CircuitDeviceRowRepository } from "../../db/repositories/circuit-device-row.repository.js";
|
|
||||||
import { ProjectDeviceRepository } from "../../db/repositories/project-device.repository.js";
|
|
||||||
import { ProjectDeviceSyncService } from "../../domain/services/project-device-sync.service.js";
|
import { ProjectDeviceSyncService } from "../../domain/services/project-device-sync.service.js";
|
||||||
|
import {
|
||||||
|
circuitDeviceRowRepository,
|
||||||
|
projectDeviceRepository,
|
||||||
|
} from "./application-repositories.js";
|
||||||
|
|
||||||
export const projectDeviceSyncService = new ProjectDeviceSyncService({
|
export const projectDeviceSyncService = new ProjectDeviceSyncService({
|
||||||
projectDeviceRepository: new ProjectDeviceRepository(),
|
projectDeviceRepository,
|
||||||
deviceRowRepository: new CircuitDeviceRowRepository(),
|
deviceRowRepository: circuitDeviceRowRepository,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { CircuitListRepository } from "../../db/repositories/circuit-list.repository.js";
|
import { circuitListRepository } from "../composition/application-repositories.js";
|
||||||
|
|
||||||
const circuitListRepository = new CircuitListRepository();
|
|
||||||
|
|
||||||
export async function listCircuitListsByProject(req: Request, res: Response) {
|
export async function listCircuitListsByProject(req: Request, res: Response) {
|
||||||
const { projectId } = req.params;
|
const { projectId } = req.params;
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { CircuitRepository } from "../../db/repositories/circuit.repository.js";
|
|
||||||
import { CircuitDeviceRowRepository } from "../../db/repositories/circuit-device-row.repository.js";
|
|
||||||
import { CircuitListRepository } from "../../db/repositories/circuit-list.repository.js";
|
|
||||||
import { CircuitSectionRepository } from "../../db/repositories/circuit-section.repository.js";
|
|
||||||
import { ProjectRepository } from "../../db/repositories/project.repository.js";
|
|
||||||
import {
|
import {
|
||||||
calculateCircuitTotalPower,
|
calculateCircuitTotalPower,
|
||||||
calculateRowTotalPower,
|
calculateRowTotalPower,
|
||||||
} from "../../domain/calculations/circuit-power-calculation.js";
|
} from "../../domain/calculations/circuit-power-calculation.js";
|
||||||
import type { CircuitTreeResponse } from "../../domain/models/circuit-tree.model.js";
|
import type { CircuitTreeResponse } from "../../domain/models/circuit-tree.model.js";
|
||||||
|
import {
|
||||||
const circuitListRepository = new CircuitListRepository();
|
circuitDeviceRowRepository,
|
||||||
const circuitSectionRepository = new CircuitSectionRepository();
|
circuitListRepository,
|
||||||
const circuitRepository = new CircuitRepository();
|
circuitRepository,
|
||||||
const circuitDeviceRowRepository = new CircuitDeviceRowRepository();
|
circuitSectionRepository,
|
||||||
const projectRepository = new ProjectRepository();
|
projectRepository,
|
||||||
|
} from "../composition/application-repositories.js";
|
||||||
|
|
||||||
export function isMissingCircuitTreeSchemaError(error: unknown): boolean {
|
export function isMissingCircuitTreeSchemaError(error: unknown): boolean {
|
||||||
if (!(error instanceof Error)) {
|
if (!(error instanceof Error)) {
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { db } from "../../db/client.js";
|
|
||||||
import { DistributionBoardRepository } from "../../db/repositories/distribution-board.repository.js";
|
|
||||||
import {
|
import {
|
||||||
createDistributionBoardInsertProjectCommand,
|
createDistributionBoardInsertProjectCommand,
|
||||||
createDistributionBoardStructureSnapshot,
|
createDistributionBoardStructureSnapshot,
|
||||||
} from "../../domain/models/distribution-board-structure-project-command.model.js";
|
} from "../../domain/models/distribution-board-structure-project-command.model.js";
|
||||||
import { createDistributionBoardSchema } from "../../shared/validation/project-structure.schemas.js";
|
import { createDistributionBoardSchema } from "../../shared/validation/project-structure.schemas.js";
|
||||||
import { projectCommandService } from "../composition/project-command-stores.js";
|
import { projectCommandService } from "../composition/project-command-stores.js";
|
||||||
|
import { distributionBoardRepository } from "../composition/application-repositories.js";
|
||||||
import { respondWithProjectCommandError } from "./project-command.controller.js";
|
import { respondWithProjectCommandError } from "./project-command.controller.js";
|
||||||
|
|
||||||
const distributionBoardRepository = new DistributionBoardRepository(db);
|
|
||||||
|
|
||||||
export async function listDistributionBoardsByProject(req: Request, res: Response) {
|
export async function listDistributionBoardsByProject(req: Request, res: Response) {
|
||||||
const { projectId } = req.params;
|
const { projectId } = req.params;
|
||||||
if (typeof projectId !== "string") {
|
if (typeof projectId !== "string") {
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { FloorRepository } from "../../db/repositories/floor.repository.js";
|
|
||||||
import {
|
import {
|
||||||
createProjectFloorInsertProjectCommand,
|
createProjectFloorInsertProjectCommand,
|
||||||
createProjectFloorSnapshot,
|
createProjectFloorSnapshot,
|
||||||
} from "../../domain/models/project-location-structure-project-command.model.js";
|
} from "../../domain/models/project-location-structure-project-command.model.js";
|
||||||
import { createFloorSchema } from "../../shared/validation/project-structure.schemas.js";
|
import { createFloorSchema } from "../../shared/validation/project-structure.schemas.js";
|
||||||
import { projectCommandService } from "../composition/project-command-stores.js";
|
import { projectCommandService } from "../composition/project-command-stores.js";
|
||||||
|
import { floorRepository } from "../composition/application-repositories.js";
|
||||||
import { respondWithProjectCommandError } from "./project-command.controller.js";
|
import { respondWithProjectCommandError } from "./project-command.controller.js";
|
||||||
|
|
||||||
const floorRepository = new FloorRepository();
|
|
||||||
|
|
||||||
export async function listFloorsByProject(req: Request, res: Response) {
|
export async function listFloorsByProject(req: Request, res: Response) {
|
||||||
const { projectId } = req.params;
|
const { projectId } = req.params;
|
||||||
if (typeof projectId !== "string") {
|
if (typeof projectId !== "string") {
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { GlobalDeviceRepository } from "../../db/repositories/global-device.repository.js";
|
|
||||||
import { ProjectDeviceRepository } from "../../db/repositories/project-device.repository.js";
|
|
||||||
import {
|
import {
|
||||||
createGlobalDeviceSchema,
|
createGlobalDeviceSchema,
|
||||||
updateGlobalDeviceSchema,
|
updateGlobalDeviceSchema,
|
||||||
} from "../../shared/validation/global-device.schemas.js";
|
} from "../../shared/validation/global-device.schemas.js";
|
||||||
|
import {
|
||||||
const globalDeviceRepository = new GlobalDeviceRepository();
|
globalDeviceRepository,
|
||||||
const projectDeviceRepository = new ProjectDeviceRepository();
|
projectDeviceRepository,
|
||||||
|
} from "../composition/application-repositories.js";
|
||||||
|
|
||||||
export async function listGlobalDevices(_req: Request, res: Response) {
|
export async function listGlobalDevices(_req: Request, res: Response) {
|
||||||
const rows = await globalDeviceRepository.list();
|
const rows = await globalDeviceRepository.list();
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { randomUUID } from "node:crypto";
|
import { randomUUID } from "node:crypto";
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { GlobalDeviceRepository } from "../../db/repositories/global-device.repository.js";
|
|
||||||
import { ProjectDeviceRepository } from "../../db/repositories/project-device.repository.js";
|
|
||||||
import { createProjectDeviceUpdateProjectCommand } from "../../domain/models/project-device-project-command.model.js";
|
import { createProjectDeviceUpdateProjectCommand } from "../../domain/models/project-device-project-command.model.js";
|
||||||
import {
|
import {
|
||||||
createProjectDeviceDeleteProjectCommand,
|
createProjectDeviceDeleteProjectCommand,
|
||||||
@@ -10,6 +8,10 @@ import {
|
|||||||
} from "../../domain/models/project-device-structure-project-command.model.js";
|
} from "../../domain/models/project-device-structure-project-command.model.js";
|
||||||
import { projectDeviceSyncService } from "../composition/project-device-sync-service.js";
|
import { projectDeviceSyncService } from "../composition/project-device-sync-service.js";
|
||||||
import { projectCommandService } from "../composition/project-command-stores.js";
|
import { projectCommandService } from "../composition/project-command-stores.js";
|
||||||
|
import {
|
||||||
|
globalDeviceRepository,
|
||||||
|
projectDeviceRepository,
|
||||||
|
} from "../composition/application-repositories.js";
|
||||||
import {
|
import {
|
||||||
createProjectDeviceCommandSchema,
|
createProjectDeviceCommandSchema,
|
||||||
disconnectProjectDeviceRowsSchema,
|
disconnectProjectDeviceRowsSchema,
|
||||||
@@ -20,8 +22,6 @@ import {
|
|||||||
import type { CreateProjectDeviceInput } from "../../shared/validation/project-device.schemas.js";
|
import type { CreateProjectDeviceInput } from "../../shared/validation/project-device.schemas.js";
|
||||||
import { respondWithProjectCommandError } from "./project-command.controller.js";
|
import { respondWithProjectCommandError } from "./project-command.controller.js";
|
||||||
|
|
||||||
const globalDeviceRepository = new GlobalDeviceRepository();
|
|
||||||
const projectDeviceRepository = new ProjectDeviceRepository();
|
|
||||||
export async function listProjectDevicesByProject(req: Request, res: Response) {
|
export async function listProjectDevicesByProject(req: Request, res: Response) {
|
||||||
const { projectId } = req.params;
|
const { projectId } = req.params;
|
||||||
if (typeof projectId !== "string") {
|
if (typeof projectId !== "string") {
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { ProjectRepository } from "../../db/repositories/project.repository.js";
|
|
||||||
import {
|
import {
|
||||||
createProjectSchema,
|
createProjectSchema,
|
||||||
updateProjectSettingsSchema,
|
updateProjectSettingsSchema,
|
||||||
} from "../../shared/validation/project-structure.schemas.js";
|
} from "../../shared/validation/project-structure.schemas.js";
|
||||||
import { createProjectSettingsUpdateProjectCommand } from "../../domain/models/project-settings-project-command.model.js";
|
import { createProjectSettingsUpdateProjectCommand } from "../../domain/models/project-settings-project-command.model.js";
|
||||||
import { projectCommandService } from "../composition/project-command-stores.js";
|
import { projectCommandService } from "../composition/project-command-stores.js";
|
||||||
|
import { projectRepository } from "../composition/application-repositories.js";
|
||||||
import { respondWithProjectCommandError } from "./project-command.controller.js";
|
import { respondWithProjectCommandError } from "./project-command.controller.js";
|
||||||
|
|
||||||
const projectRepository = new ProjectRepository();
|
|
||||||
|
|
||||||
export async function listProjects(_req: Request, res: Response) {
|
export async function listProjects(_req: Request, res: Response) {
|
||||||
const result = await projectRepository.list();
|
const result = await projectRepository.list();
|
||||||
res.json(result);
|
res.json(result);
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { RoomRepository } from "../../db/repositories/room.repository.js";
|
|
||||||
import {
|
import {
|
||||||
createProjectRoomInsertProjectCommand,
|
createProjectRoomInsertProjectCommand,
|
||||||
createProjectRoomSnapshot,
|
createProjectRoomSnapshot,
|
||||||
} from "../../domain/models/project-location-structure-project-command.model.js";
|
} from "../../domain/models/project-location-structure-project-command.model.js";
|
||||||
import { createRoomSchema } from "../../shared/validation/project-structure.schemas.js";
|
import { createRoomSchema } from "../../shared/validation/project-structure.schemas.js";
|
||||||
import { projectCommandService } from "../composition/project-command-stores.js";
|
import { projectCommandService } from "../composition/project-command-stores.js";
|
||||||
|
import { roomRepository } from "../composition/application-repositories.js";
|
||||||
import { respondWithProjectCommandError } from "./project-command.controller.js";
|
import { respondWithProjectCommandError } from "./project-command.controller.js";
|
||||||
|
|
||||||
const roomRepository = new RoomRepository();
|
|
||||||
|
|
||||||
export async function listRoomsByProject(req: Request, res: Response) {
|
export async function listRoomsByProject(req: Request, res: Response) {
|
||||||
const { projectId } = req.params;
|
const { projectId } = req.params;
|
||||||
if (typeof projectId !== "string") {
|
if (typeof projectId !== "string") {
|
||||||
|
|||||||
@@ -10,6 +10,15 @@ import {
|
|||||||
verifyDatabaseFile,
|
verifyDatabaseFile,
|
||||||
} from "../src/db/database-backup.js";
|
} from "../src/db/database-backup.js";
|
||||||
import { createDatabaseContext } from "../src/db/database-context.js";
|
import { createDatabaseContext } from "../src/db/database-context.js";
|
||||||
|
import { CircuitDeviceRowRepository } from "../src/db/repositories/circuit-device-row.repository.js";
|
||||||
|
import { CircuitListRepository } from "../src/db/repositories/circuit-list.repository.js";
|
||||||
|
import { CircuitSectionRepository } from "../src/db/repositories/circuit-section.repository.js";
|
||||||
|
import { CircuitRepository } from "../src/db/repositories/circuit.repository.js";
|
||||||
|
import { FloorRepository } from "../src/db/repositories/floor.repository.js";
|
||||||
|
import { GlobalDeviceRepository } from "../src/db/repositories/global-device.repository.js";
|
||||||
|
import { ProjectDeviceRepository } from "../src/db/repositories/project-device.repository.js";
|
||||||
|
import { ProjectRepository } from "../src/db/repositories/project.repository.js";
|
||||||
|
import { RoomRepository } from "../src/db/repositories/room.repository.js";
|
||||||
import { projects } from "../src/db/schema/projects.js";
|
import { projects } from "../src/db/schema/projects.js";
|
||||||
|
|
||||||
describe("database backup and restore", () => {
|
describe("database backup and restore", () => {
|
||||||
@@ -86,3 +95,71 @@ describe("database backup and restore", () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("application repository database contexts", () => {
|
||||||
|
it("keep reads and writes inside their injected database", async () => {
|
||||||
|
const first = createDatabaseContext(":memory:");
|
||||||
|
const second = createDatabaseContext(":memory:");
|
||||||
|
try {
|
||||||
|
for (const context of [first, second]) {
|
||||||
|
migrate(context.db, {
|
||||||
|
migrationsFolder: path.resolve("src", "db", "migrations"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstProjects = new ProjectRepository(first.db);
|
||||||
|
const secondProjects = new ProjectRepository(second.db);
|
||||||
|
const project = await firstProjects.create({ name: "Nur in Datenbank A" });
|
||||||
|
|
||||||
|
assert.equal((await firstProjects.list()).length, 1);
|
||||||
|
assert.deepEqual(await secondProjects.list(), []);
|
||||||
|
|
||||||
|
const firstGlobalDevices = new GlobalDeviceRepository(first.db);
|
||||||
|
const secondGlobalDevices = new GlobalDeviceRepository(second.db);
|
||||||
|
await firstGlobalDevices.create({
|
||||||
|
name: "Steckdose",
|
||||||
|
displayName: "Steckdose",
|
||||||
|
quantity: 1,
|
||||||
|
installedPowerPerUnitKw: 0.2,
|
||||||
|
demandFactor: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal((await firstGlobalDevices.list()).length, 1);
|
||||||
|
assert.deepEqual(await secondGlobalDevices.list(), []);
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
await new CircuitListRepository(first.db).listByProject(project.id),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
assert.deepEqual(
|
||||||
|
await new CircuitSectionRepository(first.db).listByCircuitList(
|
||||||
|
"unknown-list"
|
||||||
|
),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
assert.deepEqual(
|
||||||
|
await new CircuitRepository(first.db).listByCircuitList("unknown-list"),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
assert.deepEqual(
|
||||||
|
await new CircuitDeviceRowRepository(first.db).listByCircuitList([]),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
assert.deepEqual(
|
||||||
|
await new FloorRepository(first.db).listByProject(project.id),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
assert.deepEqual(
|
||||||
|
await new RoomRepository(first.db).listByProject(project.id),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
assert.deepEqual(
|
||||||
|
await new ProjectDeviceRepository(first.db).listByProject(project.id),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
first.close();
|
||||||
|
second.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user