Files
Ekklesia/docs/architecture/platform-architecture.md
T
ekklesia 831a48187c
CI / verify (pull_request) Successful in 19s
CI / infrastructure-smoke (pull_request) Successful in 21s
CI / migration-smoke (pull_request) Failing after 16s
test: add PostgreSQL migration integration coverage
2026-07-21 09:37:15 -05:00

78 lines
4.3 KiB
Markdown

# Platform architecture
Ekklesia is a long-lived platform from which churches can compose many applications and user
experiences. It begins as a modular monolith so contracts can stabilize before distribution is
introduced.
## Dependency model
The arrows below mean "depends on." Presentation and composition depend on stable lower-level
contracts; infrastructure never learns individual feature names.
```text
Surface Builder configuration -> Surfaces -> public capability contracts
^
|
HTTP/API and client contracts
|
Feature Modules -> Module SDK / platform contracts <- Core implementations
```
The four ownership layers are:
1. **Core** orchestrates generic platform infrastructure: startup, identity, permissions,
configuration, database connectivity, storage, events, jobs, module discovery, and lifecycle.
2. **Modules** own backend domain behavior, data schemas, resources, actions, routes, events,
permissions, and jobs.
3. **Surfaces** own every presentation concern: components, renderers, layout, navigation,
accessibility, interaction, branding, and client state.
4. **Surface Builder** stores validated declarative composition. It selects capabilities and
surface-owned renderers but contains neither executable code nor module business logic.
Modules do not own UI. For example, Calendar data, actions, and permissions will live in
`modules/calendar`; Calendar renderers for a dashboard or public website will live in those
surfaces.
## Stable seams
- Modules use public SDK ports and injected Core services, never undocumented Core internals.
- Modules do not import another module's schema or private code. Integrations use public service
contracts, capabilities, events, or APIs.
- Surfaces consume API/client and capability contracts, never feature-module packages.
- Core discovers feature modules generically. It contains no feature-specific imports or
conditional branches.
- Deployable apps are thin composition roots and do not become domain-logic owners.
- Generated bootstrap artifacts may connect discovered entry points at the application edge;
they do not become manually maintained Core registries.
## Security invariants
- Authorization is enforced server-side.
- Secrets are isolated from public configuration and logs.
- Authentication tokens, private form content, prayer requests, and pastoral information are not
logged.
- Sensitive actions are designed for auditability without copying sensitive content into audit
records.
- Private objects use signed access and namespaced storage paths.
- Every network service starts from least-privilege and local-only development defaults.
## Current implementation status
Implemented now: the Phase 1 repository and infrastructure foundation plus public module contracts,
static versioned manifests, independent capability versions and dependency ranges, automatic
filesystem discovery, compiled server loading, runtime-definition verification, staged capability
registration, dependency-ordered startup and reverse shutdown, rollback, and a backend-only module
template. Optional compiled schema entrypoints now contribute validated, namespaced module-owned
Drizzle tables to a deterministic aggregate without connecting to a database. Optional module-owned
Drizzle migration directories now produce an atomic dependency-ordered offline inventory with
validated metadata, explicit destructive-change declarations, and exact SHA-256 checksums. Core can
now compare that inventory with its fixed PostgreSQL history table, produce a read-only plan, and
apply the complete pending batch under a session advisory lock and one transaction. Destructive
migrations require an exact externally supplied approval bound to module, identity, and checksum.
Hermetic integration coverage now exercises those contracts through the production adapter against
the pinned PostgreSQL container, including real DDL rollback and advisory-lock concurrency.
Target architecture, not yet implemented: production approval-provider composition, Better Auth,
permission enforcement, physical storage-bucket provisioning, Surface SDK, richer public resource
and action contracts, API server, dashboard, Builder, and reference feature modules.