Files
govoplan-core/docs/MODULE_ARCHITECTURE.md
2026-06-25 19:58:20 +02:00

180 lines
7.1 KiB
Markdown

# GovOPlaN Module Architecture
GovOPlaN is structured as a core platform runner plus installable feature modules. Core owns the runtime shell and cross-cutting primitives. Modules own feature behavior and contribute backend routes, database metadata, permissions, WebUI routes, and navigation metadata.
## Core Responsibilities
Core owns:
- the server entry point and platform configuration
- module discovery, registry validation, route aggregation, and platform metadata APIs
- database engine/session primitives and migration orchestration
- auth, tenants, RBAC, governance, audit, CSRF/API helpers, and secret helpers
- shared WebUI shell components such as `AppShell`, `IconRail`, `DataGrid`, `ExplorerTree`, `MessageDisplayPanel`, dialogs, loading frames, access boundaries, and form primitives
- centralized mapping from serializable icon names to renderable frontend icons
Core must not import module feature pages or module business logic directly. It should interact with modules through manifests, entry points, metadata, and route contributions.
## Module Responsibilities
A module owns one bounded feature area. A module can include both backend and WebUI code in the same repository so feature behavior and frontend integration evolve together.
A module owns:
- backend routers and feature services
- SQLAlchemy models for module-owned tables
- module migrations and migration metadata
- module permissions and role templates
- module-specific schemas, policies, and domain rules
- WebUI pages, feature-specific components, API clients, route contributions, and navigation metadata
A module should not own generic platform UI. If a component is useful outside one module, move it to `@govoplan/core-webui` and parameterize it there before reusing it.
## Backend Contract
Backend modules register through the `govoplan.modules` entry point and expose a `ModuleManifest`.
Example:
```toml
[project.entry-points."govoplan.modules"]
files = "govoplan_files.backend.manifest:get_manifest"
```
The manifest should declare:
- `id`, `name`, `version`
- required `dependencies` and `optional_dependencies`
- permissions and role templates
- router factory
- migration metadata and script location
- frontend package metadata
- navigation metadata using serializable icon names
Backend nav metadata must use icon-name strings, not frontend components:
```python
NavItem(
path="/files",
label="Files",
icon="folder",
required_any=("files:file:read",),
order=40,
)
```
## Database And Migrations
Core owns the database/session lifecycle. Modules access the database through core session dependencies and register their models/migrations through their manifest.
Rules:
- Do not create independent database engines in modules.
- Use core session dependencies, base metadata, and migration orchestration.
- Keep module-owned tables and migrations in the module repository.
- Keep cross-module foreign-key assumptions explicit and conservative.
- Register module metadata in `MigrationSpec` so core can discover it.
## WebUI Contract
A WebUI module exports a `PlatformWebModule` from its package. The object contributes local/fallback metadata and route render functions.
Example:
```ts
export const filesModule: PlatformWebModule = {
id: "files",
label: "Files",
version: "1.0.0",
dependencies: ["access"],
navItems: [
{ to: "/files", label: "Files", iconName: "folder", anyOf: ["files:file:read"], order: 40 }
],
routes: [
{ path: "/files", anyOf: ["files:file:read"], order: 40, render: ({ settings, auth }) => createElement(FilesPage, { settings, auth }) }
]
};
```
WebUI modules receive only the core route context:
- `settings`
- `auth`
A module should call its own API client and module-owned backend routes. Shared API helpers should live in core only when they are truly platform-level concerns.
## Icon Rules
Icons are resolved centrally by core.
Modules must provide icon names with `iconName` in frontend nav contributions and `icon` in backend manifest metadata. Modules must not import Lucide icons for navigation metadata.
Current core icon names include:
- `activity`
- `campaign`
- `dashboard`
- `file`
- `files`
- `folder`
- `form`
- `mail`
- `reports`
- `users`
If a module needs a new navigation icon, add the name-to-component mapping in core first, then use the name in backend and frontend metadata.
## Shared Component Rules
Use this rule of thumb:
- If it is platform-level or likely reusable by more than one module, define it in `@govoplan/core-webui` with parameters.
- If it is feature-specific and only meaningful inside one bounded module, keep it in that module.
- Modules must not import components from another feature module.
- If one module needs a component currently owned by another module, promote a generic version into core and replace the old usage with the core component.
Examples:
- `ExplorerTree` is core because files, mailboxes, and future modules can all render hierarchical navigation.
- `MessageDisplayPanel` is core because mail, campaign sending, and later audit/review surfaces can display message-like content.
- `MailProfileManagement` remains in the mail module because it is specific to mail transport policies and profiles.
## Cross-Module Integration
A module can declare required dependencies and optional dependencies. Optional behavior should be enabled by module presence and permissions, not by importing another module's WebUI internals.
Rules:
- Use core module metadata to check whether another module is installed.
- Use backend APIs/events/service contracts for runtime cooperation.
- Keep UI integration declarative where possible: nav items, route contributions, context actions, and explicit extension points.
- Avoid direct imports from one feature module into another feature module unless the imported package is a published API contract designed for that purpose. UI components should be promoted to core instead.
## Build And Verification
Backend verification from core:
```bash
cd /mnt/DATA/git/govoplan-core
./.venv/bin/python -m compileall src/govoplan_core ../govoplan-files/src/govoplan_files ../govoplan-mail/src/govoplan_mail ../govoplan-campaign/src/govoplan_campaign
```
Core WebUI host verification:
```bash
cd /mnt/DATA/git/govoplan-core/webui
PATH=/home/zemion/.nvm/versions/node/v22.22.3/bin:$PATH /home/zemion/.nvm/versions/node/v22.22.3/bin/npm run build
```
Clean generated `dist`, `.vite`, and source-tree `__pycache__` artifacts after verification unless they are intentionally part of a release artifact.
## Release Dependency Rules
Local development may use editable Python installs and local WebUI `file:` dependencies so sibling module changes reload quickly. Release builds must use tagged git refs or published packages instead. Core provides:
- `requirements-dev.txt` for local editable backend installs
- `requirements-release.txt` for tagged backend module installs
- `webui/package.release.json` for tagged WebUI module installs
Module repositories include root-level npm manifests for git installs. When cutting a release, update the Python versions, WebUI versions, release dependency refs, and repository tags together.