Sync Repo-docs-MODULE-ARCHITECTURE from project files
@@ -1,4 +1,4 @@
|
||||
<!-- codex-wiki-sync:bb7422b551349eda3e934059 -->
|
||||
<!-- codex-wiki-sync:b5012b7cacc0ba3fc59eae7f -->
|
||||
|
||||
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/MODULE_ARCHITECTURE.md`.
|
||||
> Origin: `repository`.
|
||||
@@ -334,6 +334,101 @@ Any future exception is extraction debt and must be temporary, documented in the
|
||||
script with a reason, and removed when a capability/API/event contract replaces
|
||||
it.
|
||||
|
||||
## Module Lifecycle
|
||||
|
||||
Core exposes the installed module catalog through the admin API and WebUI. The
|
||||
current lifecycle model separates four states:
|
||||
|
||||
- installed: the Python/WebUI package is available to the process
|
||||
- active: the module is present in the running platform registry
|
||||
- desired: the module should be active on the next server startup
|
||||
- planned package change: an operator-reviewed package install/uninstall item
|
||||
saved in system settings but not executed by the running server
|
||||
|
||||
The admin module manager can change the desired enabled set and apply it to the
|
||||
running server. It always keeps `tenancy`, `access`, and `admin` enabled when
|
||||
saving through the admin UI, and it adds required module dependencies before
|
||||
saving the desired state. On startup, core always keeps the minimum
|
||||
authenticated platform set `tenancy`/`access` enabled and keeps `admin` enabled
|
||||
when the operator configuration includes it. Unknown saved module ids are
|
||||
ignored when the matching package is no longer installed. The core app factory,
|
||||
devserver, development bootstrap, background worker registry, and migration
|
||||
metadata plan all read the saved desired state from `system_settings` before
|
||||
building their module registry.
|
||||
|
||||
Hot enable/disable is a core design principle for every module:
|
||||
|
||||
- Core keeps one mutable active `PlatformRegistry` object and swaps its manifest
|
||||
set through the module lifecycle manager. Modules must read module presence,
|
||||
optional integrations, permissions, role templates, capabilities, navigation,
|
||||
and frontend contributions from that registry instead of caching sibling
|
||||
module availability.
|
||||
- Core validates install state and dependency closure before activation.
|
||||
- Core applies configured module migrations before activation. Deactivation
|
||||
never drops tables or data.
|
||||
- Core mounts module routers once and guards them by active module state. A
|
||||
deactivated module's routes remain mounted internally but return a disabled
|
||||
module response until the module is active again.
|
||||
- Module route factories must be side-effect-light and idempotent. They may
|
||||
configure module runtime references, but they must not start workers,
|
||||
schedulers, or irreversible external subscriptions. Use lifecycle hooks for
|
||||
those resources.
|
||||
- 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
|
||||
page reload.
|
||||
- Modules can provide `on_activate` and `on_deactivate` hooks for worker,
|
||||
scheduler, cache, or external subscription lifecycle. These hooks must be
|
||||
idempotent and must not mutate another module directly.
|
||||
- Package install/uninstall remains a deployment/operator action unless the
|
||||
runtime provides a trusted package installer and rollback path. The admin UI
|
||||
can activate/deactivate installed packages; it must not remove package files
|
||||
or attempt dependency-manager operations in-process.
|
||||
|
||||
The package install-plan API records operator intent only:
|
||||
|
||||
- `GET /api/v1/admin/system/modules/install-plan` reads the saved plan and
|
||||
renders shell commands for the operator.
|
||||
- `PUT /api/v1/admin/system/modules/install-plan` saves planned install or
|
||||
uninstall rows. Install rows must use tagged package or git references, not
|
||||
local `file:`/workspace paths.
|
||||
- `DELETE /api/v1/admin/system/modules/install-plan` clears the plan.
|
||||
- `govoplan-module-install-plan --format shell` or
|
||||
`python -m govoplan_core.commands.module_install_plan --format shell` renders
|
||||
the same commands from a server shell.
|
||||
|
||||
The running server intentionally reports `install_uninstall_supported=false`
|
||||
and `package_mutation_supported=false`. This is by design: mutating the
|
||||
interpreter environment, npm dependency graph, frontend bundle, migrations, and
|
||||
worker process set from inside the same running app is not safe without a
|
||||
separate trusted installer, rollback model, and bundle loader.
|
||||
|
||||
## Maintenance Mode
|
||||
|
||||
Maintenance mode is the required operating state for package install/uninstall
|
||||
and other disruptive system maintenance.
|
||||
|
||||
Core stores maintenance mode in `system_settings.settings.maintenance_mode`.
|
||||
The public platform status endpoint exposes only the flag and message so the
|
||||
WebUI can show a clear login-screen notice. Login remains reachable during
|
||||
maintenance so an operator can sign in.
|
||||
|
||||
Authenticated API access is enforced at the access-principal boundary. When
|
||||
maintenance mode is enabled, authenticated requests require the system scope
|
||||
`system:maintenance:access`; otherwise the API returns `503 Service
|
||||
Unavailable` with a maintenance-mode detail payload. The protected
|
||||
`system_owner` role grants this through `system:*`. A dedicated
|
||||
`maintenance_operator` role exists for accounts that should be able to access
|
||||
the system during maintenance without receiving broad write permissions.
|
||||
|
||||
Changing the maintenance-mode flag requires both system settings write access
|
||||
and `system:maintenance:access`, so an administrator cannot accidentally enable
|
||||
a mode they cannot use.
|
||||
|
||||
The first implementation is a platform access gate. It does not replace
|
||||
database backups, process supervision, migration checks, or external load
|
||||
balancer maintenance pages.
|
||||
|
||||
## Build And Verification
|
||||
|
||||
Backend verification from core:
|
||||
|
||||
Reference in New Issue
Block a user