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", ]; 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 removedCircuitColumns = [ "protection_type", "protection_rated_current", "protection_characteristic", ]; const remainingRemovedCircuitColumns = removedCircuitColumns.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", "is_public_building", "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 (remainingRemovedCircuitColumns.length > 0) { console.error( "Transitional circuit protection columns still present:", remainingRemovedCircuitColumns.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.");