Release v0.1.6
This commit is contained in:
456
docs/ACCESS_EXTRACTION_PLAN.md
Normal file
456
docs/ACCESS_EXTRACTION_PLAN.md
Normal file
@@ -0,0 +1,456 @@
|
||||
# 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 still hosts the generic login/settings shell and shared WebUI primitives.
|
||||
The legacy administration page has moved to the `govoplan-access` WebUI package
|
||||
and is contributed as the `/admin` route by the access module. Individual admin
|
||||
panels can now be split further into access, admin, tenancy, policy, and audit
|
||||
WebUI contributions without changing the core shell route wiring again.
|
||||
|
||||
### Current Module Consumers
|
||||
|
||||
Feature modules no longer import core auth dependency wrappers or access-owned
|
||||
ORM models. Backend routers import the access-published FastAPI dependency API
|
||||
from `govoplan_access.backend.auth.dependencies`; runtime cooperation uses
|
||||
kernel capabilities such as `access.directory`, `campaigns.access`,
|
||||
`campaigns.mailPolicyContext`, and `campaigns.deliveryTasks`.
|
||||
|
||||
## 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`.
|
||||
|
||||
Current state: the stable table naming strategy is to keep legacy table names
|
||||
and move SQLAlchemy class definitions under their platform owners. The old
|
||||
`govoplan_core.db.models` compatibility re-export has been removed; callers
|
||||
must import module-owned models or use kernel capabilities. The earlier
|
||||
`access_*` candidate tables are not active metadata.
|
||||
|
||||
Current table ownership:
|
||||
|
||||
- `govoplan-tenancy`: `tenants`
|
||||
- `govoplan-access`: `accounts`, tenant memberships in `users`, `groups`,
|
||||
`roles`, role/group assignment tables, `api_keys`, and `auth_sessions`
|
||||
- `govoplan-admin`: governance templates and assignments
|
||||
- `govoplan-audit`: audit log
|
||||
- `govoplan-core`: system settings
|
||||
|
||||
Tasks:
|
||||
|
||||
- [x] Decide the stable table naming strategy.
|
||||
- [x] Map legacy model names to access-owned model classes.
|
||||
- [x] Keep database table names where possible to avoid data migration churn.
|
||||
- [x] Add Alembic migration metadata owned by the platform module owners.
|
||||
- [x] Remove core model compatibility aliases after callers moved to
|
||||
module-owned imports.
|
||||
- [x] Update bootstrap/create-all compatibility paths.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Existing development databases migrate without data loss.
|
||||
- New databases initialize with module-owned metadata.
|
||||
- Core no longer owns or re-exports live account/user/group/role/session/API-key
|
||||
model definitions.
|
||||
|
||||
### 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 the
|
||||
access-published FastAPI dependency API.
|
||||
- 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 except the published
|
||||
`govoplan_access.backend.auth.dependencies` dependency API used by FastAPI
|
||||
routers.
|
||||
- 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:
|
||||
|
||||
- [x] 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.
|
||||
- [x] Move overview, system settings, and governance-template panels into
|
||||
`govoplan-admin`.
|
||||
- [x] Register admin navigation and admin sections through module
|
||||
contributions.
|
||||
- [x] 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.
|
||||
- The access admin shell consumes module-owned `admin.sections` capability
|
||||
contributions without importing sibling module panels.
|
||||
|
||||
### 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 stays empty after each replacement.
|
||||
|
||||
### Stage 7: Remove Compatibility Debt
|
||||
|
||||
Finalize the split.
|
||||
|
||||
Tasks:
|
||||
|
||||
- Remove obsolete core compatibility aliases.
|
||||
- Keep the dependency-boundary checker allowlist empty.
|
||||
- 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] Register an access tenant-provisioner capability so tenancy can seed
|
||||
access-owned default roles without importing access service internals.
|
||||
- [x] Replace `govoplan-files` direct user/group/tenant model imports with the
|
||||
`access.directory` capability for group membership and share-target checks.
|
||||
- [x] Replace `govoplan-files` direct campaign model imports with the
|
||||
`campaigns.access` capability for campaign share/existence checks.
|
||||
- [x] Replace `govoplan-mail` direct user/group/tenant model imports with
|
||||
mail-owned policy storage plus access-directory validation and legacy-read
|
||||
fallback.
|
||||
- [x] Replace `govoplan-mail` direct campaign model imports with the
|
||||
`campaigns.mailPolicyContext` capability for campaign-scoped mail policy and
|
||||
owner context.
|
||||
- [x] Replace `govoplan-campaign` runtime user/group/tenant model imports with
|
||||
access-directory lookups and string-based ORM relationships.
|
||||
- [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 FastAPI auth dependency wrappers out of core and into
|
||||
`govoplan-access`.
|
||||
- [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 access-owned legacy admin service helpers into `govoplan-access`.
|
||||
- [x] Move governance-template CRUD helpers and routes into `govoplan-admin`.
|
||||
- [x] Move governance-template materialization of access-owned groups and roles
|
||||
behind the `access.governanceMaterializer` capability.
|
||||
- [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.
|
||||
- [x] Move campaign schema routes into the campaign route contribution.
|
||||
- [x] Move development mailbox routes into the mail route contribution.
|
||||
- [x] Replace core Celery direct campaign/mail imports with the
|
||||
`campaigns.deliveryTasks` capability.
|
||||
- [x] Replace core retention direct campaign queries with
|
||||
`campaigns.policyContext` and `campaigns.retention` capabilities.
|
||||
- [x] Replace core `create_all` feature-model imports with module registry
|
||||
metadata discovery.
|
||||
- [x] Remove transitional boundary checker allowlist entries.
|
||||
- [x] Move live legacy model definitions out of core and into
|
||||
`govoplan-access` while preserving existing table names.
|
||||
- [x] Split the transitional access-owned legacy model graph further into
|
||||
tenancy, audit, admin, access, and core settings ownership.
|
||||
- [x] Reverse the tenancy/access dependency direction so `govoplan-access`
|
||||
depends on `govoplan-tenancy`, and the registry inserts tenancy before access.
|
||||
- [x] Replace tenancy-to-access default role seeding with an access
|
||||
tenant-provisioner capability.
|
||||
- [x] Replace tenancy-to-access owner candidate and owner membership handling
|
||||
with the access tenant-provisioner capability.
|
||||
- [x] Replace admin overview counts and audit actor lookup/filtering with the
|
||||
`access.administration` capability.
|
||||
- [x] Replace feature-module direct user/group/tenant model imports.
|
||||
- [x] `govoplan-files`
|
||||
- [x] `govoplan-mail`
|
||||
- [x] `govoplan-campaign`
|
||||
- [x] Replace files/mail/campaign direct cross-module SQL lookups with
|
||||
provider/capability contracts.
|
||||
- [x] Move access admin WebUI pages to module route contributions.
|
||||
- [x] Move generic admin-owned WebUI panels into `govoplan-admin` and register
|
||||
them through the `admin.sections` UI capability.
|
||||
- [x] Remove transitional boundary checker allowlist entries as each contract
|
||||
lands.
|
||||
- [x] Remove old core import shims for access models, access routes, admin
|
||||
service helpers, and access-owned security services.
|
||||
- [ ] Move campaign-scoped mail policy ownership fully behind an API/event
|
||||
workflow if direct synchronous capability calls become too tight for later
|
||||
deployment boundaries.
|
||||
|
||||
## Open Decisions
|
||||
|
||||
- Is `govoplan-access` required for any authenticated deployment, while
|
||||
core-only remains a diagnostics/settings shell?
|
||||
- Tenant models live in `govoplan-tenancy`; `govoplan-access` depends on
|
||||
tenancy for authenticated platform composition.
|
||||
- Historical table names remain stable for painless migrations.
|
||||
- Should secret encryption remain a kernel primitive or become an access-owned
|
||||
capability?
|
||||
- Audit log storage lives in `govoplan-audit`; policy provenance can build on
|
||||
that module boundary.
|
||||
- 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.
|
||||
Reference in New Issue
Block a user