feat: user attribution on notes — track who creates and edits #268

Closed
opened 2026-04-12 18:04:15 +00:00 by forgejo_admin · 0 comments

Type

Feature

Lineage

Depends on dual auth middleware issue (must land first). Part of pal-e-app "app definition" compliance.

Repo

forgejo_admin/pal-e-api

User Story

As a pal-e-app user, I want to see who created and last edited a note so that I know who to ask about it.
As a platform operator, I want authoritative edit tracking so that revised_by reflects actual identity, not free-text strings.

Context

Notes have revised_by (free-text String(500)) on NoteRevision (models.py line 201). It's client-provided and unverified — agents pass "PR #42", humans pass nothing. There's no created_by on notes at all. With JWT auth in place from the dual auth ticket, the API can auto-populate these from the authenticated user's token claims.

File Targets

Files the agent should modify or create:

  • src/pal_e_docs/models.py — add created_by_sub, created_by_name, updated_by_sub, updated_by_name columns to Note model
  • src/pal_e_docs/schemas.py — add attribution fields to NoteOut response
  • src/pal_e_docs/routes/notes.py — wire auto-populate from UserContext on create/update, add ?created_by_sub= filter param
  • alembic/versions/ — new migration file for the 4 new columns

Files the agent should NOT touch:

  • src/pal_e_docs/auth.py — already modified in the dual auth ticket

Acceptance Criteria

  • Note created via JWT has created_by_name in API response
  • Note updated via JWT has updated_by_name in API response
  • Notes created via API key have NULL attribution (no crash)
  • GET /notes?created_by_sub={sub} returns only that user's notes
  • NoteRevision revised_by auto-populated from JWT name when present

Test Expectations

  • Unit test: create note with UserContext → attribution columns populated
  • Unit test: create note without UserContext → attribution columns NULL
  • Unit test: update note with UserContext → updated_by fields change
  • Integration test: filter GET /notes?created_by_sub=X returns correct subset
  • Run command: pytest tests/ -v

Constraints

  • All new columns must be nullable (backwards compatible with existing data)
  • API key callers (MCP agents) must not break — NULL attribution is fine
  • Match existing Alembic migration naming convention
  • revised_by stays as String(500) on NoteRevision — auto-populate from token name but don't change the column type

Checklist

  • PR opened
  • Tests pass
  • Migration runs cleanly on existing data
  • No unrelated changes
  • pal-e-docs — project this affects
  • Dual auth middleware issue — must land first
### Type Feature ### Lineage Depends on dual auth middleware issue (must land first). Part of pal-e-app "app definition" compliance. ### Repo `forgejo_admin/pal-e-api` ### User Story As a **pal-e-app user**, I want to see who created and last edited a note so that I know who to ask about it. As a **platform operator**, I want authoritative edit tracking so that `revised_by` reflects actual identity, not free-text strings. ### Context Notes have `revised_by` (free-text String(500)) on NoteRevision (models.py line 201). It's client-provided and unverified — agents pass "PR #42", humans pass nothing. There's no `created_by` on notes at all. With JWT auth in place from the dual auth ticket, the API can auto-populate these from the authenticated user's token claims. ### File Targets Files the agent should modify or create: - `src/pal_e_docs/models.py` — add `created_by_sub`, `created_by_name`, `updated_by_sub`, `updated_by_name` columns to Note model - `src/pal_e_docs/schemas.py` — add attribution fields to NoteOut response - `src/pal_e_docs/routes/notes.py` — wire auto-populate from UserContext on create/update, add `?created_by_sub=` filter param - `alembic/versions/` — new migration file for the 4 new columns Files the agent should NOT touch: - `src/pal_e_docs/auth.py` — already modified in the dual auth ticket ### Acceptance Criteria - [ ] Note created via JWT has `created_by_name` in API response - [ ] Note updated via JWT has `updated_by_name` in API response - [ ] Notes created via API key have NULL attribution (no crash) - [ ] `GET /notes?created_by_sub={sub}` returns only that user's notes - [ ] NoteRevision `revised_by` auto-populated from JWT name when present ### Test Expectations - [ ] Unit test: create note with UserContext → attribution columns populated - [ ] Unit test: create note without UserContext → attribution columns NULL - [ ] Unit test: update note with UserContext → updated_by fields change - [ ] Integration test: filter `GET /notes?created_by_sub=X` returns correct subset - Run command: `pytest tests/ -v` ### Constraints - All new columns must be nullable (backwards compatible with existing data) - API key callers (MCP agents) must not break — NULL attribution is fine - Match existing Alembic migration naming convention - `revised_by` stays as String(500) on NoteRevision — auto-populate from token name but don't change the column type ### Checklist - [ ] PR opened - [ ] Tests pass - [ ] Migration runs cleanly on existing data - [ ] No unrelated changes ### Related - `pal-e-docs` — project this affects - Dual auth middleware issue — must land first
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#268
No description provided.