100 lines
2.8 KiB
Markdown
100 lines
2.8 KiB
Markdown
# Module development
|
|
|
|
An Ekklesia module is a backend capability package. It owns business behavior and data declarations;
|
|
it never owns components, styles, layouts, renderers, navigation, or other UI.
|
|
|
|
## Required package shape
|
|
|
|
Each immediate child of `modules/` must contain:
|
|
|
|
```text
|
|
modules/example/
|
|
├── ekklesia.module.json
|
|
├── package.json
|
|
└── src/server/index.ts
|
|
```
|
|
|
|
`package.json` must use ESM, a strict semantic version, a unique package name, and:
|
|
|
|
```json
|
|
{
|
|
"ekklesia": {
|
|
"layer": "module"
|
|
}
|
|
}
|
|
```
|
|
|
|
Its version must match the module manifest version. Internal package dependencies use `workspace:`
|
|
ranges and supported package entrypoints.
|
|
|
|
## Manifest
|
|
|
|
The canonical manifest is inert JSON so discovery can validate a module without executing it:
|
|
|
|
```json
|
|
{
|
|
"manifestVersion": 1,
|
|
"id": "calendar",
|
|
"name": "Calendar",
|
|
"version": "0.1.0",
|
|
"compatibility": {
|
|
"platform": "^0.1.0",
|
|
"moduleSdk": "^0.1.0"
|
|
},
|
|
"dependencies": {
|
|
"modules": {
|
|
"required": {
|
|
"people": "^0.1.0"
|
|
}
|
|
},
|
|
"capabilities": {
|
|
"optional": ["media.items"]
|
|
}
|
|
},
|
|
"capabilities": ["calendar.events"],
|
|
"permissions": ["calendar.events.read"],
|
|
"storage": {
|
|
"buckets": [
|
|
{
|
|
"id": "assets",
|
|
"description": "Private event assets owned by Calendar."
|
|
}
|
|
]
|
|
},
|
|
"entrypoints": {
|
|
"server": "./src/server/index.ts"
|
|
}
|
|
}
|
|
```
|
|
|
|
Module, capability, and permission identifiers are lowercase and namespaced. Entrypoints must begin
|
|
with `./`, stay inside the package, and exist. Unknown manifest properties are rejected, including
|
|
presentation fields such as components or renderers.
|
|
|
|
Storage bucket IDs are logical names scoped to the module. Modules may request multiple buckets.
|
|
Core will later map them to deployment-specific physical S3 buckets and provide scoped access;
|
|
module code must not configure SeaweedFS or other S3 clients directly.
|
|
|
|
## Discovery behavior
|
|
|
|
Run:
|
|
|
|
```bash
|
|
pnpm modules:validate
|
|
```
|
|
|
|
Discovery checks every installed module atomically. It rejects malformed manifests, duplicate IDs
|
|
or package names, version mismatches, incompatible platform or SDK ranges, missing required modules
|
|
or capabilities, incompatible installed dependencies, cycles, and missing or escaping entrypoints.
|
|
Missing optional dependencies are allowed. Valid modules are ordered dependency-first with stable
|
|
identifier sorting.
|
|
|
|
Discovery does not load server code. Lifecycle execution, route/job registration, Drizzle schema
|
|
aggregation and migrations, and physical bucket provisioning are deliberately deferred.
|
|
|
|
## Start from the template
|
|
|
|
Copy `templates/module` to `modules/<your-module-id>` and follow its README. The template is part of
|
|
the workspace and is validated by the same contracts and discovery implementation as installed
|
|
modules.
|