Du kannst nicht mehr als 25 Themen auswählenThemen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
Story 2.1 - Municipality-to-Cycle Kanban Entry Point
- ElectionCycleKanbanController (GET /api/election-cycles/kanban) with
ClientServicesAccess RBAC policy
- ElectionCycleKanbanReadModel aggregates active jobs and unassigned
municipalities into multi-lane board; legacy Access tables read-only
- Frontend: electionCycleKanbanView with keyboard-navigable lanes, card
windowing, sticky lane headers, and Unassigned lane always present
- Frontend: electionCycleKanbanContracts with fetch, focus management,
and visibility utilities
- InMemoryElectionCycleJobRepository with seed data for kanban display
- 5 integration tests covering grouping, unassigned municipalities,
inactive exclusion, RBAC enforcement, and legacy read-only invariant
Story 2.2 - Create Election-Cycle Job
- POST /api/election-cycles/jobs accepts existing cycle reference or
new cycle name; persists with "In Setup" status, actor identity,
and server timestamp in extension-layer storage only
- ElectionCycleJobsController with validation (rejects missing JCode
or cycle selection), audit emission via shared IAuditService, and
idempotent creates for duplicate jCode+cycleId pairs
- Frontend: CreateJobModal with existing-cycle selector, new-cycle-name
input, inline validation errors, and kanban reload on success
- "Create cycle job" button wired into Unassigned lane cards; card
relocates to selected cycle lane after creation
10 backend integration tests covering happy path, new cycle generation,
missing cycle/JCode validation, unauthenticated/wrong-role rejection,
audit event emission, legacy read-only invariant, idempotency, and 404