Sync Repo-docs-ACCESS-EXTRACTION-PLAN from project files

2026-07-06 14:33:37 +02:00
parent 48d1876f50
commit 5cf776f0c0

@@ -0,0 +1,410 @@
<!-- codex-wiki-sync:65899b8e3865e9d7a6839d82 -->
> Mirrored from `/mnt/DATA/git/govoplan-core/docs/ACCESS_EXTRACTION_PLAN.md`.
> Origin: `repository`.
> Active tasks and changing state belong in Gitea issues; this wiki page is durable project context.
---
# GovOPlaN Access Extraction Plan
> Backlog state migrated to Gitea issues on 2026-07-06. Keep this document as
> durable extraction context and architecture notes. Track active tasks,
> decisions, blockers, and implementation state in `add-ideas/govoplan-core`
> issues with `module/access` and `source/backlog-import`.
This plan describes how to extract access, authentication, RBAC, and related
administration behavior from the current compatibility core into a dedicated
`govoplan-access` platform module.
The goal is not to make access optional in every real deployment. The goal is to
make ownership explicit: the kernel composes modules and exposes contracts;
`govoplan-access` owns identity, sessions, API keys, roles, groups, and access
administration.
## Current Inventory
### Existing Access Module Seed
`govoplan-access` contains the extracted module-shaped seed package under
`src/govoplan_access/backend`. `govoplan-core` keeps compatibility import shims
under `src/govoplan_core/access`:
- `manifest.py` declares `ModuleManifest(id="access")`.
- `db/models.py` defines access-owned model candidates.
- `auth/principals.py`, `auth/roles.py`, and `auth/tokens.py` contain auth
helper concepts.
- `permissions/definitions.py`, `permissions/evaluator.py`, and
`permissions/registry.py` contain permission catalogue/evaluation concepts.
- `tenancy/datastore.py` contains early tenancy access helpers.
This seed package is now the starting point for the access module, but it is
not yet the full live source of truth for the running product.
### Live Compatibility Ownership In Core
The active implementation still uses core-owned models and services:
- `src/govoplan_core/db/models.py`
- `Account`
- `Tenant`
- `User`
- `Group`
- `Role`
- `SystemSettings`
- `GovernanceTemplate`
- `GovernanceTemplateAssignment`
- `SystemRoleAssignment`
- `UserGroupMembership`
- `UserRoleAssignment`
- `GroupRoleAssignment`
- `ApiKey`
- `AuthSession`
- `AuditLog`
- `src/govoplan_core/auth/dependencies.py`
- `src/govoplan_core/security/api_keys.py`
- `src/govoplan_core/security/permissions.py`
- `src/govoplan_core/security/sessions.py`
- `src/govoplan_core/security/passwords.py`
- `src/govoplan_core/security/secrets.py`
- `src/govoplan_core/security/module_permissions.py`
- `src/govoplan_core/admin/service.py`
- `src/govoplan_core/admin/governance.py`
- `src/govoplan_core/api/v1/auth.py`
- `src/govoplan_core/api/v1/admin.py`
- `src/govoplan_core/api/v1/admin_schemas.py`
- `src/govoplan_core/api/v1/audit.py`
- `src/govoplan_core/db/bootstrap.py`
Core also still hosts WebUI access/admin/auth surfaces. Those should become
access/admin module route contributions once the backend ownership split is
stable.
### Current Module Consumers
Feature modules currently depend on core compatibility access surfaces:
- `govoplan-files`
- imports `govoplan_core.auth.dependencies`
- imports `Group` and `UserGroupMembership` for ACL decisions
- imports `Group`, `Tenant`, and `User` for file storage ownership/audit
- `govoplan-mail`
- imports `govoplan_core.auth.dependencies`
- imports `Group`, `Tenant`, `User`, and `UserGroupMembership` for mail
profile policy resolution
- imports core settings and secret helpers
- `govoplan-campaign`
- imports `govoplan_core.auth.dependencies`
- imports `Group`, `Tenant`, `User`, and `UserGroupMembership` for ownership
relationships and access decisions
- imports `govoplan_core.security.time.utc_now`
These imports are valid compatibility dependencies today. They are also the
main extraction debt to remove.
## Target Ownership
### Kernel
The kernel keeps only platform composition and stable contracts:
- module discovery and registry validation
- route aggregation
- migration orchestration
- database engine/session lifecycle
- permission catalogue aggregation
- capability registry
- event/command envelopes
- dependency injection hooks
- health and diagnostics
- compatibility facades while modules migrate
The kernel should not own account, tenant, role, group, session, or API-key
semantics.
### `govoplan-access`
`govoplan-access` owns:
- accounts
- authentication routes
- session lifecycle
- API keys
- users
- groups and memberships
- roles and assignments
- principal resolution
- permission evaluation
- access administration routes
- access administration WebUI contributions
- access-related migrations
- access permissions and role templates
### Later Platform Modules
Some current access-adjacent behavior can remain in access initially, but should
have clean seams for later extraction:
- `govoplan-tenancy`: tenants, tenant lifecycle, tenant switching, tenant
metadata, tenant settings boundaries.
- `govoplan-policy`: hierarchical policy/effective policy resolution and
provenance display contracts.
- `govoplan-audit`: audit log storage, audit routes, retention hooks, evidence
exports.
- `govoplan-admin`: generic administration shell contributions if they are not
owned by access/tenancy/policy/audit directly.
## Kernel Contracts To Stabilize First
Before moving live code, define contracts that feature modules can depend on
without importing access ORM models:
- `PrincipalResolver`
- resolves the current actor from a request/session/API key.
- returns a stable DTO, not an ORM model.
- `AccessDirectory`
- resolves users, groups, memberships, and display labels by stable IDs.
- supports batch lookups for grids and policy screens.
- `TenantResolver`
- resolves current tenant context and tenant metadata by stable ID.
- `PermissionEvaluator`
- evaluates required scopes for a principal and resource.
- `ResourceAccessProvider`
- lets modules register resource ACL behavior without importing each other.
- `SecretProvider`
- encrypts/decrypts named secrets without tying consumers to access models.
- `AuditSink`
- records audit events without importing audit storage models.
DTOs should be small and serializable:
- `PrincipalRef`
- `AccountRef`
- `TenantRef`
- `UserRef`
- `GroupRef`
- `RoleRef`
## Extraction Stages
### Stage 0: Baseline Safeguards
Status: started.
- Document the kernel/platform module model.
- Add dependency-boundary checks.
- Add backend module permutation startup tests.
- Inventory access/auth/RBAC imports.
- Draft this extraction plan.
Acceptance criteria:
- `scripts/check_dependency_boundaries.py` passes.
- backend module permutation tests start every supported module combination.
- current direct imports are tracked as explicit transitional debt.
### Stage 1: Contract Definitions
Add kernel-owned protocols and DTOs for access-related interaction.
Tasks:
- Add protocol definitions under a kernel contract package.
- Add registry/capability names for access services.
- Keep existing core dependency functions as compatibility wrappers.
- Make wrappers resolve through capabilities when `govoplan-access` is present.
- Add tests for missing-capability behavior and clear error messages.
Acceptance criteria:
- Feature modules can receive principal/tenant/group/user references without
importing access ORM models.
- Existing routes continue to work through compatibility wrappers.
### Stage 2: Create `govoplan-access`
Create the new repository/package and move the access seed package into it.
Tasks:
- Create package metadata and entry points for `govoplan-access`.
- Move `govoplan_core/access` implementation into the new package.
- Publish `ModuleManifest(id="access")`.
- Register access permissions, role templates, routers, and migrations.
- Add compatibility imports in core where needed.
- Add release/dev dependency entries in core.
Acceptance criteria:
- `govoplan-core + govoplan-access` starts through normal module discovery.
- `govoplan-core` compatibility imports still work during transition.
- access manifest, migrations, and route contributions are discovered by core.
### Stage 3: Move Live Models And Migrations
Move active identity/access models out of `govoplan_core.db.models`.
Tasks:
- Decide the stable table naming strategy.
- Map legacy model names to access-owned model classes.
- Keep database table names where possible to avoid data migration churn.
- Add Alembic migration metadata owned by access.
- Keep compatibility aliases in core while modules migrate.
- Update bootstrap/create-all compatibility paths.
Acceptance criteria:
- Existing development databases migrate without data loss.
- New databases initialize with access-owned metadata.
- Core no longer owns live account/user/group/role/session/API-key model
definitions except compatibility aliases.
### Stage 4: Move Auth Routes And Dependencies
Move authentication, sessions, API keys, and principal dependencies.
Tasks:
- Move `/api/v1/auth/*` implementation to access.
- Move session/API-key services to access.
- Keep core route compatibility only if required by clients.
- Replace feature-module imports of core auth dependencies with stable kernel
contracts or access-provided capabilities.
- Add tests for login, session refresh, tenant selection, API-key auth, and
missing access capability failures.
Acceptance criteria:
- Auth behavior works through the access module.
- Feature modules do not import access internals.
- Core can explain startup failure clearly if auth-required routes are enabled
without the access capability.
### Stage 5: Move Admin And WebUI Contributions
Move access administration UI/API ownership into modules.
Tasks:
- Move users, groups, roles, API keys, and access settings pages into
`govoplan-access`.
- Move tenant-specific pages to `govoplan-tenancy` when that module exists, or
keep them temporarily in access with clear boundaries.
- Register admin navigation through module contributions.
- Keep core shell, layout, route rendering, and generic components only.
Acceptance criteria:
- Core WebUI shell renders admin/access pages from module contributions.
- Core does not import access page components directly.
- Module nav and route metadata remain serializable.
### Stage 6: Decouple Feature Modules
Remove direct ORM/model imports from files, mail, and campaign.
Tasks:
- Replace `Group`, `Tenant`, `User`, and `UserGroupMembership` imports with
directory/capability lookups.
- Replace direct cross-module cleanup/count queries with registered providers,
events, or module-owned API contracts.
- Replace mail-profile ownership resolution with stable owner references.
- Replace campaign/file access checks with resource ACL provider contracts.
Acceptance criteria:
- `govoplan-files`, `govoplan-mail`, and `govoplan-campaign` do not import
access implementation modules or sibling feature modules.
- Dependency-boundary allowlist shrinks after every replacement.
### Stage 7: Remove Compatibility Debt
Finalize the split.
Tasks:
- Remove obsolete core compatibility aliases.
- Remove remaining allowlist entries from the boundary checker.
- Update release dependency docs.
- Update operator migration notes.
- Add full module permutation tests including access-present and access-absent
behavior.
Acceptance criteria:
- Core is a composition kernel.
- Access behavior is owned by `govoplan-access`.
- Feature modules communicate through kernel contracts, capabilities, events,
and their own APIs.
## Immediate Backlog
- [x] Document kernel/platform module model.
- [x] Add dependency-boundary check.
- [x] Add backend permutation startup smoke checks.
- [x] Inventory access/auth/RBAC import debt.
- [x] Draft access extraction plan.
- [x] Define kernel access DTOs and protocols.
- [x] Add access capability registry names.
- [x] Register live access directory and tenant resolver capability
implementations backed by the current compatibility tables.
- [x] Replace `govoplan-files` direct user/group/tenant model imports with the
`access.directory` capability for group membership and share-target checks.
- [x] Create `govoplan-access` repository workspace and issue workflow scaffold.
- [x] Create `govoplan-access` repository/package skeleton.
- [x] Move `govoplan_core/access` seed package into `govoplan-access`.
- [x] Add compatibility wrappers in core for old import paths.
- [x] Route existing auth dependency wrappers through access principal/evaluator capabilities.
- [x] Move session, API-key, and password helper services into `govoplan-access`.
- [x] Move interactive auth/session routes behind access module manifest.
- [x] Move legacy admin/API-key routes behind access module manifest.
- [x] Move legacy admin service and governance helpers into `govoplan-access`.
- [x] Replace legacy access-to-files/campaign admin lookups with module
tenant-summary and group-delete veto providers.
- [x] Split legacy admin route contribution across `govoplan-admin`,
`govoplan-tenancy`, `govoplan-policy`, `govoplan-audit`, and
`govoplan-access` route slices.
- [x] Move legacy admin route-handler ownership out of the access compatibility
router into access, admin, tenancy, policy, and audit module routers.
- [x] Move shared system-settings, tenant-governance, slug/error, and
tenant-count helpers out of access internals into core settings/tenancy
helpers used by the split platform route modules.
- [ ] Move legacy admin service and model ownership out of the access
compatibility implementation into access, tenancy, policy, audit, and core
settings modules.
- [ ] Replace tenancy-to-access default role seeding with a tenant-created
lifecycle/event contract.
- [ ] Replace feature-module direct user/group/tenant model imports.
- [x] `govoplan-files`
- [ ] `govoplan-mail`
- [ ] `govoplan-campaign`
- [ ] Replace direct cross-module SQL lookups with provider/event contracts.
- [ ] Move access admin WebUI pages to module route contributions.
- [ ] Remove transitional boundary checker allowlist entries as each contract
lands.
## Open Decisions
- Is `govoplan-access` required for any authenticated deployment, while
core-only remains a diagnostics/settings shell?
- Should tenant models move with access first, or should `govoplan-tenancy` be
created before moving live models?
- Which table names must remain stable for painless migrations?
- Should secret encryption remain a kernel primitive or become an access-owned
capability?
- Should audit move before policy provenance, or after access/tenancy are split?
- How long should core keep compatibility route paths for existing clients?
## Verification
Use the following checks while extracting access:
```bash
cd /mnt/DATA/git/govoplan-core
./.venv/bin/python scripts/check_dependency_boundaries.py
./.venv/bin/python -m unittest tests.test_module_system
```
For each removed dependency-boundary exception, add or update a focused test
that proves the replacement contract starts without the old direct import.