Sync Repo-docs-MODULE-ARCHITECTURE from project files

2026-07-07 09:41:10 +02:00
parent 3147c7deb7
commit 4233283668

@@ -1,4 +1,4 @@
<!-- codex-wiki-sync:1e5412d3886cc08717c3e330 -->
<!-- codex-wiki-sync:09c0491dd182c85f3a2ff2a2 -->
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/MODULE_ARCHITECTURE.md`.
> Origin: `repository`.
@@ -65,6 +65,8 @@ Core must not import module feature pages or module business logic directly. It
The following contracts are the baseline API that modules can rely on:
- `ModuleManifest`
- `ModuleCompatibility`
- module uninstall guard provider contract
- `MigrationSpec`
- route factory contract
- capability factory contract
@@ -176,12 +178,15 @@ files = "govoplan_files.backend.manifest:get_manifest"
The manifest should declare:
- `id`, `name`, `version`
- `compatibility` when the module needs a minimum/maximum core version or a
newer manifest contract
- 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
- uninstall guard providers for data, migration, worker, or scheduler vetoes
Backend nav metadata must use icon-name strings, not frontend components:
@@ -373,6 +378,11 @@ Hot enable/disable is a core design principle for every module:
configure module runtime references, but they must not start workers,
schedulers, or irreversible external subscriptions. Use lifecycle hooks for
those resources.
- Modules that own persistent data, background jobs, schedulers, external
subscriptions, or irreversible migration state must expose uninstall guard
providers through their manifest. Guards return `blocker`, `warning`, or
`info` results and may inspect live state through the core-owned DB session.
A guard failure is treated as a blocker.
- Core refreshes the active registry before frontend metadata is returned from
`/api/v1/platform/modules`; the WebUI shell refetches this metadata after
module changes so navigation, routes, and UI capabilities update without a
@@ -401,19 +411,32 @@ The package install-plan API records operator intent only:
after preflight passes, snapshots `pip freeze` and WebUI package files, writes
a run record under the runtime installer directory, and marks planned rows as
applied after success.
- `govoplan-module-installer --supervise --health-url http://127.0.0.1:8000/health --restart-command '<restart govoplan server>'`
is the preferred disruptive-change path. It applies the plan, runs the
restart command if provided, polls health, and automatically rolls packages
back from the run snapshot if commands, restart, or health recovery fail.
- `govoplan-module-installer --rollback <run-id>` restores the saved package
snapshots and reruns package installation from the previous freeze file.
The installer preflight is intentionally conservative:
- maintenance mode must be active;
- installed module manifests must be compatible with the supported manifest
contract and current core version;
- uninstalling `tenancy`, `access`, or `admin` is blocked;
- uninstalling an active module is blocked;
- uninstalling a module still present in desired startup state is blocked;
- uninstalling a module with active/desired dependents is blocked;
- module-owned uninstall guard providers can veto data/migration/worker unsafe
removals;
- install refs must be exact versions or tagged git refs;
- WebUI package changes require a WebUI root and trigger rebuild/reload status.
The installer supervisor must run outside the FastAPI server process. A server
request handler cannot reliably restart or roll back the process that is
currently executing the request. The admin UI therefore remains an operator
planning surface; the trusted daemon/CLI is the executor.
The running FastAPI server still reports `package_mutation_supported=false`
because dependency-manager operations are not executed inside request handlers.
The trusted mutation boundary is the operator CLI. This keeps the interpreter,