Add slug rename support to note update API #24
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/pal-e-api!24
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "23-slug-rename"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
PUT /notes/{slug}endpoint so notes can be renamed via the APIChanges
src/pal_e_docs/schemas.py: Addedslug: str | None = Nonefield toNoteUpdateschemasrc/pal_e_docs/routes/notes.py: Added slug rename logic inupdate_note— checks for conflicts before renamingtests/test_crud.py: Added 3 tests — rename succeeds, rename conflict returns 409, rename to same slug is a no-opTest Plan
PALDOCS_DATABASE_PATH=:memory: python -m pytest— 14/14 passed)Review Checklist
Related Notes
plan-2026-02-25-agent-profiles— phasephase-2026-02-25-3.5-claude-custom-cleanupAllow renaming a note's slug via PUT /notes/{slug} by including a `slug` field in the request body. Returns 409 if the new slug is already taken. Same-slug is a no-op. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>PR #24 Review
Reviewer: QA Agent
Phase:
phase-2026-02-25-3.5-claude-custom-cleanupPlan:
plan-2026-02-25-agent-profilesBLOCKERS
None.
The slug rename logic is correct. The conflict check properly queries for an existing note with the target slug, the
body.slug != slugguard prevents false self-conflicts, and the rename is placed before other field updates so it fails fast on 409. All three key test scenarios (rename succeeds, conflict returns 409, same-slug no-op) are covered.Foreign keys (
NoteLink,NoteRevision,NoteTag) all referencenote_id(integer PK), not slug, so renames cannot break relationships. No injection risk -- all queries go through SQLAlchemy ORM.NITS
No slug format validation — The new
slugfield onNoteUpdateaccepts any string (spaces, special characters, empty string).NoteCreate.slughas the same gap, so this is pre-existing and not in scope for this PR. Consider adding a Pydanticfield_validatorwith a regex like^[a-z0-9]+(-[a-z0-9]+)*$in a future PR to bothNoteCreateandNoteUpdate.TOCTOU race on conflict check — The check-then-set pattern (
query existing→set slug) could race under concurrent requests. The DBUNIQUEconstraint onNote.slugwould catch it, but it would surface as a 500IntegrityErrorinstead of a clean 409. Low risk given the single-user deployment, but atry/except IntegrityError → 409wrapper would be more robust. Not blocking.Forgejo issue reference in Related Notes — The PR body references "Forgejo issue #23" alongside the plan slug. Current convention is that issues are tracked as pal-e-docs notes, not Forgejo issues. Very minor — this issue likely predates the convention change.
SOP COMPLIANCE
23-slug-rename)template-pr-body(Summary, Changes, Test Plan, Review Checklist, Related Notes)plan-2026-02-25-agent-profiles)VERDICT: APPROVED
Clean, focused PR. The slug rename logic is correct, edge cases are handled, tests are thorough, and SOP compliance is complete. The nits (slug format validation, TOCTOU race) are pre-existing gaps that should be addressed in a separate PR, not blockers for this one.