diff --git a/src/modules/activity/domain/entities/activity-item.entity.ts b/src/modules/activity/domain/entities/activity-item.entity.ts index a918ddd6..5f7ca83b 100644 --- a/src/modules/activity/domain/entities/activity-item.entity.ts +++ b/src/modules/activity/domain/entities/activity-item.entity.ts @@ -27,6 +27,12 @@ export interface ActivityActor { export interface ActivityTarget { type: string; id: string; + /** + * #144: arah pencarian search-miss. `lemma` = kata Sambas dicari, + * `translation` = kata Indonesia dicari. Null untuk kind lain - mobile + * memakai ini agar prefill form usul mengisi field yang benar. + */ + direction?: 'lemma' | 'translation' | null; } export interface ActivityItem { diff --git a/src/modules/activity/infrastructure/activity-event-feed.repository.impl.ts b/src/modules/activity/infrastructure/activity-event-feed.repository.impl.ts index f75e02f7..f088dd17 100644 --- a/src/modules/activity/infrastructure/activity-event-feed.repository.impl.ts +++ b/src/modules/activity/infrastructure/activity-event-feed.repository.impl.ts @@ -147,6 +147,8 @@ interface FeedRow { actorAvatarUrl: string | null; actorDeletedAt: Date | null; missTerm: string | null; + /** #144: arah search-miss untuk di-wirer ke target.direction di feed. */ + missDirection: string | null; voteValue: number | null; } @@ -354,6 +356,8 @@ export class ActivityEventFeedRepositoryImpl { // search_miss: term body feed; guard kind supaya kolisi id antar // tabel (ULID) tak pernah match utk kind lain. missTerm: searchMisses.term, + // #144: arah search-miss (term Indonesia vs kata Sambas). + missDirection: searchMisses.direction, // fallback arah vote utk event lama tanpa payload (#94). voteValue: votes.value, }) @@ -576,7 +580,11 @@ export class ActivityEventFeedRepositoryImpl { private targetFor( kind: ActivityEventKind, - row: { targetId: string | null; targetWordId: string | null }, + row: { + targetId: string | null; + targetWordId: string | null; + missDirection: string | null; + }, word: { id: string; lemma: string } | null, ): ActivityItem['target'] { switch (kind) { @@ -600,7 +608,17 @@ export class ActivityEventFeedRepositoryImpl { case 'discussion_created': return row.targetId ? { type: 'discussion', id: row.targetId! } : null; case 'search_miss': - return row.targetId ? { type: 'search_miss', id: row.targetId! } : null; + return row.targetId + ? { + type: 'search_miss', + id: row.targetId!, + // #144: arah pencarian untuk prefill form usul di mobile. + direction: + row.missDirection === 'lemma' || row.missDirection === 'translation' + ? row.missDirection + : null, + } + : null; case 'user_joined': return row.targetId ? { type: 'user', id: row.targetId! } : null; case 'announcement': diff --git a/src/modules/activity/infrastructure/activity.repository.impl.ts b/src/modules/activity/infrastructure/activity.repository.impl.ts index 3b6fcd38..b5c6ff68 100644 --- a/src/modules/activity/infrastructure/activity.repository.impl.ts +++ b/src/modules/activity/infrastructure/activity.repository.impl.ts @@ -618,6 +618,11 @@ export class ActivityRepositoryImpl implements ActivityRepository { target: { type: 'search_miss', id: row.id, + // #144: arah pencarian untuk prefill form usul di mobile. + direction: + row.direction === 'lemma' || row.direction === 'translation' + ? row.direction + : null, }, })); } diff --git a/src/modules/activity/presentation/v1/validators/activity.validator.ts b/src/modules/activity/presentation/v1/validators/activity.validator.ts index 9fadd8f9..254a0fad 100644 --- a/src/modules/activity/presentation/v1/validators/activity.validator.ts +++ b/src/modules/activity/presentation/v1/validators/activity.validator.ts @@ -33,6 +33,8 @@ const activityTargetSchema = z .object({ type: z.string(), id: z.string(), + /** #144: arah search-miss untuk prefill form usul (null = kind lain). */ + direction: z.enum(['lemma', 'translation']).nullable().optional(), }) .nullable();