import { Injectable, Logger } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; export interface PolimedPatient { id: string; fullName: string; birthDate: string; phone: string; cardNumber: string; } export interface PolimedAppointment { id: string; patientId: string; patientFullName: string; doctorFullName: string; specialty: string; scheduledFor: string; status: 'scheduled' | 'completed' | 'cancelled' | 'no_show'; } export type PolimedVisitEventType = | 'arrived' | 'service_started' | 'service_ended' | 'left_without_service'; @Injectable() export class PolimedClient { private readonly logger = new Logger(PolimedClient.name); private readonly baseUrl: string; constructor(config: ConfigService) { this.baseUrl = config.getOrThrow('POLIMED_BASE_URL'); } async searchPatients(query: string, limit = 20): Promise { const url = new URL('/patients/search', this.baseUrl); url.searchParams.set('q', query); url.searchParams.set('limit', String(limit)); return this.fetchJson(url); } async getAppointments(date?: string): Promise { const url = new URL('/appointments', this.baseUrl); if (date) url.searchParams.set('date', date); return this.fetchJson(url); } async getAppointment(id: string): Promise { const url = new URL(`/appointments/${id}`, this.baseUrl); return this.fetchJson(url); } async pushVisitEvent( appointmentId: string, event: { type: PolimedVisitEventType; occurredAt: string; source?: string }, ): Promise { const url = new URL(`/visits/${appointmentId}/events`, this.baseUrl); const res = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ...event, source: event.source ?? 'reception-video' }), }); if (!res.ok) { this.logger.warn(`pushVisitEvent failed: ${res.status} ${url}`); throw new Error(`Polimed event failed: ${res.status}`); } } private async fetchJson(url: URL): Promise { const res = await fetch(url); if (!res.ok) { throw new Error(`Polimed ${url.pathname} failed: ${res.status}`); } return (await res.json()) as T; } }