From a53ba9381f372417babb599dfec688bbc02491d4 Mon Sep 17 00:00:00 2001 From: Yaros Date: Mon, 8 Dec 2025 13:06:05 +0100 Subject: [PATCH 1/3] fix(server): people count doesn't match array --- server/src/repositories/person.repository.ts | 8 +++++++- server/src/services/person.service.ts | 5 ++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/server/src/repositories/person.repository.ts b/server/src/repositories/person.repository.ts index 725304938c..cff4d8909e 100644 --- a/server/src/repositories/person.repository.ts +++ b/server/src/repositories/person.repository.ts @@ -358,7 +358,7 @@ export class PersonRepository { } @GenerateSql({ params: [DummyValue.UUID] }) - getNumberOfPeople(userId: string) { + getNumberOfPeople(userId: string, options?: PersonSearchOptions) { const zero = sql.lit(0); return this.db .selectFrom('person') @@ -368,6 +368,12 @@ export class PersonRepository { .selectFrom('asset_face') .whereRef('asset_face.personId', '=', 'person.id') .where('asset_face.deletedAt', 'is', null) + .having((eb) => + eb.or([ + eb('person.name', '!=', ''), + eb((innerEb) => innerEb.fn.count('asset_face.assetId'), '>=', options?.minimumFaceCount || 1), + ]), + ) .where((eb) => eb.exists((eb) => eb diff --git a/server/src/services/person.service.ts b/server/src/services/person.service.ts index 6fa9b3fdd2..87278b8291 100644 --- a/server/src/services/person.service.ts +++ b/server/src/services/person.service.ts @@ -67,7 +67,10 @@ export class PersonService extends BaseService { withHidden, closestFaceAssetId, }); - const { total, hidden } = await this.personRepository.getNumberOfPeople(auth.user.id); + const { total, hidden } = await this.personRepository.getNumberOfPeople(auth.user.id, { + minimumFaceCount: machineLearning.facialRecognition.minFaces, + withHidden, + }); return { people: items.map((person) => mapPerson(person)), From 6d8c166d866ee493b52261968d684254ec2696f6 Mon Sep 17 00:00:00 2001 From: Yaros Date: Mon, 8 Dec 2025 15:32:36 +0100 Subject: [PATCH 2/3] chore: update sql query file --- server/src/queries/person.repository.sql | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/server/src/queries/person.repository.sql b/server/src/queries/person.repository.sql index 8ad5b96bbc..d987bf3f3f 100644 --- a/server/src/queries/person.repository.sql +++ b/server/src/queries/person.repository.sql @@ -259,8 +259,13 @@ where and "asset"."visibility" = 'timeline' and "asset"."deletedAt" is null ) + having + ( + "person"."name" != $2 + or count("asset_face"."assetId") >= $3 + ) ) - and "person"."ownerId" = $2 + and "person"."ownerId" = $4 -- PersonRepository.refreshFaces with From f1111bbc62c80b700942206e33b27cb404a75237 Mon Sep 17 00:00:00 2001 From: Yaros Date: Mon, 8 Dec 2025 16:47:36 +0100 Subject: [PATCH 3/3] chore: adjusted e2e tests --- e2e/src/api/specs/person.e2e-spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/e2e/src/api/specs/person.e2e-spec.ts b/e2e/src/api/specs/person.e2e-spec.ts index 20290cd941..c4ed8dd1e6 100644 --- a/e2e/src/api/specs/person.e2e-spec.ts +++ b/e2e/src/api/specs/person.e2e-spec.ts @@ -122,7 +122,7 @@ describe('/people', () => { expect(status).toBe(200); expect(body).toEqual({ hasNextPage: false, - total: 11, + total: 10, hidden: 1, people: [ expect.objectContaining({ name: 'Freddy' }), @@ -144,7 +144,7 @@ describe('/people', () => { expect(status).toBe(200); expect(body.hasNextPage).toBe(false); - expect(body.total).toBe(11); // All persons + expect(body.total).toBe(10); // All persons expect(body.hidden).toBe(1); // 'hidden_person' const people = body.people as PersonResponseDto[]; @@ -170,7 +170,7 @@ describe('/people', () => { expect(status).toBe(200); expect(body).toEqual({ hasNextPage: false, - total: 11, + total: 10, hidden: 1, people: [ expect.objectContaining({ name: 'Freddy' }), @@ -195,7 +195,7 @@ describe('/people', () => { expect(status).toBe(200); expect(body).toEqual({ hasNextPage: true, - total: 11, + total: 10, hidden: 1, people: [expect.objectContaining({ name: 'Alice' })], });