Update board API to use board notes instead of boards table #197

Closed
opened 2026-03-24 16:50:50 +00:00 by forgejo_admin · 3 comments

Type

Feature

Lineage

Standalone — board-pal-e-docs kanban unification. Depends on: "Add board_note_id FK"

Repo

forgejo_admin/pal-e-docs

User Story

As an API consumer (frontend, MCP, SDK)
I want the board API to read/write against board notes
So that the migration is transparent and boards participate in the note system

Context

After board_note_id is populated, the 14 board API endpoints switch from querying the boards table to querying notes where note_type="board". Board CRUD becomes note CRUD with a type filter. Board item endpoints use board_note_id instead of board_id.

Key decision: board API routes stay at /boards/{slug} for backwards compatibility, but internally query notes. Or, board operations become note operations and /boards is an alias.

File Targets

Files to modify:

  • src/pal_e_docs/routes/boards.py — all 14 endpoints switch to note-based queries
  • src/pal_e_docs/schemas.py — BoardOut may change to include note fields (parent_slug, tags, etc.)

Files NOT to touch:

  • src/pal_e_docs/routes/notes.py — note CRUD already handles board notes via note_type
  • src/pal_e_docs/models.py — model changes were in the previous ticket

Acceptance Criteria

  • GET /boards returns notes where note_type="board"
  • POST /boards creates a note with note_type="board"
  • GET /boards/{slug}/items queries via board_note_id
  • All 14 endpoints work against board notes
  • sync_board works with board notes (phase sync, issue sync)
  • Existing board slugs resolve correctly

Test Expectations

  • Full board test suite passes against note-backed boards
  • Sync creates/updates items correctly via board_note_id
  • Run: pytest tests/test_boards.py -v

Constraints

  • API contract (request/response shapes) should not break
  • MCP and SDK consume this API — changes must be backwards compatible

Checklist

  • PR opened
  • Tests pass
  • No unrelated changes
  • project-pal-e-docs — API layer of kanban unification
### Type Feature ### Lineage Standalone — board-pal-e-docs kanban unification. Depends on: "Add board_note_id FK" ### Repo `forgejo_admin/pal-e-docs` ### User Story As an API consumer (frontend, MCP, SDK) I want the board API to read/write against board notes So that the migration is transparent and boards participate in the note system ### Context After board_note_id is populated, the 14 board API endpoints switch from querying the boards table to querying notes where note_type="board". Board CRUD becomes note CRUD with a type filter. Board item endpoints use board_note_id instead of board_id. Key decision: board API routes stay at /boards/{slug} for backwards compatibility, but internally query notes. Or, board operations become note operations and /boards is an alias. ### File Targets Files to modify: - `src/pal_e_docs/routes/boards.py` — all 14 endpoints switch to note-based queries - `src/pal_e_docs/schemas.py` — BoardOut may change to include note fields (parent_slug, tags, etc.) Files NOT to touch: - `src/pal_e_docs/routes/notes.py` — note CRUD already handles board notes via note_type - `src/pal_e_docs/models.py` — model changes were in the previous ticket ### Acceptance Criteria - [ ] GET /boards returns notes where note_type="board" - [ ] POST /boards creates a note with note_type="board" - [ ] GET /boards/{slug}/items queries via board_note_id - [ ] All 14 endpoints work against board notes - [ ] sync_board works with board notes (phase sync, issue sync) - [ ] Existing board slugs resolve correctly ### Test Expectations - [ ] Full board test suite passes against note-backed boards - [ ] Sync creates/updates items correctly via board_note_id - Run: `pytest tests/test_boards.py -v` ### Constraints - API contract (request/response shapes) should not break - MCP and SDK consume this API — changes must be backwards compatible ### Checklist - [ ] PR opened - [ ] Tests pass - [ ] No unrelated changes ### Related - `project-pal-e-docs` — API layer of kanban unification
Author
Owner

Scope Review: NEEDS_REFINEMENT

Review note: review-316-2026-03-24

