Files
gridpilot.gg/adapters/identity/persistence/inmemory/InMemoryExternalGameRatingRepository.ts
2026-01-16 13:48:18 +01:00

112 lines
3.5 KiB
TypeScript

import { ExternalGameRatingRepository, PaginatedQueryOptions, PaginatedResult } from '@core/identity/domain/repositories/ExternalGameRatingRepository';
import { ExternalGameRatingProfile } from '@core/identity/domain/entities/ExternalGameRatingProfile';
/**
* In-Memory Implementation: IExternalGameRatingRepository
*
* For testing and development purposes.
*/
export class InMemoryExternalGameRatingRepository implements ExternalGameRatingRepository {
private profiles: Map<string, ExternalGameRatingProfile> = new Map();
private getKey(userId: string, gameKey: string): string {
return `${userId}|${gameKey}`;
}
async findByUserIdAndGameKey(
userId: string,
gameKey: string
): Promise<ExternalGameRatingProfile | null> {
const key = this.getKey(userId, gameKey);
return this.profiles.get(key) || null;
}
async findByUserId(userId: string): Promise<ExternalGameRatingProfile[]> {
return Array.from(this.profiles.values()).filter(
p => p.userId.toString() === userId
);
}
async findByGameKey(gameKey: string): Promise<ExternalGameRatingProfile[]> {
return Array.from(this.profiles.values()).filter(
p => p.gameKey.toString() === gameKey
);
}
async save(profile: ExternalGameRatingProfile): Promise<ExternalGameRatingProfile> {
const key = this.getKey(profile.userId.toString(), profile.gameKey.toString());
this.profiles.set(key, profile);
return profile;
}
async saveMany(profiles: ExternalGameRatingProfile[]): Promise<ExternalGameRatingProfile[]> {
for (const profile of profiles) {
await this.save(profile);
}
return profiles;
}
async delete(userId: string, gameKey: string): Promise<boolean> {
const key = this.getKey(userId, gameKey);
return this.profiles.delete(key);
}
async exists(userId: string, gameKey: string): Promise<boolean> {
const key = this.getKey(userId, gameKey);
return this.profiles.has(key);
}
async findProfilesPaginated(userId: string, options?: PaginatedQueryOptions): Promise<PaginatedResult<ExternalGameRatingProfile>> {
const allProfiles = await this.findByUserId(userId);
// Apply filters
let filtered = allProfiles;
if (options?.filter) {
const filter = options.filter;
if (filter.gameKeys) {
filtered = filtered.filter(p => filter.gameKeys!.includes(p.gameKey.toString()));
}
if (filter.sources) {
filtered = filtered.filter(p => filter.sources!.includes(p.provenance.source));
}
if (filter.verified !== undefined) {
filtered = filtered.filter(p => p.provenance.verified === filter.verified);
}
if (filter.lastSyncedAfter) {
filtered = filtered.filter(p => p.provenance.lastSyncedAt >= filter.lastSyncedAfter!);
}
}
const total = filtered.length;
const limit = options?.limit ?? 10;
const offset = options?.offset ?? 0;
const items = filtered.slice(offset, offset + limit);
const hasMore = offset + limit < total;
const nextOffset = hasMore ? offset + limit : undefined;
const result: PaginatedResult<ExternalGameRatingProfile> = {
items,
total,
limit,
offset,
hasMore
};
if (nextOffset !== undefined) {
result.nextOffset = nextOffset;
}
return result;
}
// Helper method for testing
clear(): void {
this.profiles.clear();
}
// Helper method for testing
getAll(): ExternalGameRatingProfile[] {
return Array.from(this.profiles.values());
}
}