25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

5.7KB

Story 1.11: Municipality Operational Addresses

Status: done

Story

As a a client services staff member, I want to store and update municipality operational mailing and delivery addresses, so that election services reference current address information without depending on legacy records.

Acceptance Criteria

  1. Given a municipality profile exists When a client services user adds an address Then they can specify mailing or delivery address type, and the record is saved to the extension address table linked to the municipality profile
  2. Given an address is updated When saved Then the previous address is preserved in history, the new address is marked as current, and the change is logged with actor and timestamp
  3. Given an address record is saved When retrieved Then it includes address type, street, city, state, zip, and effective date fields
  4. Given a municipality profile is viewed When addresses are displayed Then mailing and delivery addresses are shown with clear type labels and current/historical status

Tasks / Subtasks

  • Implement story behavior in aligned backend/frontend modules (AC: #1)
    • Add or update API/service/UI components required by the story scope
    • Keep legacy Access entities read-only and route writes to extension-layer structures
  • Cover acceptance criteria #2 in implementation and tests (AC: #2)
    • Add validation/error handling and UX state updates as needed
  • Cover acceptance criteria #3 in implementation and tests (AC: #3)
    • Add validation/error handling and UX state updates as needed
  • Cover acceptance criteria #4 in implementation and tests (AC: #4)
    • Add validation/error handling and UX state updates as needed
  • Validate and document completion evidence
    • Verify build/tests for touched modules
    • Capture changed files and any migration/config implications

Review Findings

Patch

  • [Review][Patch] AC2: UpdateAddressAsync must insert a new record for the updated address and mark the old one IsCurrent=false — do not mutate existing row in-place [MunicipalityAddressService.cs:55-78]
  • [Review][Patch] AC2: Implement audit log entry on create/update using existing audit infrastructure — capture actor identity and timestamp [MunicipalityAddressService.cs]
  • [Review][Patch] Convert DeleteAddressAsync to soft-delete — set IsCurrent=false rather than removing the row [MunicipalityAddressService.cs:81-88]
  • [Review][Patch] Route attribute string literals missing quotes — compilation failure [MunicipalityAddressesController.cs:8,18,25,57]
  • [Review][Patch] UpdateAddress decorated with [HttpPost] instead of [HttpPut("{id}")] — conflicts with CreateAddress, id cannot bind [MunicipalityAddressesController.cs:42]
  • [Review][Patch] GetAddresses and GetAddress share ambiguous route template shape — AmbiguousMatchException at runtime [MunicipalityAddressesController.cs:18,25]
  • [Review][Patch] Interface declares non-nullable return types where null is returned — NullReferenceException risk for callers [IMunicipalityAddressService.cs:10-12]
  • [Review][Patch] ApplicationDbContext is not defined anywhere in the project — service will fail to compile and register [MunicipalityAddressService.cs:9]
  • [Review][Patch] IsCurrent logic ignores address type — adding a Delivery address incorrectly marks the current Mailing address as not-current [MunicipalityAddressService.cs:32,59]
  • [Review][Patch] No transaction around IsCurrent read-modify-write — concurrent requests can produce multiple IsCurrent=true rows per address type [MunicipalityAddressService.cs:30-48,55-73]
  • [Review][Patch] No [Authorize] attribute on controller — RBAC requirement from Dev Notes not enforced [MunicipalityAddressesController.cs:8]
  • [Review][Patch] CreatedAt/UpdatedAt default to object construction time rather than save time [MunicipalityAddress.cs:38-40]
  • [Review][Patch] Microsoft.EntityFrameworkCore unnecessarily imported in interface — leaks infrastructure dependency into abstraction [IMunicipalityAddressService.cs:3]
  • [Review][Patch] [ForeignKey] placed on navigation property instead of scalar FK — string-based reference breaks silently on rename [MunicipalityAddress.cs:42]

Deferred

  • [Review][Defer] State field is free-text with no format validation [MunicipalityAddress.cs:25] — deferred, may support non-US addresses
  • [Review][Defer] MunicipalityId existence not validated before insert — surfaces as DbUpdateException [MunicipalityAddressService.cs:46] — deferred, EF FK constraint handles at DB level

Dev Notes

  • Follow Epic 1 architecture constraints: ASP.NET Core + React separation, RBAC-aware patterns, and immutable legacy tables.
  • Reuse shared component and workflow patterns defined in UX and architecture docs; avoid parallel custom implementations.
  • Keep changes scoped to this story; do not pull forward Epic 2+ features.

Project Structure Notes

  • Backend: Campaign_Tracker.Server/
  • Frontend: campaign-tracker-client/
  • Story artifacts: _bmad-output/implementation-artifacts/

References

  • Story source: _bmad-output/planning-artifacts/epics.md (Epic 1 / Story 1.11)
  • Architecture constraints: _bmad-output/planning-artifacts/architecture.md
  • UX patterns: _bmad-output/planning-artifacts/ux-design-specification.md

Dev Agent Record

Agent Model Used

GPT-5 Codex

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

  • _bmad-output/implementation-artifacts/1-11-municipality-operational-addresses.md

Powered by TurnKey Linux.