feat: add selection validation with optimistic locking

Implements Step 5.3 - selection validation for optimistic locking:

- SelectionContext: holds client's filter, resolved_ids, roster_hash, ts_utc
- SelectionDiff: shows added/removed animals on mismatch
- SelectionValidationResult: validation result with diff if applicable
- validate_selection(): re-resolves at ts_utc, compares hashes, returns diff
- SelectionMismatchError: exception for unconfirmed mismatches

Tests cover: hash match, mismatch detection, diff correctness, confirmed bypass,
from_location_id in hash comparison.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-29 15:46:19 +00:00
parent c80d9f7fda
commit e9d3f34994
4 changed files with 625 additions and 6 deletions

10
PLAN.md
View File

@@ -205,11 +205,11 @@ Check off items as completed. Each phase builds on the previous.
- [x] **Commit checkpoint**
### Step 5.3: Optimistic Locking
- [ ] Create `selection/validation.py` for selection validation
- [ ] Re-resolve on submit, compute hash, return diff on mismatch
- [ ] Create SelectionContext and SelectionDiff models
- [ ] Write tests: mismatch detected, diff correct, confirmed bypasses
- [ ] **Commit checkpoint**
- [x] Create `selection/validation.py` for selection validation
- [x] Re-resolve on submit, compute hash, return diff on mismatch
- [x] Create SelectionContext and SelectionDiff models
- [x] Write tests: mismatch detected, diff correct, confirmed bypasses
- [x] **Commit checkpoint**
---