fix: memories mobile sync for older clients (#32167)
fix: memories mobile sync for older clients (#32150) (cherry picked from commit 8d377bfef5a0c9d840bf2c19d155f9779387baeb) Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com> Co-authored-by: Santo Shakil <shakil.mezbah@gmail.com>
This commit is contained in:
co-authored by
Daniel Dietzler
Santo Shakil
parent
1aede8d8c3
commit
ed3073624b
@@ -295,7 +295,7 @@ const SyncMemoryV1Schema = z
|
||||
updatedAt: isoDatetimeToDate.describe('Updated at'),
|
||||
deletedAt: isoDatetimeToDate.nullable().describe('Deleted at'),
|
||||
ownerId: z.uuidv4().describe('Owner ID'),
|
||||
type: MemoryTypeSchema,
|
||||
type: MemoryTypeSchema.extract(['OnThisDay']).meta({ id: 'MemoryTypeV1' }),
|
||||
data: z.record(z.string(), z.unknown()).describe('Data'),
|
||||
isSaved: z.boolean().describe('Is saved'),
|
||||
memoryAt: isoDatetimeToDate.describe('Memory at'),
|
||||
@@ -305,6 +305,10 @@ const SyncMemoryV1Schema = z
|
||||
})
|
||||
.meta({ id: 'SyncMemoryV1' });
|
||||
|
||||
const SyncMemoryV2Schema = SyncMemoryV1Schema.extend({
|
||||
type: MemoryTypeSchema,
|
||||
}).meta({ id: 'SyncMemoryV2' });
|
||||
|
||||
const SyncMemoryDeleteV1Schema = z
|
||||
.object({ memoryId: z.uuidv4().describe('Memory ID') })
|
||||
.meta({ id: 'SyncMemoryDeleteV1' });
|
||||
@@ -403,6 +407,8 @@ const SyncCompleteV1Schema = z.object({}).meta({ id: 'SyncCompleteV1' });
|
||||
@ExtraModel()
|
||||
class SyncMemoryV1 extends createZodDto(SyncMemoryV1Schema) {}
|
||||
@ExtraModel()
|
||||
class SyncMemoryV2 extends createZodDto(SyncMemoryV2Schema) {}
|
||||
@ExtraModel()
|
||||
class SyncMemoryDeleteV1 extends createZodDto(SyncMemoryDeleteV1Schema) {}
|
||||
@ExtraModel()
|
||||
class SyncMemoryAssetV1 extends createZodDto(SyncMemoryAssetV1Schema) {}
|
||||
@@ -505,8 +511,10 @@ export type SyncItem = {
|
||||
[SyncEntityType.AlbumToAssetBackfillV1]: SyncAlbumToAssetV1;
|
||||
[SyncEntityType.AlbumToAssetDeleteV1]: SyncAlbumToAssetDeleteV1;
|
||||
[SyncEntityType.MemoryV1]: SyncMemoryV1;
|
||||
[SyncEntityType.MemoryV2]: SyncMemoryV2;
|
||||
[SyncEntityType.MemoryDeleteV1]: SyncMemoryDeleteV1;
|
||||
[SyncEntityType.MemoryToAssetV1]: SyncMemoryAssetV1;
|
||||
[SyncEntityType.MemoryToAssetV2]: SyncMemoryAssetV1;
|
||||
[SyncEntityType.MemoryToAssetDeleteV1]: SyncMemoryAssetDeleteV1;
|
||||
[SyncEntityType.StackV1]: SyncStackV1;
|
||||
[SyncEntityType.StackDeleteV1]: SyncStackDeleteV1;
|
||||
|
||||
@@ -1055,7 +1055,9 @@ export enum SyncRequestType {
|
||||
AuthUsersV1 = 'AuthUsersV1',
|
||||
AuthUsersV2 = 'AuthUsersV2',
|
||||
MemoriesV1 = 'MemoriesV1',
|
||||
MemoriesV2 = 'MemoriesV2',
|
||||
MemoryToAssetsV1 = 'MemoryToAssetsV1',
|
||||
MemoryToAssetsV2 = 'MemoryToAssetsV2',
|
||||
PartnersV1 = 'PartnersV1',
|
||||
/** @deprecated */
|
||||
PartnerAssetsV1 = 'PartnerAssetsV1',
|
||||
@@ -1139,9 +1141,11 @@ export enum SyncEntityType {
|
||||
AlbumToAssetBackfillV1 = 'AlbumToAssetBackfillV1',
|
||||
|
||||
MemoryV1 = 'MemoryV1',
|
||||
MemoryV2 = 'MemoryV2',
|
||||
MemoryDeleteV1 = 'MemoryDeleteV1',
|
||||
|
||||
MemoryToAssetV1 = 'MemoryToAssetV1',
|
||||
MemoryToAssetV2 = 'MemoryToAssetV2',
|
||||
MemoryToAssetDeleteV1 = 'MemoryToAssetDeleteV1',
|
||||
|
||||
StackV1 = 'StackV1',
|
||||
|
||||
@@ -768,6 +768,28 @@ where
|
||||
order by
|
||||
"memory_asset_audit"."id" asc
|
||||
|
||||
-- SyncRepository.memoryToAsset.getUpsertsV1
|
||||
select
|
||||
"memoriesId" as "memoryId",
|
||||
"assetId" as "assetId",
|
||||
"updateId"
|
||||
from
|
||||
"memory_asset" as "memory_asset"
|
||||
where
|
||||
"memory_asset"."updateId" < $1
|
||||
and "memory_asset"."updateId" > $2
|
||||
and "memoriesId" in (
|
||||
select
|
||||
"id"
|
||||
from
|
||||
"memory"
|
||||
where
|
||||
"ownerId" = $3
|
||||
and "type" = 'on_this_day'
|
||||
)
|
||||
order by
|
||||
"memory_asset"."updateId" asc
|
||||
|
||||
-- SyncRepository.memoryToAsset.getUpserts
|
||||
select
|
||||
"memoriesId" as "memoryId",
|
||||
|
||||
@@ -4,6 +4,7 @@ import { InjectKysely } from 'nestjs-kysely';
|
||||
import type { SyncAck } from 'src/types.js';
|
||||
import { columns } from 'src/database.js';
|
||||
import { DummyValue, GenerateSql } from 'src/decorators.js';
|
||||
import { MemoryType } from 'src/enum.js';
|
||||
import { DB } from 'src/schema/index.js';
|
||||
|
||||
export type SyncBackfillOptions = {
|
||||
@@ -596,6 +597,21 @@ class MemoryToAssetSync extends BaseSync {
|
||||
return this.auditCleanup('memory_asset_audit', daysAgo);
|
||||
}
|
||||
|
||||
@GenerateSql({ params: [dummyQueryOptions], stream: true })
|
||||
getUpsertsV1(options: SyncQueryOptions) {
|
||||
return this.upsertQuery('memory_asset', options)
|
||||
.select(['memoriesId as memoryId', 'assetId as assetId'])
|
||||
.select('updateId')
|
||||
.where('memoriesId', 'in', (eb) =>
|
||||
eb
|
||||
.selectFrom('memory')
|
||||
.select('id')
|
||||
.where('ownerId', '=', options.userId)
|
||||
.where('type', '=', sql.lit(MemoryType.OnThisDay)),
|
||||
)
|
||||
.stream();
|
||||
}
|
||||
|
||||
@GenerateSql({ params: [dummyQueryOptions], stream: true })
|
||||
getUpserts(options: SyncQueryOptions) {
|
||||
return this.upsertQuery('memory_asset', options)
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
SyncStreamDto,
|
||||
syncAlbumV2ToV1,
|
||||
} from 'src/dtos/sync.dto.js';
|
||||
import { JobName, QueueName, SyncEntityType, SyncRequestType } from 'src/enum.js';
|
||||
import { JobName, MemoryType, QueueName, SyncEntityType, SyncRequestType } from 'src/enum.js';
|
||||
import { SyncQueryOptions } from 'src/repositories/sync.repository.js';
|
||||
import { SessionSyncCheckpointTable } from 'src/schema/tables/sync-checkpoint.table.js';
|
||||
import { BaseService } from 'src/services/base.service.js';
|
||||
@@ -83,7 +83,9 @@ export const SYNC_TYPES_ORDER = [
|
||||
SyncRequestType.AssetOcrV1,
|
||||
SyncRequestType.PartnerAssetExifsV1,
|
||||
SyncRequestType.MemoriesV1,
|
||||
SyncRequestType.MemoriesV2,
|
||||
SyncRequestType.MemoryToAssetsV1,
|
||||
SyncRequestType.MemoryToAssetsV2,
|
||||
SyncRequestType.PeopleV1,
|
||||
SyncRequestType.AssetFacesV1,
|
||||
SyncRequestType.AssetFacesV2,
|
||||
@@ -210,7 +212,9 @@ export class SyncService extends BaseService {
|
||||
[SyncRequestType.AlbumAssetExifsV1]: () =>
|
||||
this.syncAlbumAssetExifsV1(options, response, checkpointMap, session.id),
|
||||
[SyncRequestType.MemoriesV1]: () => this.syncMemoriesV1(options, response, checkpointMap),
|
||||
[SyncRequestType.MemoriesV2]: () => this.syncMemoriesV2(options, response, checkpointMap),
|
||||
[SyncRequestType.MemoryToAssetsV1]: () => this.syncMemoryAssetsV1(options, response, checkpointMap),
|
||||
[SyncRequestType.MemoryToAssetsV2]: () => this.syncMemoryAssetsV2(options, response, checkpointMap),
|
||||
[SyncRequestType.StacksV1]: () => this.syncStackV1(options, response, checkpointMap),
|
||||
[SyncRequestType.PartnerStacksV1]: () => this.syncPartnerStackV1(options, response, checkpointMap, session.id),
|
||||
[SyncRequestType.PeopleV1]: () => this.syncPeopleV1(options, response, checkpointMap),
|
||||
@@ -786,6 +790,22 @@ export class SyncService extends BaseService {
|
||||
|
||||
const upsertType = SyncEntityType.MemoryV1;
|
||||
const upserts = this.syncRepository.memory.getUpserts({ ...options, ack: checkpointMap[upsertType] });
|
||||
for await (const { updateId, ...data } of upserts) {
|
||||
if (data.type === MemoryType.OnThisDay) {
|
||||
await send(response, { type: upsertType, ids: [updateId], data: { ...data, type: data.type } });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async syncMemoriesV2(options: SyncQueryOptions, response: Writable, checkpointMap: CheckpointMap) {
|
||||
const deleteType = SyncEntityType.MemoryDeleteV1;
|
||||
const deletes = this.syncRepository.memory.getDeletes({ ...options, ack: checkpointMap[deleteType] });
|
||||
for await (const { id, ...data } of deletes) {
|
||||
await send(response, { type: deleteType, ids: [id], data });
|
||||
}
|
||||
|
||||
const upsertType = SyncEntityType.MemoryV2;
|
||||
const upserts = this.syncRepository.memory.getUpserts({ ...options, ack: checkpointMap[upsertType] });
|
||||
for await (const { updateId, ...data } of upserts) {
|
||||
await send(response, { type: upsertType, ids: [updateId], data });
|
||||
}
|
||||
@@ -799,6 +819,20 @@ export class SyncService extends BaseService {
|
||||
}
|
||||
|
||||
const upsertType = SyncEntityType.MemoryToAssetV1;
|
||||
const upserts = this.syncRepository.memoryToAsset.getUpsertsV1({ ...options, ack: checkpointMap[upsertType] });
|
||||
for await (const { updateId, ...data } of upserts) {
|
||||
await send(response, { type: upsertType, ids: [updateId], data });
|
||||
}
|
||||
}
|
||||
|
||||
private async syncMemoryAssetsV2(options: SyncQueryOptions, response: Writable, checkpointMap: CheckpointMap) {
|
||||
const deleteType = SyncEntityType.MemoryToAssetDeleteV1;
|
||||
const deletes = this.syncRepository.memoryToAsset.getDeletes({ ...options, ack: checkpointMap[deleteType] });
|
||||
for await (const { id, ...data } of deletes) {
|
||||
await send(response, { type: deleteType, ids: [id], data });
|
||||
}
|
||||
|
||||
const upsertType = SyncEntityType.MemoryToAssetV2;
|
||||
const upserts = this.syncRepository.memoryToAsset.getUpserts({ ...options, ack: checkpointMap[upsertType] });
|
||||
for await (const { updateId, ...data } of upserts) {
|
||||
await send(response, { type: upsertType, ids: [updateId], data });
|
||||
|
||||
Reference in New Issue
Block a user