Add governed module and interface controls
This commit is contained in:
@@ -834,6 +834,24 @@ the shared loading and retryable error state around route rendering. The
|
||||
initial static import closure and largest asynchronous chunk are enforced by
|
||||
the budgets documented in [WEBUI_BUNDLE_BUDGETS.md](WEBUI_BUNDLE_BUDGETS.md).
|
||||
|
||||
Every public platform interface has a stable declaration identity. Backend
|
||||
routes, capabilities, interfaces, search providers/sources, permissions,
|
||||
frontend routes/navigation, and View surfaces derive that identity from typed
|
||||
`ModuleManifest` values. Typed WebUI capabilities declare IDs for settings,
|
||||
admin sections, widgets, search contexts, and extension actions. Shared form
|
||||
and action controls accept `interfaceId` and `helpTopicId`; use module-namespaced
|
||||
values when another contract, documentation topic, or automated check must
|
||||
refer to the control across source changes. The static inventory assigns a
|
||||
line-independent source anchor when an explicit ID is absent and reports that
|
||||
fact for later review.
|
||||
|
||||
Core exposes the sanitized runtime declaration set at
|
||||
`GET /api/v1/platform/interface-catalog`. The endpoint is read-only, requires
|
||||
`admin:module:read` or `system:settings:read`, and includes only modules
|
||||
effective in the caller's active tenant context. It never serializes factories,
|
||||
credentials, executable callbacks, or mutable module state. Registry validation
|
||||
rejects conflicting declaration IDs before startup.
|
||||
|
||||
WebUI modules receive only the core route context:
|
||||
|
||||
- `settings`
|
||||
@@ -1239,6 +1257,40 @@ devserver, development bootstrap, background worker registry, and migration
|
||||
metadata plan all read the saved desired state from `system_settings` before
|
||||
building their module registry.
|
||||
|
||||
### Tenant entitlement and personal visibility
|
||||
|
||||
Deployment activation remains process-wide: one installed and active registry
|
||||
is shared by every tenant served by that process. Tenant module selection is a
|
||||
separate entitlement document in `core_scopes.settings.module_entitlements`:
|
||||
|
||||
- a system policy marks each installed module `unavailable`, `available`, or
|
||||
`forced` for one tenant;
|
||||
- the tenant selection may enable or disable only available modules;
|
||||
- protected platform modules, forced modules, and transitive dependencies stay
|
||||
effective;
|
||||
- malformed explicit entitlement fails closed to protected modules, while an
|
||||
absent document preserves the pre-entitlement behavior for upgraded tenants;
|
||||
- an optimistic revision prevents concurrent system and tenant administrators
|
||||
from silently replacing each other's changes.
|
||||
|
||||
The authenticated platform metadata and module route guard intersect global
|
||||
runtime activation with the active tenant's effective entitlement. Entitlement
|
||||
does not grant a permission. Access authorization must still allow every API
|
||||
operation and resource.
|
||||
|
||||
Users and groups do not own another module-runtime state. Every WebUI module
|
||||
already contributes a root `<module>.module` View surface, so personal and
|
||||
group module visibility is expressed through Views. View policy controls who
|
||||
may select, assign, edit, derive, or workflow-activate those projections;
|
||||
required View assignments can retain required UI. Thus tenant entitlement owns
|
||||
operational availability, Views own presentation, and Access owns authority.
|
||||
|
||||
Capability-style modules such as Encryption must keep activation separate from
|
||||
domain data state. Making Encryption effective only exposes its capability and
|
||||
administration surfaces. Encrypting, rekeying, decrypting, or migrating data is
|
||||
an explicit versioned protection-policy operation owned by Encryption and the
|
||||
module that owns the data.
|
||||
|
||||
Hot enable/disable is a core design principle for every module:
|
||||
|
||||
- Core keeps one mutable active `PlatformRegistry` object and swaps its manifest
|
||||
|
||||
Reference in New Issue
Block a user