Skip to content

Feature/examination access decision#32

Open
Soldier224K wants to merge 3 commits into
mainfrom
feature/examination-access-decision
Open

Feature/examination access decision#32
Soldier224K wants to merge 3 commits into
mainfrom
feature/examination-access-decision

Conversation

@Soldier224K

@Soldier224K Soldier224K commented May 23, 2026

Copy link
Copy Markdown
Collaborator

closes #20

Raj added 3 commits May 23, 2026 19:35
- 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 AuditLogService for comprehensive identity event logging
- Log verification attempts, face matches/mismatches, suspicious events
- Log admin override actions and examination access decisions
- Add get_timeline() for roll-number or session filtered audit trails
- Add search() for querying audit log content
- Add new event types: VERIFICATION_ATTEMPT, FACE_MATCH, FACE_MISMATCH, SUSPICIOUS_IDENTITY, ADMIN_OVERRIDE, EXAMINATION_ACCESS
- Add API endpoints: /audit/timeline, /audit/search, /audit/events/{type}
- Add 15 tests covering all audit logging functionality
- Add ExaminationAccessDecision for producing access decisions before viva
- Support ACCESS_GRANTED, ACCESS_DENIED, MANUAL_REVIEW_REQUIRED, TEMPORARY_BLOCK outcomes
- Aggregate verification outputs, identity conflict results, safety checks
- Generate explainable access decisions with evidence
- Issue secure examination authorization with decision IDs
- Add 12 tests covering all decision outcomes and flow scenarios
Copilot AI review requested due to automatic review settings May 23, 2026 15:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds administrative review metadata to face-detection conflict alerts, introduces an in-memory audit logging service with API endpoints to query it, and adds an examination access decision engine with corresponding tests.

Changes:

  • Extend ConflictAlert with reviewer metadata and add conflict-detail/admin-review/override-log helper APIs in FaceDetectionService.
  • Add AuditLogService + AuditEvent and expose audit query endpoints in the FastAPI app.
  • Add ExaminationAccessDecision decision engine (verification/conflict/safety-check driven) with unit tests.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
backend/src/services/face_detection.py Adds reviewer fields to alerts and new conflict/admin review helper methods.
backend/src/services/audit_log.py Introduces an in-memory audit log service and event model.
backend/src/services/access_decision.py Adds the examination access decision engine and supporting data models.
backend/src/main.py Wires in new admin/audit endpoints and extends resolve-alert request schema.
backend/src/models/events.py Adds new EventType constants for admin/audit-related events.
backend/tests/test_face_detection.py Updates/extends face-detection tests for reviewer metadata and new APIs.
backend/tests/test_audit_log.py Adds unit tests for the new audit log service.
backend/tests/test_access_decision.py Adds unit tests for the examination access decision engine.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread backend/src/main.py
Comment on lines +82 to +86
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 thread backend/src/main.py
Comment on lines +90 to +98
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 +46 to +50
event = AuditEvent(
event_id=self._generate_event_id(roll_number, "verification_attempt", datetime.now(timezone.utc)),
timestamp=datetime.now(timezone.utc),
event_type="verification_attempt",
roll_number=roll_number,
@@ -0,0 +1,201 @@
from typing import Optional, List, Dict, Any
from dataclasses import dataclass, field
Comment on lines +152 to +156
def get_decisions_for_roll(self, roll_number: str) -> List[AccessDecisionResult]:
return [
d for d in self._decisions.values()
if roll_number in str(d.evidence.get("verification", {}))
]
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 +1 to +5
import pytest
from backend.src.services.audit_log import (
AuditLogService,
AuditEvent,
)

def test_deterministic_event_id(self):
log = AuditLogService()
import time
@@ -0,0 +1,238 @@
import pytest
Comment thread backend/src/main.py
Comment on lines +104 to +113
@app.get("/audit/timeline")
async def get_audit_timeline(roll_number: Optional[str] = None, session_id: Optional[str] = None):
result = []
if session_id:
result = audit_log.get_session_timeline(session_id)
elif roll_number:
result = audit_log.get_timeline(roll_number)
else:
result = audit_log.get_timeline()
return result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ISSUE 6 — Examination Access Authorization Engine

2 participants