diff --git a/apps/hq/src/seed.ts b/apps/hq/src/seed.ts index 8aac5b2..e8fa5ea 100644 --- a/apps/hq/src/seed.ts +++ b/apps/hq/src/seed.ts @@ -100,6 +100,53 @@ export async function seedIfEmpty(db: DB): Promise { const seededMilestone = (await db.run(INSERT_SETTING_SQL, 'project.milestone_template', MILESTONE_TEMPLATE)).changes if (seededMilestone > 0) await writeAudit(db, 'system', 'seed', 'setting', 'project.milestone_template', undefined, { set: true }) + // Per-module onboarding templates (config over code). SMS/RTGS/Mobile App differ; each ends + // with advance + balance payment so a payment tick maps cleanly on migration. + const PER_MODULE_TEMPLATES: Record = { + SMS: [ + { key: 'document_collection', label: 'Document collection' }, + { key: 'dlt_registration', label: 'DLT registration' }, + { key: 'account_creation', label: 'Account creation & registration' }, + { key: 'installation', label: 'Installation' }, + { key: 'testing', label: 'Testing' }, + { key: 'training', label: 'Training' }, + { key: 'go_live', label: 'Go-live' }, + { key: 'advance_payment', label: 'Advance payment' }, + { key: 'balance_payment', label: 'Balance payment' }, + ], + RTGS: [ + { key: 'document_collection', label: 'Document collection' }, + { key: 'server_checkup', label: 'Server checkup' }, + { key: 'setup_configuration', label: 'Setup & configuration' }, + { key: 'installation', label: 'Installation' }, + { key: 'testing', label: 'Testing' }, + { key: 'training', label: 'Training' }, + { key: 'go_live', label: 'Go-live' }, + { key: 'advance_payment', label: 'Advance payment' }, + { key: 'balance_payment', label: 'Balance payment' }, + ], + MOBILEAPP: [ + { key: 'requirement_setup', label: 'Requirement & setup' }, + { key: 'configuration', label: 'Configuration' }, + { key: 'data_import', label: 'Data import' }, + { key: 'installation', label: 'Installation' }, + { key: 'testing', label: 'Testing' }, + { key: 'training', label: 'Training' }, + { key: 'go_live', label: 'Go-live' }, + { key: 'advance_payment', label: 'Advance payment' }, + { key: 'balance_payment', label: 'Balance payment' }, + ], + } + let seededPerModule = 0 + for (const [code, list] of Object.entries(PER_MODULE_TEMPLATES)) { + seededPerModule += (await db.run( + INSERT_SETTING_SQL, `project.milestone_template:${code}`, JSON.stringify(list))).changes + } + if (seededPerModule > 0) { + await writeAudit(db, 'system', 'seed', 'setting', 'project.milestone_template:*', undefined, + { modules: Object.keys(PER_MODULE_TEMPLATES) }) + } + // Dated reminder schedules (rule 3 / D-REMIND): one open-ended row per rule kind, // matching the code-constant fallback. A cadence change is a NEW dated row, not an edit. const scheduleKinds: ScheduleRuleKind[] = ['quote_followup', 'invoice_overdue'] diff --git a/apps/hq/test/seed-templates.test.ts b/apps/hq/test/seed-templates.test.ts new file mode 100644 index 0000000..a5f62b4 --- /dev/null +++ b/apps/hq/test/seed-templates.test.ts @@ -0,0 +1,25 @@ +import { describe, it, expect, beforeEach } from 'vitest' +import { openDb, type DB } from '../src/db' +import { seedIfEmpty } from '../src/seed' +import { milestoneTemplate } from '../src/repos-milestones' + +describe('seed per-module onboarding templates', () => { + let db: DB + beforeEach(async () => { db = openDb(':memory:'); await seedIfEmpty(db) }) + + it('seeds the SMS 9-step list', async () => { + const keys = (await milestoneTemplate(db, 'SMS')).map((e) => e.key) + expect(keys).toEqual([ + 'document_collection', 'dlt_registration', 'account_creation', 'installation', + 'testing', 'training', 'go_live', 'advance_payment', 'balance_payment', + ]) + }) + + it('seeds the RTGS list ending in payment steps', async () => { + const keys = (await milestoneTemplate(db, 'RTGS')).map((e) => e.key) + expect(keys).toEqual([ + 'document_collection', 'server_checkup', 'setup_configuration', 'installation', + 'testing', 'training', 'go_live', 'advance_payment', 'balance_payment', + ]) + }) +})