Review: API namespace + Notes controller -- 12 endpoints

review-1567-2026-06-22 Review

review ready

Verdict: APPROVED

Round 2 review. Issue body updated with NoteLink/NoteRevision model files, Note.rb tsvector scope, and clarification that no migrations are needed. All issues resolved.

Template Completeness

  • [x] Type -- Feature
  • [x] Lineage -- decomposed from paldocs#51, depends on #49
  • [x] Repo -- ldraney/paldocs
  • [x] User Story -- MCP layer needs Rails Notes API
  • [x] Context -- explains consolidation, NoteLink/NoteRevision table existence, tsvector scope need
  • [x] File Targets -- 6 files (4 create, 2 modify), plus explicit "do not touch" list
  • [x] Feature Flag -- "none" (new namespace, no UI impact)
  • [x] Acceptance Criteria -- 6 criteria
  • [x] Test Expectations -- 4 test expectations with run command
  • [x] Constraints -- jbuilder exclusion, JSON shape parity, tsvector raw SQL, no migrations
  • [x] Checklist -- 9 items
  • [x] Related -- project, story, arch note, upstream/sibling/downstream tickets

Traceability

  • [x] story:consolidation label -- present on board item
  • [x] story note verified -- story-paldocs-consolidation exists in pal-e-docs, listed in project-paldocs user-stories section
  • [x] arch:rails-api label -- present on board item
  • [x] arch note verified -- arch-rails-api note exists (id 2094), confirms Api::NotesController as component
  • [x] Forgejo issue -- ldraney/paldocs#57, state: open

File Targets

  • [x] app/controllers/api/base_controller.rb -- CREATE. Directory does not exist yet (confirmed). Correct: inherits from ActionController::Base or API, skips CSRF.
  • [x] app/controllers/api/notes_controller.rb -- CREATE. Directory does not exist yet (confirmed). 12 endpoints mapped.
  • [x] app/models/note_link.rb -- CREATE. Confirmed: file does not exist. Tables exist in production DB (imported via pg_dump in #49). No migration needed.
  • [x] app/models/note_revision.rb -- CREATE. Confirmed: file does not exist. Tables exist in production DB. No migration needed.
  • [x] app/models/note.rb -- MODIFY. Confirmed: exists with belongs_to :project, has_many :note_tags, :tags, :board_items, :blocks. Needs has_many :note_links, :note_revisions and tsvector search scope added.
  • [x] config/routes.rb -- MODIFY. Confirmed: exists, currently has resources for projects/notes/boards/board_items. No api namespace yet. Correct target.

Repo Placement

OK. Issue filed on ldraney/paldocs, fix is in ldraney/paldocs. Single repo, no cross-repo work.

Dependencies

  • Upstream: paldocs#49 (schema ownership transfer) -- currently in_progress on board. This ticket depends on #49 because note_links and note_revisions tables must exist via pg_dump import. Documented in issue Lineage section.
  • Siblings: paldocs#58 (boards API), paldocs#59 (projects/repos/tags/search API) -- all in backlog, same wave. No blocking dependency between siblings; they share Api::BaseController which this ticket creates.
  • Downstream: paldocs#54 (new MCP server) -- in todo. Depends on this ticket's API endpoints existing.

Acceptance Criteria

All 6 criteria are testable by an agent:
  • Criteria 1-5: standard HTTP request/response assertions in request specs
  • Criterion 6 (JSON shape comparison): verifiable by comparing Rails output to pal-e-docs output. The pal-e-docs FastAPI source is available locally at ~/pal-e-docs for reference.
Test expectations are concrete: request specs, integration cycle, unit test for search scope, shape comparison. Run command is standard (bundle exec rspec).

Blast Radius

  • New /api/ namespace is fully isolated from existing HTML routes (/projects, /notes, /boards). No route conflicts.
  • ApplicationController uses ActionController::Base; API base controller will use either ::API or ::Base with CSRF skip. No impact on existing controllers.
  • Adding has_many associations to Note model is additive-only; existing associations unchanged.
  • No jbuilder dependency confirmed (not in Gemfile).
  • Sibling tickets (#58, #59) will reuse Api::BaseController created here -- good foundation.

Decomposition Assessment

6 file targets in 1 repo. 6 acceptance criteria (at the 5-rule boundary). However: all work is cohesive (single API namespace, single model domain), the 12 endpoints follow the same CRUD pattern, and the models are trivial (belongs_to + validations). Estimated agent time: 3-4 minutes. No decomposition needed.

Recommendation

No action needed. Ticket is well-scoped, all file targets verified, traceability complete, backing notes exist, dependencies documented. Ready for implementation after #49 (schema ownership) completes.