Files
clinicpro/docs/api/admin.md
T
hamed 45ee725820 feat: update appointment management API and frontend components
- Added new endpoint to get today's appointment statistics with optional date filter.
- Enhanced appointment listing API to support filtering by date and doctor UUID.
- Updated Appointment model to include new fields and modified status values.
- Implemented AppointmentStatusDropdown component for status management with visual feedback.
- Created PersianCalendar component for date selection in Jalali format.
- Updated API documentation to reflect changes in appointment management.
2026-06-11 14:13:42 +03:30

16 KiB
Raw Blame History

Admin API

Prefix: /api/v1/admin
Permission: ALL endpoints in this file require ROLE_ADMIN
Headers: Authorization: Bearer <admin_jwt_token>


Dashboard

GET /api/v1/admin/dashboard/stats

Get key performance indicators (KPIs) for the dashboard.

Permission: ROLE_ADMIN

Response 200

{
  "success": true,
  "data": {
    "total_users": 1200,
    "active_doctors": 85,
    "total_doctors": 92,
    "total_clinics": 34,
    "today_appointments": 47,
    "total_appointments": 8540,
    "today_payments_count": 30,
    "today_payments_amount": 15000000,
    "total_payments_amount": 425000000,
    "pending_comments": 12,
    "pending_settlements": 5,
    "this_month_revenue": 52000000,
    "this_month_appointments": 620
  }
}

GET /api/v1/admin/dashboard/charts

Get chart data for the last 30 days.

Permission: ROLE_ADMIN

Response 200

{
  "success": true,
  "data": {
    "appointments_30d": [
      { "date": "2024-06-01", "count": 42 }
    ],
    "revenue_30d": [
      { "date": "2024-06-01", "amount_rials": 21000000 }
    ],
    "appointment_status": {
      "confirmed": 350,
      "completed": 180,
      "cancelled": 45,
      "pending": 20,
      "no_show": 25
    },
    "top_specialties": [
      { "name": "قلب و عروق", "count": 120 }
    ]
  }
}

GET /api/v1/admin/dashboard/recent

Get recent activity (last 10 of each type).

Permission: ROLE_ADMIN

Response 200

{
  "success": true,
  "data": {
    "appointments": [
      {
        "uuid": "...",
        "doctor_title": "دکتر علی احمدی",
        "patient_name": "محمد رضایی",
        "slot_start": 1718438400,
        "status": "confirmed"
      }
    ],
    "payments": [
      {
        "uuid": "...",
        "amount_rials": 500000,
        "gateway": "mellat",
        "status": "paid",
        "created_at": 1717000000
      }
    ],
    "users": [
      {
        "uuid": "...",
        "real_name": "محمد رضایی",
        "mobile_number": "09...",
        "roles": ["ROLE_USER"],
        "created_at": 1717000000
      }
    ]
  }
}

User Management

GET /api/v1/admin/users

List all users with pagination and filters.

Permission: ROLE_ADMIN

Query Parameters

Param Type Required Description
page integer Default: 1
limit integer Default: 20
search string Search by name or mobile
role string Filter: ROLE_USER, ROLE_DOCTOR, ROLE_ADMIN, etc.
status string "active" or "inactive"
sort string "created_at" (default desc)

Response 200

{
  "success": true,
  "data": [
    {
      "uuid": "...",
      "real_name": "علی احمدی",
      "mobile_number": "09123456789",
      "roles": ["ROLE_USER"],
      "status": "active",
      "created_at": 1717000000
    }
  ],
  "meta": { "totalRecords": 1200, "totalPages": 60, "currentPage": 1 }
}

GET /api/v1/admin/users/{uuid}

Get detailed user info.

Permission: ROLE_ADMIN

Response 200

{
  "success": true,
  "data": {
    "uuid": "...",
    "real_name": "علی احمدی",
    "mobile_number": "09123456789",
    "roles": ["ROLE_USER"],
    "status": "active",
    "wallet_balance_rials": 500000,
    "appointments_count": 5,
    "created_at": 1717000000
  }
}

Errors

Code HTTP Description
ERR_NOT_FOUND_001 404 User not found

GET /api/v1/admin/users/stats

Get user statistics.

Permission: ROLE_ADMIN

Response 200

{
  "success": true,
  "data": {
    "total": 1200,
    "active": 1150,
    "inactive": 50,
    "admins": 3,
    "doctors": 92,
    "patients": 1100
  }
}

PUT /api/v1/admin/users/{uuid}

Update user info (name, email, password).

Permission: ROLE_ADMIN

Request Body (application/json)

{
  "real_name": "علی احمدی جدید",
  "password": "newPassword123"
}

Response 200

Updated user object.


PUT /api/v1/admin/users/{uuid}/role

Change a user's role.

Permission: ROLE_ADMIN

Request Body (application/json)

{
  "role": "ROLE_DOCTOR"
}
Field Type Required Allowed Values
role string ROLE_USER, ROLE_DOCTOR, ROLE_CLINIC, ROLE_SECRETARY, ROLE_ADMIN

Response 200

