feat: add temporal context and contextual help
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
# Temporal Data Context
|
||||
|
||||
GovOPlaN exposes one read context for data validity and system knowledge. The
|
||||
calendar control in the authenticated titlebar applies that context to
|
||||
supported list and detail reads for the current account and tenant.
|
||||
|
||||
## Two Independent Axes
|
||||
|
||||
- **Valid time** answers when a fact applied in the represented domain.
|
||||
- **Recorded time** answers what the system had recorded by a particular
|
||||
instant.
|
||||
|
||||
The default is data valid now under the latest recorded state. `At time`
|
||||
selects a valid-time instant. `All` removes the valid-time interval filter but
|
||||
still uses the selected recorded state. The optional recorded-state cutoff can
|
||||
be combined with any valid-time mode, which keeps correction history distinct
|
||||
from changes in real-world validity.
|
||||
|
||||
An interval is half open: `valid_from <= instant < valid_to`. A revision belongs
|
||||
to a recorded-state snapshot when `recorded_at <= cutoff` and it was not
|
||||
superseded at or before that cutoff.
|
||||
|
||||
## Security And Mutation Rules
|
||||
|
||||
The temporal data context is a read projection, not an authorization context.
|
||||
Authentication, permissions, active delegations, tenant boundaries, module
|
||||
policy, and maintenance controls are always evaluated under current security
|
||||
state. A historical projection never restores an expired permission.
|
||||
|
||||
The context also does not supply mutation dates. Writes continue to target the
|
||||
current lifecycle revision and must carry their explicit valid/effective dates,
|
||||
expected revision, reason, and evidence where the owning contract requires
|
||||
them. A screen showing historical data must not silently turn a normal edit
|
||||
into a historical correction.
|
||||
|
||||
## HTTP Contract
|
||||
|
||||
Core accepts these request headers:
|
||||
|
||||
| Header | Meaning |
|
||||
| --- | --- |
|
||||
| `X-Govoplan-Validity-Mode` | `current`, `at`, or `all` |
|
||||
| `X-Govoplan-Valid-At` | Timezone-aware ISO 8601 instant required by `at` |
|
||||
| `X-Govoplan-Recorded-At` | Optional timezone-aware system-knowledge cutoff |
|
||||
|
||||
Invalid or naive timestamps fail with HTTP 400. Responses expose the resolved
|
||||
mode and evaluated instant. Conditional JSON responses vary by all three
|
||||
request headers, and the shared WebUI API client includes them in request
|
||||
deduplication and conditional-cache keys.
|
||||
|
||||
## Module Adoption
|
||||
|
||||
Revision-owning modules apply
|
||||
`govoplan_core.db.temporal.apply_temporal_revision_filter` only to read queries
|
||||
that are meant to follow the platform context. Explicit version references and
|
||||
explicit resolver `effective_at` arguments take precedence. Current-row
|
||||
lookups used for optimistic concurrency, authorization, routing, effects, or
|
||||
other mutations must remain explicit and context-independent.
|
||||
|
||||
The initial bitemporal adoption covers Decisions, Mandates, Parties, and
|
||||
Services. Their immutable revisions have indexed valid, recorded, and
|
||||
superseded timestamps. Modules with effective-dated security records or
|
||||
recorded-only revision histories require separate display-query adoption so
|
||||
the global selector cannot affect current authorization or execution.
|
||||
|
||||
The WebUI selection is stored in session storage per account and tenant. A
|
||||
change remounts the active module route so existing page loaders issue a fresh
|
||||
request. Returning both axes to their defaults removes the stored selection.
|
||||
Reference in New Issue
Block a user