feat(oc_recording): require triple identity to invalidate secondary (ENG-72)#82
Open
henokteixeira wants to merge 3 commits into
Open
feat(oc_recording): require triple identity to invalidate secondary (ENG-72)#82henokteixeira wants to merge 3 commits into
henokteixeira wants to merge 3 commits into
Conversation
…ENG-72) The secondary classification rule changes from "secondary genre must differ from primary genre" (single field) to "the (register, genre, subcategory) triple of the secondary must differ from the primary by at least one field". The invalid state is only when all three are identical. Shared helper `secondary_equals_primary(...)` backs every callsite: - `RecordingCreate` / `RecordingUpdate` model validators (Pydantic). - `update_recording` service: merges patch with existing recording before evaluating the triple, so partial updates are caught accurately. - `split_service.request_split` adds a defense-in-depth check that each segment's effective primary triple (override-overlaid-on-inherit) is not identical to the parent's secondary triple — which would force the child row into primary == secondary. Companion to the oral-collector client PR #60. Together they restore the ability to set a secondary classification that shares the genre with the primary as long as register or subcategory differs. 🤖 Generated with [Nori](https://noriagentic.com) Co-Authored-By: Nori <contact@tilework.tech>
Per review: business rules belong in the service layer, not in the Pydantic DTO. RecordingCreate/RecordingUpdate are now plain schemas; the `secondary_equals_primary` helper lives in `recording_service` and is invoked at the start of both `create_recording` and `update_recording` (the latter already had the merged-triple check). `split_service.request_split` imports the same helper from `recording_service` instead of from the model. Tests rewritten: the previously Pydantic-level rejection tests are now service-level tests that call `create_recording` and assert `GenreConflictError`. 🤖 Generated with [Nori](https://noriagentic.com) Co-Authored-By: Nori <contact@tilework.tech>
Adds a dedicated exception type for the split-segment triple-collision case following the existing GenreConflictError pattern, replacing the inline string passed to ValidationError. Also drops the prose comments added in this PR (naming carries the meaning) and updates GenreConflictError's message to reflect the new triple-equality rule. 🤖 Generated with [Nori](https://noriagentic.com) Co-Authored-By: Nori <contact@tilework.tech>
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.
Summary
🤖 Generated with Nori
secondary_genre_id != genre_id) to triple-equality ((register, genre, subcategory)of secondary must differ from primary by at least one field).secondary_equals_primary(...)helper inapp/models/oc_recording.pybacksRecordingCreate/RecordingUpdatemodel validators,update_recordingservice (with patch-vs-existing merge), and a new defense-in-depth check insplit_service.request_splitfor segment effective primary triple vs parent secondary triple.Linear: ENG-72
Test Plan
pytest tests/— 627 tests pass.ruff check,ruff format— clean.mypy app/— clean.(Formal, Narrative, Myth)+ secondary(Ceremonial, Narrative, Myth), save, sync, confirm no 422 from server.Share Nori with your team: https://www.npmjs.com/package/nori-skillsets