// Challenge Service Types export interface ChallengeUser { _id: string id: string nickname: string createdAt: string } export interface ChallengeTask { _id: string id: string title: string description: string // Markdown hiddenInstructions?: string // Только для преподавателей creator?: { sub: string preferred_username: string email?: string } // Только для преподавателей createdAt: string updatedAt: string } export interface ChallengeChain { _id: string id: string name: string tasks: ChallengeTask[] // Populated isActive: boolean createdAt: string updatedAt: string } export type SubmissionStatus = 'pending' | 'in_progress' | 'accepted' | 'needs_revision' export interface ChallengeSubmission { _id: string id: string user: ChallengeUser | string task: ChallengeTask | string result: string status: SubmissionStatus queueId?: string feedback?: string submittedAt: string checkedAt?: string attemptNumber: number } export type QueueStatusType = 'waiting' | 'in_progress' | 'completed' | 'error' | 'not_found' export interface QueueStatus { status: QueueStatusType submission?: ChallengeSubmission & { task: ChallengeTask } error?: string position?: number } export interface TaskStats { taskId: string taskTitle: string attempts: Array<{ attemptNumber: number status: SubmissionStatus submittedAt: string checkedAt?: string feedback?: string }> totalAttempts: number status: 'not_attempted' | 'pending' | 'in_progress' | 'completed' | 'needs_revision' lastAttemptAt: string | null } export interface ChainStats { chainId: string chainName: string totalTasks: number completedTasks: number progress: number // 0-100 } export interface UserStats { totalTasksAttempted: number completedTasks: number inProgressTasks: number needsRevisionTasks: number totalSubmissions: number averageCheckTimeMs: number taskStats: TaskStats[] chainStats: ChainStats[] } export interface SystemStats { users: number tasks: number chains: number submissions: { total: number accepted: number rejected: number pending: number inProgress: number } averageCheckTimeMs: number queue: { queueLength: number waiting: number inProgress: number maxConcurrency: number currentlyProcessing: number } } // API Request/Response types export interface APIResponse { error: unknown data: T } export interface CreateTaskRequest { title: string description: string hiddenInstructions?: string } export interface UpdateTaskRequest { title?: string description?: string hiddenInstructions?: string } export interface CreateChainRequest { name: string taskIds: string[] // Array of task IDs isActive?: boolean } export interface UpdateChainRequest { name?: string taskIds?: string[] isActive?: boolean } export interface DuplicateChainRequest { name?: string } export interface ClearSubmissionsResponse { deletedCount: number chainId: string userId?: string } // ========== Stats v2 Types ========== export type TaskProgressStatus = 'not_started' | 'pending' | 'in_progress' | 'needs_revision' | 'completed' export interface TaskTableItem { taskId: string title: string totalAttempts: number uniqueUsers: number acceptedCount: number successRate: number averageAttemptsToSuccess: number } export interface ChainProgress { chainId: string chainName: string totalTasks: number completedTasks: number progressPercent: number } export interface ActiveParticipant { userId: string nickname: string totalSubmissions: number completedTasks: number chainProgress: ChainProgress[] } export interface TaskProgress { taskId: string taskTitle: string status: TaskProgressStatus } export interface ParticipantProgress { userId: string nickname: string taskProgress: TaskProgress[] completedCount: number progressPercent: number } export interface ChainTask { taskId: string title: string description: string } export interface ChainDetailed { chainId: string name: string totalTasks: number tasks: ChainTask[] participantProgress: ParticipantProgress[] } export interface SystemStatsV2 { // Базовая статистика из v1 users: number tasks: number chains: number submissions: { total: number accepted: number rejected: number pending: number inProgress: number } averageCheckTimeMs: number queue: { queueLength: number waiting: number inProgress: number maxConcurrency: number currentlyProcessing: number } // Новые данные v2 tasksTable: TaskTableItem[] activeParticipants: ActiveParticipant[] chainsDetailed: ChainDetailed[] } // ========== Submissions / Checking ========== export interface SubmitRequest { userId: string taskId: string result: string // Флаг тестового режима: проверка без создания Submission и очереди isTest?: boolean // Временные скрытые инструкции для тестовой проверки (не сохраняются в задачу) hiddenInstructions?: string } export interface TestSubmissionResult { isTest: true status: Exclude feedback?: string } // ========== Chain Submissions API ========== export interface ChainSubmissionsParticipant { userId: string nickname: string completedTasks: number totalTasks: number progressPercent: number } export interface ChainSubmissionsResponse { chain: { id: string name: string tasks: Array<{ id: string; title: string }> } participants: ChainSubmissionsParticipant[] submissions: ChallengeSubmission[] pagination: { total: number limit: number offset: number } }