Files
clinicpro/docs/api/README.md
T
hamedandClaude Opus 4.8 00cb9aaa1a feat(admin): normalize Persian/Arabic digits in every numeric field
Users typing on a Persian keyboard produced two distinct failures. Fields with
type="number" silently returned an empty string — the browser rejects Persian
digits, so the value was lost and saved as empty or zero. Text fields passed the
Persian characters straight through to the database, where a mobile stored as
۰۹۱۲… never matches 09… again. The secretary form hit the second case with no
validation at all.

Frontend:
- Adds digitsOnly() and the national-code schemas to lib/utils, plus lib/forms
  with numericField()/latinDigitsField() wrappers for React Hook Form fields.
- Converts every type="number" input to type="text" inputMode="numeric" with
  digit normalization; none remain. Fields that legitimately carry non-digits
  (sheba, landline) only get the digits translated, keeping IR and separators.
- Points the patient national-code and mobile schemas at the shared normalizing
  schemas, which accept Persian input instead of rejecting it.
- Drops two duplicate local digit converters in favour of the shared helper.

Backend:
- Adds NumericFieldNormalizerSubscriber, translating digits in whitelisted
  numeric keys of JSON request bodies under /api/v1/ before controllers run, so
  nobat724_front and clinic-pro-tauri are covered too. Translation only — no
  characters are stripped, non-string values and other keys are untouched.

Three component tests asserted on role="spinbutton" and numeric input values;
both are properties of type="number", so they were updated to match the new
text inputs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 10:38:56 +03:30

5.1 KiB
Raw Blame History

ClinicPro — API Documentation Index

Base URL: https://clinic-pro.ddev.site
API Prefix: /api/v1
Swagger UI: https://clinic-pro.ddev.site/api/doc — user: admin / pass: clinic123


Authentication

All protected endpoints require:

Authorization: Bearer <JWT_TOKEN>
Role Description
PUBLIC No token required
AUTH Any valid JWT
ROLE_ADMIN Admin user
ROLE_DOCTOR Doctor user
ROLE_CLINIC Clinic owner
ROLE_SECRETARY Secretary

Standard Response Envelope

// Success
{ "success": true, "data": { ... } }

// Paginated
{ "success": true, "data": [...], "meta": { "totalRecords": 100, "totalPages": 5, "currentPage": 1 } }

// Error
{ "success": false, "data": null, "errors": [{ "code": "ERR_XXX_000", "message": "..." }] }

Persian digit normalization (global)

Persian (۰) and Arabic (٠) digits sent in numeric request fields are translated to Latin server-side, before the controller runssrc/Shared/EventSubscriber/NumericFieldNormalizerSubscriber.php. Every client benefits: the React admin panel, nobat724_front, and clinic-pro-tauri.

Applies to POST / PUT / PATCH requests under /api/v1/ with a JSON body, recursively through nested arrays.

Normalized keys:

mobile, mobile_number, telephone, phone, notification_mobile,
national_code, postal_code,
card_number, account_number, sheba, shaba, iban,
price_rials, amount_rials, amount, free_visit_price_rials,
insurance_price_rials, patient_share_rials, visit_price_rials,
duration_minutes, duration, commission_percent, coverage,
coverage_percent, franchise, ceiling, tax_percent,
base_insurance_discount_percent, supplementary_discount_percent

Only digits are translated — no characters are stripped, so IR in a sheba and - in a landline survive. Non-string values (int, bool, null) and keys outside the list are untouched, so a name like منشی شماره ۲ keeps its Persian digit.

// request
{ "mobile_number": "۰۹۱۲۳۴۵۶۷۸۹", "national_code": "۰۰۱۲۳۴۵۶۷۸", "name": "منشی شماره ۲" }

// what the controller sees
{ "mobile_number": "09123456789", "national_code": "0012345678", "name": "منشی شماره ۲" }

Adding a new numeric field to any endpoint? Add its key to NUMERIC_KEYS in the subscriber, otherwise Persian digits reach the database.


Modules

File Domain Endpoints
auth.md Authentication — OTP, Login, JWT 8
doctor.md Doctor profile & addresses 11
clinic.md Clinics 7
clinic-invitation.md Doctor invitations to clinics 8
appointment.md Appointments & slot booking 6
appointment-settings.md Weekly schedule, date overrides, holidays 14
payment.md Payments (Mellat / Sep) 5
settlement.md Wallet & settlement requests 7
rating.md Ratings, comments, likes 9
secretary.md Doctor secretaries 5
representation.md Representations (agents) 6
sms.md SMS send & templates 10
blog.md Blog posts 6
specialty.md Medical specialties 5
insurance.md Insurances & doctor-insurance links 10
doctor-service.md Doctor services 5
tag.md Blog tags 5
location.md Provinces & cities 10
user-profile.md User medical profile 4
admin.md Admin dashboard & management 25+

Error Code Reference

Code Message (FA) HTTP
ERR_AUTH_001 توکن JWT منقضی یا نامعتبر 401
ERR_AUTH_002 کد OTP نامعتبر 401
ERR_AUTH_003 کد OTP منقضی شده 401
ERR_AUTH_004 تعداد تلاش‌های OTP به حد مجاز رسیده 429
ERR_AUTH_005 نام کاربری یا رمز عبور اشتباه 401
ERR_AUTH_006 دسترسی ممنوع 403
ERR_VALIDATION_001 ورودی نامعتبر 422
ERR_VALIDATION_002 فیلد الزامی وارد نشده 422
ERR_NOT_FOUND_001 منبع درخواستی یافت نشد 404
ERR_CONFLICT_001 تداخل: منبع در حال استفاده 409
ERR_FORBIDDEN_001 دسترسی به این منبع مجاز نیست 403
ERR_PAYMENT_001 درگاه پرداخت در دسترس نیست 503
ERR_PAYMENT_002 مبلغ پرداخت نامعتبر 422
ERR_PAYMENT_003 وضعیت نوبت برای پرداخت مناسب نیست 422
ERR_FILE_001 فرمت فایل مجاز نیست 422
ERR_SMS_003 تمپلیت قبلاً ارسال شده 422
ERR_SECRETARY_001 پلن فعلی اجازه منشی بیشتر نمی‌دهد 422
ERR_RATE_LIMIT_001 درخواست‌های زیاد، بعداً تلاش کنید 429