Prepare GovOPlaN self-hosted release workflow
Some checks failed
Dependency Audit / dependency-audit (push) Failing after 50s
Module Matrix / module-matrix (push) Failing after 49s

This commit is contained in:
2026-07-10 21:57:22 +02:00
parent 8dd5123aab
commit 94236a7d7e
51 changed files with 3576 additions and 803 deletions

View File

@@ -80,6 +80,7 @@ The following contracts are the baseline API that modules can rely on:
- `ModuleManifest`
- `ModuleCompatibility`
- named interface contract provider/requirement metadata
- module uninstall guard provider contract
- `MigrationSpec`
- route factory contract
@@ -125,6 +126,50 @@ Feature modules should prefer these capabilities over direct reads of
access/tenant ORM models when they need labels, group membership, default
access provisioning, counts, audit actor labels, or tenant metadata.
### Named Interface Contracts
Capabilities are runtime objects. Named interface contracts are compatibility
metadata. A module uses them when it depends on a versioned cross-module API
shape but should not hard-code a package or repository release line.
Manifest fields:
- `provides_interfaces`: contracts this module provides, each with `name` and
`version`
- `requires_interfaces`: contracts this module needs, each with `name`,
optional `version_min`, optional `version_max_exclusive`, and optional
`optional: true`
Interface names use dot-separated lower-case identifiers such as
`files.spaces` or `mail.delivery`. A requirement range is interpreted as
`>= version_min` and `< version_max_exclusive`; the exclusive upper bound is
intended for SemVer major-version lines. Missing optional interfaces are
allowed, but an installed provider with an incompatible version blocks
activation because the integration would otherwise bind to an unsafe API.
Current named interfaces:
- `files.campaign_attachments`
- `mail.campaign_delivery`
- `campaigns.access`
- `campaigns.delivery_tasks`
- `campaigns.mail_policy_context`
- `campaigns.policy_context`
- `campaigns.retention`
Core validates named interface contracts in three places:
- registry activation rejects missing required interfaces and incompatible
providers
- installer preflight reports the same failures before a module set is
activated
- signed catalog validation normalizes the metadata and warns when catalog
entries cannot satisfy each other's ranges
Module-id dependencies still decide startup ordering and mandatory package
presence. Named interfaces decide whether the versions in the active module
set are compatible.
FastAPI route dependencies for authenticated endpoints are imported from the
core `govoplan_core.auth` facade. Routers may import that public API for
`ApiPrincipal`, `get_api_principal`, `has_scope`, `require_scope`, and
@@ -450,6 +495,8 @@ Modules should provide:
- pinned backend and WebUI package refs for official catalog entries
- compatibility metadata in the module manifest
- named interface contracts in the manifest and catalog entry when the module
provides or consumes cross-module APIs
- lifecycle hooks when a runtime enable/disable action needs module-specific
work
- uninstall guards for persistent data, active workers, schedulers, or external
@@ -621,6 +668,10 @@ The repository includes `scripts/check_dependency_boundaries.py`. It enforces th
- access source may not import files/mail/campaign internals
- feature modules may not import access implementation internals
- feature modules may not add new direct imports of sibling feature modules
- feature WebUI packages may not depend on or import sibling feature WebUI packages
- core WebUI may list module packages as host dependencies, but core WebUI source
may not import feature WebUI internals directly; module loading stays
declarative through the module contribution contract
- FastAPI routers import the core `govoplan_core.auth` dependency facade
- the transitional allowlist is expected to stay empty