campaign sending prototype
This commit is contained in:
176
docs/MODULE_ARCHITECTURE.md
Normal file
176
docs/MODULE_ARCHITECTURE.md
Normal file
@@ -0,0 +1,176 @@
|
||||
# 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
|
||||
```
|
||||
|
||||
Wrapper WebUI verification, while the legacy wrapper still exists:
|
||||
|
||||
```bash
|
||||
cd /mnt/DATA/git/multi-seal-mail-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.
|
||||
Reference in New Issue
Block a user