@ -1,10 +1,16 @@
// One-off deploy step for the Client Detail redesign: over write the live onboarding-template
// One-off deploy step for the Client Detail redesign: writes the live onboarding-template
// settings with the composed quotation-led pipeline (shared front + per-module tail), then run
// settings with the composed quotation-led pipeline (shared front + per-module tail), then run s
// the tick-preserving migration so existing SMS/RTGS/MobileApp projects adopt the new steps.
// the tick-preserving migration so existing SMS/RTGS/MobileApp projects adopt the new steps.
// Idempotent. Run from repo root: npx tsx apps/hq/scripts/apply-onboarding-pipeline.ts
// Idempotent ONLY as long as the templates below haven't been owner-edited since: each setting
// is written only if it is still ABSENT, so a plain re-run never clobbers an owner's edit made
// in the Modules onboarding-template editor. Pass --force to unconditionally overwrite every
// template with the settings below — this DOES clobber owner edits, use with care.
// Run from repo root:
// npx tsx apps/hq/scripts/apply-onboarding-pipeline.ts [--force]
import { openDb } from '../src/db'
import { openDb } from '../src/db'
import { openPgDb } from '../src/db-pg'
import { openPgDb } from '../src/db-pg'
import { migrateOnboardingTemplates } from '../src/migrate-onboarding-templates'
import { migrateOnboardingTemplates } from '../src/migrate-onboarding-templates'
import { getSetting , setSetting } from '../src/repos-reminders'
const FRONT = [
const FRONT = [
{ key : 'enquiry' , label : 'Enquiry received' } ,
{ key : 'enquiry' , label : 'Enquiry received' } ,
@ -48,21 +54,27 @@ const TAILS: Record<string, { key: string; label: string }[]> = {
async function main ( ) : Promise < void > {
async function main ( ) : Promise < void > {
const pgUrl = process . env [ 'DATABASE_URL' ] ? ? ''
const pgUrl = process . env [ 'DATABASE_URL' ] ? ? ''
const db = pgUrl !== '' ? await openPgDb ( pgUrl ) : openDb ( process . env [ 'HQ_DATA_DIR' ] )
const db = pgUrl !== '' ? await openPgDb ( pgUrl ) : openDb ( process . env [ 'HQ_DATA_DIR' ] )
const force = process . argv . includes ( '--force' )
// Audited via setSetting (append-only-audit rule) and, unless --force, skips any key
// that's already set — so an owner's edit in the Modules onboarding-template editor is
// left alone on a re-run instead of being silently clobbered.
const upsert = async ( key : string , list : unknown ) : Promise < void > = > {
const upsert = async ( key : string , list : unknown ) : Promise < void > = > {
await db . run (
if ( ! force && ( await getSetting ( db , key ) ) !== null ) {
` INSERT INTO setting (key, value) VALUES (?, ?) ON CONFLICT (key) DO UPDATE SET value = excluded.value ` ,
// eslint-disable-next-line no-console
key , JSON . stringify ( list ) ,
console . log ( ` Skipped ${ key } — already set (pass --force to overwrite an owner edit). ` )
)
return
}
await setSetting ( db , 'system' , key , JSON . stringify ( list ) )
}
}
await upsert ( 'project.milestone_template.front' , FRONT )
await upsert ( 'project.milestone_template.front' , FRONT )
for ( const [ code , list ] of Object . entries ( TAILS ) ) await upsert ( ` project.milestone_template: ${ code } ` , list )
for ( const [ code , list ] of Object . entries ( TAILS ) ) await upsert ( ` project.milestone_template: ${ code } ` , list )
// eslint-disable-next-line no-console
// eslint-disable-next-line no-console
console . log ( 'Template settings updated : front + SMS/RTGS/MOBILEAPP tails.')
console . log ( 'Template settings step done : front + SMS/RTGS/MOBILEAPP tails.')
const res = await migrateOnboardingTemplates ( db )
const res = await migrateOnboardingTemplates ( db )
// eslint-disable-next-line no-console
// eslint-disable-next-line no-console
console . log ( ` Onboarding migration: ${ res . projects } project(s) rebuilt, ${ res . carried } tick(s) carried, ${ res . dropped } dropped .` )
console . log ( ` Onboarding migration: ${ res . projects } project(s) rebuilt, ${ res . carried } tick(s) carried, ${ res . dropped } dropped , ${ res . preserved } custom step(s) preserved .` )
}
}
main ( ) . catch ( ( e ) = > { console . error ( e ) ; process . exit ( 1 ) } )
main ( ) . catch ( ( e ) = > { console . error ( e ) ; process . exit ( 1 ) } )