From 8b126226f5ff5c1504ff55275a25b9325c412e52 Mon Sep 17 00:00:00 2001 From: kpcto Date: Thu, 27 Aug 2026 17:22:08 +0000 Subject: [PATCH] Create Extension-Architecture wiki page --- Extension-Architecture.-.md | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 Extension-Architecture.-.md diff --git a/Extension-Architecture.-.md b/Extension-Architecture.-.md new file mode 100644 index 0000000..79b373b --- /dev/null +++ b/Extension-Architecture.-.md @@ -0,0 +1,50 @@ +# Extension architecture + +Internal Fastify plugins (organise server internals) are a deliberately different concept from **EPPP extensions** (the public product contract). An EPPP extension never receives unrestricted Fastify/Kysely access. + +## Manifest v1 (§16.2) + +`ExtensionManifestV1`: id, name, version, `extensionApiVersion: "1"`, minimumCoreVersion, type (`theme`|`feature`|`content`|`integration`), dependencies, capabilities, settingsSchema, contributes (routes/contentTypes/blocks/sections/themes/jobs/events/admin). + +IDs must be namespaced (`org.eppp.reading`, `org.eppp.theme-amber`, `com.example.gallery`); unqualified IDs (`reading`, `theme1`) are rejected. + +## Extension context v1 (§16.3) + +`ExtensionContextV1` exposes only narrow EPPP-owned services: `extension`, `settings`, `routes`, `contentTypes`, `blocks`, `sections`, `themes`, `jobs`, `events`, `storage`, `logger`. Raw Fastify instance, Kysely instance, pg pool, and application internals are never exposed through the public SDK. + +## Lifecycle states (§16.4) + +`installed → disabled / enabled / error / incompatible`. Disabled extensions retain data/settings but deactivate contributions. Incompatible or failed optional extensions provide diagnostics without taking unrelated public features down. + +## Trust model (§16.5) + +Extensions are **trusted deploy-time code**: package exists in build config → installed during image build → EPPP discovers/validates → admin enables/configures. No v1 workflow uploads and executes arbitrary npm packages. A future marketplace is a separate security architecture (provenance, signatures, scanning, capability enforcement, isolation, rollback). + +## Activation sequence (§17) + +```text +manifest valid? → API version supported? → core version satisfies range? +→ dependencies present? → migrations successful? → settings validate? +→ activate contributions +``` + +Failures map to `incompatible` / `error` / `config-error` states; diagnostics visible in admin and structured logs. + +## Extension package layout (§61) + +```text +extensions/reading/ + package.json · eppp.manifest.json + server/{index.ts, migrations/, jobs/, repositories/} + admin/index.tsx · public/islands/ · styles/ · tests/ +``` + +Only documented entry points are importable; extensions never import arbitrary EPPP internal files. + +## Engineering conventions (§62) + +No raw Fastify/Kysely/pg in the SDK; no generic `everythingContext`; no direct extension-to-extension internal import; real needs drive hooks (avoid speculative hook explosion); server/database internals never enter browser bundles; stored content references stable semantic IDs; framework upgrades hidden behind EPPP contracts; architecture rules automated in CI when mechanically enforceable. + +## Validation (§22) + +JSON Schema is canonical for HTTP input, selected HTTP output, extension manifests/settings, block props, page section settings, import/export documents, and selected event payloads. TypeBox authors typed schemas; Ajv validates runtime data. **TypeScript types are not runtime validation.**