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>
- Created a new JSON file for the PaymentGatewayInterface.php, detailing its methods and return types.
- Added a JSON file for payment.md, documenting various API endpoints and their parameters, responses, and errors.
- Introduced a JSON file for fix-admin-modal-and-calendar.md, outlining issues and solutions related to admin modal and calendar functionalities.
GET /billing/claims and GET /settlement now return only the first 50 rows by
default (data.data unchanged, data.meta added). ClaimsPage and
RepresentationSettlementPage read the full array with no pager, so rows beyond 50
were unreachable. Add page state + ?page/limit + the existing <Pagination>
(reading data.meta.totalRecords).
No change needed for: 422 on claim approve/pay (api.ts already surfaces the
backend message via toast; the admin UI sends no amount so it's unreachable),
the owner-only appointment-settings endpoints (admin user bypasses), and refresh
rotation (authStore.refresh already persists the rotated refresh_token).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Added a new column `national_code_verified` to the `users` table.
- Normalized the `bank_account` field in the `representations` table from a single object to an array of IBANs with a default `verified` status of false.
feat(ApiIrService): implement identity verification client for api.ir
- Created `ApiIrService` to handle identity verification via api.ir.
- Implemented methods for matching national code with mobile and IBAN with national code and birth date.
- Added error handling and logging for external API requests.
- Added domain guard in CommissionService to ensure commission is calculated only when the appointment is booked under the same representation as the doctor.
- Updated RepresentationController to filter statistics by representation, ensuring accurate data is shown for each representative.
- Introduced new endpoints for the representation dashboard to provide summary statistics, doctor performance, and financial reports.
- Created new pages for RepresentationFinance and RepresentationSettlement to display financial data and allow for settlement requests.
- Added migration to include booking_representation_id in appointments for tracking the representative under which the appointment was booked.