{ "success": true, "data": { "message": "نقش کاربر تغییر کرد", "roles": ["ROLE_DOCTOR"] } }

POST /api/v1/admin/users/{uuid}/status

Toggle user active/inactive status.

Permission: ROLE_ADMIN

Response 200

{ "success": true, "data": { "status": "inactive" } }

DELETE /api/v1/admin/users/{uuid}

Delete a user.

Permission: ROLE_ADMIN

Response 200

{ "success": true, "data": { "message": "کاربر حذف شد" } }

Errors

Code HTTP Description
ERR_NOT_FOUND_001 404 User not found

Doctor Management

GET /api/v1/admin/doctors

List all doctors with pagination.

Permission: ROLE_ADMIN

Query Parameters

Param Type Required Description
page integer Default: 1
limit integer Default: 20
search string Search in title
status string "active" or "inactive"
gender string "male" or "female"
specialty_id integer Filter by specialty
sort string Sort field

Response 200

{
  "success": true,
  "data": [
    {
      "uuid": "...",
      "title": "دکتر علی احمدی",
      "degree": "متخصص",
      "gender": "male",
      "doctor_rate": 4.5,
      "active_doctor_appointment": true
    }
  ],
  "meta": { "totalRecords": 92, "totalPages": 5, "currentPage": 1 }
}

GET /api/v1/admin/doctors/stats

Get doctor statistics.

Permission: ROLE_ADMIN

Response 200

{
  "success": true,
  "data": {
    "total": 92,
    "active": 85,
    "inactive": 7,
    "male": 60,
    "female": 32,
    "top_specialty": "قلب و عروق"
  }
}

POST /api/v1/admin/doctors/{uuid}/status

Toggle doctor active status.

Permission: ROLE_ADMIN

Response 200

{ "success": true, "data": { "active": false } }

Clinic Management

GET /api/v1/admin/clinics

List all clinics with pagination.

Permission: ROLE_ADMIN

Query Parameters

Param Type Required Description
page integer Default: 1
limit integer Default: 20
search string Search by clinic name
status string "active" or "inactive"

Response 200

{
  "success": true,
  "data": [
    {
      "uuid": "...",
      "name": "کلینیک الوند",
      "city": "تهران",
      "telephone": "02112345678",
      "is_active": true,
      "created_at": 1717000000
    }
  ],
  "meta": { "totalRecords": 34, "totalPages": 2, "currentPage": 1 }
}

PATCH /api/v1/admin/clinic/{uuid}/status

Toggle clinic active/inactive.

Permission: ROLE_ADMIN

Response 200

{ "success": true, "data": { "is_active": false } }

Errors

Code HTTP Description
ERR_NOT_FOUND_001 404 Clinic not found

DELETE /api/v1/admin/clinic/{uuid}

Delete a clinic.

Permission: ROLE_ADMIN

Response 200

{ "success": true, "data": { "message": "کلینیک حذف شد" } }

Appointment Management

GET /api/v1/admin/appointments/today-stats

Get appointment statistics for a specific date (defaults to today).

Permission: ROLE_ADMIN

Query Parameters

Param Type Required Description
date string (YYYY-MM-DD) Default: today

Response 200

{
  "success": true,
  "data": {
    "total": 47,
    "completed": 20,
    "waiting": 18,
    "cancelled": 9
  }
}

GET /api/v1/admin/appointments

List appointments filtered by date and/or doctor. Sorted by slot_start ASC.

Permission: ROLE_ADMIN

Query Parameters

Param Type Required Description
page integer Default: 1
limit integer Default: 15, max: 500
search string Search by patient name/mobile or doctor name
status string Filter by status
date string (YYYY-MM-DD) Filter by slot date
doctor_uuid string Filter by doctor UUID

Response 200

{
  "success": true,
  "data": [
    {
      "uuid": "appt-uuid",
      "patient_name": "محمد رضایی",
      "patient_mobile": "09123456789",
      "doctor_uuid": "doctor-uuid",
      "doctor_name": "دکتر علی احمدی",
      "slot_start": 1718438400,
      "slot_end": 1718439600,
      "appointment_date": "2025-06-15",
      "appointment_time": "09:00",
      "end_time": "09:20",
      "status": "confirmed",
      "version": 1,
      "created_at": "2025-06-14T10:30:00+03:30"
    }
  ],
  "meta": { "totalRecords": 47, "totalPages": 1, "currentPage": 1 }
}

Status values: pending | confirmed | completed | cancelled_by_doctor | cancelled_by_user | no_show | expired


POST /api/v1/admin/appointment

Create a new appointment for a patient identified by mobile number.

Permission: ROLE_ADMIN

Request Body

{
  "doctor_uuid": "doctor-uuid",
  "slot_start": 1718438400,
  "slot_end": 1718439600,
  "patient_mobile": "09123456789",
  "note": "optional note"
}

Response 201

{
  "success": true,
  "data": {
    "uuid": "appt-uuid",
    "slot_start": 1718438400,
    "slot_end": 1718439600,
    "status": "pending"
  }
}

Error Responses

