Files
govoplan-scheduling/README.md

10 KiB

GovOPlaN Scheduling

Repository type: module (domain).

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.