import { sql } from "drizzle-orm"; import { boolean, check, pgTable, text, timestamp } from "drizzle-orm/pg-core"; /** * Core-owned storage for the one operational decision an administrator makes about an installed * module: should it run? * * This is **configuration, not runtime state**. Nothing about what happened during a boot is stored * here — not a start failure, not a last-seen timestamp, not a health result. A restart naturally * retries every enabled module, which is the behavior an operator expects and which persisting a * transient failure would quietly break (ADR 0028). * * It is also **not an installation registry**. A module is "installed" by being a valid module * package on disk that discovery accepts; this table records nothing about where it came from, how * it got there, or what version it is. There is deliberately no install source, download URL, * update channel, signature, marketplace metadata, or free-form JSON column: none of those concepts * exist in this platform, and a column for one is how an installer gets built by accident. * * Platform-global, for the same reason the Dashboard tables are (ADR 0027): Ekklesia has no * organization or tenant model to scope it to. When one exists, this table gains a scope column. * * Table and constraint names are explicit and namespaced exactly like * `core/src/authorization/schema.ts` and `core/src/dashboard/schema.ts`, so ownership is * unambiguous inside the shared public PostgreSQL schema. */ /** * One explicit enablement decision. * * **A row exists only because somebody decided.** `enabled` has no column default on purpose: the * platform's default for a newly discovered module is expressed by the *absence* of a row and * resolved in `resolveModuleEligibility`, not by a default that would silently materialize a * decision nobody made. Storing `enabled = true` explicitly is still meaningful — it records that * an administrator looked at this module and left it on. * * `module_id` carries **no foreign key to any module**, because modules are packages discovered on * disk, not rows — the same reasoning `ekklesia_core_dashboard_placement.module_id` already * follows. A record for a module that is not currently deployed is therefore normal and is * retained, so redeploying a module restores the decision instead of resetting it. * `resolveModuleEligibility` ignores such a record entirely. */ export const ekklesiaCoreModuleState = pgTable( "ekklesia_core_module_state", { moduleId: text("module_id").primaryKey(), enabled: boolean("enabled").notNull(), createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(), updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(), }, (table) => [ // Defense in depth beneath the application-layer `moduleIdSchema` contract, which never // produces this: an empty module id would be an unaddressable, permanently inert record. check("ekklesia_core_module_state_module_check", sql`length(${table.moduleId}) > 0`), ], ); /** Explicit map passed to Drizzle, mirroring `authorizationSchema` and `dashboardSchema`. */ export const moduleLifecycleSchema = { moduleState: ekklesiaCoreModuleState, } as const;