49 lines
1.9 KiB
TypeScript
49 lines
1.9 KiB
TypeScript
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
|
|
// Public, bounded source contract. Selection is admission; adoption is retained custody.
|
|
export const OPTIONAL_MODULE_IDS = [
|
|
"activities",
|
|
"archive",
|
|
"catalog",
|
|
"crm",
|
|
"inventory",
|
|
"invoicing",
|
|
"ledger",
|
|
"documents",
|
|
"knowledge",
|
|
"agent",
|
|
"guides",
|
|
"support",
|
|
] as const
|
|
export type OptionalModuleId = (typeof OPTIONAL_MODULE_IDS)[number]
|
|
export interface ModuleInclusion {
|
|
readonly schemaVersion: 1
|
|
readonly selected: readonly OptionalModuleId[]
|
|
readonly everAdopted: readonly OptionalModuleId[]
|
|
}
|
|
export function validateInclusion(value: unknown): ModuleInclusion {
|
|
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Invalid module inclusion record")
|
|
const record = value as Record<string, unknown>
|
|
if (Object.keys(record).sort().join(",") !== "everAdopted,schemaVersion,selected" || record.schemaVersion !== 1) {
|
|
throw new Error("Unsupported module inclusion record; explicit reviewed adoption required")
|
|
}
|
|
for (const key of ["selected", "everAdopted"] as const) {
|
|
const ids = record[key]
|
|
if (
|
|
!Array.isArray(ids) ||
|
|
ids.length > OPTIONAL_MODULE_IDS.length ||
|
|
new Set(ids).size !== ids.length ||
|
|
ids.some((id) => !OPTIONAL_MODULE_IDS.includes(id))
|
|
)
|
|
throw new Error("Invalid module inclusion IDs")
|
|
}
|
|
const result = value as ModuleInclusion
|
|
if (result.selected.some((id) => !result.everAdopted.includes(id)))
|
|
throw new Error("Selected module lacks custody record")
|
|
return result
|
|
}
|
|
|
|
import record from "./inclusion.json" with { type: "json" }
|
|
export const moduleInclusion = validateInclusion(record)
|
|
export const moduleSelected = (id: OptionalModuleId): boolean => moduleInclusion.selected.includes(id)
|
|
export const moduleAdopted = (id: OptionalModuleId): boolean => moduleInclusion.everAdopted.includes(id)
|