# GovOPlaN Poll **Repository type:** module (domain). `govoplan-poll` owns lightweight decision and availability polls: date polls, option polls, yes/no decisions, single-choice, multi-choice, ranked choice, response visibility rules, anonymity settings, closing rules, and result summaries. Poll is intentionally small and reusable. It provides polling primitives for modules such as Scheduling, Campaign, Portal, Calendar, and Evaluation without owning their domain workflows. ## Boundaries Poll owns: - poll definitions, options, invitations, responses, and result summaries - availability matrices for scheduling use cases - anonymity and result visibility semantics - closing, reopening, and decision outcome metadata Poll does not own: - meeting scheduling workflows; those belong in `govoplan-scheduling` - post-event surveys, scoring, rubrics, and analytics; those belong in `govoplan-evaluation` - generic form rendering and submission runtime; those belong in `govoplan-forms` and `govoplan-forms-runtime` - mail, notification, and portal delivery infrastructure ## Optional Access Integration `govoplan-access` is optional. With Access installed, Poll can use identity resolution, permission checks, and role templates. Without Access, Poll remains usable for reduced flows such as anonymous participation, signed public links, or participant lists supplied by another adapter. ## Current Backend Slice The first backend implementation adds poll storage, option storage, response storage, validation, result aggregation, tenant summaries, module migrations, and authenticated API routes for: - single-choice, multiple-choice, yes/no, ranked-choice, and availability polls - yes/no/maybe polls for tentative decisions - opening, closing, and deciding polls - submitting and updating respondent answers - listing responses and reading result summaries - signed participation links for reduced/no-Access participation - context and workflow metadata for modules such as Scheduling ## Scheduling As A Poll-Backed Workflow Scheduling should use Poll as the reusable response collection primitive, not reimplement availability polling. A scheduling flow is modeled as an `availability` poll with `context_module="scheduling"`, a scheduling-owned context resource id, and workflow steps such as collect availability, rank candidate slots, decide, notify participants, and hand off to Calendar or Appointments. Poll stores the shared poll/options/responses/result summary. Scheduling owns the domain workflow around rooms, calendars, free/busy checks, reminders, appointment creation, and optional Workflow integration. ## Poll lifecycle Poll configures its lifecycle through the separate, pure transition engine in `backend/transitions.py`. The default policy is: - `draft` → `open` or `archived` - `open` → `draft`, `closed`, or `archived` - `closed` → `open`, `decided`, or `archived` - `decided` → `open`, `decided` (an explicit re-decision), or `archived` - `archived` → the status from which the Poll was archived Reopening and archiving preserve responses, close history, and decision metadata. Every applied transition has a Poll-owned lifecycle audit record. Re-deciding always appends a record and supersedes the current decision. An exact retry carrying the same `Idempotency-Key` is a no-op and returns the original transition record; reusing that key for a different action or option is rejected. Without an idempotency identity, a repeated transition is invalid except for the deliberately auditable `decided` → `decided` action. Poll API representations expose every lifecycle action with its availability and, when unavailable, the policy reason. Management clients can use the `GET /poll/polls/{poll_id}/transitions` endpoint to read the durable history instead of duplicating the matrix in their UI. Polls created through the v0.1.9 contract start in `draft` or `open`; later states are entered through the transition engine. Older archived rows may not contain the status from which they were archived. Their prior state cannot be inferred safely, so unarchive restores them to the least-permissive `draft` state and marks that legacy fallback explicitly in the audit metadata. ## Development Install ```bash cd /mnt/DATA/git/govoplan-core ./.venv/bin/python -m pip install -e ../govoplan-poll ``` Focused manifest verification: ```bash cd /mnt/DATA/git/govoplan-poll PYTHONPATH=src:/mnt/DATA/git/govoplan-core/src /mnt/DATA/git/govoplan-core/.venv/bin/python -m unittest discover -s tests ```