fix: memories off by one (#16434)

This commit is contained in:
Jason Rasmussen 2025-02-28 13:51:28 -05:00 committed by GitHub
parent 5c0538e52c
commit e684062569
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 24 additions and 24 deletions

View File

@ -55,9 +55,10 @@ with
inner join "exif" on "a"."id" = "exif"."assetId" inner join "exif" on "a"."id" = "exif"."assetId"
) )
select select
( date_part(
(now() at time zone 'UTC')::date - ("localDateTime" at time zone 'UTC')::date 'year',
) / 365 as "yearsAgo", ("localDateTime" at time zone 'UTC')::date
)::int as "year",
json_agg("res") as "assets" json_agg("res") as "assets"
from from
"res" "res"

View File

@ -192,7 +192,7 @@ export class AssetRepository {
} }
@GenerateSql({ params: [DummyValue.UUID, { day: 1, month: 1 }] }) @GenerateSql({ params: [DummyValue.UUID, { day: 1, month: 1 }] })
getByDayOfYear(ownerIds: string[], { day, month }: MonthDay): Promise<DayOfYearAssets[]> { getByDayOfYear(ownerIds: string[], { day, month }: MonthDay) {
return this.db return this.db
.with('res', (qb) => .with('res', (qb) =>
qb qb
@ -239,16 +239,12 @@ export class AssetRepository {
.select((eb) => eb.fn.toJson(eb.table('exif')).as('exifInfo')), .select((eb) => eb.fn.toJson(eb.table('exif')).as('exifInfo')),
) )
.selectFrom('res') .selectFrom('res')
.select( .select(sql<number>`date_part('year', ("localDateTime" at time zone 'UTC')::date)::int`.as('year'))
sql<number>`((now() at time zone 'UTC')::date - ("localDateTime" at time zone 'UTC')::date) / 365`.as(
'yearsAgo',
),
)
.select((eb) => eb.fn.jsonAgg(eb.table('res')).as('assets')) .select((eb) => eb.fn.jsonAgg(eb.table('res')).as('assets'))
.groupBy(sql`("localDateTime" at time zone 'UTC')::date`) .groupBy(sql`("localDateTime" at time zone 'UTC')::date`)
.orderBy(sql`("localDateTime" at time zone 'UTC')::date`, 'desc') .orderBy(sql`("localDateTime" at time zone 'UTC')::date`, 'desc')
.limit(10) .limit(10)
.execute() as any as Promise<DayOfYearAssets[]>; .execute();
} }
@GenerateSql({ params: [[DummyValue.UUID]] }) @GenerateSql({ params: [[DummyValue.UUID]] })

View File

@ -64,18 +64,18 @@ describe(AssetService.name, () => {
mocks.partner.getAll.mockResolvedValue([]); mocks.partner.getAll.mockResolvedValue([]);
mocks.asset.getByDayOfYear.mockResolvedValue([ mocks.asset.getByDayOfYear.mockResolvedValue([
{ {
yearsAgo: 1, year: 2023,
assets: [image1, image2], assets: [image1, image2],
}, },
{ {
yearsAgo: 9, year: 2015,
assets: [image3], assets: [image3],
}, },
{ {
yearsAgo: 15, year: 2009,
assets: [image4], assets: [image4],
}, },
]); ] as any);
await expect(sut.getMemoryLane(authStub.admin, { day: 15, month: 1 })).resolves.toEqual([ await expect(sut.getMemoryLane(authStub.admin, { day: 15, month: 1 })).resolves.toEqual([
{ yearsAgo: 1, title: '1 year ago', assets: [mapAsset(image1), mapAsset(image2)] }, { yearsAgo: 1, title: '1 year ago', assets: [mapAsset(image1), mapAsset(image2)] },

View File

@ -38,12 +38,15 @@ export class AssetService extends BaseService {
const userIds = [auth.user.id, ...partnerIds]; const userIds = [auth.user.id, ...partnerIds];
const groups = await this.assetRepository.getByDayOfYear(userIds, dto); const groups = await this.assetRepository.getByDayOfYear(userIds, dto);
return groups.map(({ yearsAgo, assets }) => ({ return groups.map(({ year, assets }) => {
yearsAgo, const yearsAgo = DateTime.utc().year - year;
// TODO move this to clients return {
title: `${yearsAgo} year${yearsAgo > 1 ? 's' : ''} ago`, yearsAgo,
assets: assets.map((asset) => mapAsset(asset, { auth })), // TODO move this to clients
})); title: `${yearsAgo} year${yearsAgo > 1 ? 's' : ''} ago`,
assets: assets.map((asset) => mapAsset(asset as AssetEntity, { auth })),
};
});
} }
async getStatistics(auth: AuthDto, dto: AssetStatsDto) { async getStatistics(auth: AuthDto, dto: AssetStatsDto) {

View File

@ -45,18 +45,18 @@ export class MemoryService extends BaseService {
for (const [userId, userIds] of Object.entries(userMap)) { for (const [userId, userIds] of Object.entries(userMap)) {
const memories = await this.assetRepository.getByDayOfYear(userIds, target); const memories = await this.assetRepository.getByDayOfYear(userIds, target);
for (const memory of memories) { for (const { year, assets } of memories) {
const data: OnThisDayData = { year: target.year - memory.yearsAgo }; const data: OnThisDayData = { year };
await this.memoryRepository.create( await this.memoryRepository.create(
{ {
ownerId: userId, ownerId: userId,
type: MemoryType.ON_THIS_DAY, type: MemoryType.ON_THIS_DAY,
data, data,
memoryAt: target.minus({ years: memory.yearsAgo }).toISO(), memoryAt: target.set({ year }).toISO(),
showAt, showAt,
hideAt, hideAt,
}, },
new Set(memory.assets.map(({ id }) => id)), new Set(assets.map(({ id }) => id)),
); );
} }
} }