chore: consolidate platform split checks
This commit is contained in:
@@ -2,10 +2,17 @@
|
||||
|
||||
GovOPlaN is structured as a platform kernel plus installable modules. The kernel starts and composes the platform. Modules own product behavior and contribute backend routes, database metadata, permissions, WebUI routes, navigation metadata, capabilities, and events.
|
||||
|
||||
The current package name is still `govoplan-core`, but the architecture target is a smaller kernel. Access, tenancy, policy, audit, and admin semantics are platform-module responsibilities and should be extracted in stages.
|
||||
The current package name is still `govoplan-core`, but the architecture target is a smaller kernel. Access, tenancy, policy, audit, and admin semantics are platform-module responsibilities.
|
||||
|
||||
The concrete access/auth/RBAC extraction path is tracked in
|
||||
[`ACCESS_EXTRACTION_PLAN.md`](ACCESS_EXTRACTION_PLAN.md).
|
||||
Access extraction is complete enough that current ownership is described here,
|
||||
in [`ACCESS_RBAC_MODEL.md`](ACCESS_RBAC_MODEL.md), and in the
|
||||
`govoplan-access` repository docs.
|
||||
The event and audit trace contract is tracked in
|
||||
[`EVENTS_AND_AUDIT.md`](EVENTS_AND_AUDIT.md).
|
||||
Policy decision, source provenance, and explain-response contracts are tracked
|
||||
in [`POLICY_CONTRACTS.md`](POLICY_CONTRACTS.md).
|
||||
The experimental remote WebUI bundle loading design is tracked in
|
||||
[`REMOTE_WEBUI_BUNDLES.md`](REMOTE_WEBUI_BUNDLES.md).
|
||||
|
||||
## Layer Model
|
||||
|
||||
@@ -35,14 +42,15 @@ The kernel must not own product semantics such as users, tenants, RBAC decisions
|
||||
## Current Compatibility Responsibilities
|
||||
|
||||
During the staged split, `govoplan-core` still contains compatibility surfaces
|
||||
for access, auth, tenancy, RBAC, governance, audit, CSRF/API helpers, and
|
||||
secret helpers. The extracted access implementation now lives in
|
||||
`govoplan-access`; live legacy ORM table definitions have been split across
|
||||
their platform owners while retaining historical table names. The old core
|
||||
model, route, admin-service, and access-security import shims have been
|
||||
removed; callers must use module-owned imports or kernel capabilities. The
|
||||
remaining compatibility surfaces are temporary until the matching platform
|
||||
modules are fully self-contained:
|
||||
for tenancy settings, governance/policy contracts, audit helpers, CSRF/API
|
||||
helpers, and secret helpers. The extracted access implementation lives in
|
||||
`govoplan-access`; live ORM table definitions have been split across their
|
||||
platform owners using module-prefixed table names. The old core route,
|
||||
admin-service, and access-security re-export modules have been removed.
|
||||
Callers must use module-owned imports, the public `govoplan_access.auth` request
|
||||
dependency API, or kernel capabilities.
|
||||
The remaining platform compatibility surfaces are temporary until the matching
|
||||
platform modules are fully self-contained:
|
||||
|
||||
- `govoplan-access`
|
||||
- `govoplan-tenancy`
|
||||
@@ -54,6 +62,18 @@ New code should avoid deepening these compatibility dependencies. Prefer explici
|
||||
|
||||
Core must not import module feature pages or module business logic directly. It should interact with modules through manifests, entry points, metadata, capabilities, events, and route contributions.
|
||||
|
||||
The compatibility/deprecation plan for the current split line is:
|
||||
|
||||
- keep documented public compatibility imports until the owning module exposes a
|
||||
stable replacement and all in-tree callers have migrated
|
||||
- remove deep implementation re-export modules once callers can use module-owned
|
||||
public APIs or kernel capabilities
|
||||
- preserve migration/table compatibility for already-created development and
|
||||
release databases
|
||||
- document remaining compatibility surfaces here and in the owning module README
|
||||
- reject new cross-module imports that bypass manifests, capabilities, events,
|
||||
or public module APIs
|
||||
|
||||
## Stable Kernel Contracts
|
||||
|
||||
The following contracts are the baseline API that modules can rely on:
|
||||
@@ -71,9 +91,15 @@ The following contracts are the baseline API that modules can rely on:
|
||||
- WebUI module contribution contract
|
||||
- navigation metadata contract
|
||||
- command/event envelope contract
|
||||
- policy decision and source provenance contract in `govoplan_core.core.policy`
|
||||
|
||||
Changes to these contracts must be versioned or accompanied by compatibility shims.
|
||||
|
||||
This list is the Milestone A kernel-contract freeze baseline. New module work
|
||||
may extend the kernel by adding explicit contracts, but existing contracts must
|
||||
remain source-compatible through the 0.1.x split line unless a migration shim
|
||||
and deprecation note are provided.
|
||||
|
||||
Known access-related capability names are defined in
|
||||
`govoplan_core.core.access`, including:
|
||||
|
||||
@@ -99,22 +125,23 @@ access/tenant ORM models when they need labels, group membership, default
|
||||
access provisioning, counts, audit actor labels, or tenant metadata.
|
||||
|
||||
FastAPI route dependencies for authenticated endpoints are access-owned and
|
||||
published from `govoplan_access.backend.auth.dependencies`. Routers may import
|
||||
that dependency module directly until a more generic request-principal adapter
|
||||
exists; they must not import access ORM models or other access implementation
|
||||
internals.
|
||||
published from `govoplan_access.auth`. Routers may import that public API for
|
||||
`ApiPrincipal`, `get_api_principal`, `has_scope`, `require_scope`, and
|
||||
`require_any_scope`; they must not import access ORM models or
|
||||
`govoplan_access.backend.*` implementation internals.
|
||||
|
||||
Current live table ownership:
|
||||
|
||||
- `govoplan-tenancy`: `tenants`
|
||||
- `govoplan-access`: `accounts`, `users`, `groups`, `roles`,
|
||||
`system_role_assignments`, `user_group_memberships`,
|
||||
`user_role_assignments`, `group_role_assignments`, `api_keys`,
|
||||
`auth_sessions`
|
||||
- `govoplan-admin`: `governance_templates`,
|
||||
`governance_template_assignments`
|
||||
- `govoplan-tenancy`: `tenancy_tenants`
|
||||
- `govoplan-access`: `access_accounts`, `access_users`, `access_groups`,
|
||||
`access_roles`, `access_system_role_assignments`,
|
||||
`access_user_group_memberships`, `access_user_role_assignments`,
|
||||
`access_group_role_assignments`, `access_api_keys`,
|
||||
`access_auth_sessions`
|
||||
- `govoplan-admin`: `admin_governance_templates`,
|
||||
`admin_governance_template_assignments`
|
||||
- `govoplan-audit`: `audit_log`
|
||||
- `govoplan-core`: `system_settings`
|
||||
- `govoplan-core`: `core_system_settings`
|
||||
|
||||
Current admin route ownership follows the same boundary: access contributes
|
||||
users, groups, roles, system accounts/roles, auth, sessions, and API-key
|
||||
@@ -143,6 +170,183 @@ campaign file-share access, and core retention can call campaign-owned cleanup
|
||||
logic without importing campaign ORM models. Keep these contracts small
|
||||
DTO/protocol surfaces and register concrete behavior from the owning module.
|
||||
|
||||
## API Efficiency Contracts
|
||||
|
||||
GovOPlaN uses conditional GET and delta collections to reduce reload cost
|
||||
without giving every module a custom synchronization format.
|
||||
|
||||
### Conditional GET
|
||||
|
||||
Core applies conditional GET handling centrally for successful JSON `GET`
|
||||
responses:
|
||||
|
||||
- Responses receive a weak `ETag` based on the serialized JSON body.
|
||||
- Responses are marked `Cache-Control: private, no-cache`.
|
||||
- Responses vary by `Authorization`, `Cookie`, `X-API-Key`, and
|
||||
`Accept-Language`.
|
||||
- Matching `If-None-Match` requests return `304 Not Modified` without a body.
|
||||
- Responses with `Set-Cookie`, `Content-Disposition`, `Content-Encoding`, a
|
||||
non-JSON content type, a non-200 status, or `Cache-Control: no-store` are not
|
||||
converted.
|
||||
|
||||
The WebUI `apiFetch` client keeps an in-memory conditional cache for reusable
|
||||
safe requests. It sends `If-None-Match` after an endpoint has returned an ETag,
|
||||
returns the cached payload on `304`, and clears the cache generation after
|
||||
unsafe methods.
|
||||
|
||||
This avoids retransmitting unchanged snapshots. It does not identify which row
|
||||
changed inside a collection.
|
||||
|
||||
### Delta Collections
|
||||
|
||||
Collection endpoints that can expose row-level changes should use the shared
|
||||
delta contract instead of inventing module-specific formats.
|
||||
|
||||
Core provides `core_change_sequence` as the shared monotonic change sequence.
|
||||
Modules record append-only entries in the same database transaction as the
|
||||
resource write. Watermarks are encoded as `seq:<number>` and should be treated
|
||||
as opaque by clients.
|
||||
|
||||
Backend shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"items": [],
|
||||
"deleted": [],
|
||||
"watermark": "opaque-next-watermark",
|
||||
"has_more": false,
|
||||
"full": false
|
||||
}
|
||||
```
|
||||
|
||||
Fields:
|
||||
|
||||
- `items`: changed or current items since the requested watermark.
|
||||
- `deleted`: deleted item markers with at least `id`, and optionally
|
||||
`resource_type`, `revision`, and `deleted_at`.
|
||||
- `watermark`: opaque value the client sends as `since` on the next request.
|
||||
- `has_more`: true when the client should request the next page with the
|
||||
returned watermark.
|
||||
- `full`: true when the response is a full snapshot rather than an incremental
|
||||
delta.
|
||||
|
||||
Section-level settings endpoints use the same contract but replace `items`
|
||||
with:
|
||||
|
||||
- `item`: the full settings object when `full: true`.
|
||||
- `sections`: a map of changed settings sections when `full: false`.
|
||||
- `changed_sections`: ordered section identifiers the client can merge into its
|
||||
local settings object.
|
||||
|
||||
Recommended query parameters:
|
||||
|
||||
- `since`: opaque previous watermark. If omitted or expired, return a full
|
||||
snapshot with `full: true`.
|
||||
- `limit`: maximum number of changed items plus deleted markers.
|
||||
- `include_deleted`: whether deleted markers should be returned.
|
||||
- `cursor`: opaque keyset cursor for table pages where offset shifts would make
|
||||
row-level merging unsafe.
|
||||
|
||||
Modules should record changes with:
|
||||
|
||||
- `module_id`: the owning module, for example `files`.
|
||||
- `collection`: the delta collection, for example `files.assets`.
|
||||
- `resource_type`: stable row kind, for example `file` or `folder`.
|
||||
- `resource_id`: stable resource identifier.
|
||||
- `operation`: `created`, `updated`, or `deleted`.
|
||||
- `tenant_id`: tenant scope when the change is tenant-owned.
|
||||
- `payload`: small, non-secret routing metadata that helps determine whether a
|
||||
tombstone belongs to the requested view.
|
||||
|
||||
Sequence retention is explicit. Cleanup jobs must call
|
||||
`prune_sequence_entries(...)` rather than deleting `core_change_sequence` rows
|
||||
directly. Pruning records a retention floor per module, collection, and tenant
|
||||
scope. Endpoints compare incoming watermarks with that floor; a watermark older
|
||||
than the floor is not safe for incremental replay, so the endpoint must return a
|
||||
full snapshot with `full: true`. A first-use `seq:0` watermark remains valid
|
||||
until such a floor exists, even if unrelated collections have advanced the
|
||||
global sequence.
|
||||
|
||||
### Cursor/Keyset Pages
|
||||
|
||||
Offset pagination remains supported for compatibility and for first page loads,
|
||||
but it is not safe as the merge anchor for row-level deltas on page 2 and later.
|
||||
When a delta-capable table can be paged beyond the first page, the endpoint
|
||||
should expose keyset cursors:
|
||||
|
||||
- Core provides `encode_keyset_cursor`, `decode_keyset_cursor`, and
|
||||
`keyset_query_fingerprint` in `govoplan_core.core.pagination`.
|
||||
- Cursors are opaque to clients and contain the endpoint scope, query
|
||||
fingerprint, and last-row keyset values.
|
||||
- The fingerprint must include every query input that changes membership or
|
||||
order: scope, tenant, page size, sort column, sort direction, and filters.
|
||||
- Reusing a cursor with different sort or filter parameters must fail with a
|
||||
client error rather than returning a mismatched slice.
|
||||
- Responses may still include `page`, `page_size`, `pages`, and `total` for
|
||||
existing UI components, but `cursor` identifies the current slice and
|
||||
`next_cursor` is the safe anchor for the next slice.
|
||||
- The first visit to an arbitrary page can use offset compatibility. The
|
||||
response should include the start cursor for that page so later reloads and
|
||||
delta requests use keyset semantics.
|
||||
|
||||
Concrete consumers:
|
||||
|
||||
- `GET /api/v1/files/delta`: without `since`, returns the current files/folders
|
||||
snapshot for the requested owner/campaign scope. With `since=seq:<number>`,
|
||||
returns changed files, changed folders, and tombstones for resources that
|
||||
left the current view.
|
||||
- `GET /api/v1/campaigns/delta`: returns accessible campaign rows and campaign
|
||||
tombstones when ownership, sharing, or soft deletion removes a campaign from
|
||||
the current list.
|
||||
- `GET /api/v1/campaigns/{campaign_id}/workspace/delta`: returns a workspace
|
||||
snapshot first, then changed campaign/version metadata and optional summary
|
||||
refreshes when version, job, issue, or delivery-attempt changes invalidate the
|
||||
workspace view.
|
||||
- `GET /api/v1/campaigns/{campaign_id}/jobs/delta`: returns a paginated job
|
||||
table snapshot first, then stable row deltas for cursor-backed job pages.
|
||||
The job list also supports offset compatibility for first visits to a page and
|
||||
returns `cursor`/`next_cursor` for stable reloads. Filtered, created, deleted,
|
||||
or stale-watermark requests fall back to a full page snapshot when pagination
|
||||
membership can shift.
|
||||
- `GET /api/v1/admin/users/delta`, `/groups/delta`, `/roles/delta`,
|
||||
`/system/roles/delta`, `/system/accounts/delta`, and `/api-keys/delta`:
|
||||
return access administration row deltas with tombstones where rows leave the
|
||||
visible view.
|
||||
- `GET /api/v1/admin/system/settings/delta`: returns section deltas for system
|
||||
defaults, tenant capability flags, language packages, privacy retention
|
||||
policy, maintenance mode, and raw settings.
|
||||
- `GET /api/v1/admin/tenant/settings/delta`: returns tenant-local setting
|
||||
sections and also reports language-section changes when system language
|
||||
packages or enabled language codes change.
|
||||
- `GET /api/v1/admin/configuration-changes/delta`: returns changed
|
||||
configuration requests and history records.
|
||||
- `GET /api/v1/admin/audit` and `/api/v1/admin/audit/delta`: return append-only
|
||||
audit events using the same scope, sort, and filter query parameters. The list
|
||||
supports offset compatibility plus `cursor`/`next_cursor` keyset paging; the
|
||||
delta endpoint can replay changes against a cursor-backed slice.
|
||||
- `GET /api/v1/mail/settings/delta`: returns mail profile row deltas plus the
|
||||
current scoped mail profile policy when profile-policy dependencies changed.
|
||||
The WebUI consumes this for system, tenant, user, group, and campaign mail
|
||||
settings panels.
|
||||
- `GET /api/v1/files/connectors/settings/delta`: returns file connector
|
||||
profile, credential, connector-space, and scoped connector-policy deltas.
|
||||
Credential changes also include referencing profiles because profile rows
|
||||
display credential-derived state.
|
||||
|
||||
Open retrofit scope:
|
||||
|
||||
- Additional module-specific settings pages should expose section deltas as
|
||||
their settings APIs stabilize. Remaining likely candidates are future
|
||||
booking/resource configuration pages and settings pages introduced by new
|
||||
modules.
|
||||
- Remaining high-volume tables should adopt the cursor/keyset contract before
|
||||
enabling arbitrary-page row deltas. Current rollout follow-ups:
|
||||
`govoplan-files#22` for large file-space server windows,
|
||||
`govoplan-mail#9` for provider-aware mailbox message cursors,
|
||||
`govoplan-calendar#7` for event-window deltas,
|
||||
`govoplan-tenancy#1` for tenant administration row deltas, and
|
||||
`govoplan-admin#2` for governance/module-operation list deltas.
|
||||
|
||||
## Module Responsibilities
|
||||
|
||||
A module owns one bounded feature area. A module can include both backend and WebUI code in the same repository so feature behavior and frontend integration evolve together.
|
||||
@@ -195,6 +399,18 @@ NavItem(
|
||||
)
|
||||
```
|
||||
|
||||
Core validates manifest shape when the platform registry is built. The current
|
||||
supported manifest contract version is `1`, and frontend asset manifests use
|
||||
contract version `1`. Registry validation rejects unsupported contract versions,
|
||||
invalid module ids, duplicate dependency declarations, self-dependencies,
|
||||
mismatched migration/frontend metadata, invalid frontend package names, and
|
||||
frontend/nav routes that do not declare usable paths and labels.
|
||||
|
||||
Backend route contributions are also validated before they are mounted. Startup
|
||||
routers and live module activation fail fast if two routers register the same
|
||||
HTTP method and path. That keeps OpenAPI output and FastAPI route order from
|
||||
silently masking a module collision.
|
||||
|
||||
## Database And Migrations
|
||||
|
||||
Core owns the database/session lifecycle. Modules access the database through core session dependencies and register their models/migrations through their manifest.
|
||||
@@ -209,6 +425,10 @@ Rules:
|
||||
- Optional module migrations may create multiple Alembic heads. Verification
|
||||
should compare the database heads to the configured script heads instead of
|
||||
assuming one linear revision when multiple modules are enabled.
|
||||
- Treat migrations as release artifacts. Unreleased migrations may be squashed
|
||||
or rewritten before a stable release; released revision IDs are immutable
|
||||
once an installation may have recorded them. Each stable release records its
|
||||
public migration heads in `docs/migration-release-baselines.json`.
|
||||
|
||||
## Install, Uninstall, And Catalogs
|
||||
|
||||
@@ -290,6 +510,31 @@ capabilities with `usePlatformUiCapabilities("admin.sections")`, filters them
|
||||
by `anyOf`/`allOf`, and renders them without importing the contributing module's
|
||||
components directly.
|
||||
|
||||
The configurable dashboard follows the same pattern. Core contributes only a
|
||||
minimal `/dashboard` fallback when no `dashboard` WebUI module is active. The
|
||||
`govoplan-dashboard` module owns the real `/dashboard` route and collects
|
||||
widgets exposed through the `dashboard.widgets` capability:
|
||||
|
||||
```ts
|
||||
const dashboardWidgets: DashboardWidgetsUiCapability = {
|
||||
widgets: [
|
||||
{
|
||||
id: "ops.health",
|
||||
title: "Operations health",
|
||||
moduleId: "ops",
|
||||
defaultSize: "wide",
|
||||
anyOf: ["ops:operations:read"],
|
||||
render: ({ settings, refreshKey }) => createElement(OpsHealthWidget, { settings, refreshKey })
|
||||
}
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
Dashboard widgets are module contributions, not cross-module imports. A widget
|
||||
may render components from its own module and core components only. The
|
||||
dashboard module is responsible for layout, visibility, refresh context, and
|
||||
future server-side layout persistence.
|
||||
|
||||
## Icon Rules
|
||||
|
||||
Icons are resolved centrally by core.
|
||||
@@ -354,14 +599,221 @@ The repository includes `scripts/check_dependency_boundaries.py`. It enforces th
|
||||
- access source may not import files/mail/campaign internals
|
||||
- feature modules may not import access implementation internals
|
||||
- feature modules may not add new direct imports of sibling feature modules
|
||||
- FastAPI routers may import the published
|
||||
`govoplan_access.backend.auth.dependencies` dependency API
|
||||
- FastAPI routers may import the published `govoplan_access.auth` dependency API
|
||||
- the transitional allowlist is expected to stay empty
|
||||
|
||||
Any future exception is extraction debt and must be temporary, documented in the
|
||||
script with a reason, and removed when a capability/API/event contract replaces
|
||||
it.
|
||||
|
||||
## Boundary Decision Register
|
||||
|
||||
These durable decisions close older exploratory core issues. Implementation
|
||||
work should live in the owning module repositories once a boundary is clear.
|
||||
|
||||
Decision principles:
|
||||
|
||||
- Prefer connector-first when an external specialist system is likely to remain
|
||||
the system of record.
|
||||
- Create a native module only when GovOPlaN must own domain semantics,
|
||||
permissions, audit, retention, configuration-package fragments, or workflow
|
||||
state.
|
||||
- Keep optional behavior behind core-mediated capabilities, events, DTOs, route
|
||||
contributions, and UI contribution points.
|
||||
- Do not create repositories just because a possible product area exists.
|
||||
|
||||
### Templates And Reporting
|
||||
|
||||
Tracking: `govoplan-core#190`, `govoplan-templates#1`,
|
||||
`govoplan-reporting#1`.
|
||||
|
||||
Decision: templates and reporting are separate modules.
|
||||
|
||||
`govoplan-templates` owns:
|
||||
|
||||
- reusable renderable templates for letters, permits, emails, forms, reports,
|
||||
certificates, and notices
|
||||
- template versioning, merge-field declarations, rendering profiles, output
|
||||
format choices, and preview contracts
|
||||
- template package fragments that other modules can reference
|
||||
|
||||
`govoplan-reporting` owns:
|
||||
|
||||
- report definitions, data selection, dashboards, BI views, scheduled outputs,
|
||||
and export targets
|
||||
- report permissions, report execution history, generated report evidence, and
|
||||
report-specific retention inputs
|
||||
- downstream export handoff to files, dataflow, connectors, or publication
|
||||
surfaces
|
||||
|
||||
Boundary:
|
||||
|
||||
- Templates do not own data selection, aggregation, scheduling, or BI semantics.
|
||||
- Reporting may call template rendering through a capability when a formatted
|
||||
report output is needed.
|
||||
- Campaign, mail, files, workflow, and cases use templates/reporting through
|
||||
capabilities and DTOs, never direct imports.
|
||||
|
||||
### Sources, RSS, Datasources, And Dataflow
|
||||
|
||||
Tracking: `govoplan-core#192`, `govoplan-core#197`,
|
||||
`govoplan-core#198`, `govoplan-connectors#3`,
|
||||
`govoplan-connectors#4`.
|
||||
|
||||
Decision: do not create `govoplan-datasources` or `govoplan-dataflow` until a
|
||||
first executable use case proves that connector/reporting/workflow ownership is
|
||||
too narrow.
|
||||
|
||||
First slice:
|
||||
|
||||
- `govoplan-connectors` owns RSS/Atom consume/emit connector profiles,
|
||||
connector health, external references, source lifecycle metadata, and
|
||||
source/publish capability boundaries.
|
||||
- `govoplan-files` owns file-backed governed locations and uploaded/stored file
|
||||
evidence.
|
||||
- `govoplan-reporting` owns report/data views and scheduled outputs.
|
||||
- `govoplan-workflow` owns process state, approvals, scheduling of process
|
||||
steps, and human review.
|
||||
|
||||
Future `govoplan-datasources` is justified when GovOPlaN needs a broad source
|
||||
catalogue for SQL databases, CSV/Excel files, APIs, RSS feeds, uploaded files,
|
||||
and governed file locations with shared ownership, credentials, schema
|
||||
discovery, refresh cadence, provenance, and permission boundaries.
|
||||
|
||||
Future `govoplan-dataflow` is justified when GovOPlaN needs first-class
|
||||
pipelines for ingestion, transformation, validation, scheduling, lineage,
|
||||
publication, audit events, reruns, and source-to-source workflows.
|
||||
|
||||
Monthly extraction/transformation work should start as a configuration package
|
||||
and module collaboration across connectors, files, workflow, reporting, and
|
||||
possibly templates. Create datasources/dataflow repositories only after that
|
||||
package exposes repeated contracts that do not belong to an existing module.
|
||||
|
||||
### Calendar, Scheduling, And Appointments
|
||||
|
||||
Tracking: `govoplan-core#193`, `govoplan-calendar#1`,
|
||||
`govoplan-calendar#2`, `govoplan-scheduling#1`,
|
||||
`govoplan-appointments#1`.
|
||||
|
||||
Decision: use three separate modules.
|
||||
|
||||
`govoplan-calendar` owns:
|
||||
|
||||
- calendar collections, events, recurrence, availability/free-busy, resources,
|
||||
iCalendar import/export, CalDAV/Open-Xchange-style calendar adapters, and
|
||||
calendar WebUI surfaces
|
||||
|
||||
`govoplan-scheduling` owns:
|
||||
|
||||
- Terminfindung, meeting-time polls, participant availability collection,
|
||||
candidate-slot ranking, conflict explanations, reminders, and the handoff
|
||||
from a selected slot to calendar/appointment/workflow modules
|
||||
|
||||
`govoplan-appointments` owns:
|
||||
|
||||
- Terminbuchung/fixed-slot appointment booking, appointment types, booking
|
||||
rules, capacity, cancellation/no-show state, public/internal booking flows,
|
||||
and appointment evidence
|
||||
|
||||
Boundary:
|
||||
|
||||
- Calendar provides time primitives and external calendar integration.
|
||||
- Scheduling chooses a suitable time.
|
||||
- Appointments owns booked appointment workflows and public/internal booking
|
||||
semantics.
|
||||
- Mail and notifications deliver invitations/reminders through capabilities.
|
||||
|
||||
### Forms And Workflow Handoff
|
||||
|
||||
Tracking: `govoplan-core#194`, `govoplan-forms#1`.
|
||||
|
||||
Decision: forms are a reusable module boundary, with runtime behavior separated
|
||||
from workflow semantics.
|
||||
|
||||
`govoplan-forms` owns:
|
||||
|
||||
- form definitions, schemas, validation rules, field visibility rules,
|
||||
localization, versioning, admin editing, and reusable form package fragments
|
||||
|
||||
`govoplan-forms-runtime` owns, when implemented:
|
||||
|
||||
- public/internal submissions, drafts, submitted values, validation evidence,
|
||||
attachment references, submission receipts, and handoff events
|
||||
|
||||
Boundary:
|
||||
|
||||
- Forms do not own cases, workflow transitions, tasks, or portal identity.
|
||||
- Workflow/cases consume form submission events and evidence references.
|
||||
- Files owns uploaded file storage and file permissions.
|
||||
- Reporting/dataflow may consume submitted data through governed DTOs or
|
||||
source lifecycle contracts.
|
||||
|
||||
### OpenDesk Integration Profile
|
||||
|
||||
Tracking: `govoplan-core#195`, `govoplan-connectors#5`,
|
||||
`govoplan-idm#1`, `govoplan-mail#5`, `govoplan-calendar#2`,
|
||||
`govoplan-connectors#1`.
|
||||
|
||||
Decision: OpenDesk is an integration profile, not a monolithic module.
|
||||
|
||||
Ownership:
|
||||
|
||||
- identity: `govoplan-idm` plus `govoplan-access`
|
||||
- mail/groupware: `govoplan-mail`
|
||||
- calendar: `govoplan-calendar`
|
||||
- files/documents: `govoplan-files` and later `govoplan-dms`
|
||||
- projects/tasks: `govoplan-connectors` OpenProject connector first
|
||||
- inventory/health/profile diagnostics: `govoplan-connectors`
|
||||
|
||||
The OpenDesk profile should describe required connector profiles, shared
|
||||
identity assumptions, health checks, and optional module combinations. It must
|
||||
not create direct module-to-module imports.
|
||||
|
||||
### Project Management And OpenProject
|
||||
|
||||
Tracking: `govoplan-core#196`, `govoplan-connectors#1`.
|
||||
|
||||
Decision: connector-first. Do not create a native `govoplan-projects` module
|
||||
yet.
|
||||
|
||||
OpenProject integration belongs in `govoplan-connectors` first:
|
||||
|
||||
- profile test
|
||||
- project and work-package lookup
|
||||
- external-reference storage
|
||||
- selected publish/synchronize capabilities for tasks, workflow, or cases
|
||||
|
||||
A native project module is justified only if GovOPlaN needs to own project
|
||||
semantics beyond cases, tasks, workflow, appointments, documents, and reporting,
|
||||
for example portfolios, project budgets, project-level resource planning, or
|
||||
governed project records that cannot remain in OpenProject.
|
||||
|
||||
### Public-Sector Integration Landscape
|
||||
|
||||
Tracking: `govoplan-core#186`, `govoplan-core#215`,
|
||||
`govoplan-connectors#2`, `govoplan-connectors#3`.
|
||||
|
||||
Decision: core owns strategy and routing; connectors owns executable
|
||||
integration catalogue entries and operator inventory.
|
||||
|
||||
Core documents:
|
||||
|
||||
- product-level integration strategy
|
||||
- native-vs-connector decisions
|
||||
- owning module routing
|
||||
- roadmap sequencing
|
||||
|
||||
`govoplan-connectors` owns:
|
||||
|
||||
- connector entry schema
|
||||
- external system catalogue
|
||||
- connector profiles and diagnostics
|
||||
- source consume/publish lifecycle
|
||||
- external references
|
||||
|
||||
When a target needs executable behavior, create the implementation issue in the
|
||||
owning module repository and keep only cross-module decisions in core.
|
||||
|
||||
## Module Lifecycle
|
||||
|
||||
Core exposes the installed module catalog through the admin API and WebUI. The
|
||||
@@ -565,6 +1017,8 @@ directory with:
|
||||
|
||||
- `GOVOPLAN_INSTALLER_RUN_DIR`
|
||||
- `GOVOPLAN_DATABASE_URL`
|
||||
- `GOVOPLAN_DATABASE_URL_PGTOOLS` for PostgreSQL URLs converted to the
|
||||
`postgresql://` form expected by `pg_dump`, `pg_restore`, and `psql`
|
||||
- `GOVOPLAN_DATABASE_BACKUP_PATH`
|
||||
- `GOVOPLAN_DATABASE_BACKUP_METADATA`
|
||||
|
||||
@@ -631,10 +1085,20 @@ Backend verification from core:
|
||||
|
||||
```bash
|
||||
cd /mnt/DATA/git/govoplan-core
|
||||
./.venv/bin/python -m compileall src/govoplan_core ../govoplan-access/src/govoplan_access ../govoplan-admin/src/govoplan_admin ../govoplan-tenancy/src/govoplan_tenancy ../govoplan-policy/src/govoplan_policy ../govoplan-audit/src/govoplan_audit ../govoplan-files/src/govoplan_files ../govoplan-mail/src/govoplan_mail ../govoplan-campaign/src/govoplan_campaign
|
||||
./.venv/bin/python -m compileall src/govoplan_core ../govoplan-access/src/govoplan_access ../govoplan-admin/src/govoplan_admin ../govoplan-tenancy/src/govoplan_tenancy ../govoplan-policy/src/govoplan_policy ../govoplan-audit/src/govoplan_audit ../govoplan-dashboard/src/govoplan_dashboard ../govoplan-files/src/govoplan_files ../govoplan-mail/src/govoplan_mail ../govoplan-campaign/src/govoplan_campaign
|
||||
./.venv/bin/python scripts/check_dependency_boundaries.py
|
||||
```
|
||||
|
||||
`scripts/check-focused.sh` runs npm with an isolated temporary npm user config
|
||||
so developer-local npm settings do not create release-check warning noise.
|
||||
|
||||
Focused module contract and permutation verification:
|
||||
|
||||
```bash
|
||||
cd /mnt/DATA/git/govoplan-core
|
||||
bash scripts/check-module-matrix.sh
|
||||
```
|
||||
|
||||
Core WebUI host verification:
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user