Address wallet feedback: use the clinic's real payment infrastructure,
redesign the tab to match the admin panel, and make every wallet movement
fully auditable.
Backend:
- WalletTransaction: add createdBy (acting user) + createdByName, payment_method,
reference, status; toArray exposes them (migration Version20260716083939).
- WalletService (Settlement): balance/charge/withdraw + settleSessionFromWallet,
records actor/method/reason; insufficient balance throws ERR_WALLET_INSUFFICIENT.
- PatientController: charge/withdraw delegate to WalletService and accept
payment_method/reference; PATCH /session/{uuid} with payment_method=wallet
debits the patient's final share from the wallet (reference=session:{uuid}).
- docs/api/patient.md updated.
Frontend:
- Wallet modal redesigned to panel style (no gradient); payment method now uses
the clinic's real bank accounts + POS devices (usePaymentMethods) plus cash.
- Wallet tab: panel balance card + DataTable ledger with columns مبلغ/نوع/روش/
دلیل/ثبتکننده/تاریخ/ساعت/وضعیت + همه/واریزی/برداشت filters.
- Session card «تکمیل پرداخت» opens a payment-method chooser incl. کیف پول.
Tests: backend transparency + session-from-wallet (success/insufficient/cash);
frontend modal (real methods, toman→rials) + wallet tab + settle chooser.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add unique constraints (one migration, no dup data in either DB):
- users.email, users.national_code (M16) — NULLs still allowed.
- payments.gateway_token (M17).
- date_overrides (doctor_id, date) (M18) — was a non-unique index.
- financial_breakdowns (payment_id, source) (M19) — anti double-accounting.
Regression: tests/Database/UniqueConstraintsTest (4 duplicate-insert cases).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Helps the per-type SUM balance query. M13 (service_items.section_id) and M15
(clinic_doctor_invitations.doctor_id) were false positives — both columns carry
a FK and are therefore auto-indexed by InnoDB; verified against the live schema.
Structural regression: InfraSmokeTest::testWalletUserTypeIndexExists.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The ledger FK used ON DELETE CASCADE on a non-nullable column, so deleting a
Payment silently destroyed its immutable financial breakdown rows. Switch to
RESTRICT — a settled payment can no longer be deleted out from under its ledger.
Regression: tests/Settlement/FinancialBreakdownIntegrityTest.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
On prod (opcache.preload + prod container), getRepository(Entity::class)
returned Doctrine's default repository instead of the custom one when the
entity's #[ORM\Entity] had no repositoryClass — so custom finders like
DoctorSecretaryRepository::findAllActiveBySecretary threw BadMethodCallException,
making /oauth/userinfo return 500 after login. Declare repositoryClass explicitly
on all 25 affected entities.
Also add app:create-admin command (create/promote a ROLE_ADMIN user by mobile).
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 new configuration keys for appointment and upgrade commissions, tax settings, and SMS panel fee in SiteConfigController and SiteConfigRepository.
- Introduced CommissionService to handle commission calculations for appointments and subscriptions, including tax deductions and SMS fees.
- Created FinancialBreakdown entity and repository to log financial transactions.
- Updated PaymentController to process commissions upon successful payments for appointments and subscriptions.
- Developed FinancialReportPage in the admin panel to display financial breakdowns and summaries.
- Added database migration for the new financial_breakdowns table.
- Add SendSmsMessage class for encapsulating SMS message data.
- Create KavehNegarProvider and RanginehProvider classes implementing SmsProviderInterface for sending SMS.
- Implement SmsLogRepository and SmsTemplateRepository for managing SMS logs and templates.
- Develop SendSmsHandler for handling SMS sending messages.
- Create SmsService to manage SMS dispatching and logging.
- Add UserProfileController for managing user profiles with CRUD operations.
- Implement UserProfile entity and repository for user profile data management.
- Update symfony.lock and bootstrap.php for project dependencies and environment setup.