feat(views): add governed DSAR coverage
This commit is contained in:
@@ -11,6 +11,7 @@ from govoplan_core.core.module_guards import (
|
||||
persistent_table_uninstall_guard,
|
||||
)
|
||||
from govoplan_core.core.modules import (
|
||||
CapabilityDocumentation,
|
||||
DocumentationLink,
|
||||
DocumentationTopic,
|
||||
FrontendModule,
|
||||
@@ -26,6 +27,10 @@ from govoplan_core.core.policy import CAPABILITY_POLICY_IMPACT_SUBJECT_PREFIX
|
||||
from govoplan_core.core.views import CAPABILITY_VIEWS_RESOLVER, ViewSurface
|
||||
from govoplan_core.db.base import Base
|
||||
from govoplan_views.backend.db import models as view_models
|
||||
from govoplan_views.backend.dsar_provider import (
|
||||
VIEWS_DSAR_CAPABILITY,
|
||||
ViewsDsarProvider,
|
||||
)
|
||||
|
||||
|
||||
MODULE_ID = "views"
|
||||
@@ -216,6 +221,10 @@ def _policy_impact_subjects(context: ModuleContext):
|
||||
return ViewsPolicyImpactSubjectProvider(context.registry)
|
||||
|
||||
|
||||
def _dsar_provider(_context: ModuleContext) -> ViewsDsarProvider:
|
||||
return ViewsDsarProvider()
|
||||
|
||||
|
||||
manifest = ModuleManifest(
|
||||
id=MODULE_ID,
|
||||
name=MODULE_NAME,
|
||||
@@ -228,6 +237,7 @@ manifest = ModuleManifest(
|
||||
provides_interfaces=(
|
||||
ModuleInterfaceProvider(name="views.surface_contract", version="1.0.0"),
|
||||
ModuleInterfaceProvider(name="views.resolver", version="0.1.0"),
|
||||
ModuleInterfaceProvider(name=VIEWS_DSAR_CAPABILITY, version="0.1.0"),
|
||||
),
|
||||
permissions=PERMISSIONS,
|
||||
role_templates=ROLE_TEMPLATES,
|
||||
@@ -298,8 +308,71 @@ manifest = ModuleManifest(
|
||||
capability_factories={
|
||||
CAPABILITY_VIEWS_RESOLVER: _resolver,
|
||||
f"{CAPABILITY_POLICY_IMPACT_SUBJECT_PREFIX}views": _policy_impact_subjects,
|
||||
VIEWS_DSAR_CAPABILITY: _dsar_provider,
|
||||
},
|
||||
capability_documentation={
|
||||
VIEWS_DSAR_CAPABILITY: CapabilityDocumentation(
|
||||
label="Views data-subject request provider",
|
||||
summary=(
|
||||
"Exports and deletes account-owned View preferences while "
|
||||
"retaining minimized institutional configuration attribution."
|
||||
),
|
||||
contract_version="0.1.0",
|
||||
),
|
||||
},
|
||||
documentation=(
|
||||
DocumentationTopic(
|
||||
id="views.data-subject-requests",
|
||||
title="Views data-subject requests",
|
||||
summary=(
|
||||
"Export or delete personal Views, assignments, and selections "
|
||||
"without changing institutional projections or domain data."
|
||||
),
|
||||
body=(
|
||||
"Views correlates one exact account in the active tenant and can "
|
||||
"narrow the request to a definition, assignment, or preference. "
|
||||
"The access package includes bounded personal definition and "
|
||||
"revision presentation, user assignments, and the active-View "
|
||||
"selection. Arbitrary assignment metadata is excluded and View "
|
||||
"surfaces are identifiers only; the provider never traverses them "
|
||||
"into feature data. Tenant and group configuration authored or "
|
||||
"updated by the subject contributes minimized attribution only and "
|
||||
"is retained as institutional accountability evidence. System-wide "
|
||||
"Views are outside tenant-scoped requests. Erasure can delete an "
|
||||
"exact personal selection, user assignment, or user-owned definition "
|
||||
"after timestamp, revision, ownership, and dependent-record checks. "
|
||||
"A personal definition that affects another account is sent to "
|
||||
"manual review. Deleting a selection or assignment never deletes "
|
||||
"the referenced institutional View. Repeated execution is unchanged."
|
||||
),
|
||||
layer="configured",
|
||||
documentation_types=("admin", "user"),
|
||||
audience=("user", "tenant_admin", "operator", "auditor"),
|
||||
related_modules=("core", "access", "quick_access"),
|
||||
metadata={
|
||||
"help_contexts": [
|
||||
"views.selector",
|
||||
"views.settings.personal",
|
||||
"views.admin.tenant",
|
||||
"privacy.data-subject-requests",
|
||||
],
|
||||
"consequence_classes": {
|
||||
"delete_selection": (
|
||||
"Removes the account selection; effective defaults apply again."
|
||||
),
|
||||
"delete_assignment": (
|
||||
"Removes only the personal assignment, not its View definition."
|
||||
),
|
||||
"delete_personal_definition": (
|
||||
"Removes the personal definition and revisions only when no "
|
||||
"other account depends on it."
|
||||
),
|
||||
"retain_attribution": (
|
||||
"Preserves minimized tenant/group configuration accountability."
|
||||
),
|
||||
},
|
||||
},
|
||||
),
|
||||
DocumentationTopic(
|
||||
id="views.interface-projections",
|
||||
title="Task-focused Views",
|
||||
@@ -443,9 +516,21 @@ manifest = ModuleManifest(
|
||||
maturity="vertical_slice",
|
||||
documentation_ref="README.md",
|
||||
test_ref="tests/test_views.py",
|
||||
known_limits=("A View filters presentation only; modules still vary in the granularity of announced surfaces.",),
|
||||
owned_concepts=("view definition", "view revision", "view assignment", "view selection"),
|
||||
non_owned_concepts=("authorization", "module navigation", "workflow definition", "dashboard layout"),
|
||||
known_limits=(
|
||||
"A View filters presentation only; modules still vary in the granularity of announced surfaces.",
|
||||
),
|
||||
owned_concepts=(
|
||||
"view definition",
|
||||
"view revision",
|
||||
"view assignment",
|
||||
"view selection",
|
||||
),
|
||||
non_owned_concepts=(
|
||||
"authorization",
|
||||
"module navigation",
|
||||
"workflow definition",
|
||||
"dashboard layout",
|
||||
),
|
||||
recovery_docs=("README.md",),
|
||||
security_docs=("README.md",),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user