Code HTTP Description
VALIDATION 422 Missing required fields
DOCTOR_NOT_FOUND 404 Doctor UUID not found
USER_NOT_FOUND 404 No user with that mobile number
SLOT_TAKEN 409 Slot already booked

Payment Management

GET /api/v1/admin/payments

List all payments.

Permission: ROLE_ADMIN

Query Parameters

Param Type Required Description
page integer Default: 1
limit integer Default: 20
status string "pending", "paid", "failed", "cancelled"

Response 200

{
  "success": true,
  "data": [
    {
      "uuid": "...",
      "order_id": "CLINICPRO-...",
      "amount_rials": 500000,
      "status": "paid",
      "gateway": "mellat",
      "created_at": 1717000000
    }
  ],
  "meta": { "totalRecords": 7800, "totalPages": 390, "currentPage": 1 }
}

Settlement Management

GET /api/v1/admin/settlements

List all settlement requests.

Permission: ROLE_ADMIN

Query Parameters

Param Type Required Description
page integer Default: 1
limit integer Default: 20
status string "pending", "approved", "rejected"

Response 200

{
  "success": true,
  "data": [
    {
      "uuid": "...",
      "user": { "uuid": "...", "real_name": "دکتر علی احمدی" },
      "amount_rials": 1000000,
      "status": "pending",
      "bank_account": { "bank_name": "بانک ملت", "owner_name": "..." },
      "created_at": 1717000000
    }
  ],
  "meta": { "totalRecords": 45, "totalPages": 3, "currentPage": 1 }
}

To approve or reject, use the Settlement API: POST /api/v1/settlement/{uuid}/approve or /reject


Representation Management

GET /api/v1/admin/representations

List all representations.

Permission: ROLE_ADMIN

Query Parameters

Param Type Required Description
page integer Default: 1
limit integer Default: 20
search string Search by name
city_id integer Filter by city

Response 200

Paginated representation list.


Secretary Management

GET /api/v1/admin/secretaries

List all secretaries.

Permission: ROLE_ADMIN

Query Parameters

Param Type Required Description
page integer Default: 1
limit integer Default: 20
search string Search by mobile

Response 200

Paginated secretary list with linked doctor info.


Rating & Comment Management

GET /api/v1/admin/rates

List all ratings.

Permission: ROLE_ADMIN

Query Parameters

Param Type Required Description
page integer Default: 1
limit integer Default: 20
search string Search by doctor/patient

GET /api/v1/admin/comments

List all comments (all statuses).

Permission: ROLE_ADMIN

Query Parameters

Param Type Required Description
page integer Default: 1
limit integer Default: 20
search string Search in body
status string "pending", "approved", "rejected"

To approve/reject comments, use the Rating API: POST /api/v1/admin/comment/{uuid}/approve or /reject


SMS Management (Admin)

GET /api/v1/admin/sms/logs

List SMS send logs.

Permission: ROLE_ADMIN

Query Parameters

Param Type Required Description
page integer Default: 1
limit integer Default: 20

Response 200

{
  "success": true,
  "data": [
    {
      "id": 1,
      "mobile": "09123456789",
      "message": "کد تأیید: 123456",
      "provider": "kavenegar",
      "success": true,
      "created_at": 1717000000
    }
  ],
  "meta": { "totalRecords": 5000, "totalPages": 250, "currentPage": 1 }
}

GET /api/v1/admin/sms/templates

List all SMS templates.

Permission: ROLE_ADMIN

Response 200

{
  "success": true,
  "data": [
    {
      "uuid": "...",
      "name": "تأیید نوبت",
      "status": "approved",
      "provider_code": "verify_appointment",
      "created_at": 1717000000
    }
  ]
}

To create/approve/reject templates, see sms.md


Clinic Invitation Management

See clinic-invitation.md for full endpoint details.

Endpoint Description
POST /api/v1/admin/clinic/{uuid}/invite-doctor Send invitation
GET /api/v1/admin/clinic/{uuid}/invitations List invitations
POST /api/v1/admin/clinic/invitation/{invUuid}/resend Resend SMS
PATCH /api/v1/admin/clinic/invitation/{invUuid}/status Change status
DELETE /api/v1/admin/clinic/invitation/{invUuid} Delete

Settings

GET /api/v1/admin/settings

Returns all site configuration values.

Response 200

{
  "success": true,
  "data": {
    "commission_enabled": "0",
    "commission_percent": "0",
    "site_name": "ClinicPro",
    "support_phone": "",
    "max_cancel_hours_before": "24",
    "appointment_reminder_hours": "2"
  }
}

All values are strings. Missing keys return their default values.

PATCH /api/v1/admin/settings

Update one or more settings. Unknown keys are silently ignored.

Request body (partial update — send only keys to change):

{
  "commission_enabled": "1",
  "commission_percent": "5",
  "site_name": "کلینیک‌پرو"
}

Response 200 — same shape as GET, returns all settings after save.

Commission rules:

  • commission_enabled"1" = active, "0" = inactive
  • commission_percent — integer string, 0100
  • Commission applies only to regular users (booked_by = user); secretaries are exempt