2026-05-08 14:51:05 -06:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
// Run all Postgres-compatible migrations in order.
|
|
|
|
|
// Each migration is idempotent (safe to re-run).
|
|
|
|
|
// Used by CI/CD pipeline during deploy to ensure schema is up to date.
|
|
|
|
|
//
|
|
|
|
|
// Usage: cd backend && node migrations/run-all.js
|
|
|
|
|
|
|
|
|
|
const { execSync } = require('child_process');
|
|
|
|
|
const path = require('path');
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
|
|
|
|
|
const MIGRATIONS_DIR = __dirname;
|
|
|
|
|
|
|
|
|
|
// Only run migrations that use the Postgres pool (not legacy SQLite ones).
|
|
|
|
|
// Add new migrations to this list as they're created.
|
|
|
|
|
const POSTGRES_MIGRATIONS = [
|
|
|
|
|
'add_decom_workflow_type.js',
|
2026-05-11 14:29:50 -06:00
|
|
|
'add_fp_submissions_dismissed.js',
|
2026-05-13 16:46:49 -06:00
|
|
|
'add_fp_submissions_requeued_at.js',
|
2026-05-11 15:48:10 -06:00
|
|
|
'add_vcl_reporting_columns.js',
|
2026-05-13 07:57:41 -06:00
|
|
|
'add_vcl_vertical_metadata.js',
|
Add CCP Metrics page with multi-vertical VCL upload and cross-org reporting
New feature: multi-file per-vertical compliance xlsx upload with scoped
resolution logic, executive-level aggregated reporting, and drill-down
by vertical and metric. Supports daily upload cadence and batch commit.
Backend:
- Migration: add vertical column to compliance_items/uploads, create
vcl_multi_vertical_summary table
- New route module: routes/vclMultiVertical.js with preview, commit,
stats, trend, metric drill-down, device list, and burndown endpoints
- New helpers: parseVerticalFilename(), computeVerticalBurndown()
- Vertical-scoped resolution: uploading one vertical never resolves
items from other verticals
Frontend:
- CCPMetricsPage with stats bar, trend chart, donut, vertical table
- Drill-down: vertical -> metrics by category -> device list
- Per-vertical burndown forecast chart
- MultiVerticalUploadModal: multi-file drag-drop, batch preview, commit
- Nav entry: CCP Metrics (Building2 icon)
Docs:
- Design brief for stakeholder meeting (docs/vcl-multi-vertical-design-brief.md)
2026-05-14 09:49:59 -06:00
|
|
|
'add_vcl_multi_vertical.js',
|
2026-05-15 10:53:14 -06:00
|
|
|
'add_compliance_item_history.js',
|
2026-05-21 15:06:16 -06:00
|
|
|
'add_flexible_jira_ticket_creation.js',
|
2026-05-08 14:51:05 -06:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
async function runAll() {
|
|
|
|
|
console.log(`[Migrations] Running ${POSTGRES_MIGRATIONS.length} Postgres migration(s)...`);
|
|
|
|
|
let succeeded = 0;
|
|
|
|
|
let failed = 0;
|
|
|
|
|
|
|
|
|
|
for (const file of POSTGRES_MIGRATIONS) {
|
|
|
|
|
const fullPath = path.join(MIGRATIONS_DIR, file);
|
|
|
|
|
if (!fs.existsSync(fullPath)) {
|
|
|
|
|
console.error(` [FAIL] ${file}: file not found`);
|
|
|
|
|
failed++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
console.log(` [run] ${file}`);
|
|
|
|
|
execSync(`node ${fullPath}`, {
|
|
|
|
|
cwd: path.join(MIGRATIONS_DIR, '..'),
|
|
|
|
|
stdio: 'inherit',
|
|
|
|
|
timeout: 30000,
|
|
|
|
|
});
|
|
|
|
|
succeeded++;
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error(` [FAIL] ${file}: exit code ${err.status}`);
|
|
|
|
|
failed++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log(`[Migrations] Done: ${succeeded} applied, ${failed} failed`);
|
|
|
|
|
if (failed > 0) process.exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
runAll();
|