@ -121,6 +121,47 @@ describe('onboarding template migration', () => {
expect ( ( audits [ 0 ] as unknown as { n : number } ) . n ) . toBe ( 1 )
} )
it ( 'counts ticked dropped keys (unmapped or not in new template)' , async ( ) = > {
const cmId = await makeSmsClientModule ( )
// Insert old generic rows with two ticked keys that will be dropped:
// - amc_start: unmapped (not in KEY_MAP)
// - setup_done: maps to 'setup_configuration', but SMS template doesn't have it
// Plus one carried key (installed -> installation) to verify carried count too.
const rows : [ string , number , string | null ] [ ] = [
[ 'amc_start' , 1 , '2026-02-15' ] , // ticked, unmapped -> dropped
[ 'setup_done' , 1 , '2026-03-01' ] , // ticked, maps to setup_configuration but SMS template lacks it -> dropped
[ 'installed' , 1 , '2026-03-25' ] , // ticked, maps to installation which IS in SMS template -> carried
[ 'advance_paid' , 0 , null ] ,
[ 'go_live' , 0 , null ] ,
[ 'balance_paid' , 0 , null ] ,
]
for ( const [ i , r ] of rows . entries ( ) ) {
await db . run (
` INSERT INTO project_milestone (id,client_module_id,key,label,done,done_on,sort)
VALUES ( ? , ? , ? , ? , ? , ? , ? ) ` ,
` m ${ i } ` , cmId , r [ 0 ] , String ( r [ 0 ] ) , r [ 1 ] , r [ 2 ] , i ,
)
}
const res = await migrateOnboardingTemplates ( db )
expect ( res . projects ) . toBe ( 1 )
expect ( res . carried ) . toBe ( 1 ) // only installed -> installation
expect ( res . dropped ) . toBe ( 2 ) // amc_start (unmapped) + setup_done (not in SMS template)
// Verify the dropped keys are gone from the migrated template
const ms = await listProjectMilestones ( db , cmId )
expect ( ms . map ( ( m ) = > m . key ) ) . toEqual ( [
'document_collection' , 'dlt_registration' , 'account_creation' , 'installation' ,
'testing' , 'training' , 'go_live' , 'advance_payment' , 'balance_payment' ,
] )
expect ( ms . some ( ( m ) = > m . key === 'amc_start' || m . key === 'setup_done' ) ) . toBe ( false )
// Verify the carried installation tick is preserved
const installation = ms . find ( ( m ) = > m . key === 'installation' ) !
expect ( installation . done ) . toBe ( true )
expect ( installation . doneOn ) . toBe ( '2026-03-25' )
} )
it ( 'leaves a module without a per-module template untouched' , async ( ) = > {
const client = await createClient ( db , 'u1' , { name : 'Other Society' , stateCode : '32' } )
const mod = await createModule ( db , 'u1' , { code : 'NOTEMPLATE' , name : 'No Template Module' } )