Review: Drop legacy boards table

review-318-2026-03-27 Review

review needs-refinement

Verdict: NEEDS_REFINEMENT

Template Completeness

  • [x] Type — Feature
  • [x] Lineage — Standalone, kanban unification
  • [x] Repo — present (but stale, see Recommendation)
  • [x] User Story — clear, well-formed
  • [x] Context — thorough, explains motivation and unlocks
  • [x] File Targets — present with source + test + migration breakdown
  • [x] Acceptance Criteria — 6 items
  • [x] Test Expectations — present with run command
  • [x] Constraints — present, includes rollback guidance
  • [x] Checklist — present
  • [x] Related — present
  • [x] Cross-Repo Blast Radius — bonus section, well-documented

Traceability

  • [x] story:kanban-daily-review label — present on board item #318
  • [ ] arch:X label — missing. Recommend arch:board-api to match sibling tickets (#315, #316, #327)
  • [x] Forgejo issue — forgejo_admin/pal-e-api#199, open

File Targets

Source files:
  • [x] src/pal_e_docs/models.py — verified: Board model at line 235, board_id on BoardItem at line 257, board_note_id at line 260 (dual-FK state confirmed)
  • [x] src/pal_e_docs/schemas.py — verified: BoardCreate at line 231, BoardUpdate at line 236, board_id at line 242
  • [x] src/pal_e_docs/routes/boards.py — verified: ~15 board_id refs + ~122 Board refs (issue says "126 board_id/Board refs" — close enough, actual combined is ~137)
  • [ ] src/pal_e_docs/routes/notes.py — ISSUE: ticket claims "2 board_id refs" but grep finds 0 board_id refs and 0 Board model refs. File imports BoardItem and references BoardItem.note_slug but has no Board table dependency. Remove from file targets or clarify what "minor" change is intended.
  • [x] alembic/versions/ — new migration needed (verified alembic dir exists)
Test files (8):
  • [x] All 8 test files verified — exact match: test_boards.py, test_board_sync.py, test_board_issue_sync.py, test_private_projects_boards.py, test_pagination_activity.py, test_note_type_enum.py, test_retype_migration.py, conftest.py
Cross-repo (pal-e-app):
  • [x] src/lib/api-client.ts line 40 — verified: board_id: number;
  • [x] src/routes/+page.svelte line 139 — verified: boardMap[item.board_id]

Repo Placement

ISSUE: ### Repo header says forgejo_admin/pal-e-docs but the repo was renamed to forgejo_admin/pal-e-api (board item #439, done). The Forgejo issue is correctly filed on pal-e-api. The ### Repo line in the issue body is stale.
Python package remains pal_e_docs so file paths are correct.
Cross-repo impact (pal-e-app) is documented. No separate pal-e-app Forgejo issue exists yet — ticket says alias handles backward compat. Acceptable if alias is implemented; otherwise pal-e-app issue needed.

Dependencies

All three predecessor tickets are done:
  • #315 — Add board_note_id FK + data migration (done)
  • #316 — Update board API for board notes (done)
  • #317 — Update MCP + SDK + hooks for board-as-note (done)
No blocking items in in_progress. SDK and MCP have zero board_id references — clean.

Acceptance Criteria

Contradiction found: AC #4 says "API response schemas no longer include board_id field" but the Cross-Repo Blast Radius section says "Alias board_note_id as board_id in API responses for backward compatibility." These contradict each other:
  • If we alias (keep board_id in responses), AC #4 fails
  • If we remove board_id from responses (AC #4 passes), pal-e-app breaks immediately
This needs a human decision: either rewrite AC #4 to account for the alias, or remove the alias strategy and create a coordinated pal-e-app ticket.
Remaining AC are verifiable by an agent via pytest + manual API calls.

Blast Radius

  • pal-e-app: 2 files, 2 references — documented in issue. Handled by alias (if alias is kept) or follow-up ticket (if alias is dropped).
  • pal-e-docs-sdk: 0 board_id references — clean.
  • pal-e-mcp: 0 board_id references — clean.
  • claude-custom: 1 doc reference (update-docs.md line 119) — MCP tool parameter name, not a code consumer. No action needed.

Decomposition

14 files across 1 repo. 6 AC. Borderline on the 5-minute rule.
However, the work is atomic and cohesive — you either drop the table or you don't. Test changes are mechanical (board_id to board_note_id). The migration is a single DDL. Splitting would create an artificial intermediate state harder to reason about than doing it in one pass.
No decomposition needed. Single agent pass is appropriate.

Recommendation

  • [BODY] Fix repo header: ### Repo should say forgejo_admin/pal-e-api (not forgejo_admin/pal-e-docs)
  • [BODY] Fix notes.py claim: remove src/pal_e_docs/routes/notes.py from file targets or clarify — grep finds 0 board_id/Board refs in that file
  • [SCOPE] Resolve AC #4 vs alias contradiction: either rewrite AC #4 to say "API response schemas use board_note_id as the canonical field; board_id returned as deprecated alias" OR remove alias strategy and create a pal-e-app coordination ticket
  • [LABEL] Add arch:board-api label to board item #318