Add per-clinic payment methods (bank accounts + POS/card-reader devices)
under the "مدیریت پرداخت" settings tab at /admin/my-financial, ported from
clinic-pro-tauri's mock-only PaymentManagement tab into a real persisted
feature. These records are referenceable (by uuid) from patient invoices to
record which method a service payment was made with.
Backend (new src/PaymentMethod domain):
- BankAccount + Pos entities, repositories, PaymentMethodService (validation,
ownership scoping, create/update/toggle logic).
- Thin PaymentMethodController exposing /api/v1/my/payment-methods/{bank-accounts,pos}
(GET/POST/PUT + PATCH .../status), guarded to clinic/doctor/secretary/admin.
- Migration for bank_accounts + pos_devices tables.
- Functional tests (success + validation/404/403 + empty boundaries).
- docs/api/payment-method.md.
Frontend:
- Replace MyFinancialPage content with the payment-management UI (two tabs,
tables, add/edit modals, status toggle) using the admin design system.
- usePaymentMethods hook (TanStack Query) + presentational components.
- Update page test to cover tabs, data, empty state and the add modal.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Align /admin/my-payments with the tauri /payments source (per user): the list
is now a flat, newest-first list of the tenant's recorded invoices — one row
per invoice — instead of the per-patient aggregation built from Figma.
Backend:
- replace InvoiceRepository::patientPaymentSummary aggregation with
tenantInvoices/countTenantInvoices (flat, joins patient name/national code).
- InvoiceService::patientPaymentList → tenantInvoiceList.
- BillingController: GET /api/v1/my/billing/patient-payments →
GET /api/v1/my/billing/payments returning
{ invoice_uuid, patient_uuid, patient_name, national_code, issued_at,
amount_rials, status } rows.
- node-2 patient invoices endpoint unchanged.
Frontend:
- useMyPayments: usePatientPayments → usePayments (flat PaymentRow).
- MyPaymentsPage columns match tauri DetailT: row #, avatar+name, national
code, date-time, amount paid, مشاهده (no status column); 'اضافه کردن بیمار'
links to /admin/patients/new. Filters (national code / status / Jalali date
range) kept.
Tests + docs/api/billing.md updated. Intentionally omitted tauri extras:
mobile Cards view and the advanced ModalFilter.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Port two nobat724 Figma screens into the admin SPA for the doctor/clinic
tenant panel:
- node 1 — لیست پرداختها (/admin/my-payments): per-patient payment summary
(invoice count, paid, remaining, derived status paid/unsettled/unpaid),
filters by national code / status / Jalali date range, pagination.
- node 2 — پرداختهای ثبتشده (/admin/my-payments/:patientUuid): a patient's
recorded invoices with patient header, service title, total, status badge,
and an expandable per-invoice item breakdown.
Backend (App\Billing):
- InvoiceRepository::patientPaymentSummary/countPatientPaymentSummary — DQL
aggregation grouped by patient record (arbitrary join Invoice→PatientRecord
→User), draft/void excluded, derived-status HAVING filters.
- InvoiceRepository::invoicesForPatient/count + InvoiceService methods that
shape rows and derive status.
- BillingController: GET /api/v1/my/billing/patient-payments and
GET /api/v1/my/billing/patients/{patientUuid}/invoices (thin, resolveEntity,
tenant-scoped, 403/404). Invoice::getIssuedAt / InvoiceItem::getTitle added.
- docs/api/billing.md documents both endpoints.
Frontend: useMyPayments hooks, MyPaymentsPage, MyPaymentDetailPage, routes in
App.tsx (doctor/secretary/clinic, blockClinicScope) and a sidebar entry.
Persian strings hardcoded per existing admin convention (no i18n infra).
Tests: tests/Billing/PatientPaymentsTest.php (8), useMyPayments + both page
tests (11). Note: pre-existing LoginPage.test failures are unrelated (proven
by stashing this change).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Backend:
- Add profile columns field_of_study, province_id, city_id, postal_code,
referral_source (UserProfile + migration).
- Extend PATCH /api/v1/patient/{uuid} to persist all demographic fields
and return them in the patient profile payload.
- Support editable mobile (login identifier): validation, uniqueness,
User.setMobileNumber, new ERR_PROFILE_002.
- Update docs/api/patient.md.
Frontend:
- New reusable Input, Field, and PatientRecordInfoForm (RHF + Zod).
- usePatient/useUpdatePatient hooks and patientForm mapping helpers.
- Extend the existing "info" tab in MyPatientsPage to the full field set
via the shared form (province/city/insurance options, Jalali date).
Tests: Patient entity + PATCH integration (PHPUnit); form, hooks, and
mapping helpers (Vitest).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Implement tests for Pagination, StatusBadge, ConfirmDialog, and MobileInput components.
- Add tests for useSubscription, usePaymentConfig, and usePwaInstall hooks.
- Create tests for API requests in the api module, including success and error handling.
- Add utility function tests for formatting and validating Iranian mobile numbers.
- Implement tests for BlogFormPage and BlogsPage to validate form submissions and data fetching.
- Add tests for LoginPage to ensure proper validation and state management.
- Create tests for authStore and uiStore to validate state management and functionality.
- Set up Vitest configuration and testing utilities for consistent testing environment.
- Changed the tab name from 'post-visit-review' to 'post-visit-approved' in SmsPage.
- Introduced a new query for fetching approved post-visit texts.
- Updated the UI to display approved post-visit texts and their details.
- Enhanced the API endpoint to filter SMS settings based on status (pending/approved).
- Added entity name resolution for doctors and clinics in the SMS settings.
- Updated the SmsWalletPage to include new post-visit text variables for SMS templates.
- Improved type definitions in index.ts for better clarity and consistency.