Release v0.1.7
This commit is contained in:
@@ -28,6 +28,13 @@ Tenant lifecycle planning uses registered tenant summary providers and delete
|
|||||||
veto providers. Modules that own tenant-scoped data must contribute summaries
|
veto providers. Modules that own tenant-scoped data must contribute summaries
|
||||||
so destructive deletion cannot silently miss their rows.
|
so destructive deletion cannot silently miss their rows.
|
||||||
|
|
||||||
|
Delete veto providers are registered through module manifests and receive
|
||||||
|
`(session, tenant_id, resource_id)`. Providers should return a structured
|
||||||
|
`DeleteVetoIssue`, a list of issues, or `None`; legacy providers that raise an
|
||||||
|
exception are treated as blocking module vetoes. Tenancy exposes those issues in
|
||||||
|
the deletion plan with module attribution and resource details, so operators can
|
||||||
|
see which module blocks or qualifies the lifecycle action.
|
||||||
|
|
||||||
## Lifecycle Events
|
## Lifecycle Events
|
||||||
|
|
||||||
`govoplan-tenancy.backend.lifecycle` is the module-local contract for tenant
|
`govoplan-tenancy.backend.lifecycle` is the module-local contract for tenant
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "govoplan-tenancy"
|
name = "govoplan-tenancy"
|
||||||
version = "0.1.6"
|
version = "0.1.7"
|
||||||
description = "GovOPlaN tenancy platform module."
|
description = "GovOPlaN tenancy platform module."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
authors = [{ name = "GovOPlaN" }]
|
authors = [{ name = "GovOPlaN" }]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"govoplan-core>=0.1.6",
|
"govoplan-core>=0.1.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages.find]
|
||||||
|
|||||||
@@ -156,7 +156,16 @@ def _tenant_deletion_plan(session: Session, tenant: Tenant, principal: ApiPrinci
|
|||||||
))
|
))
|
||||||
|
|
||||||
registry = get_registry()
|
registry = get_registry()
|
||||||
if registry is not None and hasattr(registry, "delete_veto_providers"):
|
if registry is not None and hasattr(registry, "collect_delete_veto_issues"):
|
||||||
|
for issue in registry.collect_delete_veto_issues("tenant", session, tenant.id, tenant.id):
|
||||||
|
issues.append(TenantLifecycleIssue(
|
||||||
|
severity=issue.severity,
|
||||||
|
code=issue.code,
|
||||||
|
message=issue.message,
|
||||||
|
module_id=issue.module_id,
|
||||||
|
details=dict(issue.details),
|
||||||
|
))
|
||||||
|
elif registry is not None and hasattr(registry, "delete_veto_providers"):
|
||||||
for provider in registry.delete_veto_providers("tenant"):
|
for provider in registry.delete_veto_providers("tenant"):
|
||||||
try:
|
try:
|
||||||
provider(session, tenant.id, tenant.id)
|
provider(session, tenant.id, tenant.id)
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ class TenantLifecycleIssue(BaseModel):
|
|||||||
code: str
|
code: str
|
||||||
message: str
|
message: str
|
||||||
module_id: str | None = None
|
module_id: str | None = None
|
||||||
|
details: dict[str, Any] = Field(default_factory=dict)
|
||||||
|
|
||||||
|
|
||||||
class TenantDeletionPlanResponse(BaseModel):
|
class TenantDeletionPlanResponse(BaseModel):
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ def _route_factory(context: ModuleContext):
|
|||||||
manifest = ModuleManifest(
|
manifest = ModuleManifest(
|
||||||
id="tenancy",
|
id="tenancy",
|
||||||
name="Tenancy",
|
name="Tenancy",
|
||||||
version="0.1.6",
|
version="0.1.7",
|
||||||
required_capabilities=(
|
required_capabilities=(
|
||||||
CAPABILITY_AUTH_PRINCIPAL_RESOLVER,
|
CAPABILITY_AUTH_PRINCIPAL_RESOLVER,
|
||||||
CAPABILITY_AUTH_PERMISSION_EVALUATOR,
|
CAPABILITY_AUTH_PERMISSION_EVALUATOR,
|
||||||
|
|||||||
Reference in New Issue
Block a user