179 lines
9.0 KiB
Markdown
179 lines
9.0 KiB
Markdown
# govoplan-postbox
|
|
|
|
<!-- govoplan-repository-type:start -->
|
|
**Repository type:** module (domain).
|
|
<!-- govoplan-repository-type:end -->
|
|
|
|
GovOPlaN Postbox provides platform-owned postboxes for internal work, portals,
|
|
campaign flows, and function-bound organizational communication.
|
|
|
|
## Ownership
|
|
|
|
This repository owns:
|
|
|
|
- backend module manifest `postbox`
|
|
- postbox permissions and policy checks
|
|
- postbox, binding, message, participant, attachment-reference, and audit-facing data models
|
|
- function-organization-bound access resolution for postboxes through
|
|
normalized Identity, IDM, Organizations, and Core/Access contracts
|
|
- API routes for postbox directory, messages, access checks, and administration
|
|
- optional integration capabilities for campaign, files, portal, notification, and mail-facing workflows
|
|
- inbox and tenant administration WebUI package `@govoplan/postbox-webui`
|
|
|
|
Core owns auth, tenants, RBAC evaluation, database/session primitives, module
|
|
discovery, migrations, CSRF/API helpers, and shell layout. Identity owns
|
|
identities and account links. Organizations owns units, structures, function
|
|
types, and concrete functions. IDM owns effective identity-to-function
|
|
assignments, delegation, and acting-for facts. Access owns generic application
|
|
roles, permissions, and administrative RBAC surfaces.
|
|
|
|
## Function-bound postboxes
|
|
|
|
A function-bound postbox has a stable institutional address linked to an
|
|
organizational unit and one or more functions. It can exist with zero, one, or
|
|
several current incumbents. A person can access it only while their identity
|
|
has an effective assignment or time-bounded delegation in that organizational
|
|
context and their account may perform the relevant Postbox action. Access is
|
|
not tied to a login mailbox, personal email address, static user assignment, or
|
|
function-to-RBAC-role mapping.
|
|
|
|
When the assignment changes, postbox access and encrypted key grants change
|
|
with it. The postbox keeps durable content and evidence history through
|
|
vacancy, hand-over, and delegation; multiple incumbents receive independently
|
|
auditable access. Revocation prevents future platform key access but cannot
|
|
erase plaintext already fetched or exported.
|
|
|
|
Reusable Postbox templates may target a function type and organization scope.
|
|
Unit-specific addresses are resolved lazily and remain stable through vacancy
|
|
and reassignment. Exact postboxes remain available for exceptional
|
|
responsibilities or case/service contexts.
|
|
|
|
Subtree templates select an explicit Organizations structure and optional
|
|
hierarchical relation types. The administration UI can dry-run a draft against
|
|
the current organization and incumbency state, showing generated addresses,
|
|
vacancy, existing targets, collisions, and hierarchy diagnostics without
|
|
materializing data.
|
|
|
|
Users holding several functions may group selected postboxes into unified
|
|
inbox views. These are query projections only: messages, address, read state,
|
|
retention, and evidence remain attached to their source postboxes. Each exact
|
|
Postbox or template revision may allow grouping, require equal classifications,
|
|
or remain entirely separate with an administrator-supplied explanation. The
|
|
rule is re-evaluated on every combined query, including after assignment or
|
|
policy changes; a View can select a personal projection through the stable
|
|
`?grouping=<grouping-id>` route parameter without granting access.
|
|
|
|
Hierarchy propagation is off by default. Explicit copy, attention/escalation,
|
|
and shared-visibility rules are distinct, bounded, classification-aware, and
|
|
snapshotted when a message is delivered.
|
|
|
|
## Module integration
|
|
|
|
Backend entry point:
|
|
|
|
```toml
|
|
[project.entry-points."govoplan.modules"]
|
|
postbox = "govoplan_postbox.backend.manifest:get_manifest"
|
|
```
|
|
|
|
Frontend package:
|
|
|
|
```text
|
|
@govoplan/postbox-webui
|
|
```
|
|
|
|
Platform RBAC, module capability contracts, and governance rules are documented in `govoplan-core/docs/`.
|
|
|
|
The module's interface archetypes, consequence classes, contextual-help
|
|
contracts, and accessibility evidence are recorded in
|
|
[`docs/INTERFACE_PATTERN_MIGRATION.md`](docs/INTERFACE_PATTERN_MIGRATION.md).
|
|
|
|
## Current implementation
|
|
|
|
The first usable slice includes immutable template revisions, stable lazy
|
|
addresses, exact function-bound Postboxes, current IDM assignment access
|
|
decisions, vacancy status, idempotent producer delivery, source-preserving
|
|
message and attachment references, personal read/acknowledgement receipts,
|
|
unified inbox projections, access evidence, an inbox route, and tenant
|
|
administration. Grouping summaries expose batched total and unread counts for
|
|
currently visible sources. Published template revisions can also opt into bounded linked
|
|
copies through one explicit organization structure. Classification, producer,
|
|
retention, stop, depth, target-template, and target-function gates are frozen
|
|
at delivery time and exposed through delivery evidence and the routing dry-run
|
|
API.
|
|
|
|
Vacancy escalation is a separate attention policy. It creates no personal
|
|
account grant: a durable route waits for its configured delay and then creates
|
|
an independently readable copy in the next frozen function Postbox. The
|
|
`govoplan.postbox.dispatch_routes` periodic Core worker drains due routes when
|
|
Celery beat and a worker consuming the `postbox` queue are enabled.
|
|
|
|
That worker also reconciles current IDM incumbencies in batches against a
|
|
durable metadata-only cursor. Assignment, delegation, vacancy, and
|
|
reassignment changes emit versioned platform events and optional in-app
|
|
Notifications for newly eligible current holders. Delivery, action-required,
|
|
escalation-due, read, and acknowledgement events link back to Postbox-owned
|
|
resources without copying message subjects, bodies, or attachment details into
|
|
lifecycle events. Notification preferences, quiet periods, and future external
|
|
channel policy remain owned by Notifications; every deep link rechecks current
|
|
Postbox access.
|
|
|
|
Postboxes expose three configurable content-protection profiles. The recommended
|
|
`server_envelope_v1` profile stores message bodies as ciphertext through an
|
|
institution-controlled Encryption vault and fails closed if its capability or
|
|
key is unavailable. `external_e2ee_v1` accepts only ciphertext, a signed
|
|
manifest, wrapped recipient keys, and a verified content digest produced by an
|
|
approved external client; GovOPlaN cannot decrypt that content. `plaintext_v1`
|
|
keeps content unencrypted for deployments that explicitly accept that boundary.
|
|
Subjects, participants, routing, attachment references, and lifecycle metadata
|
|
remain observable in every profile.
|
|
|
|
Administrators may govern future-only changes or migrate retained history.
|
|
Transitions record user-consent and/or institutional key-holder evidence,
|
|
quorum, reason, per-message digest continuity, and completion state. Managed
|
|
envelope changes use the Encryption migration ledger. Any transition to or from
|
|
E2EE waits for client-supplied transforms for historical messages; the module
|
|
does not claim or silently simulate native browser/device key custody.
|
|
|
|
## Data-subject requests
|
|
|
|
Postbox contributes a tenant-isolated provider to the Core data-subject request
|
|
workflow. It finds bounded personal message, participant, receipt, grouping,
|
|
access, configuration-authorship, and content-protection metadata. It never
|
|
decrypts or exports ciphertext, envelopes, wrapped keys, external-recipient
|
|
tokens, opaque metadata, or unrelated participant data. Institutional delivery,
|
|
routing, acknowledgement, access, template, and protection-transition evidence
|
|
is retained with an explicit reason and message content remains subject to
|
|
manual records and third-party privacy review.
|
|
|
|
Personal unified-inbox groupings are the one directly executable erasure
|
|
operation. Execution revalidates tenant, subject ownership, and the grouping
|
|
revision, then deletes only the personal projection and its source preferences;
|
|
source Postboxes and messages are unchanged. Files attachments, producer
|
|
records, identities, and function assignments remain with their owning modules.
|
|
|
|
Run focused checks with:
|
|
|
|
```bash
|
|
/mnt/DATA/git/govoplan/.venv/bin/python -m unittest discover -s tests
|
|
cd webui && npm run test:ui-structure
|
|
```
|
|
|
|
## Git-source WebUI package
|
|
|
|
The repository root exposes `@govoplan/postbox-webui` for Git-tagged release
|
|
dependencies. It mirrors the owning `webui/package.json` version, public
|
|
TypeScript/CSS exports and peer requirements, with entry paths under
|
|
`webui/src`. Consumers provide the shared Core/React peers; the facade runs no
|
|
development or install scripts. The source archive contains `webui/src`, this
|
|
README and any repository license file. Run module development checks from `webui/`; Python
|
|
installation remains governed by `pyproject.toml`.
|
|
|
|
Das Repository stellt `@govoplan/postbox-webui` am Wurzelpfad für versionierte
|
|
Git-Abhängigkeiten bereit. Version, öffentliche TypeScript-/CSS-Exporte und
|
|
Peer-Anforderungen entsprechen `webui/package.json`; die Einstiegspfade liegen
|
|
unter `webui/src`. Gemeinsame Core-/React-Peers stellt die einbindende Anwendung
|
|
bereit. Die Fassade führt keine Entwicklungs- oder Installationsskripte aus.
|
|
Entwicklungsprüfungen bleiben in `webui/`, die Python-Installation weiterhin in
|
|
`pyproject.toml` definiert.
|