Files
2026-11-14 09:56:45 +00:00

81 lines
3.7 KiB
TypeScript

// The module list of this app, and the only registry there is (decision AT-D2, spec §4.1).
// `buildRegistry` turns these manifests into the router, the navigation, the jobs, the events, the
// permissions, the tables and the isolation-fixture list, so nothing is listed twice anywhere else.
//
// Adding a domain module is two steps: `pnpm new:module <id>` writes modules/<id>/, then its
// manifest joins the array below. Nothing in apps/ changes.
import { custodyModule } from "./custody.js"
import { moduleInclusion, moduleSelected } from "./inclusion.js"
export { moduleAdopted, moduleInclusion, moduleSelected } from "./inclusion.js"
import { authModule } from "@conusai-kit/auth"
import type { ModuleManifest } from "@conusai-kit/core"
import { filesModule } from "@conusai-kit/files"
import { guidesModule } from "@conusai-kit/guides" // kit:guides
import { proposalsModule } from "@conusai-kit/proposals"
import { supportModule } from "@conusai-kit/support" // kit:support
import { tenancyModule } from "@conusai-kit/tenancy"
import { accountModule } from "./account/index.js"
import { activitiesModule } from "./activities/index.js"
import { agentModule, assistantAppModule } from "./agent/index.js" // kit:agent
import { archiveModule } from "./archive/index.js"
import { brandingModule } from "./branding/index.js"
import { catalogModule } from "./catalog/index.js"
import { crmModule } from "./crm/index.js"
import { documentsModule } from "./documents/index.js" // kit:documents
import { inventoryModule } from "./inventory/index.js"
import { invoicingModule } from "./invoicing/index.js"
import { knowledgeModule } from "./knowledge/index.js" // kit:knowledge
import { ledgerModule } from "./ledger/index.js"
import { notesModule } from "./notes/index.js" // kit:notes
import { notificationsModule } from "./notifications/index.js"
/** Always included local/base modules; optional source presence grants no admission. */
export const kernelModules: readonly ModuleManifest[] = [
tenancyModule,
authModule,
filesModule,
proposalsModule,
notificationsModule,
]
export const BUSINESS_MODULES = {
activities: activitiesModule,
archive: archiveModule,
catalog: catalogModule,
crm: crmModule,
inventory: inventoryModule,
invoicing: invoicingModule,
ledger: ledgerModule,
} as const
export type BusinessModuleId = keyof typeof BUSINESS_MODULES
/** Business clients still use this list in composition roots. */
export const businessModulesOn: readonly BusinessModuleId[] = moduleInclusion.selected.filter(
(id): id is BusinessModuleId => Object.hasOwn(BUSINESS_MODULES, id),
)
const optionalModules: Readonly<Record<string, readonly ModuleManifest[]>> = {
...Object.fromEntries(Object.entries(BUSINESS_MODULES).map(([id, manifest]) => [id, [manifest]])),
documents: [documentsModule], // kit:documents
knowledge: [knowledgeModule], // kit:knowledge
agent: [agentModule, assistantAppModule], // kit:agent
guides: [guidesModule], // kit:guides
support: [supportModule], // kit:support
}
export const domainModules: readonly ModuleManifest[] = [
brandingModule,
// kit:notes:begin
moduleSelected("guides")
? notesModule
: { ...notesModule, extends: (notesModule.extends ?? []).filter((entry) => !entry.point.id.startsWith("guides.")) },
// kit:notes:end
accountModule,
...moduleInclusion.everAdopted.flatMap((id) => {
const manifests = optionalModules[id]
if (!manifests) throw new Error(`Adopted module ${id} source is missing; restore its custody implementation`)
return manifests.map((manifest) => (moduleSelected(id) ? manifest : custodyModule(manifest)))
}),
]
export const appModules: readonly ModuleManifest[] = [...kernelModules, ...domainModules]