Infrastructure only — no existing data or tables modified.
src/db/migrate.js — programmatic runner, fires at boot after
the existing idempotent initDatabase()
migrations/1744600000000... — intentionally empty example, documents
the file shape. Registered in the new
pgmigrations tracking table so it won't
rerun.
.node-pg-migraterc.json — CLI config (migrations-dir, utc naming)
docs/migrations.md — workflow + conventions
package.json — migrate:up/down/new/status npm scripts
(status is a direct pgmigrations query
since node-pg-migrate v7 lacks a status
subcommand)
src/utils/sessions.js:
- parseUserAgent now recognizes the Capacitor wrapper (UA suffix
"PedScribe-Android" / "PedScribe-iOS") and labels sessions
"PedScribe (Android)" instead of "Chrome on Android".
Going forward: schema changes go in /migrations as versioned files
with up() + down(); the inline init in database.js is the implicit
baseline for everything already in production.
43 lines
1.6 KiB
JavaScript
43 lines
1.6 KiB
JavaScript
// ============================================================
|
|
// Run pending migrations at boot. Uses node-pg-migrate
|
|
// programmatically — same engine the CLI uses, no shell-out.
|
|
// ============================================================
|
|
//
|
|
// Design notes:
|
|
// - `src/db/database.js` runs its inline, idempotent CREATE TABLE IF
|
|
// NOT EXISTS init on every boot. That is the implicit "baseline"
|
|
// schema. node-pg-migrate tracks incremental changes layered on top.
|
|
// - Migration files go in /app/migrations/{timestamp}_name.js with
|
|
// an up(pgm) and optional down(pgm).
|
|
// - Migration state persists in the `pgmigrations` table so each
|
|
// file runs exactly once.
|
|
// ============================================================
|
|
|
|
var runner = require('node-pg-migrate').default;
|
|
var path = require('path');
|
|
|
|
async function runMigrations() {
|
|
var databaseUrl = process.env.DATABASE_URL
|
|
|| 'postgresql://pedscribe:pedscribe_secret_change_me@localhost:5432/pedscribe';
|
|
try {
|
|
var applied = await runner({
|
|
databaseUrl: databaseUrl,
|
|
dir: path.join(__dirname, '..', '..', 'migrations'),
|
|
migrationsTable: 'pgmigrations',
|
|
direction: 'up',
|
|
count: Infinity,
|
|
verbose: false,
|
|
singleTransaction: true
|
|
});
|
|
if (applied && applied.length) {
|
|
console.log('✅ Migrations applied: ' + applied.map(function(m) { return m.name; }).join(', '));
|
|
} else {
|
|
console.log('✅ Migrations: up-to-date');
|
|
}
|
|
} catch (err) {
|
|
console.error('[FATAL] Migration failed:', err.message);
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
module.exports = { runMigrations: runMigrations };
|