module creation
This commit is contained in:
@@ -1,179 +1,102 @@
|
||||
/**
|
||||
* Infrastructure Adapter: InMemoryLeagueMembershipRepository
|
||||
*
|
||||
* In-memory implementation of ILeagueMembershipRepository.
|
||||
* Stores memberships and join requests in maps keyed by league.
|
||||
*/
|
||||
|
||||
import type {
|
||||
LeagueMembership,
|
||||
JoinRequest,
|
||||
} from '@gridpilot/racing/domain/entities/LeagueMembership';
|
||||
import type { ILeagueMembershipRepository } from '@gridpilot/racing/domain/repositories/ILeagueMembershipRepository';
|
||||
import type { ILogger } from '@gridpilot/shared/logging/ILogger';
|
||||
import { ILeagueMembershipRepository } from '@gridpilot/racing/domain/repositories/ILeagueMembershipRepository';
|
||||
import { LeagueMembership, JoinRequest } from '@gridpilot/racing/domain/entities/LeagueMembership';
|
||||
import { ILogger } from '@gridpilot/shared/logging/ILogger';
|
||||
|
||||
export class InMemoryLeagueMembershipRepository implements ILeagueMembershipRepository {
|
||||
private membershipsByLeague: Map<string, LeagueMembership[]>;
|
||||
private joinRequestsByLeague: Map<string, JoinRequest[]>;
|
||||
private readonly logger: ILogger;
|
||||
private memberships: Map<string, LeagueMembership> = new Map(); // Key: `${leagueId}:${driverId}`
|
||||
private joinRequests: Map<string, JoinRequest> = new Map(); // Key: requestId
|
||||
|
||||
constructor(logger: ILogger, seedMemberships?: LeagueMembership[], seedJoinRequests?: JoinRequest[]) {
|
||||
this.logger = logger;
|
||||
constructor(private readonly logger: ILogger, initialMemberships: LeagueMembership[] = [], initialJoinRequests: JoinRequest[] = []) {
|
||||
this.logger.info('InMemoryLeagueMembershipRepository initialized.');
|
||||
this.membershipsByLeague = new Map();
|
||||
this.joinRequestsByLeague = new Map();
|
||||
|
||||
if (seedMemberships) {
|
||||
seedMemberships.forEach((membership) => {
|
||||
const list = this.membershipsByLeague.get(membership.leagueId) ?? [];
|
||||
list.push(membership);
|
||||
this.membershipsByLeague.set(membership.leagueId, list);
|
||||
this.logger.debug(`Seeded membership for league ${membership.leagueId}, driver ${membership.driverId}.`);
|
||||
});
|
||||
for (const membership of initialMemberships) {
|
||||
this.memberships.set(`${membership.leagueId}:${membership.driverId}`, membership);
|
||||
this.logger.debug(`Seeded membership: ${membership.id}.`);
|
||||
}
|
||||
|
||||
if (seedJoinRequests) {
|
||||
seedJoinRequests.forEach((request) => {
|
||||
const list = this.joinRequestsByLeague.get(request.leagueId) ?? [];
|
||||
list.push(request);
|
||||
this.joinRequestsByLeague.set(request.leagueId, list);
|
||||
this.logger.debug(`Seeded join request for league ${request.leagueId}, driver ${request.driverId}.`);
|
||||
});
|
||||
for (const req of initialJoinRequests) {
|
||||
this.joinRequests.set(req.id, req);
|
||||
this.logger.debug(`Seeded join request: ${req.id}.`);
|
||||
}
|
||||
}
|
||||
|
||||
async getMembership(leagueId: string, driverId: string): Promise<LeagueMembership | null> {
|
||||
this.logger.debug(`Getting membership for league: ${leagueId}, driver: ${driverId}`);
|
||||
try {
|
||||
const list = this.membershipsByLeague.get(leagueId);
|
||||
if (!list) {
|
||||
this.logger.warn(`No membership list found for league: ${leagueId}.`);
|
||||
return null;
|
||||
}
|
||||
const membership = list.find((m) => m.driverId === driverId) ?? null;
|
||||
if (membership) {
|
||||
this.logger.info(`Found membership for league: ${leagueId}, driver: ${driverId}.`);
|
||||
} else {
|
||||
this.logger.warn(`Membership not found for league: ${leagueId}, driver: ${driverId}.`);
|
||||
}
|
||||
return membership;
|
||||
} catch (error) {
|
||||
this.logger.error(`Error getting membership for league ${leagueId}, driver ${driverId}:`, error);
|
||||
throw error;
|
||||
this.logger.debug(`[InMemoryLeagueMembershipRepository] Getting membership for league ${leagueId}, driver ${driverId}.`);
|
||||
const key = `${leagueId}:${driverId}`;
|
||||
const membership = this.memberships.get(key) ?? null;
|
||||
if (membership) {
|
||||
this.logger.info(`Found membership for league ${leagueId}, driver ${driverId}.`);
|
||||
} else {
|
||||
this.logger.warn(`No membership found for league ${leagueId}, driver ${driverId}.`);
|
||||
}
|
||||
return Promise.resolve(membership);
|
||||
}
|
||||
|
||||
async findActiveByLeagueIdAndDriverId(leagueId: string, driverId: string): Promise<LeagueMembership | null> {
|
||||
this.logger.debug(`[InMemoryLeagueMembershipRepository] Finding active membership for league ${leagueId}, driver ${driverId}.`);
|
||||
const membership = await this.getMembership(leagueId, driverId);
|
||||
return Promise.resolve(membership && membership.status === 'active' ? membership : null);
|
||||
}
|
||||
|
||||
async findAllByLeagueId(leagueId: string): Promise<LeagueMembership[]> {
|
||||
this.logger.debug(`[InMemoryLeagueMembershipRepository] Finding all memberships for league ${leagueId}.`);
|
||||
const filteredMemberships = Array.from(this.memberships.values()).filter(mem => mem.leagueId === leagueId);
|
||||
this.logger.info(`Found ${filteredMemberships.length} memberships for league ${leagueId}.`);
|
||||
return Promise.resolve(filteredMemberships);
|
||||
}
|
||||
|
||||
async findAllByDriverId(driverId: string): Promise<LeagueMembership[]> {
|
||||
this.logger.debug(`[InMemoryLeagueMembershipRepository] Finding all memberships for driver ${driverId}.`);
|
||||
const memberships = Array.from(this.memberships.values()).filter(mem => mem.driverId === driverId);
|
||||
this.logger.info(`Found ${memberships.length} memberships for driver ${driverId}.`);
|
||||
return Promise.resolve(memberships);
|
||||
}
|
||||
|
||||
async getLeagueMembers(leagueId: string): Promise<LeagueMembership[]> {
|
||||
this.logger.debug(`Getting league members for league: ${leagueId}`);
|
||||
try {
|
||||
const members = [...(this.membershipsByLeague.get(leagueId) ?? [])];
|
||||
this.logger.info(`Found ${members.length} members for league: ${leagueId}.`);
|
||||
return members;
|
||||
} catch (error) {
|
||||
this.logger.error(`Error getting league members for league ${leagueId}:`, error);
|
||||
throw error;
|
||||
}
|
||||
this.logger.debug(`[InMemoryLeagueMembershipRepository] Getting active members for league ${leagueId}.`);
|
||||
const members = Array.from(this.memberships.values()).filter(mem => mem.leagueId === leagueId && mem.status === 'active');
|
||||
this.logger.info(`Found ${members.length} active members for league ${leagueId}.`);
|
||||
return Promise.resolve(members);
|
||||
}
|
||||
|
||||
async getJoinRequests(leagueId: string): Promise<JoinRequest[]> {
|
||||
this.logger.debug(`Getting join requests for league: ${leagueId}`);
|
||||
try {
|
||||
const requests = [...(this.joinRequestsByLeague.get(leagueId) ?? [])];
|
||||
this.logger.info(`Found ${requests.length} join requests for league: ${leagueId}.`);
|
||||
return requests;
|
||||
} catch (error) {
|
||||
this.logger.error(`Error getting join requests for league ${leagueId}:`, error);
|
||||
throw error;
|
||||
}
|
||||
this.logger.debug(`[InMemoryLeagueMembershipRepository] Getting join requests for league ${leagueId}.`);
|
||||
const requests = Array.from(this.joinRequests.values()).filter(req => req.leagueId === leagueId);
|
||||
this.logger.info(`Found ${requests.length} join requests for league ${leagueId}.`);
|
||||
return Promise.resolve(requests);
|
||||
}
|
||||
|
||||
async saveMembership(membership: LeagueMembership): Promise<LeagueMembership> {
|
||||
this.logger.debug(`Saving membership for league: ${membership.leagueId}, driver: ${membership.driverId}`);
|
||||
try {
|
||||
const list = this.membershipsByLeague.get(membership.leagueId) ?? [];
|
||||
const existingIndex = list.findIndex(
|
||||
(m) => m.leagueId === membership.leagueId && m.driverId === membership.driverId,
|
||||
);
|
||||
|
||||
if (existingIndex >= 0) {
|
||||
list[existingIndex] = membership;
|
||||
this.logger.info(`Updated existing membership for league: ${membership.leagueId}, driver: ${membership.driverId}.`);
|
||||
} else {
|
||||
list.push(membership);
|
||||
this.logger.info(`Created new membership for league: ${membership.leagueId}, driver: ${membership.driverId}.`);
|
||||
}
|
||||
|
||||
this.membershipsByLeague.set(membership.leagueId, list);
|
||||
return membership;
|
||||
} catch (error) {
|
||||
this.logger.error(`Error saving membership for league ${membership.leagueId}, driver ${membership.driverId}:`, error);
|
||||
throw error;
|
||||
}
|
||||
this.logger.debug(`[InMemoryLeagueMembershipRepository] Saving membership for ${membership.id}.`);
|
||||
const key = `${membership.leagueId}:${membership.driverId}`;
|
||||
this.memberships.set(key, membership);
|
||||
this.logger.info(`Membership ${membership.id} saved successfully.`);
|
||||
return Promise.resolve(membership);
|
||||
}
|
||||
|
||||
async removeMembership(leagueId: string, driverId: string): Promise<void> {
|
||||
this.logger.debug(`Removing membership for league: ${leagueId}, driver: ${driverId}`);
|
||||
try {
|
||||
const list = this.membershipsByLeague.get(leagueId);
|
||||
if (!list) {
|
||||
this.logger.warn(`No membership list found for league: ${leagueId}. Cannot remove.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const next = list.filter((m) => m.driverId !== driverId);
|
||||
if (next.length < list.length) {
|
||||
this.membershipsByLeague.set(leagueId, next);
|
||||
this.logger.info(`Removed membership for league: ${leagueId}, driver: ${driverId}.`);
|
||||
} else {
|
||||
this.logger.warn(`Membership not found for league: ${leagueId}, driver: ${driverId}. Cannot remove.`);
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`Error removing membership for league ${leagueId}, driver ${driverId}:`, error);
|
||||
throw error;
|
||||
this.logger.debug(`[InMemoryLeagueMembershipRepository] Removing membership for league ${leagueId}, driver ${driverId}.`);
|
||||
const key = `${leagueId}:${driverId}`;
|
||||
if (this.memberships.delete(key)) {
|
||||
this.logger.info(`Membership for league ${leagueId}, driver ${driverId} removed successfully.`);
|
||||
} else {
|
||||
this.logger.warn(`Membership for league ${leagueId}, driver ${driverId} not found for removal.`);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
async saveJoinRequest(request: JoinRequest): Promise<JoinRequest> {
|
||||
this.logger.debug(`Saving join request for league: ${request.leagueId}, driver: ${request.driverId}, id: ${request.id}`);
|
||||
try {
|
||||
const list = this.joinRequestsByLeague.get(request.leagueId) ?? [];
|
||||
const existingIndex = list.findIndex((r) => r.id === request.id);
|
||||
|
||||
if (existingIndex >= 0) {
|
||||
list[existingIndex] = request;
|
||||
this.logger.info(`Updated existing join request: ${request.id}.`);
|
||||
} else {
|
||||
list.push(request);
|
||||
this.logger.info(`Created new join request: ${request.id}.`);
|
||||
}
|
||||
|
||||
this.joinRequestsByLeague.set(request.leagueId, list);
|
||||
return request;
|
||||
} catch (error) {
|
||||
this.logger.error(`Error saving join request ${request.id}:`, error);
|
||||
throw error;
|
||||
}
|
||||
this.logger.debug(`[InMemoryLeagueMembershipRepository] Saving join request for ${request.id}.`);
|
||||
this.joinRequests.set(request.id, request);
|
||||
this.logger.info(`Join request ${request.id} saved successfully.`);
|
||||
return Promise.resolve(request);
|
||||
}
|
||||
|
||||
async removeJoinRequest(requestId: string): Promise<void> {
|
||||
this.logger.debug(`Removing join request with ID: ${requestId}`);
|
||||
try {
|
||||
let removed = false;
|
||||
for (const [leagueId, requests] of this.joinRequestsByLeague.entries()) {
|
||||
const next = requests.filter((r) => r.id !== requestId);
|
||||
if (next.length !== requests.length) {
|
||||
this.joinRequestsByLeague.set(leagueId, next);
|
||||
removed = true;
|
||||
this.logger.info(`Removed join request ${requestId} from league ${leagueId}.`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!removed) {
|
||||
this.logger.warn(`Join request with ID ${requestId} not found for removal.`);
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(`Error removing join request ${requestId}:`, error);
|
||||
throw error;
|
||||
this.logger.debug(`[InMemoryLeagueMembershipRepository] Removing join request: ${requestId}.`);
|
||||
if (this.joinRequests.delete(requestId)) {
|
||||
this.logger.info(`Join request ${requestId} removed successfully.`);
|
||||
} else {
|
||||
this.logger.warn(`Join request ${requestId} not found for removal.`);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user