# Story 2.2: Create Election-Cycle Job Status: ready-for-dev ## Story As a client services staff member, I want to create a new election-cycle job for a municipality from the kanban board, so that the municipality is assigned to an election cycle without altering any legacy Access tables. ## Acceptance Criteria 1. **Given** a municipality card is in the Unassigned lane **When** a client services user initiates job creation **Then** they can select an existing cycle or name a new cycle, and a new election-cycle extension record is created linked to the municipality's legacy identifier (ID/JCode) 2. **Given** an election-cycle job is created **When** saved **Then** it is stored in the extension table with the municipality's legacy identifier as a required join key and the municipality card moves to the selected cycle lane on the kanban 3. **Given** an election-cycle job is created **When** the job record is inspected **Then** it includes municipality reference, cycle name, creation actor, creation timestamp, and a status of "In Setup" 4. **Given** a job creation is attempted without selecting or naming a cycle **When** the form is submitted **Then** the save is rejected with a clear inline validation message 5. **And** no INSERT, UPDATE, or DELETE operations are performed on legacy Access tables at any point ## Tasks / Subtasks - [ ] Backend: election-cycle job creation endpoint (AC: #1, #2, #3, #4, #5) - [ ] Add an extension-table entity for election-cycle jobs with required municipality legacy identifier (`ID`/`JCode`) join key, cycle name, status, created-by, and created-at - [ ] POST endpoint accepts either an existing cycle reference or a new cycle name; rejects payloads missing a cycle selection with a structured validation error - [ ] Persist new job with status `"In Setup"`, capturing actor identity from the authenticated principal and server-side timestamp - [ ] Audit the create event using the shared audit logger established in Epic 1 (Story 1.5) - [ ] Confirm via test that the operation never executes INSERT/UPDATE/DELETE against legacy Access tables — only extension storage - [ ] Frontend: create job flow from kanban (AC: #1, #2, #4) - [ ] Add a "Create cycle job" action on Unassigned lane cards that opens a modal/drawer with cycle selection (existing) and new-cycle-name input - [ ] Wire form validation and surface inline server validation errors when cycle selection is missing - [ ] On success, refresh kanban data so the card relocates to the selected cycle lane (multi-lane behavior from Story 2.1 must be preserved) - [ ] Tests & evidence (AC: #1–#5) - [ ] Backend tests for happy path, missing cycle, RBAC, audit emission, legacy table read-only invariant - [ ] Frontend tests for the create flow, validation errors, and post-create kanban update - [ ] Document changed files and any config notes ## Dev Notes - Legacy Access tables are read-only — all writes must go to extension tables joined by `ID`/`JCode`. This invariant is enforced project-wide and is the primary regression risk for this story. - Reuse the audit logger from Story 1.5 and the RBAC/authorization patterns from Stories 1.3/1.4. Do not introduce parallel auth or audit code. - Status `"In Setup"` becomes the upstream input for Stories 2.3–2.5; treat the value as the canonical initial state and keep the status enum centralized. - The kanban entry point and lane data shape are owned by Story 2.1 — extend the existing read model rather than building a parallel one. - Keep changes scoped to this story; key dates, prior-cycle defaults, readiness, and publish behavior land in Stories 2.3–2.5. ### Project Structure Notes - Backend: `Campaign_Tracker.Server/` — add election-cycle feature folder (entity, repository, controller, audit binding) following Epic 1 conventions - Frontend: `campaign-tracker-client/` — add cycle creation UI alongside the kanban view from Story 2.1 - Story artifacts: `_bmad-output/implementation-artifacts/` ### References - Story source: `_bmad-output/planning-artifacts/epics.md` (Epic 2 / Story 2.2) - Architecture constraints: `_bmad-output/planning-artifacts/architecture.md` (extension-table write path, legacy read-only) - UX patterns: `_bmad-output/planning-artifacts/ux-design-specification.md` - Prior story: Story 2.1 — kanban entry point and lane data contract; Story 1.5 — shared audit logging; Story 1.6 — legacy anti-corruption data access layer ## Dev Agent Record ### Agent Model Used {{agent_model_name_version}} ### Debug Log References - Story generated from epic source and architecture/UX planning artifacts. ### Completion Notes List - Story context created and marked ready-for-dev. ### File List ### Change Log