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
+22 -2
View File
@@ -49,6 +49,7 @@ from backend.services.face_service import (
find_similar_faces,
get_auto_match_people_list,
list_unidentified_faces,
record_match_decisions,
)
from backend.services.face_service import (
get_auto_match_person_matches as get_person_matches_service,
@@ -612,7 +613,7 @@ def auto_match_faces(
"""Start auto-match process with tolerance threshold and optional auto-acceptance.
Matches desktop auto-match workflow exactly:
1. Gets all identified people (one face per person, best quality >= 0.3)
1. Gets all identified people (one face per person, best quality >= MIN_AUTO_MATCH_REFERENCE_QUALITY)
2. For each person, finds similar unidentified faces (confidence >= 40%)
3. Returns matches grouped by person, sorted by person name
@@ -620,7 +621,7 @@ def auto_match_faces(
- Only processes persons with frontal or tilted reference faces (not profile)
- Only processes persons with reference face quality > 50% (quality_score > 0.5)
- Only matches with frontal or tilted unidentified faces (not profile)
- Only auto-accepts matches with similarity >= threshold
- Only auto-accepts matches with similarity >= threshold (default 85%)
- Only auto-accepts faces with quality > 50% (quality_score > 0.5)
"""
from backend.db.models import Person, Photo
@@ -649,6 +650,7 @@ def auto_match_faces(
# 3. Quality must be > 50% (quality_score > 0.5)
qualifying_faces = []
accept_log_items = []
for face, distance, confidence_pct in similar_faces:
# Check similarity threshold
if confidence_pct < request.auto_accept_threshold:
@@ -662,6 +664,14 @@ def auto_match_faces(
continue
qualifying_faces.append(face.id)
accept_log_items.append(
{
"face_id": face.id,
"similarity": float(confidence_pct),
"distance": float(distance),
"reference_face_id": reference_face_id,
}
)
# Auto-accept qualifying faces
if qualifying_faces:
@@ -670,6 +680,16 @@ def auto_match_faces(
db, person_id, qualifying_faces
)
auto_accepted_faces += identified_count
if identified_count:
record_match_decisions(
db,
decision="accept",
source="auto_accept",
person_id=person_id,
items=accept_log_items,
user_id=None,
commit=True,
)
except Exception as e:
import logging
logger = logging.getLogger(__name__)