Commit Graph
100 Commits
Author SHA1 Message Date
hamed 10b0743d9a Implement ALTCHA captcha service with challenge generation and solution verification
- Added AltchaService class for managing ALTCHA captcha challenges and solutions.
- Created CaptchaController to handle API requests for generating challenges.
- Introduced CaptchaGuard for validating captcha solutions on public endpoints.
- Developed unit tests for AltchaService to ensure challenge creation and solution verification functionality.
- Implemented integration tests for the Captcha API endpoint and captcha bypass behavior when disabled.
- Added documentation for the Captcha API in the corresponding markdown file.
2026-07-10 10:31:59 +03:30
hamed 11efed4100 Add AST cache for AdminLogsTest.php with extracted nodes and edges 2026-07-10 09:48:45 +03:30
hamed 9d2023a72f fix: update JSON-LD schema and trust seal links for accuracy 2026-07-10 09:33:20 +03:30
hamed 7f9ef282c0 feat: update worker commands to ensure continuous message consumption with retry logic 2026-07-09 18:15:24 +03:30
hamed 6587b78f48 namd 2026-07-09 12:27:49 +03:30
hamed 3fbdb01add meta 2026-07-09 12:12:43 +03:30
hamed 0ad8487aac feat: add SeedDemoDataCommand for seeding production-like demo data for testing representations, doctors, clinics, users, appointments, and commissions 2026-07-09 08:07:41 +03:30
hamed 0750bc9812 feat: add multi-city representation support and domain context resolution
- Created migration to add representation_cities table and domain, is_global fields to representations.
- Implemented SiteContextController to resolve domain to site context (city | representation | unknown).
- Developed DomainContext and DomainContextResolver services for domain mapping.
- Added tests for DomainContextResolver and commission logic based on domain ownership.
2026-07-09 07:26:58 +03:30
hamed 59559e2e31 feat: enhance diagnostics script and documentation for Redis connection issues 2026-07-08 20:06:45 +03:30
hamed 880648cae8 Add AST JSON files for new documentation and scripts
- Created JSON representation for `collect-diagnostics.sh` including nodes and edges for its structure.
- Added JSON for `ops-restarts.md` detailing various sections and their relationships.
- Introduced JSON for `server-down-oom-diagnosis.md` capturing its content and connections.
2026-07-08 18:00:01 +03:30
hamed a5460cbaa9 fix: reduce memory_limit to 256M and configure PHP-FPM process management settings 2026-07-08 17:54:20 +03:30
hamed c6fa92b9a4 fix: correct phone number format in home.html.twig 2026-07-08 17:40:35 +03:30
hamed 3e98514bda fix: update contact information and WhatsApp numbers in cities.json 2026-07-08 12:25:55 +03:30
hamed ccbb1d0b1f feat: Add City entity methods and migration for title field
- Created a new JSON file for the City entity's AST representation, detailing its methods and properties.
- Added a migration to alter the cities table by adding a nullable title column.
2026-07-08 12:19:06 +03:30
hamed 94541ad609 Add JSON representation of composer.json structure with nodes and edges 2026-07-08 11:27:54 +03:30
hamed 8f4f7fc951 fix: update KavehNegarProvider to use GET requests with query parameters to resolve 431 and idle timeout errors 2026-07-08 09:51:30 +03:30
hamed 5e5455cf8c fix: add ext-soap to Dockerfile and composer.json to resolve SoapClient not found error in production 2026-07-08 09:37:19 +03:30
hamed a2c809b7de Add SmsServiceLookupOnlyTest AST and migration for template_code in sms_logs
- Created a new AST JSON file for SmsServiceLookupOnlyTest.php, detailing nodes, edges, and raw calls for better code analysis.
- Added a new migration (Version20260707202553) to alter the sms_logs table by adding a nullable template_code column.
2026-07-08 00:03:33 +03:30
hamed 2982eaa7e3 update compose 2026-07-07 15:07:34 +03:30
hamed 87f4d1695f Add CorsRegexEnvProcessor and corresponding tests
- Implemented CorsRegexEnvProcessor to build CORS origin regex from a comma-separated host list (ALLOWED_FRONTEND_HOSTS).
- Added tests for CorsRegexEnvProcessor to validate regex generation and matching behavior.
- Created JSON files for AST representation of the new classes and tests.
2026-07-07 14:58:41 +03:30
hamed 4ee1524f31 Add AST JSON files for NotificationMobileController and manifest.json; create SmsServiceLookupOnlyTest for SMS service functionality 2026-07-07 14:41:22 +03:30
hamed 57d081246f feat: update scheduler_default transport to disable retries for transient failures 2026-07-07 13:00:42 +03:30
hamed adbf401ed8 feat: update cancel mutation to set appointment status to 'cancelled_by_doctor' 2026-07-07 11:47:43 +03:30
hamed fd553b2c4f feat: add promotional video script for Clinic Pro motion graphics 2026-07-05 15:25:53 +03:30
hamed a21b0ee4ab feat: update SMS templates and logic to ensure required tokens are present for Kavenegar integration 2026-07-05 11:54:12 +03:30
hamed 87d94801f8 feat: add Kavenegar template guide and update PreRegistrationController to use appUrl 2026-07-05 11:27:10 +03:30
hamed 969dc9651f Refactor SMS sending to use KavehNegar VerifyLookup templates
- Removed SmsTextResolver dependency from multiple services and controllers.
- Introduced dispatchTemplate method in SmsService to handle SMS sending with templates.
- Updated existing SMS sending logic across various services (OtpService, PreRegistrationController, ClinicInvitationService, PaymentManager, SecretaryController, RepresentationActionController) to utilize the new dispatchTemplate method.
- Enhanced SmsMessageTemplate entity to include kavenegar_template and token_map fields.
- Created migration to add new fields to the sms_message_templates table and populate them with existing data.
- Updated SeedSmsMessageTemplatesCommand to handle new template structure.
- Added documentation for the new SMS template structure and usage.
2026-07-05 11:20:53 +03:30
hamed 828e3552c0 feat(subscription): implement effective plan logic and update free plan features 2026-07-05 10:46:31 +03:30
hamed f3ca6d844f feat: implement Portal component and refactor modals to use it for improved positioning 2026-07-04 22:05:27 +03:30
hamed ae1e40aeee feat: enable portal rendering for ImageCropModal component 2026-07-04 21:55:14 +03:30
hamed 6ade17a5b4 feat: implement OTP sending via Kavenegar VerifyLookup and add image cropping modal
- Added support for sending OTP messages using Kavenegar's VerifyLookup method, ensuring compliance with specified token formatting and template usage.
- Updated OtpService to handle new template parameters and fallback mechanisms.
- Introduced ImageCropModal component for cropping images with a user-friendly interface.
- Created utility function for cropping images and generating downloadable files.
2026-07-04 21:50:55 +03:30
hamed 1bb9cedd22 feat(auth): add optional domain parameter to send OTP code for site personalization 2026-07-04 11:01:54 +03:30
hamed 8df7b2f2e0 Implement feature X to enhance user experience and optimize performance 2026-07-03 12:42:16 +03:30
hamed 426cc500cc feat(cities): update site name for نوبت 724 to remove redundancy 2026-07-03 12:30:03 +03:30
hamed 9cabdb33e8 feat(assets): replace logo image with SVG format and update favicon; adjust theme color in manifest 2026-07-03 12:00:52 +03:30
hamed 913a8c4bfa chore(logo): remove unused logo image file 2026-07-03 12:00:48 +03:30
hamed 2a420f5899 feat(cities): update site name for نوبت 724 and add new cities (دهدشت, بهبهان) with relevant details 2026-07-03 11:37:48 +03:30
hamed 6dbbeb1c70 feat(currency): update currency display to toman in admin panel; implement conversion functions for rial to toman and vice versa 2026-07-03 10:31:17 +03:30
hamed 34d521434f feat(payment): implement expiration handling for appointment payments 2026-07-03 09:53:55 +03:30
hamed ab83a64d9d Refactor code structure for improved readability and maintainability 2026-07-02 21:40:32 +03:30
hamed 1c81c6f2e5 Add JSON files for Payment Gateway Interface and API documentation updates
- 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.
2026-07-02 21:22:14 +03:30
hamed 1804b4215d feat(sms): add doctor appointment notification SMS for paid appointments 2026-07-02 21:11:17 +03:30
hamedandClaude Opus 4.8 10be1728ff fix(payment): skip Shaparak IP allowlist for browser-redirect gateways (mellat/sep)
Mellat/SEP return the result via a user-browser redirect (POST/GET), so the
received IP is the user's, not Shaparak's. The IP allowlist therefore rejected
every real callback — including user cancel — with 'forbidden'. Security is
provided by the tamper check (RefId/SaleOrderId) and server-side verify.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 20:33:35 +03:30
hamed 27b2d66afa feat(payment): enhance Mellat gateway with sandbox support and WSDL configuration 2026-07-02 20:15:41 +03:30
hamed 1b171a82f4 feat(payment): add refund and reversal functionality to payment gateways
- Implemented `refund` and `reverse` methods in `PaymentGatewayInterface`.
- Added `PaymentRefundResult` class to handle refund operation results.
- Enhanced `MockGateway` and `SepGateway` to support refund and reversal operations.
- Updated `PaymentManager` to include `refundPayment` and `reversePayment` methods for handling refunds and reversals in transactions.
- Modified `ClinicSubscriptionRepository` and `SubscriptionService` to manage subscriptions during refunds.
- Added admin API endpoints for processing refunds and reversals.
- Updated security headers to allow form actions to the sandbox environment.
- Documented the new refund and reversal features in the API documentation.
2026-07-02 18:45:34 +03:30
hamed 6bb47d343d feat(payment): update Mellat gateway implementation and enhance security checks 2026-07-02 17:51:50 +03:30
hamed e487f7437a feat(sms-wallet): add display for SMS price with Banknotes icon 2026-07-02 17:12:50 +03:30
hamed 7f5c65129c feat(payment): unify payment flow with new pure redirect entry and update related endpoints 2026-07-02 17:08:50 +03:30
hamed c247ac2c80 feat(payment): implement PaymentManager for handling payment logic and callbacks
- Refactor PaymentController to delegate payment processing to PaymentManager.
- Add findByOrderIdForUpdate method in PaymentRepository for pessimistic locking.
- Create PaymentLog entity and repository for auditing payment actions.
- Implement startGatewayHandoff and processCallback methods in PaymentManager.
- Introduce transaction handling and logging for payment verification.
- Update payment flow to ensure idempotency and prevent race conditions.
- Enhance security by logging sensitive actions without exposing credentials.
- Update database schema with migration for payment_logs table.
- Document changes in payment flow architecture.
2026-07-02 15:36:08 +03:30
hamed ca71c49451 feat(payment): add payment detail endpoint and update payment model with order_id and patient_name
feat(appointment): enhance appointment detail page with time formatting and additional info
fix(payment): update payment query to fetch from the correct endpoint and adjust response structure
docs(api): add search parameter to payments API documentation and detail response structure
test(payment): add unit test for MellatGateway to verify null credentials handling
2026-07-02 15:10:15 +03:30
hamed 1e342a695f feat(payment): enhance payment flow with new pay endpoint and POST redirect method 2026-07-02 12:19:43 +03:30
hamed 02c34bac8e fix(modal): render Modal with React Portal to center it on the screen
fix(calendar): add type="button" to all buttons in PersianCalendar to prevent form submission
2026-07-02 11:48:34 +03:30
hamed 0a1e03d0ce feat(doctors): add activity start date field with Persian calendar in admin panel 2026-07-02 11:35:59 +03:30
hamed 4565f521c4 fix(doctors): correct city/state filters in doctor listing API 2026-07-02 11:13:16 +03:30
hamed fb90e447d8 change style css 2026-07-02 10:51:48 +03:30
hamed 6d594822bf Update SettingsPage.tsx metadata in manifest.json with new mtime and ast_hash 2026-07-02 10:27:41 +03:30
hamed 949fddc57a Add AST JSON representation for SiteConfigController.php with nodes and edges 2026-07-02 10:16:40 +03:30
hamed 70d280070b Add migration to include site_name column in cities table 2026-07-02 10:09:14 +03:30
hamed a7d5d17b9c feat(cors): update CORS settings for multi-domain production support 2026-07-01 22:57:16 +03:30
hamed cf38faff88 feat: add SmokeEndpointsCommand for endpoint health checks and logging
- Introduced SmokeEndpointsCommand to send HTTP requests to all /api and /oauth endpoints on the live site, ensuring logs are generated in the app_log table.
- Implemented non-destructive testing by using real IDs for GET requests and non-existent IDs for write operations.
- Added functionality to authenticate as an admin using a fixed OTP for development.
- Created tests for endpoint sweeps to verify that no 5xx errors occur during various conditions, including no-auth and wrong-role scenarios.
- Established RouteManifest for public success paths that should return 200 without requiring fixtures.
2026-07-01 22:37:53 +03:30
hamed 7814bcc0de feat(logging): implement log pruning functionality
- Add LogPruneService to handle the deletion of old logs based on retention settings.
- Create PruneLogsCommand to provide a console command for log pruning.
- Introduce PruneLogsMessage and PruneLogsHandler for message handling related to log pruning.
- Update the AST cache with new classes and their relationships.
2026-07-01 21:50:51 +03:30
hamed a31e8b4314 Add AST JSON files for doctor service, tag controller, and SMS log entities
- Created new AST JSON file for the doctor service API documentation, detailing endpoints, parameters, and responses.
- Added AST JSON file for the TagController, including methods and their relationships with imported classes.
- Introduced AST JSON file for the SmsLog entity, outlining its methods and dependencies.
2026-07-01 14:21:08 +03:30
hamed 3120132274 fix(footer): update copyright year in footer to 2024 2026-07-01 13:21:26 +03:30
hamed dfc86391c4 feat(payment): enhance payment configuration to include active gateways and update CORS settings 2026-07-01 12:45:18 +03:30
hamed e1eae1099c feat(audit): add comprehensive QA audit report for ClinicPro with findings and recommendations 2026-07-01 12:26:02 +03:30
hamed b366baa64c feat(sms): simplify SMS settings to use only KAVENEGAR_API_KEY from env, remove other SMS-related fields from config 2026-07-01 11:53:16 +03:30
hamed 9d8d1014f1 feat: update README to include category seeding instructions 2026-06-30 22:15:45 +03:30
hamed cc193c866b Add manifest.json for graphify-out documentation with metadata for various files 2026-06-30 22:12:26 +03:30
hamed 9eb5a03258 feat: add CategoryImporter service and SeedCategoriesCommand for seeding category data
- Implemented CategoryImporter service to handle bulk export/import logic for categories.
- Created SeedCategoriesCommand to seed category tables from JSON files in data/seed/.
- Added validation and normalization for category data during import.
- Ensured proper error handling and user feedback during the seeding process.
2026-06-30 21:58:44 +03:30
hamed 22937dfa56 feat: add CategoryImportController for bulk JSON import and export of categories
- Implemented export functionality to retrieve all rows from specified category tables.
- Developed import functionality with strict validation and referential integrity checks.
- Added error handling for various import scenarios including invalid formats and duplicate entries.
- Introduced tests for import functionality to ensure correct behavior and validation.
2026-06-30 21:51:06 +03:30
hamed 803196108c feat(logging): Implement database logging with app_log table
- Created migration to set up app_log table for storing application logs.
- Added AppLog entity and repository for ORM handling of logs.
- Developed DbLogger service to persist logs of level WARNING and above to the database while maintaining existing logging behavior.
- Implemented tests for admin log retrieval and DbLogger functionality to ensure proper logging behavior.
- Enhanced logging context sanitization for better error tracking.
2026-06-29 20:01:03 +03:30
hamed 830f7e8d0c Refactor SMS Provider Classes to Support Nullable API Key and Sender
- Updated KavehNegarProvider and RanginehProvider constructors to accept nullable API key and sender parameters.
- Adjusted methods in both providers to handle cases where the API key or sender may not be set, preventing potential TypeErrors.
- Modified community IDs in graph.json for various entities to reflect updated associations.
- Updated manifest.json with new modification times and AST hashes for KavehNegarProvider and RanginehProvider.
- Added new AST cache files for KavehNegarProvider and RanginehProvider reflecting the latest structure and relationships.
2026-06-29 19:31:42 +03:30
hamed afb5b28272 Update community IDs in graph.json and manifest.json; modify migration command in liara_pre_start.sh; enhance error logging in ExceptionSubscriber.php; add new AST cache files. 2026-06-29 19:29:10 +03:30
hamed 97958ecc7d Update Kernel.php for writable base handling, add .htaccess for routing, and modify manifest.json and liara.json
- Refactored Kernel.php to ensure writable base directory is set correctly for production on Liara.
- Added .htaccess file to forward requests to the public directory, addressing the limitation of Liara's PHP platform.
- Updated manifest.json with new modification times and AST hashes for affected files.
- Minor formatting change in liara.json to ensure proper file structure.
2026-06-29 18:24:48 +03:30
hamed c71d674d22 Add new JSON files for documentation and scripts in the graphify cache
- Created JSON file for admin SPA test suite with detailed nodes and edges.
- Added JSON file for Liara deployment documentation, including various steps and references.
- Introduced JSON files for Liara pre-build and pre-start scripts, detailing their structure and entry points.
- Included an empty JSON file indicating skipped data for non-config/manifest content.
2026-06-29 17:38:05 +03:30
hamed 9bff63bf5b fix: increase health check interval to improve reliability 2026-06-29 17:19:50 +03:30
hamed 60a62489d5 feat: add health check configuration to Liara deployment 2026-06-29 17:07:06 +03:30
hamed a3dcb92669 fix: update application name and paths in Liara configuration 2026-06-29 17:03:26 +03:30
hamed b4273cfa8b feat(deploy): configure deployment for ClinicPro on Liara PHP platform 2026-06-29 16:11:54 +03:30
hamed efee966efb feat(deploy): add deployment configuration for Liara with Docker and Supervisor 2026-06-29 15:03:30 +03:30
hamed 75dcf0d2a8 refactor: remove create_test_users.php script to streamline user creation process 2026-06-28 23:02:17 +03:30
hamed 6084dc5d6b feat: add comprehensive tests for UI components, hooks, and API interactions
- 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.
2026-06-28 22:58:15 +03:30
hamed 439bb0868e Add SVG for Open Graph image featuring brand and service details 2026-06-28 22:34:28 +03:30
hamed 1bf9035f5f feat(seo): add SEO controller for robots.txt and sitemap.xml
- Implemented SeoController with methods for serving robots.txt and sitemap.xml.
- Updated robots.txt logic to disallow access to /admin and /api paths.
- Enhanced meta tags and Open Graph data in home.html.twig for better SEO.
- Added X-Robots-Tag header in SecurityHeadersSubscriber for /admin and /api routes.
2026-06-28 22:28:07 +03:30
hamed 89451e8d3b fix(home): hide download links and update section titles for better UX 2026-06-28 22:18:01 +03:30
hamed a153bded9b Add AST JSON representation for insurance API documentation 2026-06-28 22:13:12 +03:30
hamed 8705b88270 fix(auth): update refresh token behavior to be reusable within TTL and add tests for token functionality 2026-06-28 21:57:42 +03:30
hamed c2b47d6396 delete(tests): remove RefreshTokenRotationTest as it is no longer needed 2026-06-28 21:52:52 +03:30
hamedandClaude Opus 4.8 2f3f25f48e fix(admin): paginate claims & settlement lists for backend-audit 50-cap
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>
2026-06-28 21:49:44 +03:30
hamedandClaude Opus 4.8 2764e68e60 ci: phpstan baseline + GitHub Actions workflow (E5, E4)
E5: generate phpstan-baseline.neon (the 41 pre-existing errors) and include it,
so `phpstan analyse` returns OK and the gate now fails only on NEW errors. The
baseline is meant to be burned down over time.

