From e2ec04e86cd7b68e4e2271529c0da711f3e41a05 Mon Sep 17 00:00:00 2001 From: sakshamchawla Date: Thu, 7 May 2026 15:54:26 -0400 Subject: [PATCH] feat: hide hidden person from memories (#20877) * hide hidden person from memories * clean up * fix united test * clean up * moved sql to inline, rebased * clean up * clean up again * chore: sync sql --------- Co-authored-by: Jason Rasmussen --- server/src/queries/memory.repository.sql | 28 +++++++++++++++++--- server/src/repositories/memory.repository.ts | 16 +++++++++-- server/src/services/memory.service.spec.ts | 13 ++++----- server/src/services/memory.service.ts | 5 +++- 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/server/src/queries/memory.repository.sql b/server/src/queries/memory.repository.sql index da970c2c78..44339cbcd9 100644 --- a/server/src/queries/memory.repository.sql +++ b/server/src/queries/memory.repository.sql @@ -42,6 +42,16 @@ select "memory_asset"."memoriesId" = "memory"."id" and "asset"."visibility" = 'timeline' and "asset"."deletedAt" is null + and not exists ( + select + $1 as "one" + from + "asset_face" + inner join "person" on "person"."id" = "asset_face"."personId" + where + "asset_face"."assetId" = "asset"."id" + and "person"."isHidden" = $2 + ) order by "asset"."fileCreatedAt" asc ) as agg @@ -51,7 +61,7 @@ from "memory" where "deletedAt" is null - and "ownerId" = $1 + and "ownerId" = $3 order by "memoryAt" desc @@ -71,6 +81,16 @@ select "memory_asset"."memoriesId" = "memory"."id" and "asset"."visibility" = 'timeline' and "asset"."deletedAt" is null + and not exists ( + select + $1 as "one" + from + "asset_face" + inner join "person" on "person"."id" = "asset_face"."personId" + where + "asset_face"."assetId" = "asset"."id" + and "person"."isHidden" = $2 + ) order by "asset"."fileCreatedAt" asc ) as agg @@ -81,14 +101,14 @@ from where ( "showAt" is null - or "showAt" <= $1 + or "showAt" <= $3 ) and ( "hideAt" is null - or "hideAt" >= $2 + or "hideAt" >= $4 ) and "deletedAt" is null - and "ownerId" = $3 + and "ownerId" = $5 order by "memoryAt" desc diff --git a/server/src/repositories/memory.repository.ts b/server/src/repositories/memory.repository.ts index e62c083839..09aa5ad880 100644 --- a/server/src/repositories/memory.repository.ts +++ b/server/src/repositories/memory.repository.ts @@ -66,9 +66,21 @@ export class MemoryRepository implements IBulkAsset { .selectAll('asset') .innerJoin('memory_asset', 'asset.id', 'memory_asset.assetId') .whereRef('memory_asset.memoriesId', '=', 'memory.id') - .orderBy('asset.fileCreatedAt', 'asc') .where('asset.visibility', '=', sql.lit(AssetVisibility.Timeline)) - .where('asset.deletedAt', 'is', null), + .where('asset.deletedAt', 'is', null) + .where((eb) => + eb.not( + eb.exists( + eb + .selectFrom('asset_face') + .innerJoin('person', 'person.id', 'asset_face.personId') + .select((eb) => eb.val(1).as('one')) + .whereRef('asset_face.assetId', '=', 'asset.id') + .where('person.isHidden', '=', true), + ), + ), + ) + .orderBy('asset.fileCreatedAt', 'asc'), ).as('assets'), ) .selectAll('memory') diff --git a/server/src/services/memory.service.spec.ts b/server/src/services/memory.service.spec.ts index 0445cf892b..9976189e39 100644 --- a/server/src/services/memory.service.spec.ts +++ b/server/src/services/memory.service.spec.ts @@ -28,25 +28,26 @@ describe(MemoryService.name, () => { }); describe('search', () => { - it('should search memories', async () => { + it('should search memories with assets', async () => { const [userId] = newUuids(); + const asset = AssetFactory.create(); const memory1 = MemoryFactory.from({ ownerId: userId }).asset(asset).build(); const memory2 = MemoryFactory.create({ ownerId: userId }); - mocks.memory.search.mockResolvedValue([getForMemory(memory1), getForMemory(memory2)]); await expect(sut.search(factory.auth({ user: { id: userId } }), {})).resolves.toEqual( expect.arrayContaining([ - expect.objectContaining({ id: memory1.id, assets: [expect.objectContaining({ id: asset.id })] }), - expect.objectContaining({ id: memory2.id, assets: [] }), + expect.objectContaining({ + id: memory1.id, + assets: expect.arrayContaining([expect.objectContaining({ id: asset.id })]), + }), ]), ); }); - it('should map ', async () => { + it('should map empty result', async () => { mocks.memory.search.mockResolvedValue([]); - await expect(sut.search(factory.auth(), {})).resolves.toEqual([]); }); }); diff --git a/server/src/services/memory.service.ts b/server/src/services/memory.service.ts index 2378d594e1..ac8f88ad87 100644 --- a/server/src/services/memory.service.ts +++ b/server/src/services/memory.service.ts @@ -1,5 +1,6 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import { DateTime } from 'luxon'; +import { Memory } from 'src/database'; import { OnJob } from 'src/decorators'; import { BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto'; import { AuthDto } from 'src/dtos/auth.dto'; @@ -71,7 +72,9 @@ export class MemoryService extends BaseService { async search(auth: AuthDto, dto: MemorySearchDto) { const memories = await this.memoryRepository.search(auth.user.id, dto); - return memories.map((memory) => mapMemory(memory, auth)); + return memories + .filter((memory: Memory) => memory.assets && memory.assets.length > 0) + .map((memory: Memory) => mapMemory(memory, auth)); } statistics(auth: AuthDto, dto: MemorySearchDto) {