feat: add admin review workflow for identity conflict resolution#29
Merged
Conversation
Soldier224K
commented
May 23, 2026
Collaborator
- Add reviewer_id, review_timestamp, review_reason to ConflictAlert
- Add get_conflict_details() to inspect prior face history
- Add admin_review_conflict() for approval/rejection actions
- Add get_override_log() to persist manual review decisions
- Add API endpoints: /face/conflict/{id}, /admin/review-conflict, /admin/override-log
- Add new event types: ADMIN_REVIEW_STARTED, ADMIN_REVIEW_APPROVED, ADMIN_REVIEW_REJECTED, ADMIN_OVERRIDE_ACTION
- Add 5 new tests for admin review functionality
- Add reviewer_id, review_timestamp, review_reason to ConflictAlert
- Add get_conflict_details() to inspect prior face history
- Add admin_review_conflict() for approval/rejection actions
- Add get_override_log() to persist manual review decisions
- Add API endpoints: /face/conflict/{id}, /admin/review-conflict, /admin/override-log
- Add new event types: ADMIN_REVIEW_STARTED, ADMIN_REVIEW_APPROVED, ADMIN_REVIEW_REJECTED, ADMIN_OVERRIDE_ACTION
- Add 5 new tests for admin review functionality
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces an admin review workflow around face-identity conflict alerts, expanding the conflict alert model with review metadata and adding service/API capabilities to inspect conflicts and record approval/rejection decisions.
Changes:
- Extend
ConflictAlertwithreviewer_id,review_timestamp, andreview_reason, and surface them in serialization. - Add service methods for conflict inspection (
get_conflict_details), admin decisions (admin_review_conflict), override log retrieval (get_override_log), and alert lookup (get_alert_by_id). - Add FastAPI endpoints for conflict details and admin review/override-log, plus associated unit tests.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 9 comments.
| File | Description |
|---|---|
| backend/tests/test_face_detection.py | Updates/extends unit tests to cover conflict detail retrieval and admin review/override log behaviors. |
| backend/src/services/face_detection.py | Adds review fields to conflict alerts and implements admin review + conflict detail/override log helpers. |
| backend/src/models/events.py | Introduces new event type constants for admin review/override actions. |
| backend/src/main.py | Adds request schemas and new REST endpoints for conflict details and admin review/override log. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+79
to
+84
| @app.get("/face/conflict/{conflict_id}") | ||
| async def get_conflict_details(conflict_id: str): | ||
| details = face_service.get_conflict_details(conflict_id) | ||
| if details is None: | ||
| return {"error": "Conflict not found"}, 404 | ||
| return details |
Comment on lines
+86
to
+96
| @app.post("/admin/review-conflict") | ||
| async def admin_review_conflict(request: AdminReviewRequest): | ||
| success = face_service.admin_review_conflict( | ||
| request.conflict_id, | ||
| request.approved, | ||
| request.reviewer_id, | ||
| request.reason | ||
| ) | ||
| if not success: | ||
| return {"error": "Conflict not found"}, 404 | ||
| return {"success": True, "message": "Review decision recorded"} |
Comment on lines
+86
to
+100
| @app.post("/admin/review-conflict") | ||
| async def admin_review_conflict(request: AdminReviewRequest): | ||
| success = face_service.admin_review_conflict( | ||
| request.conflict_id, | ||
| request.approved, | ||
| request.reviewer_id, | ||
| request.reason | ||
| ) | ||
| if not success: | ||
| return {"error": "Conflict not found"}, 404 | ||
| return {"success": True, "message": "Review decision recorded"} | ||
|
|
||
| @app.get("/admin/override-log") | ||
| async def get_override_log(): | ||
| return face_service.get_override_log() |
Comment on lines
+79
to
+84
| @app.get("/face/conflict/{conflict_id}") | ||
| async def get_conflict_details(conflict_id: str): | ||
| details = face_service.get_conflict_details(conflict_id) | ||
| if details is None: | ||
| return {"error": "Conflict not found"}, 404 | ||
| return details |
Comment on lines
+175
to
+178
| def test_get_conflict_details(self): | ||
| service = FaceDetectionService() | ||
| emb1 = generate_embedding(base=0.5) | ||
| emb2 = create_similar_embedding(emb1, 0.92) |
Comment on lines
+181
to
+188
| for alert in self.alerts: | ||
| if alert.conflict_id == conflict_id: | ||
| alert.status = "approved" if approved else "rejected" | ||
| alert.reviewer_id = reviewer_id | ||
| alert.review_timestamp = datetime.now(timezone.utc) | ||
| alert.review_reason = reason | ||
| return True | ||
| return False |
Comment on lines
+133
to
140
| def resolve_alert(self, conflict_id: str, approved: bool, reviewer_id: Optional[str] = None, reason: Optional[str] = None) -> bool: | ||
| for alert in self.alerts: | ||
| if alert.conflict_id == conflict_id: | ||
| alert.status = "approved" if approved else "rejected" | ||
| alert.reviewer_id = reviewer_id | ||
| alert.review_timestamp = datetime.now(timezone.utc) | ||
| alert.review_reason = reason | ||
| return True |
Comment on lines
+190
to
+192
| def get_override_log(self) -> List[Dict[str, Any]]: | ||
| return [alert.to_dict() for alert in self.alerts if alert.status in ("approved", "rejected")] | ||
|
|
| @@ -147,4 +156,42 @@ def can_grant_access(self, roll_number: str) -> Tuple[bool, Optional[str]]: | |||
| for conflict in conflicts: | |||
| if conflict.status == "pending_review": | |||
| return False, f"Identity under review: conflict {conflict.conflict_id}" | |||
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.