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 <jason@rasm.me>
This commit is contained in:
sakshamchawla
2026-05-07 15:54:26 -04:00
committed by GitHub
parent 6050526360
commit e2ec04e86c
4 changed files with 49 additions and 13 deletions
+24 -4
View File
@@ -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
+14 -2
View File
@@ -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')
+7 -6
View File
@@ -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([]);
});
});
+4 -1
View File
@@ -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) {