008a43469d
Stage C of staged Phase 10 redo. Restores dangling phase10-wip work: - schema.ts: leads expansion + activities/reminders tables + relations - lead-service.ts / lead-validators.ts service layer - /admin/leads list + detail + actions, LeadTable/LeadDetail/LeadForm - LogActivityModal, SendQuoteModal, FollowUpWidget on dashboard - migration 0005 (applied to prod DB in Stage B, along with previously-missing 0001/0003/0004 — root cause of all post-deploy 500s: prod DB had no migrations applied since 0000) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
80 lines
2.4 KiB
TypeScript
80 lines
2.4 KiB
TypeScript
import postgres from "postgres";
|
|
import { readFileSync } from "fs";
|
|
import { join } from "path";
|
|
|
|
// Applies 0005_phase_10_crm_leads_activities_reminders.sql (additive-only:
|
|
// ALTER TABLE leads ADD COLUMN x8, CREATE TABLE activities/reminders, indexes).
|
|
// Idempotent: skips if already applied. Never drops or truncates anything.
|
|
|
|
async function push() {
|
|
const databaseUrl = process.env.DATABASE_URL;
|
|
if (!databaseUrl) {
|
|
console.error("DATABASE_URL environment variable is required");
|
|
process.exit(1);
|
|
}
|
|
|
|
const sql = postgres(databaseUrl, { max: 1 });
|
|
|
|
try {
|
|
const cols = await sql`
|
|
SELECT column_name FROM information_schema.columns
|
|
WHERE table_name = 'leads' ORDER BY ordinal_position
|
|
`;
|
|
const tables = await sql`
|
|
SELECT table_name FROM information_schema.tables
|
|
WHERE table_schema = 'public' AND table_name IN ('activities', 'reminders')
|
|
`;
|
|
const colNames = cols.map((c) => c.column_name);
|
|
console.log("Pre-state — leads columns:", colNames.join(", "));
|
|
console.log(
|
|
"Pre-state — CRM tables:",
|
|
tables.map((t) => t.table_name).join(", ") || "none"
|
|
);
|
|
|
|
if (colNames.includes("status") && tables.length === 2) {
|
|
console.log("✓ Migration 0005 already applied (skipped)");
|
|
process.exit(0);
|
|
}
|
|
|
|
const migrationSql = readFileSync(
|
|
join(
|
|
__dirname,
|
|
"../src/db/migrations/0005_phase_10_crm_leads_activities_reminders.sql"
|
|
),
|
|
"utf-8"
|
|
);
|
|
|
|
console.log("Applying migration 0005 in a transaction...");
|
|
await sql.begin(async (tx) => {
|
|
await tx.unsafe(migrationSql);
|
|
});
|
|
|
|
const postCols = await sql`
|
|
SELECT column_name FROM information_schema.columns
|
|
WHERE table_name = 'leads' ORDER BY ordinal_position
|
|
`;
|
|
const postTables = await sql`
|
|
SELECT table_name FROM information_schema.tables
|
|
WHERE table_schema = 'public' AND table_name IN ('activities', 'reminders')
|
|
`;
|
|
console.log(
|
|
"Post-state — leads columns:",
|
|
postCols.map((c) => c.column_name).join(", ")
|
|
);
|
|
console.log(
|
|
"Post-state — CRM tables:",
|
|
postTables.map((t) => t.table_name).join(", ")
|
|
);
|
|
console.log("✓ Migration 0005 applied successfully");
|
|
process.exit(0);
|
|
} catch (err: unknown) {
|
|
console.error(
|
|
"Error applying migration:",
|
|
err instanceof Error ? err.message : err
|
|
);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
push();
|