Repository navigation
feat(review): page, decide and edit stored upload rows, insert-only (M4a, #108) - #142
Merged
Merged
Conversation
…M4a, #108) Migration 0008 stores each upload's columns and types, and adds insert-only row_decisions and cell_edits per tenant. The latest entry wins; earlier ones are the history. - GET /api/csv/uploads/{id}/rows pages through every stored row, with original and current values, validation errors and the decision. - PUT .../rows/{n}/decision and PUT .../rows/{n}/cells/{column} record a change with a required reason (reviewer, tenant_admin). Each change is also audited with before and after values. - GET .../rows/{n}/history lists a row's decisions and edits. Review is recorded only; M6 applies it (product owner, 28 Oct). VCRM: BR-27 verified; BR-25 and BR-26 partial until the screen (M4b). CI replica 335/0/0, evals 26/26, lint and health clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019YPoXzBSj89ZHgw7nfTmbB
) Found by the M4b end-to-end check: the browser's preflight for PUT /api/csv/uploads/{id}/rows/{n}/decision was refused (400), because CORS allowed only GET, POST and DELETE. New unit test covers the preflight; it fails without PUT. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019YPoXzBSj89ZHgw7nfTmbB
docs/test-cases/M4-review.md lists 17 positive and 16 negative cases (P01-P17, N01-N16), each with its requirement, a manual PowerShell command where one is practical, the expected result and its automated test. The product owner asked for these to verify the outcomes. New tests/test_review_cases.py adds the 18 cases not already covered: paging bounds, ragged rows, failed uploads, bad edits, column index and empty values, trimmed reasons, signed-in actors, viewing by every role, out-of-range rows, unknown uploads on every route, uploader and auditor refused, invalid session, cross-tenant isolation, bad bodies, the review tables refusing UPDATE/DELETE/TRUNCATE and blank reasons at database level, and non-numeric ids. test_runtime_role.py now also covers review changes through, and refused for, the runtime role. CI replica 354/0/0, evals 26/26, lint clean. The 23 manual commands were run in PowerShell 7 against a local API: 23 of 23 as expected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019YPoXzBSj89ZHgw7nfTmbB
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #108. This is part M4a of ART Milestone 4, the API and database for review. The product owner's 28 Oct decisions are on #108:
reviewerandtenant_adminreview.What it does
uploadsgainscolumnsandcolumn_types, the names and types each upload used. The all-rows-failed result now returns them too, so failed uploads can be reviewed.row_decisionsandcell_edits. Triggers reject UPDATE, DELETE and TRUNCATE, and a CHECK rejects a blank reason.GET /api/csv/uploads/{id}/rows?offset=&limit=(read_rows) returns:PUT …/rows/{n}/decisionwith{decision, reason}records an include or exclude.PUT …/rows/{n}/cells/{column}with{value, reason}records an edit.{column}takes a name or a 0-based index. Both arereview_rows(reviewer, tenant_admin), and each also writes an audit row with before and after values. This is the first use of the M3a columns.GET …/rows/{n}/history(read_rows) lists a row's decisions and edits, oldest first.Second commit: CORS
The API now allows
PUTin CORS. Without it, the browser's preflight for the review endpoints is refused, as M4b's end-to-end check showed. A new unit test covers it and fails without the change.Third commit: test cases (requested by the product owner)
docs/test-cases/M4-review.mdsets out 17 positive and 16 negative cases (P01–P17, N01–N16). Each gives its requirement, a manual PowerShell command where one is practical, the expected result, and the automated test that covers it. The newtests/test_review_cases.pyholds the 18 cases that weren't covered yet;test_runtime_role.pyadds P15 and N15.Not in this PR
Verification
make lintmake healthtests/test_review.py(6 tests)tests/test_roles.pyreview_rows: reviewer and tenant_admin allowed, uploader and auditor refused (403)I broke the code three times to check that the tests catch it. Each time the expected test failed:
uploaderallowed to reviewVCRM:
Generated by Claude Code