E4: add .github/workflows/ci.yml — MariaDB 11.8 + redis services, composer
install, JWT keygen, phpstan (baseline-clean), migrate-on-empty-db smoke, and
phpunit. Locally verified the substantive checks: a fresh empty DB migrates
cleanly to 64 tables (guards the "migrations break on empty DB" bug class),
phpstan is green, and the 70-test suite passes. The GitHub Actions service
wiring itself is first-run-pending (can't be exercised offline).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 21:25:09 +03:30
hamedandClaude Opus 4.8 66ab597efd fix(audit): low-tier — session patient-gate + 201 statuses (L1, L11) + triage
L1: PATCH /session now enforces the patient_records subscription gate like its
sibling endpoints (ownership was already checked; the feature gate was missing).
L11: POST /pre-registration and POST /representation/iban return 201 on create.

Remaining low-tier findings triaged and accepted without change (documented in
docs/audit-backlog.md): L8 is a false positive (FK auto-indexed), L6/L7/L9 are
marginal indexes, L4/L5 are small bounded N+1, L2/L3/L10/L12 are minor — none
with security/integrity impact.

Regression: tests/Audit/LowTierFixesTest (both fail without the fix).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 21:21:03 +03:30
hamedandClaude Opus 4.8 b1aaaf3d55 fix(db): purge service-item config rows on delete (M20)
Tariff and TenantServiceCoverage reference a service item by a raw int (no FK),
so deleting an item orphaned its tariffs and tenant-coverage config. Delete them
in deleteItem() before removing the item. (The in-use FK guard for invoice/claim
usage is preserved.)

Remaining M20 refs (ClinicStaff/SmsWallet/DoctorAddress.clinicId/Claim.insurance_id
on rare owner deletions) are accepted as harmless unreferenced rows; SmsWallet is
intentionally retained as a financial record. Documented in docs/audit-backlog.md.

Regression: tests/ClinicService/ServiceItemDeleteCleanupTest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 21:17:30 +03:30
hamedandClaude Opus 4.8 4b80616a17 refactor(errors): centralise legacy string error codes in ErrorCodes (M21)
~27 ad-hoc error codes (SLOT_TAKEN, USER_NOT_FOUND, VALIDATION, …) were raw
strings, so ErrorCodes::message() returned the "unknown" fallback for them.
Register all 14 distinct codes as constants with their messages and replace the
raw usages across AdminApiController, MyAppointmentsController, CategoryController,
PreRegistrationController and ClinicInvitationController.

Wire values are kept identical (verified no consumer — admin SPA, nobat724_front,
tauri — switches on these strings), so this is backward compatible.

Regression: tests/Shared/ErrorCodesTest (wire values preserved + message resolves).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 21:12:23 +03:30
hamedandClaude Opus 4.8 96a86dbfed fix(db): business-key unique constraints (M16-M19)
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>
2026-06-28 21:03:54 +03:30
hamedandClaude Opus 4.8 ccb71e4371 perf(secretary,billing): kill N+1 in secretary + claims lists (M8, M9)
M8: DoctorSecretary::toArray() lazy-loaded secretary/doctor/clinic per row;
fetch-join them in findByDoctorScope/findByClinic (shared listWithRelations()).

M9: enrichClaims() lazy-loaded each claim's items collection and called
insuranceRepo->find() per claim. Fetch-join items in findByTenant (Paginator,
fetchJoinCollection) and batch-fetch insurance names once.

Regressions (query count constant vs row count): SecretaryListNPlusOneTest,
ClaimsListNPlusOneTest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 20:43:35 +03:30
hamedandClaude Opus 4.8 61ac775175 perf(settlement,rating): paginate 3 unbounded list endpoints (M10-M12)
- M10 GET /settlement: was unbounded; add page/limit + countByUser + data.meta.
- M11 GET /admin/comments/pending: paginate findPending + countPending.
- M12 GET /comments/{doctor}: paginate the fetch-joined roots query via
  Paginator(fetchJoinCollection) + countApprovedRootsByDoctor.

All keep the existing { data: { data: [...] } } envelope and add data.meta
(backward compatible). Default limit 50 / max 100.

Regressions: SettlementListPaginationTest, CommentPaginationTest (both fail
without the limits). Also de-flaked SendCodeMobileRateLimitTest (randomised the
IP block so the persistent per-IP limiter buckets don't accumulate across runs).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 20:36:41 +03:30
hamedandClaude Opus 4.8 447482c2ea perf(db): composite index on wallet_transactions(user_id, type) (M14)
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>
2026-06-28 20:28:24 +03:30
hamedandClaude Opus 4.8 670cef24f4 fix(security): per-mobile OTP cap + refresh-token rotation (M6, M7)
M6: send-code rate-limited only per IP, so a victim's number could be
SMS-flooded from rotating IPs. Add a per-mobile bucket (same 5/hour policy)
keyed by the validated mobile.

M7: /oauth/token/refresh reused the presented refresh token verbatim (no
rotation) and never re-checked the user. The rotation infra already existed
(issueTokens mints a fresh refresh token) — the controller just discarded it.
Now revoke the presented token (single-use), issue a fresh pair, and reject a
suspended user (status != 1).

Regressions: tests/Auth/SendCodeMobileRateLimitTest,
tests/Auth/RefreshTokenRotationTest (both fail without the fix).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 20:25:22 +03:30
hamedandClaude Opus 4.8 fe6383314e fix(security): enforce ownership on 4 IDOR read/bind endpoints (M2-M5)
- M2 GET /insurance/{id}: was unguarded; now owner-or-admin (403 otherwise) —
  stops reading another doctor's negotiated price by id enumeration.
- M3 GET /clinic-pro/doctor-address/{id}: add the same owner/admin check the
  sibling PATCH/DELETE already had.
- M4 POST/PATCH /service-item: staff_uuid must belong to the caller's tenant
  (entity_type/entity_id) → 422; stops binding another tenant's staff.
- M5 appointment-settings list endpoints (date-override/holidays/
  available-locations): add the per-doctor ownership check the sibling
  single-record endpoints already enforce.

Regressions (6 negative cases fail without the fixes):
DoctorInsuranceOwnershipTest, DoctorAddressOwnershipTest,
ServiceItemStaffOwnershipTest, AppointmentSettingsListOwnershipTest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 20:17:52 +03:30
hamedandClaude Opus 4.8 23ca56b293 fix(billing): bound approved/paid amounts on claim transition (M1)
approve/pay accepted any approved_rials/paid_rials with no bounds, so the
claiming tenant could write arbitrary figures into the insurer-debt ledger
(negative, or far above the claimed total). Validate: approved ∈ [0, claimed],
paid ∈ [0, approved] → 422 otherwise. (The "force arbitrary status" half of the
finding was already prevented by Claim::canTransitionTo.)

Regression: tests/Billing/ClaimAmountBoundsTest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 20:07:19 +03:30