Tighten Auto-Match refs and log accept/reject (Phase 2).
CI / skip-ci-check (pull_request) Successful in 30s
CI / python-lint (pull_request) Successful in 31s
CI / docker-ci (pull_request) Successful in 32s
CI / secret-scan (pull_request) Successful in 35s
CI / e2e (pull_request) Successful in 2m34s
CI / viewer-unit (pull_request) Successful in 2m53s
CI / admin-unit (pull_request) Successful in 3m8s

Raise reference quality floor to 0.5, align browse/run/auto-accept defaults with UI copy, and persist match_decisions for later confidence calibration.
This commit is contained in:
2026-08-05 11:23:24 -04:00
parent dfd0c582e6
commit 085b7962cf
13 changed files with 485 additions and 87 deletions
+58 -4
View File
@@ -21,7 +21,7 @@ from backend.schemas.people import (
PersonUpdateRequest,
PersonWithFacesResponse,
)
from backend.services.face_service import accept_auto_match_matches
from backend.services.face_service import accept_auto_match_matches, record_match_decisions
router = APIRouter(prefix="/people", tags=["people"])
@@ -278,9 +278,63 @@ def accept_matches(
user_id = current_user["user_id"]
try:
identified_count, updated_count = accept_auto_match_matches(
db, person_id, request.face_ids, user_id=user_id
)
person = db.query(Person).filter(Person.id == person_id).first()
if not person:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Person {person_id} not found",
)
if request.face_ids:
accept_auto_match_matches(
db, person_id, request.face_ids, user_id=user_id
)
# Log accepts (with optional scores from client)
score_by_face = {
item.face_id: item for item in (request.accepted_matches or [])
}
accept_items = []
for face_id in request.face_ids:
scored = score_by_face.get(face_id)
accept_items.append(
{
"face_id": face_id,
"similarity": scored.similarity if scored else None,
"distance": scored.distance if scored else None,
"reference_face_id": scored.reference_face_id if scored else None,
}
)
if accept_items:
record_match_decisions(
db,
decision="accept",
source="auto_match",
person_id=person_id,
items=accept_items,
user_id=user_id,
commit=True,
)
if request.rejected_matches:
reject_items = [
{
"face_id": item.face_id,
"similarity": item.similarity,
"distance": item.distance,
"reference_face_id": item.reference_face_id,
}
for item in request.rejected_matches
]
record_match_decisions(
db,
decision="reject",
source="auto_match",
person_id=person_id,
items=reject_items,
user_id=user_id,
commit=True,
)
except ValueError as e:
if "not found" in str(e).lower():
raise HTTPException(