feature: a minimal v1 backend implemented for treatments feature.

This commit is contained in:
2026-05-19 22:29:29 +03:30
parent 935bb8c214
commit f743046b38
27 changed files with 1636 additions and 656 deletions

View File

@@ -1,10 +1,8 @@
import { apiClient } from './client';
import {
CreatePatientInput,
CreateTreatmentHistoryInput,
Patient,
PatientsListResponse,
TreatmentHistoryItem,
} from '@/types/patient';
export const patientsApi = {
@@ -22,22 +20,4 @@ export const patientsApi = {
const response = await apiClient.get(`/patients/${id}`);
return response.data;
},
listTreatments: async (
patientId: string,
limit = 20,
): Promise<{ success: boolean; data: TreatmentHistoryItem[] }> => {
const response = await apiClient.get(`/patients/${patientId}/treatments`, {
params: { limit },
});
return response.data;
},
addTreatment: async (
patientId: string,
data: CreateTreatmentHistoryInput,
): Promise<{ success: boolean; data: TreatmentHistoryItem }> => {
const response = await apiClient.post(`/patients/${patientId}/treatments`, data);
return response.data;
},
};

View File

@@ -0,0 +1,76 @@
import { apiClient } from './client';
import type {
LinkedOrganizationOption,
PastTreatment,
SaveTreatmentPayload,
SendTreatmentCasePayload,
TreatmentAttachmentMeta,
} from '@/types/treatment';
export const treatmentsApi = {
listLinkedOrganizations: async (): Promise<{ success: boolean; data: LinkedOrganizationOption[] }> => {
const response = await apiClient.get('/treatments/linked-organizations');
return response.data;
},
listPatientHistory: async (
patientId: string,
limit = 20,
): Promise<{ success: boolean; data: PastTreatment[] }> => {
const response = await apiClient.get(`/treatments/patients/${patientId}/history`, {
params: { limit },
});
return response.data;
},
getDraft: async (
appointmentId: string,
): Promise<{ success: boolean; data: PastTreatment | null }> => {
const response = await apiClient.get(`/treatments/appointments/${appointmentId}/draft`);
return response.data;
},
saveDraft: async (
appointmentId: string,
payload: Pick<SaveTreatmentPayload, 'cases'>,
): Promise<{ success: boolean; data: PastTreatment }> => {
const response = await apiClient.put(`/treatments/appointments/${appointmentId}/draft`, payload);
return response.data;
},
uploadCaseAttachments: async (
appointmentId: string,
caseClientId: string,
files: File[],
): Promise<{ success: boolean; data: TreatmentAttachmentMeta[] }> => {
const form = new FormData();
for (const file of files) {
form.append('files', file);
}
const response = await apiClient.post(
`/treatments/appointments/${appointmentId}/cases/${encodeURIComponent(caseClientId)}/attachments`,
form,
{ headers: { 'Content-Type': 'multipart/form-data' }, timeout: 120_000 },
);
return response.data;
},
sendCase: async (
caseId: string,
payload: SendTreatmentCasePayload,
): Promise<{ success: boolean; data: PastTreatmentCaseResponse }> => {
const response = await apiClient.post(`/treatments/cases/${caseId}/send`, payload);
return response.data;
},
};
export interface PastTreatmentCaseResponse {
id: string;
clientId: string;
treatmentType: string;
teeth: string[];
notes: string | null;
sentAt: string | null;
sendToOrganizationIds: string[];
attachmentMetas: TreatmentAttachmentMeta[];
}