// types.ts (V3) // --- TIPOS DE MODELO DE DADOS (Schemas) --- export interface User { id: string; email: string; created_at: string; } export interface AuthResponse { access_token: string; token_type: string; expires_in: number; refresh_token: string; user: User; } export interface UserProfile { id: string; email: string; full_name: string; phone?: string; roles: ('admin' | 'gestor' | 'medico' | 'secretaria' | 'paciente')[]; } export interface Patient { id: string; full_name: string; cpf: string; email: string; phone_mobile: string; birth_date?: string; created_by: string; created_at: string; updated_at: string; } export interface Doctor { id: string; full_name: string; crm: string; crm_uf: string; specialty?: string; active: boolean; } export interface Appointment { id: string; doctor_id: string; patient_id: string; scheduled_at: string; duration_minutes: number; status: 'requested' | 'confirmed' | 'completed' | 'cancelled'; created_by: string; cancelled_at?: string; cancellation_reason?: string; } export type NewAppointmentPayload = Omit & { status?: 'requested' | 'confirmed'; }; export interface AvailableSlot { time: string; available: boolean; } export interface Report { id: string; order_number: string; patient_id: string; status: 'draft' | 'completed'; exam?: string; requested_by?: string; cid_code?: string; diagnosis?: string; conclusion?: string; content_html?: string; content_json?: object; hide_date: boolean; hide_signature: boolean; due_at?: string; created_by: string; updated_by: string; created_at: string; updated_at: string; } export type ReportInput = Partial> & { patient_id: string; }; export interface DoctorAvailability { id: string; doctor_id: string; weekday: 0 | 1 | 2 | 3 | 4 | 5 | 6; start_time: string; end_time: string; slot_minutes: number; appointment_type: 'presencial' | 'telemedicina'; active: boolean; } export interface DoctorException { id: string; doctor_id: string; date: string; kind: 'bloqueio' | 'disponibilidade_extra'; start_time?: string | null; end_time?: string | null; reason?: string; } // --- TIPOS DE RESPOSTA DA API (UNIÕES DISCRIMINADAS) --- /** * Erro genérico para falhas de rede (CORS, offline, etc.). */ export type NetworkError = { status: 'network_error'; error: Error }; /** * Tipo base para respostas de erro da API com um corpo JSON. */ export type ApiErrorResponse = { status: Status; data: Data }; // Respostas para: authService.login export type LoginSuccess = { status: 200; data: AuthResponse }; export type LoginError400 = ApiErrorResponse<400, { error: string; error_description: string }>; export type LoginResponse = LoginSuccess | LoginError400 | NetworkError; // Respostas para: authService.sendMagicLink export type SendMagicLinkSuccess = { status: 200; data: object }; export type SendMagicLinkError429 = ApiErrorResponse<429, { message: string }>; export type SendMagicLinkResponse = SendMagicLinkSuccess | SendMagicLinkError429 | NetworkError; // Respostas para: authService.logout export type LogoutSuccess = { status: 204; data: undefined }; export type LogoutError401 = ApiErrorResponse<401, { message: string }>; export type LogoutResponse = LogoutSuccess | LogoutError401 | NetworkError; // Respostas para: authService.getCurrentUser export type GetCurrentUserSuccess = { status: 200; data: UserProfile }; export type GetCurrentUserError401 = ApiErrorResponse<401, { message: string }>; export type GetCurrentUserResponse = GetCurrentUserSuccess | GetCurrentUserError401 | NetworkError; // Respostas para: userService.requestPasswordReset export type RequestPasswordResetSuccess = { status: 200; data: { success: boolean; message: string } }; export type RequestPasswordResetError400 = ApiErrorResponse<400, { detail: string }>; export type RequestPasswordResetResponse = RequestPasswordResetSuccess | RequestPasswordResetError400 | NetworkError; // Respostas para: userService.createUserWithPassword export type CreateUserWithPasswordSuccess = { status: 201; data: { success: boolean; user: UserProfile; patient_id?: string } }; export type CreateUserWithPasswordError400 = ApiErrorResponse<400, { error: string }>; export type CreateUserWithPasswordError403 = ApiErrorResponse<403, { error: string }>; export type CreateUserWithPasswordResponse = CreateUserWithPasswordSuccess | CreateUserWithPasswordError400 | CreateUserWithPasswordError403 | NetworkError; // Respostas para: userService.hardDeleteUser_DANGEROUS export type HardDeleteUserSuccess = { status: 200; data: { success: boolean; message: string; userId: string } }; export type HardDeleteUserError400 = ApiErrorResponse<400, { error: string }>; export type HardDeleteUserError403 = ApiErrorResponse<403, { error: string }>; export type HardDeleteUserResponse = HardDeleteUserSuccess | HardDeleteUserError400 | HardDeleteUserError403 | NetworkError; // Respostas para: patientService.registerPatient export type RegisterPatientSuccess = { status: 200; data: { success: boolean; patient_id: string; message: string } }; export type RegisterPatientError400 = ApiErrorResponse<400, { error: string; code: 'VALIDATION_ERROR'; details?: any[] }>; export type RegisterPatientError409 = ApiErrorResponse<409, { error: string; code: 'CPF_EXISTS' | 'EMAIL_EXISTS' }>; export type RegisterPatientError429 = ApiErrorResponse<429, { error: string; code: 'RATE_LIMIT_EXCEEDED' }>; export type RegisterPatientError500 = ApiErrorResponse<500, { error: string; code: string }>; export type RegisterPatientResponse = RegisterPatientSuccess | RegisterPatientError400 | RegisterPatientError409 | RegisterPatientError429 | RegisterPatientError500 | NetworkError; // Respostas para: scheduleService.getAvailableSlots export type GetAvailableSlotsSuccess = { status: 200; data: { slots: AvailableSlot[] } }; export type GetAvailableSlotsResponse = GetAvailableSlotsSuccess | NetworkError; // Respostas para: scheduleService.createAppointment export type CreateAppointmentSuccess = { status: 201; data: Appointment }; export type CreateAppointmentResponse = CreateAppointmentSuccess | NetworkError; // Respostas para: scheduleService.cancelAppointment export type CancelAppointmentSuccess = { status: 200; data: Appointment }; export type CancelAppointmentResponse = CancelAppointmentSuccess | NetworkError; // Respostas para: reportService.create export type CreateReportSuccess = { status: 201; data: Report }; export type CreateReportResponse = CreateReportSuccess | NetworkError; // Respostas para: reportService.update export type UpdateReportSuccess = { status: 200; data: Report }; export type UpdateReportResponse = UpdateReportSuccess | NetworkError; // Tipos genéricos para listagens simples export type ListSuccess = { status: 200; data: T[] }; export type ListResponse = ListSuccess | NetworkError;