Skip to content

Commit bd8a231

Browse files
committed
fix(utils): deduplicate history entries by entityType+entityId
Adds runtime deduplication in getHistory() to keep only the most recent visit per unique entity. This fixes duplicate history entries appearing when the compound index didn't prevent duplicates (e.g., race conditions or slightly different entityType values).
1 parent 51b5c28 commit bd8a231

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

packages/utils/src/storage/catalogue-db.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,7 +1075,7 @@ export class CatalogueService {
10751075

10761076
/**
10771077
* Get all history entries
1078-
* Filters out corrupted entries at runtime (entityId or URL containing [object Object])
1078+
* Filters out corrupted entries and deduplicates to show only most recent visit per entity
10791079
*/
10801080
async getHistory(): Promise<CatalogueEntity[]> {
10811081
await this.initializeSpecialLists();
@@ -1100,7 +1100,7 @@ export class CatalogueService {
11001100
// Non-entity pages that shouldn't be validated against entity patterns
11011101
const nonEntityPatterns = ["/about", "/settings", "/history", "/bookmarks", "/catalogue", "/search"];
11021102

1103-
return entities.filter((entity) => {
1103+
const validEntities = entities.filter((entity) => {
11041104
if (entity.entityId.length === 0) return false;
11051105
if (entity.entityId.includes(CORRUPTED_ENTITY_ID_PATTERN)) return false;
11061106
if (entity.entityId.includes(urlEncodedPattern)) return false;
@@ -1136,6 +1136,21 @@ export class CatalogueService {
11361136

11371137
return true;
11381138
});
1139+
1140+
// Deduplicate: keep only the most recent entry per unique entityType+entityId
1141+
// This handles cases where the compound index didn't prevent duplicates
1142+
// (e.g., race conditions, slightly different entityType values)
1143+
const seen = new Map<string, CatalogueEntity>();
1144+
for (const entity of validEntities) {
1145+
const key = `${entity.entityType}:${entity.entityId}`;
1146+
const existing = seen.get(key);
1147+
// Keep the entry with the most recent addedAt timestamp
1148+
if (!existing || entity.addedAt > existing.addedAt) {
1149+
seen.set(key, entity);
1150+
}
1151+
}
1152+
1153+
return Array.from(seen.values());
11391154
}
11401155

11411156
/**

0 commit comments

Comments
 (0)