feat: add tenant semantic documentation lifecycle
This commit is contained in:
@@ -1,30 +1,53 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from govoplan_core.core.access import (
|
||||
CAPABILITY_AUTH_PERMISSION_EVALUATOR,
|
||||
CAPABILITY_AUTH_PRINCIPAL_RESOLVER,
|
||||
)
|
||||
from govoplan_core.core.modules import (
|
||||
CapabilityDocumentation,
|
||||
DocumentationCondition,
|
||||
DocumentationLink,
|
||||
DocumentationSourceDefinition,
|
||||
DocumentationTopic,
|
||||
FrontendModule,
|
||||
FrontendRoute,
|
||||
MigrationSpec,
|
||||
ModuleContext,
|
||||
ModuleManifest,
|
||||
ModuleInterfaceProvider,
|
||||
NavItem,
|
||||
PermissionDefinition,
|
||||
RoleTemplate,
|
||||
)
|
||||
from govoplan_core.core.module_guards import (
|
||||
drop_table_retirement_provider,
|
||||
persistent_table_uninstall_guard,
|
||||
)
|
||||
from govoplan_core.core.provider_governance import (
|
||||
ModuleArchitectureDeclaration,
|
||||
ModuleArchitectureDocumentation,
|
||||
ModuleMaturityEvidence,
|
||||
)
|
||||
from govoplan_core.db.base import Base
|
||||
from govoplan_core.core.search import SearchSourceProviderRegistration
|
||||
from govoplan_docs.backend.db import models as docs_models
|
||||
from govoplan_docs.backend.dsar_provider import DOCS_DSAR_CAPABILITY, DocsDsarProvider
|
||||
from govoplan_docs.backend.search_source import (
|
||||
create_semantic_documentation_search_source,
|
||||
)
|
||||
|
||||
DOCS_READ_SCOPE = "docs:documentation:read"
|
||||
DOCS_ADMIN_READ_SCOPE = "docs:documentation:admin"
|
||||
DOCS_SEMANTIC_CREATE_SCOPE = "docs:semantic:create"
|
||||
DOCS_SEMANTIC_EDIT_SCOPE = "docs:semantic:edit"
|
||||
DOCS_SEMANTIC_PUBLISH_SCOPE = "docs:semantic:publish"
|
||||
DOCS_SEMANTIC_SUPERSEDE_SCOPE = "docs:semantic:supersede"
|
||||
DOCS_SEMANTIC_RETIRE_SCOPE = "docs:semantic:retire"
|
||||
DOCS_SEMANTIC_EXPORT_SCOPE = "docs:semantic:export"
|
||||
DOCS_SEMANTIC_POLICY_SCOPE = "docs:semantic:policy"
|
||||
DOCS_ADMIN_READ_SCOPES = (
|
||||
DOCS_ADMIN_READ_SCOPE,
|
||||
"system:settings:read",
|
||||
@@ -42,6 +65,11 @@ ARCHITECTURE = ModuleArchitectureDeclaration(
|
||||
reference="tests/test_docs_context.py",
|
||||
summary="Tests audience-safe configured documentation and architecture projections.",
|
||||
),
|
||||
ModuleMaturityEvidence(
|
||||
kind="test",
|
||||
reference="tests/test_semantic_documentation.py",
|
||||
summary="Tests tenant isolation, immutable revision lifecycle, publication policy, subject reauthorization, search, localization, and DSAR projection.",
|
||||
),
|
||||
ModuleMaturityEvidence(
|
||||
kind="documentation",
|
||||
reference="docs/DOCUMENTATION_LAYER_CONCEPT.md",
|
||||
@@ -52,11 +80,21 @@ ARCHITECTURE = ModuleArchitectureDeclaration(
|
||||
reference="docs/INTERFACE_PATTERN_MIGRATION.md",
|
||||
summary="Records the Core-owned Docs workspace and page-layout boundary.",
|
||||
),
|
||||
ModuleMaturityEvidence(
|
||||
kind="documentation",
|
||||
reference="docs/SEMANTIC_DOCUMENTATION.md",
|
||||
summary="Defines semantic authoring, authorization, lifecycle, export, and recovery behavior.",
|
||||
),
|
||||
),
|
||||
known_limits=(
|
||||
"Architecture declarations are in staged adoption, so undeclared modules remain visible as pending.",
|
||||
),
|
||||
owned_concepts=("configured documentation projection", "documentation audience filtering"),
|
||||
owned_concepts=(
|
||||
"configured documentation projection",
|
||||
"documentation audience filtering",
|
||||
"tenant semantic documentation revisions",
|
||||
"semantic documentation publication lifecycle",
|
||||
),
|
||||
non_owned_concepts=("module feature behavior", "module evidence generation"),
|
||||
documentation=ModuleArchitectureDocumentation(
|
||||
security=("docs/DOCUMENTATION_LAYER_CONCEPT.md",),
|
||||
@@ -86,21 +124,82 @@ def _route_factory(context: ModuleContext):
|
||||
return router
|
||||
|
||||
|
||||
def _dsar_provider(_context: ModuleContext) -> DocsDsarProvider:
|
||||
return DocsDsarProvider()
|
||||
|
||||
|
||||
manifest = ModuleManifest(
|
||||
id="docs",
|
||||
name="Docs",
|
||||
version="0.1.18",
|
||||
version="0.1.19",
|
||||
required_capabilities=(
|
||||
CAPABILITY_AUTH_PRINCIPAL_RESOLVER,
|
||||
CAPABILITY_AUTH_PERMISSION_EVALUATOR,
|
||||
),
|
||||
optional_dependencies=("policy", "audit", "ops", "workflow_engine", "search"),
|
||||
provides_interfaces=(
|
||||
ModuleInterfaceProvider(name=DOCS_DSAR_CAPABILITY, version="0.1.0"),
|
||||
),
|
||||
capability_factories={DOCS_DSAR_CAPABILITY: _dsar_provider},
|
||||
capability_documentation={
|
||||
DOCS_DSAR_CAPABILITY: CapabilityDocumentation(
|
||||
label="Docs data-subject request provider",
|
||||
summary=(
|
||||
"Exports minimized tenant semantic-documentation authorship, "
|
||||
"review, ownership, and stewardship references while retaining "
|
||||
"published configuration-governance evidence."
|
||||
),
|
||||
contract_version="0.1.0",
|
||||
),
|
||||
},
|
||||
optional_dependencies=(
|
||||
"policy",
|
||||
"audit",
|
||||
"ops",
|
||||
"workflow",
|
||||
"forms",
|
||||
"search",
|
||||
),
|
||||
permissions=(
|
||||
_permission(
|
||||
DOCS_READ_SCOPE,
|
||||
"View configured documentation",
|
||||
"Read user documentation generated for the current actor from installed modules and effective configuration.",
|
||||
),
|
||||
_permission(
|
||||
DOCS_SEMANTIC_CREATE_SCOPE,
|
||||
"Create semantic documentation",
|
||||
"Create tenant-owned semantic documentation for configured subjects.",
|
||||
),
|
||||
_permission(
|
||||
DOCS_SEMANTIC_EDIT_SCOPE,
|
||||
"Edit semantic documentation",
|
||||
"Edit drafts using immutable revisions and optimistic concurrency.",
|
||||
),
|
||||
_permission(
|
||||
DOCS_SEMANTIC_PUBLISH_SCOPE,
|
||||
"Publish semantic documentation",
|
||||
"Review and publish semantic documentation under tenant policy.",
|
||||
),
|
||||
_permission(
|
||||
DOCS_SEMANTIC_SUPERSEDE_SCOPE,
|
||||
"Supersede semantic documentation",
|
||||
"Replace semantic documentation with another published entry.",
|
||||
),
|
||||
_permission(
|
||||
DOCS_SEMANTIC_RETIRE_SCOPE,
|
||||
"Retire semantic documentation",
|
||||
"Retire semantic documentation while retaining its revision history.",
|
||||
),
|
||||
_permission(
|
||||
DOCS_SEMANTIC_EXPORT_SCOPE,
|
||||
"Export tenant semantic documentation",
|
||||
"Export tenant-owned semantic entries and immutable history.",
|
||||
),
|
||||
_permission(
|
||||
DOCS_SEMANTIC_POLICY_SCOPE,
|
||||
"Configure semantic publication policy",
|
||||
"Choose direct publication or independent reviewer publication.",
|
||||
),
|
||||
_permission(
|
||||
DOCS_ADMIN_READ_SCOPE,
|
||||
"View administrative documentation",
|
||||
@@ -115,6 +214,43 @@ manifest = ModuleManifest(
|
||||
permissions=(DOCS_READ_SCOPE,),
|
||||
default_authenticated=True,
|
||||
),
|
||||
RoleTemplate(
|
||||
slug="semantic_documentation_author",
|
||||
name="Semantic documentation author",
|
||||
description="Discover configured subjects and create or revise their semantic documentation.",
|
||||
permissions=(
|
||||
DOCS_READ_SCOPE,
|
||||
DOCS_SEMANTIC_CREATE_SCOPE,
|
||||
DOCS_SEMANTIC_EDIT_SCOPE,
|
||||
),
|
||||
),
|
||||
RoleTemplate(
|
||||
slug="semantic_documentation_reviewer",
|
||||
name="Semantic documentation reviewer",
|
||||
description="Review, publish, supersede, and retire semantic documentation.",
|
||||
permissions=(
|
||||
DOCS_READ_SCOPE,
|
||||
DOCS_SEMANTIC_PUBLISH_SCOPE,
|
||||
DOCS_SEMANTIC_SUPERSEDE_SCOPE,
|
||||
DOCS_SEMANTIC_RETIRE_SCOPE,
|
||||
),
|
||||
),
|
||||
RoleTemplate(
|
||||
slug="semantic_documentation_manager",
|
||||
name="Semantic documentation manager",
|
||||
description="Administer semantic authoring, review, lifecycle, policy, and tenant export.",
|
||||
permissions=(
|
||||
DOCS_READ_SCOPE,
|
||||
DOCS_ADMIN_READ_SCOPE,
|
||||
DOCS_SEMANTIC_CREATE_SCOPE,
|
||||
DOCS_SEMANTIC_EDIT_SCOPE,
|
||||
DOCS_SEMANTIC_PUBLISH_SCOPE,
|
||||
DOCS_SEMANTIC_SUPERSEDE_SCOPE,
|
||||
DOCS_SEMANTIC_RETIRE_SCOPE,
|
||||
DOCS_SEMANTIC_EXPORT_SCOPE,
|
||||
DOCS_SEMANTIC_POLICY_SCOPE,
|
||||
),
|
||||
),
|
||||
RoleTemplate(
|
||||
slug="docs_admin",
|
||||
name="Documentation administrator",
|
||||
@@ -142,6 +278,18 @@ manifest = ModuleManifest(
|
||||
required_any=DOCS_READ_SCOPES,
|
||||
order=880,
|
||||
),
|
||||
FrontendRoute(
|
||||
path="/docs/semantic",
|
||||
component="SemanticDocumentationPage",
|
||||
required_any=(
|
||||
DOCS_SEMANTIC_CREATE_SCOPE,
|
||||
DOCS_SEMANTIC_EDIT_SCOPE,
|
||||
DOCS_SEMANTIC_PUBLISH_SCOPE,
|
||||
DOCS_SEMANTIC_SUPERSEDE_SCOPE,
|
||||
DOCS_SEMANTIC_RETIRE_SCOPE,
|
||||
),
|
||||
order=881,
|
||||
),
|
||||
),
|
||||
nav_items=(
|
||||
NavItem(
|
||||
@@ -154,6 +302,88 @@ manifest = ModuleManifest(
|
||||
),
|
||||
),
|
||||
documentation=(
|
||||
DocumentationTopic(
|
||||
id="docs.semantic-documentation",
|
||||
title="Tenant semantic documentation",
|
||||
summary="Explain what configured forms, fields, workflows, steps, and other stable subjects mean in this tenant.",
|
||||
body=(
|
||||
"Authors select an authorized subject supplied by its owning module and create locale-specific plain-text guidance. "
|
||||
"Every save creates an immutable revision. Tenant policy chooses direct publication or an independent reviewer. "
|
||||
"Published content remains subject to the subject's current authorization, the documentation audience and classification, tenant isolation, and locale selection. "
|
||||
"Changed, missing, superseded, or temporarily unavailable subjects are shown explicitly; direct links, contextual help, search, caches, and tenant exports apply the same read-time authorization. "
|
||||
"Retirement and supersession preserve history. Generic public documentation exports never include tenant semantic entries; administrators use the separately authorized tenant export."
|
||||
),
|
||||
layer="always",
|
||||
documentation_types=("admin", "user"),
|
||||
audience=("tenant_admin", "module_admin", "documentation_author"),
|
||||
order=11,
|
||||
conditions=(
|
||||
DocumentationCondition(
|
||||
any_scopes=(
|
||||
DOCS_SEMANTIC_CREATE_SCOPE,
|
||||
DOCS_SEMANTIC_EDIT_SCOPE,
|
||||
DOCS_SEMANTIC_PUBLISH_SCOPE,
|
||||
DOCS_SEMANTIC_POLICY_SCOPE,
|
||||
),
|
||||
),
|
||||
),
|
||||
links=(
|
||||
DocumentationLink(
|
||||
label="Semantic documentation administration",
|
||||
href="/docs/semantic",
|
||||
kind="runtime",
|
||||
),
|
||||
DocumentationLink(
|
||||
label="Semantic documentation operations",
|
||||
href="govoplan-docs/docs/SEMANTIC_DOCUMENTATION.md",
|
||||
kind="repository",
|
||||
),
|
||||
),
|
||||
metadata={"kind": "workflow"},
|
||||
),
|
||||
DocumentationTopic(
|
||||
id="docs.data-subject-requests",
|
||||
title="Review Docs semantic attribution in a data-subject request",
|
||||
summary="Export minimized author, reviewer, owner, and steward references without disclosing unrelated tenant-authored guidance.",
|
||||
body=(
|
||||
"Docs matches exact account and namespaced semantic-entry references within the active tenant. "
|
||||
"The projection identifies the entry, revision, subject, locale, lifecycle state, and fields that matched, but excludes authored body content. "
|
||||
"Published, superseded, and retired attribution is immutable configuration-governance evidence and is retained with a reason. "
|
||||
"Draft attribution requires manual governance review so ownership or stewardship can be reassigned before any anonymization; Docs performs no automatic erasure."
|
||||
),
|
||||
layer="configured",
|
||||
documentation_types=("admin",),
|
||||
audience=("privacy_officer", "documentation_administrator", "operator"),
|
||||
order=12,
|
||||
conditions=(
|
||||
DocumentationCondition(
|
||||
required_modules=("docs", "access"),
|
||||
any_scopes=(
|
||||
"access:privacy:read",
|
||||
"access:privacy:manage",
|
||||
"access:privacy:erase",
|
||||
),
|
||||
),
|
||||
),
|
||||
links=(
|
||||
DocumentationLink(
|
||||
label="Data-subject requests",
|
||||
href="/admin?section=tenant-data-subject-requests",
|
||||
kind="runtime",
|
||||
),
|
||||
DocumentationLink(
|
||||
label="Semantic documentation operations",
|
||||
href="govoplan-docs/docs/SEMANTIC_DOCUMENTATION.md",
|
||||
kind="repository",
|
||||
),
|
||||
),
|
||||
related_modules=("access", "audit", "policy"),
|
||||
metadata={
|
||||
"kind": "workflow",
|
||||
"route": "/admin?section=tenant-data-subject-requests",
|
||||
"help_contexts": ["admin.privacy.data-subject-requests"],
|
||||
},
|
||||
),
|
||||
DocumentationTopic(
|
||||
id="docs.configured-system-documentation",
|
||||
title="Configured system documentation",
|
||||
@@ -434,6 +664,34 @@ manifest = ModuleManifest(
|
||||
},
|
||||
),
|
||||
),
|
||||
migration_spec=MigrationSpec(
|
||||
module_id="docs",
|
||||
metadata=Base.metadata,
|
||||
script_location=str(Path(__file__).with_name("migrations") / "versions"),
|
||||
retirement_supported=True,
|
||||
retirement_provider=drop_table_retirement_provider(
|
||||
docs_models.SemanticDocumentationRevision,
|
||||
docs_models.SemanticDocumentationEntry,
|
||||
label="Docs semantic documentation",
|
||||
),
|
||||
retirement_notes=(
|
||||
"Destructive retirement removes tenant semantic entries and immutable "
|
||||
"revision history after the installer captures a database snapshot."
|
||||
),
|
||||
),
|
||||
uninstall_guard_providers=(
|
||||
persistent_table_uninstall_guard(
|
||||
docs_models.SemanticDocumentationEntry,
|
||||
docs_models.SemanticDocumentationRevision,
|
||||
label="Docs semantic documentation",
|
||||
),
|
||||
),
|
||||
search_sources=(
|
||||
SearchSourceProviderRegistration(
|
||||
id="docs.semantic_documentation",
|
||||
factory=create_semantic_documentation_search_source,
|
||||
),
|
||||
),
|
||||
architecture=ARCHITECTURE,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user