wip
This commit is contained in:
196
packages/racing/application/services/memberships.ts
Normal file
196
packages/racing/application/services/memberships.ts
Normal file
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* In-memory league membership data for alpha prototype
|
||||
*/
|
||||
|
||||
import {
|
||||
MembershipRole,
|
||||
MembershipStatus,
|
||||
LeagueMembership,
|
||||
JoinRequest,
|
||||
} from '@gridpilot/racing/domain/entities/LeagueMembership';
|
||||
|
||||
// In-memory storage
|
||||
let memberships: LeagueMembership[] = [];
|
||||
let joinRequests: JoinRequest[] = [];
|
||||
|
||||
// Current driver ID (matches the one in di-container)
|
||||
const CURRENT_DRIVER_ID = 'driver-1';
|
||||
|
||||
// Initialize with seed data
|
||||
export function initializeMembershipData() {
|
||||
memberships = [
|
||||
{
|
||||
leagueId: 'league-1',
|
||||
driverId: CURRENT_DRIVER_ID,
|
||||
role: 'owner',
|
||||
status: 'active',
|
||||
joinedAt: new Date('2024-01-15'),
|
||||
},
|
||||
{
|
||||
leagueId: 'league-1',
|
||||
driverId: 'driver-2',
|
||||
role: 'member',
|
||||
status: 'active',
|
||||
joinedAt: new Date('2024-02-01'),
|
||||
},
|
||||
{
|
||||
leagueId: 'league-1',
|
||||
driverId: 'driver-3',
|
||||
role: 'admin',
|
||||
status: 'active',
|
||||
joinedAt: new Date('2024-02-15'),
|
||||
},
|
||||
];
|
||||
|
||||
joinRequests = [];
|
||||
}
|
||||
|
||||
// Get membership for a driver in a league
|
||||
export function getMembership(leagueId: string, driverId: string): LeagueMembership | null {
|
||||
return memberships.find(m => m.leagueId === leagueId && m.driverId === driverId) || null;
|
||||
}
|
||||
|
||||
// Get all members for a league
|
||||
export function getLeagueMembers(leagueId: string): LeagueMembership[] {
|
||||
return memberships.filter(m => m.leagueId === leagueId && m.status === 'active');
|
||||
}
|
||||
|
||||
// Get pending join requests for a league
|
||||
export function getJoinRequests(leagueId: string): JoinRequest[] {
|
||||
return joinRequests.filter(r => r.leagueId === leagueId);
|
||||
}
|
||||
|
||||
// Join a league
|
||||
export function joinLeague(leagueId: string, driverId: string): void {
|
||||
const existing = getMembership(leagueId, driverId);
|
||||
if (existing) {
|
||||
throw new Error('Already a member or have a pending request');
|
||||
}
|
||||
|
||||
memberships.push({
|
||||
leagueId,
|
||||
driverId,
|
||||
role: 'member',
|
||||
status: 'active',
|
||||
joinedAt: new Date(),
|
||||
});
|
||||
}
|
||||
|
||||
// Request to join a league (for invite-only leagues)
|
||||
export function requestToJoin(leagueId: string, driverId: string, message?: string): void {
|
||||
const existing = getMembership(leagueId, driverId);
|
||||
if (existing) {
|
||||
throw new Error('Already a member or have a pending request');
|
||||
}
|
||||
|
||||
const existingRequest = joinRequests.find(r => r.leagueId === leagueId && r.driverId === driverId);
|
||||
if (existingRequest) {
|
||||
throw new Error('Join request already pending');
|
||||
}
|
||||
|
||||
joinRequests.push({
|
||||
id: `request-${Date.now()}`,
|
||||
leagueId,
|
||||
driverId,
|
||||
requestedAt: new Date(),
|
||||
message,
|
||||
});
|
||||
}
|
||||
|
||||
// Leave a league
|
||||
export function leaveLeague(leagueId: string, driverId: string): void {
|
||||
const membership = getMembership(leagueId, driverId);
|
||||
if (!membership) {
|
||||
throw new Error('Not a member of this league');
|
||||
}
|
||||
|
||||
if (membership.role === 'owner') {
|
||||
throw new Error('League owner cannot leave. Transfer ownership first.');
|
||||
}
|
||||
|
||||
memberships = memberships.filter(m => !(m.leagueId === leagueId && m.driverId === driverId));
|
||||
}
|
||||
|
||||
// Approve join request
|
||||
export function approveJoinRequest(requestId: string): void {
|
||||
const request = joinRequests.find(r => r.id === requestId);
|
||||
if (!request) {
|
||||
throw new Error('Join request not found');
|
||||
}
|
||||
|
||||
memberships.push({
|
||||
leagueId: request.leagueId,
|
||||
driverId: request.driverId,
|
||||
role: 'member',
|
||||
status: 'active',
|
||||
joinedAt: new Date(),
|
||||
});
|
||||
|
||||
joinRequests = joinRequests.filter(r => r.id !== requestId);
|
||||
}
|
||||
|
||||
// Reject join request
|
||||
export function rejectJoinRequest(requestId: string): void {
|
||||
joinRequests = joinRequests.filter(r => r.id !== requestId);
|
||||
}
|
||||
|
||||
// Remove member (admin action)
|
||||
export function removeMember(leagueId: string, driverId: string, removedBy: string): void {
|
||||
const removerMembership = getMembership(leagueId, removedBy);
|
||||
if (!removerMembership || (removerMembership.role !== 'owner' && removerMembership.role !== 'admin')) {
|
||||
throw new Error('Only owners and admins can remove members');
|
||||
}
|
||||
|
||||
const targetMembership = getMembership(leagueId, driverId);
|
||||
if (!targetMembership) {
|
||||
throw new Error('Member not found');
|
||||
}
|
||||
|
||||
if (targetMembership.role === 'owner') {
|
||||
throw new Error('Cannot remove league owner');
|
||||
}
|
||||
|
||||
memberships = memberships.filter(m => !(m.leagueId === leagueId && m.driverId === driverId));
|
||||
}
|
||||
|
||||
// Update member role
|
||||
export function updateMemberRole(
|
||||
leagueId: string,
|
||||
driverId: string,
|
||||
newRole: MembershipRole,
|
||||
updatedBy: string
|
||||
): void {
|
||||
const updaterMembership = getMembership(leagueId, updatedBy);
|
||||
if (!updaterMembership || updaterMembership.role !== 'owner') {
|
||||
throw new Error('Only league owner can change roles');
|
||||
}
|
||||
|
||||
const targetMembership = getMembership(leagueId, driverId);
|
||||
if (!targetMembership) {
|
||||
throw new Error('Member not found');
|
||||
}
|
||||
|
||||
if (newRole === 'owner') {
|
||||
throw new Error('Use transfer ownership to change owner');
|
||||
}
|
||||
|
||||
memberships = memberships.map(m =>
|
||||
m.leagueId === leagueId && m.driverId === driverId
|
||||
? { ...m, role: newRole }
|
||||
: m
|
||||
);
|
||||
}
|
||||
|
||||
// Check if driver is owner or admin
|
||||
export function isOwnerOrAdmin(leagueId: string, driverId: string): boolean {
|
||||
const membership = getMembership(leagueId, driverId);
|
||||
return membership?.role === 'owner' || membership?.role === 'admin';
|
||||
}
|
||||
|
||||
// Get current driver ID
|
||||
export function getCurrentDriverId(): string {
|
||||
return CURRENT_DRIVER_ID;
|
||||
}
|
||||
|
||||
// Initialize on module load
|
||||
initializeMembershipData();
|
||||
Reference in New Issue
Block a user