docs(scheduling): document response and privacy lifecycle
This commit is contained in:
85
README.md
85
README.md
@@ -118,3 +118,88 @@ participant pages, Calendar hold cleanup after decision, and advanced scoring
|
|||||||
constraints such as required participants and quorum rules.
|
constraints such as required participants and quorum rules.
|
||||||
|
|
||||||
The active backlog lives in Gitea issues.
|
The active backlog lives in Gitea issues.
|
||||||
|
|
||||||
|
## Signed-participation policy gate
|
||||||
|
|
||||||
|
Scheduling persists the response policy and snapshots it onto each governed
|
||||||
|
Poll invitation. Public access uses
|
||||||
|
`/scheduling/public/{request_id}/{token}`; Poll's ordinary public routes reject
|
||||||
|
these gateway-bound tokens, so callers cannot bypass Scheduling's password and
|
||||||
|
request checks. Passwords are write-only, stored only as salted PBKDF2 hashes,
|
||||||
|
and failed checks are throttled through Redis when configured with a bounded
|
||||||
|
in-process fallback.
|
||||||
|
|
||||||
|
Poll is the transactional authority for response rules. Its governed submission
|
||||||
|
holds the Poll-row lock while enforcing single choice, `Maybe`, participant
|
||||||
|
email, comments, idempotency and per-option capacity. Scheduling then updates
|
||||||
|
its participant projection in the same database transaction. Candidate-slot
|
||||||
|
add/remove and participant-link revocation also go through the governed Poll
|
||||||
|
capability; exact retries are idempotent, and option mutations invalidate only
|
||||||
|
the affected answers.
|
||||||
|
|
||||||
|
Public submissions lock the Scheduling request and participant rows before
|
||||||
|
entering Poll, matching organizer edit lock order and making first-use email
|
||||||
|
binding atomic. Both authenticated and public submission paths independently
|
||||||
|
require the Scheduling request to be collecting and its deadline not to have
|
||||||
|
passed, so a stale or incorrectly reopened Poll projection cannot accept a
|
||||||
|
response. Changing a request deadline transactionally updates each governed
|
||||||
|
invitation's expiry in Poll under owner- and gateway-bound row locks. The same
|
||||||
|
link and invitation identity survive future, past, extended, and cleared
|
||||||
|
deadlines: a past deadline makes the link unusable, a later extension makes the
|
||||||
|
same link usable again, and clearing the deadline removes its expiry. No raw
|
||||||
|
replacement token crosses the PATCH response, and existing responses plus
|
||||||
|
participant status remain attached to the same durable respondent identity.
|
||||||
|
|
||||||
|
Open lifecycle decision: cancellation closes the backing Poll, so submission
|
||||||
|
fails, but an otherwise valid invitation can still resolve the reduced public
|
||||||
|
view and show that the request was cancelled. Decide whether cancellation
|
||||||
|
should revoke links immediately or retain that acknowledgement view for a
|
||||||
|
bounded period; links without a deadline would otherwise remain readable.
|
||||||
|
|
||||||
|
If the governed capability is absent, API responses advertise that policy
|
||||||
|
enforcement is unavailable and restricted links fail closed. Plaintext
|
||||||
|
passwords, token hashes, response-gateway internals and the participant roster
|
||||||
|
are not exposed by the public response model.
|
||||||
|
|
||||||
|
Authenticated participant list/detail projections likewise omit tenant,
|
||||||
|
organizer, Poll and Calendar identifiers, connector metadata, invitation and
|
||||||
|
identity bindings. Free/busy conflicts are reduced to useful time/status
|
||||||
|
fields. Organizers and scheduling administrators retain the full management
|
||||||
|
projection; participants retain candidate-slot revisions, their own marker and
|
||||||
|
email, response settings, aggregates, and any roster names/statuses permitted
|
||||||
|
by the configured privacy policy.
|
||||||
|
|
||||||
|
The WebUI package exposes typed clients for the public access and submission
|
||||||
|
endpoints. A signed-out browser page cannot yet be registered by a module:
|
||||||
|
Core's `App` renders `PublicLandingPage` directly whenever `auth` is absent and
|
||||||
|
only mounts module route contributions inside the authenticated branch. Until
|
||||||
|
Core gains an explicit, allowlisted `publicRoutes` contract, notification action
|
||||||
|
URLs under `/scheduling/public/{request}/{token}` must be treated as a blocked
|
||||||
|
frontend handoff rather than a working guest page. The token is never moved into
|
||||||
|
query parameters, browser storage, or an authenticated API contract while that
|
||||||
|
shell boundary is unresolved.
|
||||||
|
|
||||||
|
Draft saves never issue public tokens or enqueue invitation delivery, even when
|
||||||
|
`create_participant_invitations` is left at its compatibility default. A
|
||||||
|
collecting request may explicitly issue invitations; authenticated in-module
|
||||||
|
responses lazily create a gateway-bound invitation and discard its token. The
|
||||||
|
draft-to-open transition therefore supports authenticated lazy responses, but
|
||||||
|
does not make a guest link available from the current UI. The product decision
|
||||||
|
still open is the explicit organizer workflow for issuing or reissuing public
|
||||||
|
links after a draft is opened and, when Mail is installed, whether that action
|
||||||
|
should also enqueue delivery or return links for separate distribution. Until
|
||||||
|
that workflow is agreed, opening a draft does not silently send anything.
|
||||||
|
|
||||||
|
## FieldLabel omission register
|
||||||
|
|
||||||
|
Scheduling uses the shared `FieldLabel` for form controls that need explanatory
|
||||||
|
inline help. The only intentional omissions are:
|
||||||
|
|
||||||
|
- Candidate-slot and participant DataGrid cells: column headers supply the
|
||||||
|
visible label and each interactive cell has an accessible name.
|
||||||
|
- Per-slot availability selects: the enclosing visible slot/date text is the
|
||||||
|
native label for that individual choice.
|
||||||
|
|
||||||
|
There are no other authorized Scheduling omissions. Inline help remains
|
||||||
|
controlled by the user's shared interface setting; hiding it does not remove
|
||||||
|
accessible labels.
|
||||||
|
|||||||
Reference in New Issue
Block a user