Files
gridpilot.gg/apps/api/src/domain/team/dtos/TeamDto.ts
2025-12-24 21:44:58 +01:00

334 lines
5.5 KiB
TypeScript

import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsNotEmpty, IsBoolean, IsOptional, IsArray } from 'class-validator';
export class TeamListItemViewModel {
@ApiProperty()
id!: string;
@ApiProperty()
name!: string;
@ApiProperty()
tag!: string;
@ApiProperty()
description!: string;
@ApiProperty()
memberCount!: number;
@ApiProperty({ type: [String] })
leagues!: string[];
@ApiProperty({ required: false })
specialization?: 'endurance' | 'sprint' | 'mixed';
@ApiProperty({ required: false })
region?: string;
@ApiProperty({ type: [String], required: false })
languages?: string[];
}
export class AllTeamsViewModel {
@ApiProperty({ type: [TeamListItemViewModel] })
teams!: TeamListItemViewModel[];
@ApiProperty()
totalCount!: number;
}
export class TeamViewModel {
@ApiProperty()
id!: string;
@ApiProperty()
name!: string;
@ApiProperty()
tag!: string;
@ApiProperty()
description!: string;
@ApiProperty()
ownerId!: string;
@ApiProperty({ type: [String] })
leagues!: string[];
@ApiProperty({ required: false })
createdAt?: string;
@ApiProperty({ required: false })
specialization?: 'endurance' | 'sprint' | 'mixed';
@ApiProperty({ required: false })
region?: string;
@ApiProperty({ type: [String], required: false })
languages?: string[];
}
export enum MembershipRole {
OWNER = 'owner',
MANAGER = 'manager',
MEMBER = 'member',
}
export enum MembershipStatus {
ACTIVE = 'active',
PENDING = 'pending',
INVITED = 'invited',
INACTIVE = 'inactive',
}
export class MembershipViewModel {
@ApiProperty()
role!: 'owner' | 'manager' | 'member';
@ApiProperty()
joinedAt!: string;
@ApiProperty()
isActive!: boolean;
}
export class DriverTeamViewModel {
@ApiProperty({ type: TeamViewModel })
team!: TeamViewModel;
@ApiProperty({ type: MembershipViewModel })
membership!: MembershipViewModel;
@ApiProperty()
isOwner!: boolean;
@ApiProperty()
canManage!: boolean;
}
export class GetDriverTeamQuery {
@ApiProperty()
@IsString()
teamId!: string;
@ApiProperty()
@IsString()
driverId!: string;
}
export class TeamDetailsViewModel {
@ApiProperty({ type: TeamViewModel })
team!: TeamViewModel;
@ApiProperty({ type: MembershipViewModel, nullable: true })
membership!: MembershipViewModel | null;
@ApiProperty()
canManage!: boolean;
}
export class TeamMemberViewModel {
@ApiProperty()
driverId!: string;
@ApiProperty()
driverName!: string;
@ApiProperty()
role!: 'owner' | 'manager' | 'member';
@ApiProperty()
joinedAt!: string;
@ApiProperty()
isActive!: boolean;
@ApiProperty()
avatarUrl!: string;
}
export class TeamMembersViewModel {
@ApiProperty({ type: [TeamMemberViewModel] })
members!: TeamMemberViewModel[];
@ApiProperty()
totalCount!: number;
@ApiProperty()
ownerCount!: number;
@ApiProperty()
managerCount!: number;
@ApiProperty()
memberCount!: number;
}
export class TeamJoinRequestViewModel {
@ApiProperty()
requestId!: string;
@ApiProperty()
driverId!: string;
@ApiProperty()
driverName!: string;
@ApiProperty()
teamId!: string;
@ApiProperty()
status!: 'pending' | 'approved' | 'rejected';
@ApiProperty()
requestedAt!: string;
@ApiProperty()
avatarUrl!: string;
}
export class TeamJoinRequestsViewModel {
@ApiProperty({ type: [TeamJoinRequestViewModel] })
requests!: TeamJoinRequestViewModel[];
@ApiProperty()
pendingCount!: number;
@ApiProperty()
totalCount!: number;
}
export class CreateTeamInput {
@ApiProperty()
@IsString()
@IsNotEmpty()
name!: string;
@ApiProperty()
@IsString()
@IsNotEmpty()
tag!: string;
@ApiProperty({ required: false })
@IsOptional()
@IsString()
description?: string;
@ApiProperty()
@IsString()
ownerId!: string;
}
export class CreateTeamOutput {
@ApiProperty()
@IsString()
teamId!: string;
@ApiProperty()
@IsBoolean()
success!: boolean;
}
export class UpdateTeamInput {
@ApiProperty({ required: false })
@IsOptional()
@IsString()
teamId?: string;
@ApiProperty({ required: false })
@IsOptional()
@IsString()
name?: string;
@ApiProperty({ required: false })
@IsOptional()
@IsString()
tag?: string;
@ApiProperty({ required: false })
@IsOptional()
@IsString()
description?: string;
@ApiProperty()
@IsString()
updatedBy!: string;
}
export class UpdateTeamOutput {
@ApiProperty()
@IsBoolean()
success!: boolean;
}
export class ApproveTeamJoinRequestInput {
@ApiProperty()
@IsString()
requestId!: string;
@ApiProperty({ required: false })
@IsOptional()
@IsString()
teamId?: string;
}
export class ApproveTeamJoinRequestOutput {
@ApiProperty()
@IsBoolean()
success!: boolean;
}
export class RejectTeamJoinRequestInput {
@ApiProperty()
@IsString()
requestId!: string;
@ApiProperty({ required: false })
@IsOptional()
@IsString()
teamId?: string;
}
export class RejectTeamJoinRequestOutput {
@ApiProperty()
@IsBoolean()
success!: boolean;
}
// ---
// DTOs used by the public API surface (consumed by the website via generated types)
// ---
export class TeamDTO {
@ApiProperty()
@IsString()
id!: string;
@ApiProperty()
@IsString()
name!: string;
@ApiProperty()
@IsString()
tag!: string;
@ApiProperty()
@IsString()
description!: string;
@ApiProperty()
@IsString()
ownerId!: string;
@ApiProperty({ type: [String] })
@IsArray()
leagues!: string[];
@ApiProperty({ required: false })
@IsOptional()
@IsString()
createdAt?: string;
}