import { PageQuery } from '@/lib/contracts/page-queries/PageQuery'; import { Result } from '@/lib/contracts/Result'; import { TeamService } from '@/lib/services/teams/TeamService'; import { TeamDetailViewDataBuilder } from '@/lib/builders/view-data/TeamDetailViewDataBuilder'; import type { TeamDetailViewData } from '@/lib/view-data/TeamDetailViewData'; import { type PresentationError, mapToPresentationError } from '@/lib/contracts/page-queries/PresentationError'; import { SessionGateway } from '@/lib/gateways/SessionGateway'; import type { TeamMemberViewModel } from '@/lib/view-models/TeamMemberViewModel'; /** * TeamDetailPageDto - Raw serializable data for team detail page * Contains only raw data, no derived/computed properties */ export interface TeamDetailPageDto { team: { id: string; name: string; tag: string; description?: string; ownerId: string; leagues: string[]; createdAt?: string; specialization?: string; region?: string; languages?: string[]; category?: string; membership?: { role: string; joinedAt: string; isActive: boolean; } | null; canManage: boolean; }; memberships: Array<{ driverId: string; driverName: string; role: 'owner' | 'manager' | 'member'; joinedAt: string; isActive: boolean; avatarUrl: string; }>; currentDriverId: string; } /** * TeamDetailPageQuery - Server-side composition for team detail page */ export class TeamDetailPageQuery implements PageQuery { async execute(teamId: string): Promise> { // Get session to determine current driver (optional for public view) const sessionGateway = new SessionGateway(); const session = await sessionGateway.getSession(); const currentDriverId = session?.user?.primaryDriverId || ''; const service = new TeamService(); // Fetch team details const teamResult = await service.getTeamDetails(teamId, currentDriverId); if (teamResult.isErr()) { return Result.err(mapToPresentationError(teamResult.getError())); } const teamData = teamResult.unwrap(); // Fetch team members const membersResult = await service.getTeamMembers(teamId, currentDriverId, teamData.team.ownerId); if (membersResult.isErr()) { return Result.err(mapToPresentationError(membersResult.getError())); } const membersData = membersResult.unwrap(); // Transform to raw serializable DTO const dto: TeamDetailPageDto = { team: { id: teamData.team.id, name: teamData.team.name, tag: teamData.team.tag, description: teamData.team.description, ownerId: teamData.team.ownerId, leagues: teamData.team.leagues, createdAt: teamData.team.createdAt, specialization: (teamData.team as any).specialization, region: (teamData.team as any).region, languages: (teamData.team as any).languages, category: teamData.team.category, membership: teamData.membership ? { role: teamData.membership.role, joinedAt: teamData.membership.joinedAt, isActive: teamData.membership.isActive, } : null, canManage: teamData.canManage, }, memberships: membersData.map((member: TeamMemberViewModel) => ({ driverId: member.driverId, driverName: member.driverName, role: member.role, joinedAt: member.joinedAt, isActive: member.isActive, avatarUrl: member.avatarUrl, })), currentDriverId, }; const viewData = TeamDetailViewDataBuilder.build(dto); return Result.ok(viewData); } static async execute(teamId: string): Promise> { const query = new TeamDetailPageQuery(); return query.execute(teamId); } }