Files
PersonalBlog/docs/extension-architecture.md
T
2026-08-27 08:16:42 +00:00

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.