Files
clinicpro/docs/api/patient.md
T
hamed b0244f28f5 feat: implement staff management and subscription system
- Added StaffController for managing clinic staff, including listing, creating, updating, and toggling staff status.
- Created ClinicStaff entity and repository for staff data handling.
- Developed SubscriptionController to manage subscription plans and periods, including trial subscriptions.
- Introduced SubscriptionPlan, SubscriptionPeriod, and ClinicSubscription entities for subscription management.
- Implemented SubscriptionService for handling subscription logic, including trial activation and subscription creation from payments.
- Added necessary repositories for subscription entities to facilitate data access and manipulation.
2026-06-14 22:10:28 +03:30

279 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Patient Records & Sessions API
## Overview
Patient records track patients per entity (doctor or clinic). Each record holds multiple sessions (visits). Access requires an active subscription with the `patient_records` feature.
**Base path:** `/api/v1`
**Auth:** Bearer JWT (doctor or clinic role required)
---
## Endpoints
### List Patients
```
GET /api/v1/patients
```
Returns a paginated list of patient records belonging to the authenticated entity.
**Query params:**
| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `page` | int | 1 | Page number |
| `limit` | int | 20 | Items per page (1050) |
| `search` | string | — | Search by patient name or phone |
**Response 200:**
```json
{
"success": true,
"data": [
{
"uuid": "...",
"entity_type": "doctor",
"entity_id": 5,
"user": { "uuid": "...", "fullName": "علی رضایی", "phone": "09123456789" },
"created_by_type": "doctor",
"created_by_id": 5,
"created_at": 1718375000
}
],
"meta": {
"totalRecords": 42,
"totalPages": 3,
"currentPage": 1
}
}
```
**Errors:**
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_SUBSCRIPTION_REQUIRED` | 403 | No active plan with `patient_records` feature |
---
### Create Patient Record
```
POST /api/v1/patient
```
Creates a patient record for a user under the current entity. If the record already exists, returns the existing record (idempotent).
**Request body:**
```json
{
"user_uuid": "string (required)"
}
```
**Response 201:**
```json
{
"success": true,
"data": {
"uuid": "...",
"entity_type": "doctor",
"entity_id": 5,
"user": { "uuid": "...", "fullName": "...", "phone": "..." },
"created_by_type": "doctor",
"created_by_id": 5,
"created_at": 1718375000
}
}
```
**Errors:**
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_VALIDATION_001` | 422 | `user_uuid` missing |
| `ERR_NOT_FOUND_001` | 404 | User not found |
| `ERR_SUBSCRIPTION_REQUIRED` | 403 | No `patient_records` feature |
---
### Get Patient Record
```
GET /api/v1/patient/{uuid}
```
Returns a single patient record.
**Response 200:**
```json
{
"success": true,
"data": {
"uuid": "...",
"entity_type": "doctor",
"entity_id": 5,
"user": { "uuid": "...", "fullName": "...", "phone": "..." },
"created_by_type": "doctor",
"created_by_id": 5,
"created_at": 1718375000
}
}
```
**Errors:**
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_PATIENT_NOT_FOUND` | 404 | Record not found or not owned by caller |
| `ERR_SUBSCRIPTION_REQUIRED` | 403 | No `patient_records` feature |
---
### List Patient Sessions
```
GET /api/v1/patient/{uuid}/sessions
```
Returns paginated sessions for a patient record.
**Query params:** `page`, `limit` (same as list)
**Response 200:**
```json
{
"success": true,
"data": [
{
"uuid": "...",
"record_uuid": "...",
"appointment_uuid": null,
"insurance_base_id": null,
"insurance_supplementary_id": null,
"visit_price_rials": 200000,
"base_insurance_discount_percent": "10.00",
"supplementary_discount_percent": "5.00",
"services_total_rials": 50000,
"final_price_rials": 230000,
"payment_method": "cash",
"notes": "...",
"created_at": 1718375000,
"updated_at": 1718375000
}
],
"meta": { "totalRecords": 8, "totalPages": 1, "currentPage": 1 }
}
```
**Errors:**
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_PATIENT_NOT_FOUND` | 404 | Record not found or not owned by caller |
| `ERR_SUBSCRIPTION_REQUIRED` | 403 | No `patient_records` feature |
---
### Create Session
```
POST /api/v1/patient/{uuid}/session
```
Creates a new visit session for a patient record.
**Request body:**
```json
{
"visit_price_rials": 200000,
"base_insurance_discount_percent": 10,
"supplementary_discount_percent": 5,
"insurance_base_id": null,
"insurance_supplementary_id": null,
"payment_method": "cash",
"notes": "...",
"services": [
{
"service_item_uuid": "...",
"staff_uuid": null
}
]
}
```
**Field notes:**
- `payment_method`: `cash` | `card` | `insurance` | `online` | `pending`
- `services`: array of service items to attach; `price_rials` is snapshot-copied from ServiceItem
- `final_price_rials` is computed: `(visit_price × (1 - base%) × (1 - supp%)) + services_total`
**Response 201:**
```json
{
"success": true,
"data": { ...session object... }
}
```
**Errors:**
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_PATIENT_NOT_FOUND` | 404 | Record not found or not owned |
| `ERR_SUBSCRIPTION_REQUIRED` | 403 | No `patient_records` feature |
---
### Update Session
```
PATCH /api/v1/session/{uuid}
```
Updates mutable fields on a session.
**Request body (all optional):**
```json
{
"notes": "...",
"payment_method": "card"
}
```
**Response 200:**
```json
{
"success": true,
"data": { ...session object... }
}
```
**Errors:**
| Code | HTTP | Description |
|------|------|-------------|
| `ERR_SESSION_NOT_FOUND` | 404 | Session not found or not owned |
---
## Auto-Creation on Appointment Confirm
When an appointment's status changes to `confirmed` via `PATCH /api/v1/appointment/{uuid}/status`, the system automatically:
1. Creates a `PatientRecord` for the appointment's user (if not already existing) under the doctor entity
2. Creates a blank `PatientSession` linked to the appointment
This only runs if the doctor has the `patient_records` subscription feature active.