PH1.3 — API platform: pagination, idempotency, ETag, soft-delete repository, crud_router factory #11
Labels
No labels
in-progress
in-review
ready-for-agent
seam-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Blocks
Depends on
Reference
patrick/Polaris#11
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Parent
Row PH1.3 in
docs/12-implementation-plan.md(branch, owned paths and doc section are defined there).What to build
Any list endpoint returns
{items, total}with filter and sort parsing; mutating endpoints accept anIdempotency-KeyandIf-Match/ETag, require areason, and write an audit row in the same transaction. A genericcrud_router(...)builds a soft-delete CRUD router for a master-data aggregate from its model and DTOs.Acceptance criteria
crud_routerover a test aggregate serves list/get/create/update/soft-delete with role checksIdempotency-Keyreturns the stored response and performs no second writeIf-Matchyields 412; a matching one succeeds and the ETag changesreasonis a 422Blocked by
Starting PH1.3 on
feature/api-platform(branch already existed at zero commits, branched frommain).Owned paths for this ticket:
backend/src/polaris/api/{pagination,idempotency,etag,crud}.py,backend/src/polaris/db/repository.py,backend/tests/unit/api/**. Not touchingapi/main.py,api/auth.py, or anydb/models/*.py.Work is done; PR incoming shortly. Two small, isolated, flagged touches to files this ticket doesn't own were needed to complete the
reason->audit_log.reasonplumbing:polaris/core/context.py(newreason_varcontextvar, mirroringactor_sub_var/actor_role_var) andpolaris/db/audit.py(one-line read of it in_audit_row). Also addedPreconditionFailedErrortopolaris/core/errors.py(412, same pattern as the existing error classes) since the ticket brief explicitly sanctioned extending that file. See the PR description for the full reasoning.Idempotency-store persistence — design call, flagged as requested.
The ticket's own remit doesn't include
backend/alembic/versions/**, and0003(the next free migration slot) is already claimed by PH1.2 /feature/db-schema-planning(perdocs/12-implementation-plan.md's Wave 1a row: "PH1.1 -> PH1.2 ... One session does both, back to back."). Sopolaris.api.idempotency.InMemoryIdempotencyStoreis in-process, not a database table:actor_sub:method:path:Idempotency-Key.Idempotency-Keysupport at all -- never to a wrong or double-counted result. Strictly better than nothing for a single-instance dev/staging deployment; not sufficient once there's more than one API replica in front of a load balancer.Seam request: whoever takes the next free migration slot after
0003should add a durableidempotency_keytable (same key shape) and swap_default_storeinpolaris/api/idempotency.pyfor a table-backed implementation of the sameIdempotencyStoreprotocol -- no caller-side changes needed,crud_routeronly depends on the protocol. Opening this as a heads-up here rather than a separate issue since there's no ticket yet for "whatever comes after PH1.2's migration" to attach it to; happy to open a proper seam-request issue once that next migration-owning ticket exists, or a maintainer can fold it into that ticket's brief directly.