206 lines
10 KiB
Markdown
206 lines
10 KiB
Markdown
# GovOPlaN Scheduling
|
|
|
|
<!-- govoplan-repository-type:start -->
|
|
**Repository type:** module (domain).
|
|
<!-- govoplan-repository-type:end -->
|
|
|
|
GovOPlaN Scheduling owns meeting scheduling and `Terminfindung`: finding
|
|
suitable times across people, resources, calendars, constraints, and scheduling
|
|
polls.
|
|
|
|
This repository is initialized as a discoverable module seed. It exposes the
|
|
module manifest, permission surface, role templates, and documentation metadata
|
|
before runtime APIs, database models, migrations, and WebUI routes are
|
|
introduced.
|
|
|
|
The core boundary decision register is in
|
|
`/mnt/DATA/git/govoplan-core/docs/MODULE_ARCHITECTURE.md`.
|
|
|
|
## Scope
|
|
|
|
Scheduling owns:
|
|
|
|
- meeting scheduling polls and proposals built on `govoplan-poll`
|
|
- participant availability collection
|
|
- time-window and resource constraints
|
|
- candidate-slot ranking and conflict explanation
|
|
- scheduling state, reminders, and decision handoff
|
|
- optional links to external calendar/groupware systems through capabilities
|
|
- organizer permissions and poll administration semantics
|
|
|
|
Scheduling does not own:
|
|
|
|
- calendar primitives such as events, recurrence, availability storage, resources, and calendar adapters; those belong in `govoplan-calendar`
|
|
- fixed-slot public or internal appointment booking; that belongs in `govoplan-appointments`
|
|
- tasks, case work, approvals, and generic workflow state; those belong in `govoplan-tasks`, `govoplan-cases`, and `govoplan-workflow`
|
|
- mail delivery or notifications; those belong in `govoplan-mail` and `govoplan-notifications`
|
|
|
|
## Poll Audience Decision
|
|
|
|
Scheduling polls should support both internal and external/public
|
|
participation, but the first implementation may start internal-only.
|
|
|
|
- Internal polls use Access/IDM identities, groups, permissions, and calendar
|
|
free/busy capability lookups.
|
|
- External/public polls use signed participation links through Portal, minimal
|
|
participant identity, and explicit retention/privacy settings.
|
|
- Mixed polls are allowed only when the organizer has permission to invite
|
|
external participants and the poll explains which participant data is visible.
|
|
|
|
## Privacy, Retention, And Audit
|
|
|
|
Participant availability is sensitive operational data. Scheduling must record:
|
|
|
|
- poll creator, tenant, organizer, invited participants, and access scope
|
|
- what each participant can see about other participants
|
|
- retention deadline for availability responses and poll links
|
|
- audit events for poll creation, invite send, response update, decision,
|
|
cancellation, and handoff
|
|
- trace IDs for mail/notification/portal handoff
|
|
|
|
Availability responses should be removable or redacted after the poll decision
|
|
unless a configured process requires longer evidence retention.
|
|
|
|
## Candidate Capabilities
|
|
|
|
- `scheduling.polls`
|
|
- `scheduling.availabilityCollector`
|
|
- `scheduling.candidateSlots`
|
|
- `scheduling.decisionHandoff`
|
|
- `scheduling.portalParticipation`
|
|
|
|
## Manifest Dependency Decision
|
|
|
|
The Scheduling manifest declares `poll` as a required dependency because
|
|
availability collection and option/date poll primitives belong in
|
|
`govoplan-poll`.
|
|
|
|
Scheduling should model each meeting-finding flow as a poll-backed workflow:
|
|
Poll owns candidate options, signed participation links, responses, visibility,
|
|
and result aggregation. Scheduling stores the scheduling-specific context and
|
|
uses Poll context fields to point back to its request or proposal resource.
|
|
Typical workflow steps are collect availability, rank candidates, decide, notify
|
|
participants, and hand off to Calendar or Appointments.
|
|
|
|
The manifest declares `access` and `evaluation` as optional dependencies.
|
|
Scheduling may use Access for identity, groups, and permissions, and may trigger
|
|
post-event or post-appointment feedback through Evaluation. It must not require
|
|
either module just to find a meeting time.
|
|
|
|
## Expected Integrations
|
|
|
|
- `govoplan-poll`: required availability matrix and lightweight poll primitives
|
|
- `govoplan-evaluation`: optional post-event, post-appointment, or process feedback
|
|
- `govoplan-calendar`: availability, calendars, resources, rooms, recurrence, Open-Xchange/calendar adapters
|
|
- `govoplan-appointments`: conversion from a selected meeting time into a booked appointment where appropriate
|
|
- `govoplan-access` and `govoplan-idm`: optional participants, groups, directory lookup, permissions
|
|
- `govoplan-mail` and `govoplan-notifications`: invitations, reminders, confirmations
|
|
- `govoplan-portal`: external participant scheduling flows
|
|
- `govoplan-workflow` and `govoplan-tasks`: follow-up work after a time is selected
|
|
|
|
## First Package Scaffold Decision
|
|
|
|
The first backend implementation slice adds runtime APIs and storage around
|
|
poll-backed scheduling requests:
|
|
|
|
- scheduling request, candidate slot, and participant storage
|
|
- automatic `govoplan-poll` availability poll creation
|
|
- signed poll invitations for internal or external participants
|
|
- request lifecycle APIs: draft, collecting, closed, decided, handed off, cancelled
|
|
- result summaries sourced from Poll response aggregation
|
|
- optional Calendar free/busy checks, tentative holds, and final event creation
|
|
- notification outbox jobs for invitations, reminders, decisions, and cancellations
|
|
- a first Scheduling WebUI package with request creation, slot matrix, Calendar
|
|
actions, decisions, and notification-job creation
|
|
|
|
The next slices should add real notification delivery workers, richer public
|
|
participant pages, Calendar hold cleanup after decision, and advanced scoring
|
|
constraints such as required participants and quorum rules.
|
|
|
|
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.
|