Files
leistungsbilanz-ts/scripts/db-verify-circuit-schema.js
T

202 lines
6.0 KiB
JavaScript

const Database = require("better-sqlite3");
const path = require("node:path");
const dbPath = path.resolve("data", "leistungsbilanz.db");
const db = new Database(dbPath, { readonly: true });
const requiredTables = [
"circuit_sections",
"circuits",
"circuit_device_rows",
"circuit_list_equipment_identifiers",
"circuit_protection_devices",
"distribution_board_components",
"distribution_board_component_protection_devices",
"legacy_consumer_circuit_migrations",
"legacy_consumer_migration_reports",
];
const tablePlaceholders = requiredTables.map(() => "?").join(", ");
const rows = db
.prepare(
`SELECT name
FROM sqlite_master
WHERE type = 'table' AND name IN (${tablePlaceholders})`
)
.all(...requiredTables);
const existing = new Set(rows.map((row) => row.name));
const missing = requiredTables.filter((name) => !existing.has(name));
const requiredProjectDeviceColumns = [
"phase_type",
"connection_kind",
"cost_group",
"power_per_unit",
"simultaneity_factor",
"cos_phi",
"remark",
];
const projectDeviceColumns = new Set(
db.prepare("PRAGMA table_info(project_devices)").all().map((column) => column.name)
);
const missingProjectDeviceColumns = requiredProjectDeviceColumns.filter(
(name) => !projectDeviceColumns.has(name)
);
const removedProjectDeviceColumns = [
"installed_power_per_unit_kw",
"demand_factor",
"phase_count",
"power_factor",
"note",
];
const remainingRemovedProjectDeviceColumns = removedProjectDeviceColumns.filter(
(name) => projectDeviceColumns.has(name)
);
const requiredCircuitColumns = ["control_requirement"];
const circuitColumns = new Set(
db.prepare("PRAGMA table_info(circuits)").all().map((column) => column.name)
);
const missingCircuitColumns = requiredCircuitColumns.filter((name) => !circuitColumns.has(name));
const requiredCircuitSectionColumns = ["category", "group_number"];
const circuitSectionColumns = new Set(
db
.prepare("PRAGMA table_info(circuit_sections)")
.all()
.map((column) => column.name)
);
const missingCircuitSectionColumns = requiredCircuitSectionColumns.filter(
(name) => !circuitSectionColumns.has(name)
);
const requiredProjectColumns = [
"internal_project_number",
"external_project_number",
"building_owner",
"description",
"enabled_distribution_board_supply_types",
];
const projectColumns = new Set(
db.prepare("PRAGMA table_info(projects)").all().map((column) => column.name)
);
const missingProjectColumns = requiredProjectColumns.filter(
(name) => !projectColumns.has(name)
);
const requiredDistributionBoardColumns = [
"floor_id",
"supply_type",
"simultaneity_factor",
];
const distributionBoardColumns = new Set(
db
.prepare("PRAGMA table_info(distribution_boards)")
.all()
.map((column) => column.name)
);
const missingDistributionBoardColumns =
requiredDistributionBoardColumns.filter(
(name) => !distributionBoardColumns.has(name)
);
const requiredEquipmentIdentifierTriggers = [
"circuits_equipment_identifier_insert",
"circuits_equipment_identifier_update",
"circuits_equipment_identifier_delete",
"distribution_board_components_equipment_identifier_insert",
"distribution_board_components_equipment_identifier_update",
"distribution_board_components_equipment_identifier_delete",
];
const equipmentIdentifierTriggers = new Set(
db
.prepare(
`SELECT name
FROM sqlite_master
WHERE type = 'trigger'`
)
.all()
.map((trigger) => trigger.name)
);
const missingEquipmentIdentifierTriggers =
requiredEquipmentIdentifierTriggers.filter(
(name) => !equipmentIdentifierTriggers.has(name)
);
const integrityCheck = db.pragma("integrity_check", { simple: true });
const foreignKeyViolations = db.pragma("foreign_key_check");
console.log("Database:", dbPath);
console.log("Required tables:", requiredTables.join(", "));
console.log("Existing tables:", [...existing].join(", ") || "(none)");
console.log("Required project-device columns:", requiredProjectDeviceColumns.join(", "));
console.log("Required circuit columns:", requiredCircuitColumns.join(", "));
console.log(
"Required circuit-section columns:",
requiredCircuitSectionColumns.join(", ")
);
console.log("Required project columns:", requiredProjectColumns.join(", "));
console.log(
"Required distribution-board columns:",
requiredDistributionBoardColumns.join(", ")
);
console.log(
"Required BMK synchronization triggers:",
requiredEquipmentIdentifierTriggers.join(", ")
);
console.log("Integrity:", integrityCheck);
console.log("Foreign-key violations:", foreignKeyViolations.length);
if (missing.length > 0) {
console.error("Missing tables:", missing.join(", "));
process.exit(1);
}
if (missingProjectDeviceColumns.length > 0) {
console.error("Missing project-device columns:", missingProjectDeviceColumns.join(", "));
process.exit(1);
}
if (remainingRemovedProjectDeviceColumns.length > 0) {
console.error(
"Transitional project-device columns still present:",
remainingRemovedProjectDeviceColumns.join(", ")
);
process.exit(1);
}
if (missingCircuitColumns.length > 0) {
console.error("Missing circuit columns:", missingCircuitColumns.join(", "));
process.exit(1);
}
if (missingCircuitSectionColumns.length > 0) {
console.error(
"Missing circuit-section columns:",
missingCircuitSectionColumns.join(", ")
);
process.exit(1);
}
if (missingProjectColumns.length > 0) {
console.error("Missing project columns:", missingProjectColumns.join(", "));
process.exit(1);
}
if (missingDistributionBoardColumns.length > 0) {
console.error(
"Missing distribution-board columns:",
missingDistributionBoardColumns.join(", ")
);
process.exit(1);
}
if (missingEquipmentIdentifierTriggers.length > 0) {
console.error(
"Missing BMK synchronization triggers:",
missingEquipmentIdentifierTriggers.join(", ")
);
process.exit(1);
}
if (integrityCheck !== "ok" || foreignKeyViolations.length > 0) {
console.error("Database integrity or foreign-key verification failed.");
process.exit(1);
}
console.log("Circuit-first and distribution-component schema verification passed.");