@ -57,12 +57,13 @@ export interface Module {
allowedKinds : Kind [ ] ; multiSubscription : boolean ; active : boolean
quoteContent : string [ ] // optional "what's included" lines that flow onto quotes
fieldSpec : FieldDef [ ] // D21: the operational fields this module declares
sortOrder : number // D25: fixed display order (lower first); owner-editable
}
interface ModuleRow {
id : string ; code : string ; name : string ; sac : string
allowed_kinds : string ; multi_subscription : number ; active : number
quote_content : string ; field_spec : string
quote_content : string ; field_spec : string ; sort_order : number
}
function toModule ( r : ModuleRow ) : Module {
@ -73,13 +74,14 @@ function toModule(r: ModuleRow): Module {
active : r.active === 1 ,
quoteContent : JSON.parse ( r . quote_content ) as string [ ] ,
fieldSpec : JSON.parse ( r . field_spec ? ? '[]' ) as FieldDef [ ] ,
sortOrder : r.sort_order ? ? 100 ,
}
}
export interface ModuleInput {
code : string ; name : string ; sac? : string
allowedKinds? : Kind [ ] ; multiSubscription? : boolean ; quoteContent? : string [ ]
fieldSpec? : FieldDef [ ]
fieldSpec? : FieldDef [ ] ; sortOrder? : number
}
export async function getModule ( db : DB , id : string ) : Promise < Module | null > {
@ -88,7 +90,8 @@ export async function getModule(db: DB, id: string): Promise<Module | null> {
}
export async function listModules ( db : DB ) : Promise < Module [ ] > {
const rows = await db . all < ModuleRow > ( ` SELECT * FROM module ORDER BY code ` )
// D25: fixed business display order (sort_order), code as the stable tiebreak.
const rows = await db . all < ModuleRow > ( ` SELECT * FROM module ORDER BY sort_order, code ` )
return rows . map ( toModule )
}
@ -100,11 +103,12 @@ export async function createModule(db: DB, userId: string, input: ModuleInput):
const id = uuidv7 ( )
const fieldSpec = input . fieldSpec !== undefined ? validateFieldSpec ( input . fieldSpec ) : [ ]
await db . run (
` INSERT INTO module (id, code, name, sac, allowed_kinds, multi_subscription, quote_content, field_spec )
VALUES ( ? , ? , ? , ? , ? , ? , ? , ? )` ,
` INSERT INTO module (id, code, name, sac, allowed_kinds, multi_subscription, quote_content, field_spec , sort_order )
VALUES ( ? , ? , ? , ? , ? , ? , ? , ? , ? )` ,
id , input . code , input . name , input . sac ? ? '998313' ,
JSON . stringify ( kinds ) , input . multiSubscription === true ? 1 : 0 ,
JSON . stringify ( input . quoteContent ? ? [ ] ) , JSON . stringify ( fieldSpec ) ,
input . sortOrder ? ? 100 ,
)
const mod = ( await getModule ( db , id ) ) !
await writeAudit ( db , userId , 'create' , 'module' , id , undefined , mod )
@ -114,7 +118,7 @@ export async function createModule(db: DB, userId: string, input: ModuleInput):
export interface ModulePatch {
name? : string ; sac? : string ; allowedKinds? : Kind [ ]
multiSubscription? : boolean ; active? : boolean ; quoteContent? : string [ ]
fieldSpec? : FieldDef [ ]
fieldSpec? : FieldDef [ ] ; sortOrder? : number
}
export async function updateModule ( db : DB , userId : string , id : string , patch : ModulePatch ) : Promise < Module > {
@ -134,6 +138,7 @@ export async function updateModule(db: DB, userId: string, id: string, patch: Mo
if ( patch . active !== undefined ) { sets . push ( 'active=?' ) ; args . push ( patch . active ? 1 : 0 ) }
if ( patch . quoteContent !== undefined ) { sets . push ( 'quote_content=?' ) ; args . push ( JSON . stringify ( patch . quoteContent ) ) }
if ( patch . fieldSpec !== undefined ) { sets . push ( 'field_spec=?' ) ; args . push ( JSON . stringify ( validateFieldSpec ( patch . fieldSpec ) ) ) }
if ( patch . sortOrder !== undefined ) { sets . push ( 'sort_order=?' ) ; args . push ( patch . sortOrder ) }
if ( sets . length > 0 ) {
args . push ( id )
await db . run ( ` UPDATE module SET ${ sets . join ( ', ' ) } WHERE id=? ` , . . . args )