3.0 KiB
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)
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)
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.