Files
govoplan-docs/src/govoplan_docs/backend/manifest.py
2026-07-11 16:49:01 +02:00

181 lines
8.8 KiB
Python

from __future__ import annotations
from govoplan_core.core.access import CAPABILITY_AUTH_PERMISSION_EVALUATOR, CAPABILITY_AUTH_PRINCIPAL_RESOLVER
from govoplan_core.core.modules import (
DocumentationLink,
DocumentationTopic,
FrontendModule,
FrontendRoute,
ModuleContext,
ModuleManifest,
NavItem,
PermissionDefinition,
RoleTemplate,
)
DOCS_READ_SCOPE = "docs:documentation:read"
DOCS_READ_SCOPES = (DOCS_READ_SCOPE, "system:settings:read", "admin:settings:read")
def _permission(scope: str, label: str, description: str) -> PermissionDefinition:
module_id, resource, action = scope.split(":", 2)
return PermissionDefinition(
scope=scope,
label=label,
description=description,
category="Documentation",
level="tenant",
module_id=module_id,
resource=resource,
action=action,
)
def _route_factory(context: ModuleContext):
del context
from govoplan_docs.backend.api.v1.routes import router
return router
manifest = ModuleManifest(
id="docs",
name="Docs",
version="0.1.8",
required_capabilities=(CAPABILITY_AUTH_PRINCIPAL_RESOLVER, CAPABILITY_AUTH_PERMISSION_EVALUATOR),
optional_dependencies=("policy", "audit", "ops", "workflow", "search"),
permissions=(
_permission(
DOCS_READ_SCOPE,
"View configured documentation",
"Read documentation generated from installed modules, visible routes, permissions, and evidence sources.",
),
),
role_templates=(
RoleTemplate(
slug="docs_reader",
name="Documentation reader",
description="Read the configured-system documentation browser.",
permissions=(DOCS_READ_SCOPE,),
),
),
route_factory=_route_factory,
nav_items=(NavItem(path="/docs", label="Docs", icon="reports", required_any=DOCS_READ_SCOPES, order=880),),
frontend=FrontendModule(
module_id="docs",
package_name="@govoplan/docs-webui",
routes=(FrontendRoute(path="/docs", component="DocsPage", required_any=DOCS_READ_SCOPES, order=880),),
nav_items=(NavItem(path="/docs", label="Docs", icon="reports", required_any=DOCS_READ_SCOPES, order=880),),
),
documentation=(
DocumentationTopic(
id="docs.configured-system-documentation",
title="Configured system documentation",
summary="This documentation page starts with installed modules, active configuration, visible routes, and permissions for the current actor.",
body="Module manifests can contribute durable documentation topics. Modules can also register runtime documentation providers when content depends on tenant policy, installed integrations, or operational settings.",
layer="always",
documentation_types=("admin", "user"),
audience=("tenant_admin", "operator", "module_admin"),
order=10,
i18n_key="docs.topic.configured_system_documentation",
translations={
"de": {
"title": "Dokumentation dieses Systems",
"summary": "Diese Dokumentation beginnt mit den installierten Modulen, der aktiven Konfiguration und den Funktionen, die fuer diese Rolle sichtbar sind.",
"body": "Module koennen feste Dokumentationsabschnitte beitragen. Wenn Inhalte von Tenant-Regeln, installierten Integrationen oder Betriebsoptionen abhaengen, kann ein Modul laufzeitbasierte Dokumentation registrieren.",
},
},
links=(
DocumentationLink(
label="Public GovOPlaN module documentation",
href="https://govplan.add-ideas.de/",
kind="public",
),
DocumentationLink(
label="Documentation layer concept",
href="govoplan-docs/docs/DOCUMENTATION_LAYER_CONCEPT.md",
kind="repository",
),
DocumentationLink(
label="Instance-aware documentation contract",
href="govoplan-docs/docs/INSTANCE_AWARE_DOCUMENTATION.md",
kind="repository",
),
),
metadata={"kind": "system"},
),
DocumentationTopic(
id="docs.pattern.field-help",
title="Field help marker",
summary="A small help marker next to a label gives local context without turning dense forms into manuals.",
body="Use the marker for short explanations of a field, option, or compact term. Link to a workflow or reference topic when the reader needs steps, API mapping, policy provenance, or operational detail.",
layer="always",
documentation_types=("admin", "user"),
audience=("user", "tenant_admin", "operator", "module_admin"),
order=20,
i18n_key="docs.topic.pattern.field_help",
links=(
DocumentationLink(
label="Documentation experience concept",
href="govoplan-docs/docs/DOCUMENTATION_EXPERIENCE_CONCEPT.md",
kind="repository",
),
),
metadata={
"kind": "pattern",
"pattern_id": "field-help-marker",
"purpose": "Keep labels scannable while making short explanations available on demand.",
"when_used": "Form labels, toggle labels, effective-value rows, and compact admin terms.",
"user_explanation": "Open the marker when a label is unclear. It should explain the local choice in one or two sentences.",
"admin_explanation": "Field help stays local. Longer procedural, API, or policy explanations belong in linked workflow or reference topics.",
"component_refs": [
"govoplan-core/webui/src/components/help/FieldLabel.tsx",
"govoplan-core/webui/src/components/help/InlineHelp.tsx",
"govoplan-core/webui/src/utils/fieldHelp.ts",
],
"related_topic_ids": [
"access.reference.admin-access-fields",
"access.workflow.grant-user-access",
],
},
),
DocumentationTopic(
id="docs.reference.organization-identity-idm-access-boundary",
title="Organization, identity, IDM, and access boundary",
summary="Organizations defines structures and functions. Identity defines people and accounts. IDM links identities to functions. Access turns accepted facts into roles and rights.",
body=(
"Use Organizations to model units, structures, relations, and function definitions. "
"Use Identity to maintain normalized identities and account links. "
"Use IDM to link an identity or account to a function in an organization unit, including delegated or acting-for cases. "
"Use Access to map accepted function facts to roles and permissions. "
"This split keeps organization modeling separate from identity lifecycle and keeps authorization decisions explicit."
),
layer="configured",
documentation_types=("admin", "user"),
audience=("tenant_admin", "access_admin", "operator", "user"),
related_modules=("organizations", "identity", "idm", "access"),
order=21,
links=(
DocumentationLink(label="Organizations", href="/organizations", kind="runtime"),
DocumentationLink(label="IDM assignments", href="/idm", kind="runtime"),
DocumentationLink(label="Access administration", href="/admin", kind="runtime"),
),
metadata={
"kind": "reference",
"admin_explanation": "Function-to-role effects are owned by Access. IDM assignment changes can be governed independently from organization model changes.",
"user_explanation": "A person can hold a function because IDM links their identity to the organization function. Access decides which application permissions that function gives.",
"module_boundaries": [
{"module": "organizations", "owns": "unit types, structures, relations, units, and function definitions"},
{"module": "identity", "owns": "identities and account links"},
{"module": "idm", "owns": "identity-to-function assignments, delegation, acting-for links, and synchronization mapping"},
{"module": "access", "owns": "roles, permissions, and accepted function-to-role mappings"},
],
},
),
),
)
def get_manifest() -> ModuleManifest:
return manifest