Template is complete, file targets verified (14 endpoints confirmed, both files exist), dependencies correctly sequenced (#195/#196 done, #198/#199 downstream). Three issues block agent execution:

  • Unresolved architectural decision: Context poses either/or (keep /boards routes querying notes vs. /boards as alias) but does not pick one. Agent needs a clear directive.
  • Migration script prerequisite undocumented: scripts/migrate_boards_to_notes.py must run to populate board_note_id before this API change works. Not mentioned in the ticket.
  • BoardOut/BoardItemOut contract ambiguous: Does board_id stay in BoardItemOut for backwards compat or switch to board_note_id? Does BoardOut.id become the note id? The "API contract should not break" constraint needs these specifics.

Optional: add acceptance criteria for cross-board endpoints (backlog/items, activity), mention _board_to_out/_item_to_out helper rewrites in File Targets.

## Scope Review: NEEDS_REFINEMENT Review note: `review-316-2026-03-24` Template is complete, file targets verified (14 endpoints confirmed, both files exist), dependencies correctly sequenced (#195/#196 done, #198/#199 downstream). Three issues block agent execution: - **Unresolved architectural decision**: Context poses either/or (keep /boards routes querying notes vs. /boards as alias) but does not pick one. Agent needs a clear directive. - **Migration script prerequisite undocumented**: `scripts/migrate_boards_to_notes.py` must run to populate board_note_id before this API change works. Not mentioned in the ticket. - **BoardOut/BoardItemOut contract ambiguous**: Does board_id stay in BoardItemOut for backwards compat or switch to board_note_id? Does BoardOut.id become the note id? The "API contract should not break" constraint needs these specifics. Optional: add acceptance criteria for cross-board endpoints (backlog/items, activity), mention _board_to_out/_item_to_out helper rewrites in File Targets.
Author
Owner

Review Refinements (from review-316-2026-03-24)

Decision 1: Architecture — keep /boards routes, query notes internally

Keep all 14 /boards/{slug} routes at the same URLs with the same response shapes. Internally, switch from querying boards table to querying notes WHERE note_type='board'. The boards table still exists during this ticket — final removal is #199.

This means: same API contract for all consumers (SDK, MCP, frontend). No breaking changes. The transition is invisible to callers.

Decision 2: Migration script prerequisite

scripts/migrate_boards_to_notes.py (from PR #207) must be run on production BEFORE this ticket's PR is deployed. The agent should:

  • Document this prerequisite in the PR body
  • Handle NULL board_note_id gracefully (log warning, skip item) as a safety net
  • The deploy order is: run script → deploy new code

Decision 3: Response contract — additive, not breaking

During transition (this ticket):

  • BoardOut adds note_id: int field (the board note's ID). Existing id field stays (boards table ID).
  • BoardItemOutboard_id stays, board_note_id added (already in the model from #196).
  • All existing fields preserved. New fields are additive.

Final cleanup in #199 (drop boards table): remove id (boards table ID) from BoardOut, remove board_id from BoardItemOut. Rename note_idid, board_note_idboard_id.

Updated Acceptance Criteria

  • GET /boards returns notes where note_type="board" (internally), same response shape + note_id field
  • GET /boards/{slug}/items queries via board_note_id, same response shape + board_note_id field
  • All 14 endpoints work
  • sync_board works (uses board_note_id path)
  • NULL board_note_id handled gracefully (warning, not crash)
  • PR documents: "run migrate_boards_to_notes.py before deploying"
## Review Refinements (from review-316-2026-03-24) ### Decision 1: Architecture — keep /boards routes, query notes internally Keep all 14 `/boards/{slug}` routes at the same URLs with the same response shapes. Internally, switch from querying `boards` table to querying `notes WHERE note_type='board'`. The boards table still exists during this ticket — final removal is #199. This means: same API contract for all consumers (SDK, MCP, frontend). No breaking changes. The transition is invisible to callers. ### Decision 2: Migration script prerequisite `scripts/migrate_boards_to_notes.py` (from PR #207) must be run on production BEFORE this ticket's PR is deployed. The agent should: - Document this prerequisite in the PR body - Handle NULL `board_note_id` gracefully (log warning, skip item) as a safety net - The deploy order is: run script → deploy new code ### Decision 3: Response contract — additive, not breaking During transition (this ticket): - `BoardOut` adds `note_id: int` field (the board note's ID). Existing `id` field stays (boards table ID). - `BoardItemOut` — `board_id` stays, `board_note_id` added (already in the model from #196). - All existing fields preserved. New fields are additive. Final cleanup in #199 (drop boards table): remove `id` (boards table ID) from BoardOut, remove `board_id` from BoardItemOut. Rename `note_id` → `id`, `board_note_id` → `board_id`. ### Updated Acceptance Criteria - [ ] GET /boards returns notes where note_type="board" (internally), same response shape + note_id field - [ ] GET /boards/{slug}/items queries via board_note_id, same response shape + board_note_id field - [ ] All 14 endpoints work - [ ] sync_board works (uses board_note_id path) - [ ] NULL board_note_id handled gracefully (warning, not crash) - [ ] PR documents: "run migrate_boards_to_notes.py before deploying"
Author
Owner

Scope Review: READY

Review note: review-316-2026-03-24 (updated from NEEDS_REFINEMENT)

All three blockers resolved by decisions in comment #6640. Architecture (keep /boards routes, query notes internally), migration prerequisite (documented + NULL graceful handling), and response contract (additive fields, existing preserved) are all verified against the codebase.

  • 14 endpoints confirmed in boards.py, no route changes needed
  • board_note_id FK exists at models.py line 259, migration script exists
  • Test suite (1010 lines) has zero assertions on board_id in responses — additive schema change is safe
  • Dependencies correctly sequenced: #195/#196 done, #198/#199 downstream

Ticket is ready for agent execution.

## Scope Review: READY Review note: `review-316-2026-03-24` (updated from NEEDS_REFINEMENT) All three blockers resolved by decisions in comment #6640. Architecture (keep /boards routes, query notes internally), migration prerequisite (documented + NULL graceful handling), and response contract (additive fields, existing preserved) are all verified against the codebase. - 14 endpoints confirmed in boards.py, no route changes needed - `board_note_id` FK exists at models.py line 259, migration script exists - Test suite (1010 lines) has zero assertions on `board_id` in responses — additive schema change is safe - Dependencies correctly sequenced: #195/#196 done, #198/#199 downstream Ticket is ready for agent execution.
forgejo_admin 2026-03-24 18:39:46 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
forgejo_admin/pal-e-api#197
No description provided.