feat: add module database access #13

Merged
Zayin_Admin merged 3 commits from phase-5/module-database-access into main 2026-07-26 03:01:34 +00:00
Owner

Summary

  • Add a typed ModuleDatabase facade over the API-owned Drizzle/PostgreSQL connection.
  • Provide frozen ModuleRuntimeServices to module start, stop, and authorized HTTP handlers while keeping registration declarative and database-free.
  • Preserve one physical runtime pool shared by Identity, Authorization, and installed modules.
  • Add real PostgreSQL integration coverage for lifecycle queries, authorized handlers, transactions, explicit migrations, error sanitization, and shutdown ordering.
  • Add a type-checked module-template example and document the architecture in ADR 0016.

Architecture

ModuleDatabase exposes the supported Drizzle operations:

  • select
  • selectDistinct
  • selectDistinctOn
  • insert
  • update
  • delete
  • execute
  • transaction

Modules access it through context.services.database. They do not receive a pg.Pool, connection string, $client, migration runner, or platform schema registry.

Registration remains database-free. The same frozen database facade is supplied to module lifecycle hooks and HTTP handlers.

Migrations remain an explicit deployment operation and never run during application startup.

Normal shutdown ordering is:

  1. Drain and close HTTP.
  2. Stop the module runtime while database access remains available.
  3. Close the PostgreSQL pool.

Verification

  • Root: 41 tests
  • Contracts: 111 tests
  • Module SDK: 5 tests
  • Module template: 5 tests
  • Core: 338 tests
  • API: 145 tests
  • Total unit tests: 645
  • PostgreSQL integration: 114 tests
  • pnpm verify: passed
  • pnpm test:migrations:integration: passed
  • Doctor: READY WITH WARNINGS
  • pnpm migrations:validate: passed
  • git diff --check: clean

Production migration contents and checksums remain unchanged. No production schema, manifest contract, manifestVersion, dependency, lockfile, route contract, or Hono-boundary changes were introduced.

Commits

  1. 0e308eb9 — feat: define module database access
  2. d1b9efd4 — test: prove module database access with PostgreSQL
  3. c38b5727 — docs: document module database access
## Summary * Add a typed `ModuleDatabase` facade over the API-owned Drizzle/PostgreSQL connection. * Provide frozen `ModuleRuntimeServices` to module `start`, `stop`, and authorized HTTP handlers while keeping registration declarative and database-free. * Preserve one physical runtime pool shared by Identity, Authorization, and installed modules. * Add real PostgreSQL integration coverage for lifecycle queries, authorized handlers, transactions, explicit migrations, error sanitization, and shutdown ordering. * Add a type-checked module-template example and document the architecture in ADR 0016. ## Architecture `ModuleDatabase` exposes the supported Drizzle operations: * `select` * `selectDistinct` * `selectDistinctOn` * `insert` * `update` * `delete` * `execute` * `transaction` Modules access it through `context.services.database`. They do not receive a `pg.Pool`, connection string, `$client`, migration runner, or platform schema registry. Registration remains database-free. The same frozen database facade is supplied to module lifecycle hooks and HTTP handlers. Migrations remain an explicit deployment operation and never run during application startup. Normal shutdown ordering is: 1. Drain and close HTTP. 2. Stop the module runtime while database access remains available. 3. Close the PostgreSQL pool. ## Verification * Root: 41 tests * Contracts: 111 tests * Module SDK: 5 tests * Module template: 5 tests * Core: 338 tests * API: 145 tests * Total unit tests: 645 * PostgreSQL integration: 114 tests * `pnpm verify`: passed * `pnpm test:migrations:integration`: passed * Doctor: `READY WITH WARNINGS` * `pnpm migrations:validate`: passed * `git diff --check`: clean Production migration contents and checksums remain unchanged. No production schema, manifest contract, `manifestVersion`, dependency, lockfile, route contract, or Hono-boundary changes were introduced. ## Commits 1. `0e308eb9` — feat: define module database access 2. `d1b9efd4` — test: prove module database access with PostgreSQL 3. `c38b5727` — docs: document module database access
Zayin_Admin added 3 commits 2026-07-26 02:58:33 +00:00
Introduce ModuleDatabase (a typed, restricted Drizzle query surface) and the frozen
ModuleRuntimeServices boundary in @ekklesia/contracts, and thread the same services object
through Core's module start/stop lifecycle hooks and apps/api's authorized module HTTP handler
context. apps/api builds the facade via a new core/src/modules/database.ts view (createModuleDatabaseView)
over the one existing shared PostgreSQL pool, alongside the identity and authorization views, and
wires it into startApi's fixed startup order ahead of Identity/Authorization construction.
Registration stays database-free; a module reaches its database only through an authorized start,
stop, or HTTP handler invocation.
Add a real installed-module fixture (core/tests/fixtures/module-database-integration/db-facade)
with its own manifest, Drizzle schema, drizzle-kit-generated migration, and permissioned HTTP
routes, then exercise it end to end in a new apps/api PostgreSQL integration suite: explicit
migration application before the module runtime starts (never auto-created), start/stop/HTTP
handlers sharing one ModuleDatabase facade by reference, authorized read/mutation/transaction
commit and rollback against real PostgreSQL, denied/rejected-origin/OPTIONS/HEAD requests never
reaching the module or its table, and both a module-caught and an uncaught real database failure
sanitizing exactly as pass 1 established. Registered alongside the existing suites in
vitest.migrations.integration.config.ts; no production code, schema, or migration changed.
docs: document module database access
CI / verify (pull_request) Successful in 27s
CI / infrastructure-smoke (pull_request) Successful in 20s
CI / migration-smoke (pull_request) Successful in 29s
c38b572778
Add ADR 0016 recording the accepted module database access design (ModuleDatabase, the frozen
ModuleRuntimeServices boundary, one pool/one facade/one services-object identity, explicit
migrations, and the trust model), with narrow cross-reference corrections to ADR 0006 and ADR 0015
where their original text is now inaccurate. Sweep docs/development/api.md,
docs/development/authorization.md, docs/module-development/README.md, docs/development/testing.md,
and docs/development/identity.md for the new database boundary and remaining Phase 4C staleness;
correct the stale "Phase 4C is next" roadmap paragraph in platform-architecture.md and the matching
gap in README's current-status narrative. Extend the module template with a permissioned
GET /records route reading through context.services.database, using the canonical
createModuleTable helper, with matching template tests.
Zayin_Admin merged commit 5e09330001 into main 2026-07-26 03:01:34 +00:00
Zayin_Admin deleted branch phase-5/module-database-access 2026-07-26 03:01:34 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Zayin/Ekklesia#13