Person cover face: remove dead album_auto annotations and owner-scope the subquery

Author: derneuereCreated Sep 16, 2026Updated Sep 16, 2026
Labelsenhancementbackend

Summary

Follow-up to #2042 (fixes #618). Two loose ends around how PersonSerializer gets its cover face.

1. Dead annotations in album_auto.py

apps/backend/api/views/album_auto.py (around lines 36-68) annotates persons with face_url, face_photo_url and video. Those names collide with PersonSerializer's SerializerMethodFields, so DRF calls the getters and ignores the annotations. They have been dead for a while. #2042 added a second, live set (first_face_image, first_face_photo_hash, first_face_photo_video) that the serializer actually reads.

Delete the album_auto annotations, or port them to the new names. Note their semantics differ deliberately (owner scoped, hidden and trashcan excluded, ordered by added_on), so a straight rename changes which face is shown.

2. First-face subquery is not owner scoped

PersonViewSet's Face.objects.filter(person=OuterRef("pk")).order_by("id") reproduces the old obj.faces.first() exactly, so it is not a regression, but it does not follow the owned_by / visible_to scoping convention. If a face from another user's photo were ever attached to a cluster_owner scoped person, the image hash would leak in the people list. Worth scoping the subquery to photo__owner=request.user and adding a two-owner test, in line with #2031.