// ============================================ // 공통 응답 타입 // ============================================ export interface ApiResponse { success: boolean; message: string; data: T; errorCode?: string; } export interface Page { content: T[]; totalElements: number; totalPages: number; number: number; size: number; } // ============================================ // 공용 코드/상태 유니온 // ============================================ export type RoleCode = 'ADMIN' | 'MANAGER' | 'EMPLOYEE'; export type EmpStatus = 'ACTIVE' | 'ON_LEAVE' | 'RESIGNED'; export type DispatchStatus = 'WAITING' | 'DISPATCHED'; export type TicketStatus = 'OPEN' | 'ASSIGNED' | 'IN_PROGRESS' | 'RESOLVED' | 'CLOSED' | 'PENDING_APPROVAL' | 'APPROVED' | 'REJECTED'; export type TicketCategory = 'BUG' | 'FEATURE' | 'SUPPORT' | 'QA' | 'VACATION' | 'EXPENSE' | 'EQUIPMENT_REQUEST' | 'GENERAL'; export type TicketPriority = 'LOW' | 'NORMAL' | 'HIGH' | 'CRITICAL'; export type ReportType = 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'RETURN'; export type ReportStatus = 'DRAFT' | 'SUBMITTED' | 'APPROVED' | 'REJECTED'; export type EquipmentType = 'LAPTOP' | 'MONITOR' | 'TEST_DEVICE' | 'ACCESSORY'; export type EquipmentStatus = 'AVAILABLE' | 'IN_USE' | 'REPAIRING' | 'RETIRED' | 'LOST'; export type MaintenanceType = 'REPAIR' | 'UPGRADE' | 'INSPECTION' | 'DISPOSAL'; export type ProjectType = 'SI' | 'SM' | 'MIGRATION'; export type ContractType = 'TURN_KEY' | 'MM'; export type ProjectStatus = 'PREPARING' | 'ONGOING' | 'COMPLETED' | 'HOLD'; export type WorkLocationType = 'ON_SITE' | 'REMOTE' | 'HYBRID'; export type TrainingStatus = 'NOT_STARTED' | 'ONGOING' | 'COMPLETED'; // ============================================ // Employee (직원) // ============================================ export interface Employee { empId: number; loginId: string; name: string; email: string; phone: string; roleCode: RoleCode; empStatus: EmpStatus; dispatchStatus: DispatchStatus; joinedDate: string; leftDate: string | null; position: string | null; profileImage: string | null; managerId?: number; backupManagerId?: number; emergencyContacts?: EmergencyContact[]; } export interface EmergencyContact { id: number; empId: number; name: string; relation: string | null; phone: string | null; sortOrder: number; } export interface EmployeeSearchResult { empId: number; name: string; roleCode: RoleCode; dispatchStatus: DispatchStatus; email: string; } // ============================================ // Project (프로젝트) // ============================================ export interface Project { projectId: number; projectType: ProjectType; projectName: string; contractCompany: string; endUserCompany: string; contractType: ContractType; status: ProjectStatus; startDate: string; endDate: string; workLocationType: WorkLocationType; workAddress: string; techEnvironment: string; mainTaskDesc: string; internalManagerId: number | null; internalManager?: { empId: number; name: string; email: string; } | null; } // ============================================ // DispatchHistory (파견 이력 / 포트폴리오) // ============================================ export interface DispatchHistory { dispatchId: number; empId: number; projectId: number; projectName?: string; startDate: string; endDate: string | null; roleTitle: string; contributionRate: number; individualTech: string; performedTasks: string; achievements: string | null; clientFeedback: string | null; internalRating: number | null; } // ============================================ // IssueTicket (SR 티켓) // ============================================ export interface IssueTicket { ticketId: number; projectId?: number; projectName?: string; requesterId: number; requesterName?: string; assigneeId: number | null; assigneeName?: string | null; category: TicketCategory; priority: TicketPriority; title: string; description: string; status: TicketStatus; dueDate: string | null; resolvedAt: string | null; resolutionNote: string | null; slaWarnFlag: 'Y' | 'N'; isImminent?: boolean; createdAt: string; updatedAt: string; attachmentUrl?: string; attachmentName?: string; approverId?: number; backupApproverId?: number; approvedBy?: number; approvedAt?: string; } export interface TicketComment { commentId: number; ticketId: number; userId: number; userName?: string; commentText: string; attachedFileUrl: string | null; createdAt: string; } // ============================================ // WorkReport (업무 보고서) // ============================================ export interface WorkReport { reportId: number; dispatchId: number; userId: number; userName?: string; reportType: ReportType; targetDate: string; completedTasks: string; plannedTasks: string; issuesAndRisks: string | null; supportRequested: string | null; status: ReportStatus; workHours?: number | null; blockerFlag?: string; artifacts?: string; reviewerId: number | null; reviewerName?: string | null; reviewComment: string | null; createdAt: string; updatedAt: string; } // ============================================ // Equipment (IT 자산) // ============================================ export interface EquipmentImage { url: string; name: string; uploadedAt: string; } export interface Equipment { equipmentId: number; equipmentType: EquipmentType; manufacturer: string; modelName: string; serialNumber: string; assetCode: string; specifications: Record; status: EquipmentStatus; purchaseDate: string; warrantyExpDate: string; version: number; images?: EquipmentImage[] | string; } export interface SystemConfig { configId: number; configKey: string; configValue: string; description: string; } export interface MenuPermission { id: number; menuKey: string; menuName: string; parentKey: string | null; allowedRoles: string; sortOrder: number; } export interface EquipmentSummary { counts: Record; } export interface EquipmentAssignment { assignmentId: number; equipmentId: number; userId: number; userName?: string; assignedDate: string; returnedDate: string | null; condOnAssign: string; condOnReturn: string | null; equipment?: { equipmentId: number; assetCode: string; manufacturer: string; modelName: string; serialNumber: string; equipmentType: string; status: string; }; } export interface EquipmentMaintenance { maintenanceId: number; equipmentId: number; reportedBy: number; reporterName?: string; maintenanceType: MaintenanceType; issueDescription: string; actionTaken: string | null; cost: number; reportedDate: string; resolvedDate: string | null; } // ============================================ // Training (교육 진도) // ============================================ export interface TrainingProgress { progressId: number; userId: number; courseName: string; progressRate: number; status: TrainingStatus; updatedAt: string; } export interface TrainingSummary { courseName: string; totalEnrolled: number; completedCount: number; avgProgress: number; } // ============================================ // Notification (알림) // ============================================ export interface Notification { notificationId: number; type: string; title: string; message: string; isRead: boolean; linkUrl?: string; createdAt: string; } // ============================================ // CalendarEvent (통합 일정) // ============================================ export interface CalendarEvent { eventType: 'TICKET_DUE' | 'REPORT_DUE' | 'DISPATCH_START' | 'DISPATCH_END'; sourceId: number; title: string; description?: string; eventDate: string; color: string; linkUrl?: string; } // ============================================ // ReportSummary (보고서 결재 요약) // ============================================ export interface ReportSummary { submitted: number; approved: number; rejected: number; draft: number; } // ============================================ // Parking (서버 파킹) // ============================================ export interface ParkingStatus { parked: boolean; message: string; resumeTime: string; parkingSchedule: string; } export interface WakeRequest { requestedBy: string; reason: string; requestedAt: string; } export interface WakeResponse { success: boolean; message: string; estimatedWakeTime: string | null; } // ============================================ // Auth // ============================================ export interface LoginRequest { email: string; password: string; } export interface LoginResponse { accessToken: string; refreshToken: string; employee: Employee; } // ============================================ // Common Code // ============================================ export interface CommonCode { codeId: number; groupCode: string; codeValue: string; codeName: string; optionVal1: string | null; optionVal2: string | null; sortOrder: number; isActive: 'Y' | 'N'; }