riseup-squad18/src/services/availability/availabilityService.ts
guisilvagomes 3a3e4c1f55 fix: corrige exibição de nomes de médicos em laudos e relatórios
- Adiciona resolução de IDs para nomes nos laudos do painel do paciente
- Implementa dropdown de médicos nos formulários de relatórios
- Corrige API PATCH para retornar dados atualizados (header Prefer)
- Adiciona fallback para buscar relatório após update
- Limpa cache de nomes ao atualizar relatórios
- Trata dados legados (nomes diretos vs UUIDs)
- Exibe 'Médico não cadastrado' para IDs inexistentes
2025-11-05 18:25:13 -03:00

207 lines
5.3 KiB
TypeScript

/**
* Availability Service
*
* Serviço para gerenciamento de disponibilidade dos médicos
*/
import { apiClient } from "../api/client";
import {
DoctorAvailability,
ListAvailabilityFilters,
CreateAvailabilityInput,
UpdateAvailabilityInput,
DoctorException,
CreateExceptionInput,
} from "./types";
class AvailabilityService {
private readonly basePath = "/doctor_availability";
private readonly exceptionsPath = "/doctor_exceptions";
/**
* Lista as disponibilidades dos médicos via Supabase REST API
*/
async list(filters?: ListAvailabilityFilters): Promise<DoctorAvailability[]> {
const params: Record<string, string> = {};
if (filters?.doctor_id) {
params.doctor_id = `eq.${filters.doctor_id}`;
}
if (filters?.weekday !== undefined) {
params.weekday = `eq.${filters.weekday}`;
}
if (filters?.active !== undefined) {
params.active = `eq.${filters.active}`;
}
if (filters?.appointment_type) {
params.appointment_type = `eq.${filters.appointment_type}`;
}
console.log("[AvailabilityService] Listando disponibilidades:", {
filters,
params,
url: this.basePath,
});
const response = await apiClient.get<any[]>(this.basePath, {
params,
});
console.log("[AvailabilityService] Resposta:", {
count: response.data?.length || 0,
isArray: Array.isArray(response.data),
});
// Converter weekday de string para número (compatibilidade com banco antigo)
const convertedData: DoctorAvailability[] = Array.isArray(response.data)
? response.data.map((item) => {
const weekdayMap: Record<string, number> = {
sunday: 0,
monday: 1,
tuesday: 2,
wednesday: 3,
thursday: 4,
friday: 5,
saturday: 6,
};
return {
...item,
weekday:
typeof item.weekday === "string"
? weekdayMap[item.weekday.toLowerCase()]
: item.weekday,
};
})
: [];
if (convertedData.length > 0) {
console.log(
"[AvailabilityService] ✅ Convertido:",
convertedData.length,
"registros"
);
console.log(
"[AvailabilityService] Primeiro item convertido:",
JSON.stringify(convertedData[0], null, 2)
);
}
return convertedData;
}
/**
* Cria uma nova configuração de disponibilidade
*/
async create(data: CreateAvailabilityInput): Promise<DoctorAvailability> {
console.log("[AvailabilityService] Criando disponibilidade:", {
data,
url: this.basePath,
});
const response = await apiClient.post<DoctorAvailability[]>(
this.basePath,
data,
{
headers: {
Prefer: "return=representation",
},
}
);
console.log("[AvailabilityService] Resposta da criação:", response.data);
return Array.isArray(response.data) ? response.data[0] : response.data;
}
/**
* Atualiza uma configuração de disponibilidade
*/
async update(
id: string,
data: UpdateAvailabilityInput
): Promise<DoctorAvailability> {
console.log("[AvailabilityService] Atualizando disponibilidade:", {
id,
data,
url: `${this.basePath}?id=eq.${id}`,
});
const response = await apiClient.patch<DoctorAvailability[]>(
`${this.basePath}?id=eq.${id}`,
data,
{
headers: {
Prefer: "return=representation",
},
}
);
console.log(
"[AvailabilityService] Resposta da atualização:",
response.data
);
return Array.isArray(response.data) ? response.data[0] : response.data;
}
/**
* Remove uma configuração de disponibilidade
*/
async delete(id: string): Promise<void> {
await apiClient.delete(`${this.basePath}?id=eq.${id}`);
}
/**
* Lista exceções de agenda (bloqueios e disponibilidades extras)
*/
async listExceptions(filters?: {
doctor_id?: string;
date?: string;
kind?: "bloqueio" | "disponibilidade_extra";
}): Promise<DoctorException[]> {
const params: Record<string, string> = {};
if (filters?.doctor_id) {
params.doctor_id = `eq.${filters.doctor_id}`;
}
if (filters?.date) {
params.date = `eq.${filters.date}`;
}
if (filters?.kind) {
params.kind = `eq.${filters.kind}`;
}
const response = await apiClient.get<DoctorException[]>(
this.exceptionsPath,
{ params }
);
return response.data;
}
/**
* Cria uma exceção de agenda
*/
async createException(data: CreateExceptionInput): Promise<DoctorException> {
const response = await apiClient.post<DoctorException[]>(
this.exceptionsPath,
data,
{
headers: {
Prefer: "return=representation",
},
}
);
return Array.isArray(response.data) ? response.data[0] : response.data;
}
/**
* Remove uma exceção de agenda
*/
async deleteException(id: string): Promise<void> {
await apiClient.delete(`${this.exceptionsPath}?id=eq.${id}`);
}
}
export const availabilityService = new AvailabilityService();