Skip to content

angee.platform.permissions

Reconcile the REBAC permission schema to the composed addon set.

When an addon is uninstalled it leaves INSTALLED_APPS, but rebac sync only ever revisits composed apps (apps.get_app_configs()) — so the uninstalled addon's Schema* rows orphan, and the library's rebac.E009 system check then fails for every checked command (makemigrations, migrate, rebac sync), breaking the very rebuild the uninstall triggers.

:func:reconcile_permission_schema is the global counterpart to the library's per-package prune: it removes every Schema* row owned by a package no longer in the composed app set. platform owns the addon lifecycle (install / uninstall / reconcile), so it owns this cleanup; the reconcile_permissions management command runs it check-free, before the gated DB steps (see that command and the build lifecycle). The composed set is apps.get_app_configs() — the same source rebac sync keys its packages on — not the addon-only rollups: a package is orphaned only when its app is not loaded at all.

The same check-gated deadlock happens when a composed package removes or renames one definition: rebac sync would prune the stale package-managed rows, but it cannot start while the old row still fails system checks. The reconcile step therefore compares package-managed schema rows with the current permissions.zed declarations and prunes stale rows inside still-composed packages too.

PermissionSchemaReconcileError

python
class PermissionSchemaReconcileError(RuntimeError)

Raised when current REBAC schema declarations cannot be reconciled safely.

reconcile_permission_schema

python
def reconcile_permission_schema() -> int

Prune stale package-managed Schema* rows.

Idempotent and best-effort: returns the number of stale managed rows pruned, and is a no-op on a fresh/unmigrated database (no Schema* tables yet). Runs under system_context in one transaction.

Released under the AGPL-3.0 License.