- 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
207 lines
5.3 KiB
TypeScript
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();
|