Commit Graph
17 Commits
Author SHA1 Message Date
hamed e6267080b2 feat: Enhance insurance billing system to support supplementary insurance
- Updated CoverageRule and related entities to include franchise_percent instead of franchise_rials.
- Modified Appointment entity to carry supplementary insurance ID alongside base insurance.
- Implemented SessionBillingService to ensure finalized invoices for insured patient sessions.
- Created InvoiceFinalized event to trigger claims creation upon invoice finalization.
- Added BackfillMissingClaimsCommand to generate claims for finalized invoices without existing claims.
- Developed tests to validate the new functionality for supplementary insurance handling in appointments and claims.
2026-07-29 19:57:02 +03:30
hamedandClaude Opus 5 1f58b1b9b3 feat(insurance): bill an appointment with a chosen service kind and insurance
An appointment can now carry the insurance it is billed with: the service kind
(outpatient/inpatient) and the basic insurance. Confirming it no longer hands the
whole amount to the patient — the visit is split through BillingCalculator with the
coverage percent of that service kind, and the choice travels to the encounter and
the invoice built from it.

The enabled service kinds are a tenant-wide setting (all of that tenant's
insurances share it), so a tenant covering only one kind is never asked which one:
the panel resolves it the same way the server does.

- add tenant_service_category_settings + TenantServiceCategoryService, exposed on
  the existing insurance-pricing endpoint (service_categories,
  default_service_category); at least one kind must stay enabled
- add appointments.insurance_service_category / insurance_base_id with
  AppointmentInsuranceService validating them against the tenant's own settings
  and active contracts (basic only), accepted by PATCH and by confirm
- snapshot the kind on patient_sessions and invoices; the visit's coverage rule is
  resolved per kind (services keep using their own ServiceItem.service_category)
- lib/insuranceShares becomes the single client-side mirror of BillingCalculator,
  shared by the confirm modal, the appointment edit page and the session form
- surface the selection: confirm modal (with live shares), turns timeline chip,
  appointment edit page, patient record service card and invoice summary
- the session form shows the insurance block whenever the tenant has an active
  contract and prefills the patient's own insurance, so it can be changed
- fix: the confirm modal showed a zero visit price when the appointment had none —
  it now falls back to the tenant's free-visit price like the server
- fix: useServiceCategories read one level too shallow, so Persian labels never
  arrived and raw enum keys leaked into the contract summary
- fix: BlogsPage test asserted the public blogs endpoint after the page moved to
  the admin one

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 17:50:14 +03:30
hamedandClaude Opus 5 58c6d9ac18 feat(insurance): resolve coverage percent per service category
Base insurance is a percentage-only rule: patient share is now total minus the
base share, and the contract franchise no longer inflates it (franchise stays
meaningful for supplementary contracts only).

Coverage percentages are managed centrally by admin per service category
(outpatient/inpatient, extensible via the ServiceCategory enum). A tenant
contract may override a category, otherwise it follows the admin default live —
changing the central value immediately applies to every contract that did not
override it.

- add ServiceCategory enum + GET /api/v1/service-categories as the single source
  of the category list for every client
- add insurance_coverage_defaults (+ GET/PUT admin coverage-defaults endpoints)
  and expose coverage_defaults on the insurance list and insurance-pricing
- add tenant_insurance_category_coverage; tenant-insurances accepts optional
  category_coverages (needs insurances.update) and returns the effective
  percentages with their source
- add service_items.service_category; visits always resolve as outpatient
- drop the reverse-engineered percent from patient_share_rials in MyPatientsPage
  and align the client-side BillingCalculator mirror in CreateStep

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 16:21:19 +03:30
hamed 5c4976d65f feat: Implement secretary permissions enforcement across multiple resources
- Added SecretaryAccessChecker to manage resource access for secretaries.
- Integrated permission checks for payments, inventory, and tags in relevant controllers.
- Updated PaymentController and PaymentMethodController to enforce secretary permissions.
- Enhanced TenantTagController to check permissions for tag management actions.
- Introduced tests for secretary resource enforcement, ensuring proper access control.
- Updated DoctorSecretary entity to include inventory and tags permissions.
- Created a comprehensive audit document for secretary permissions coverage and enforcement.
- Fixed potential crashes in SecretaryDashboard when rendering without doctor data.
2026-07-23 16:36:35 +03:30
hamed 5507b42fd8 feat: implement per-doctor insurance settings in multi-doctor clinics
- Updated InsuranceModal to include doctorUuid in the payload for insurance contracts.
- Enhanced TenantInsuranceContracts to allow selection of doctors and pass doctorUuid in API requests.
- Modified InsuranceController to handle doctorUuid for tenant insurance endpoints, ensuring contracts are stored per doctor.
- Updated API documentation to reflect the new optional doctor_uuid parameter for tenant insurance endpoints.
- Added tests to verify the functionality of per-doctor insurance contracts and ensure isolation of contracts between doctors.
2026-07-21 19:21:55 +03:30
hamed 20bdc49e89 feat(claims): add tracking number and status history for claims
- Introduced `tracking_number` field in the `claims` table to store the insurance tracking number.
- Created `claim_status_logs` table to maintain a history of status changes for claims, including who made the change and when.
- Implemented `ClaimStatusLog` entity and repository for managing status log entries.
- Updated `ClaimService` to log transitions and handle tracking numbers during claim submissions.
- Added new API endpoint for fetching claims by patient, including detailed claim history and status logs.
- Enhanced frontend with a new `ClaimPatientDetailPage` to display claims and their status history.
- Added tests to ensure correct aggregation of claims and proper handling of status transitions.
2026-07-18 23:38:02 +03:30
hamed 42d9ad26c5 Add tests and implementation for ServiceDetailPage and PriceInput components
- Implement PriceInput component tests to validate Persian and Arabic numeral handling, input formatting, and controlled behavior.
- Create ServiceDetailPage component with detailed service information, including pricing, insurance coverage, and editing capabilities.
- Add API tests for service item detail retrieval and coverage synchronization with insurance contracts.
- Ensure proper error handling and user feedback for service item retrieval and coverage management.
2026-07-18 12:10:49 +03:30
hamedandClaude Opus 4.8 c103c393f3 feat(appointment-settings): let clinics manage each member doctor's booking
The API and React components were already parameterized by doctor uuid, but 14
copy-pasted identity checks limited every endpoint to "the doctor themselves or
an admin", so a clinic owner could not touch a member doctor's booking setup.

- Replaces those 14 checks with one denyDoctorAccess() that also admits the
  owner of a clinic the doctor belongs to, and a member doctor holding the
  clinic's appointment_settings permission (view for GET, update for writes).
  A doctor's own settings short-circuit before any permission lookup.
- Moves ScheduleSection and its tabs out of DoctorDetailPage into
  components/schedule/ScheduleSection.tsx so the doctor panel and the new
  clinic page render the same module instead of one page importing another.
  Pure relocation — no logic changed.
- Adds ClinicAppointmentSettingsPage: one tab per clinic doctor, each rendering
  that same section. The tab wrapper is keyed by doctor uuid so in-progress
  schedule edits cannot leak onto the wrong doctor.
- insurance-pricing accepts an optional doctor_uuid (query on GET, body on PUT)
  under the same access rule, so the visit-price card works inside the clinic
  tabs. Fixes saveInsurancePricing calling getInsurancePricing with the wrong
  argument by extracting the shared pricingPayload().

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 10:02:27 +03:30
hamed a0ddb4c0d1 feat: add visit price requirement feature
- Introduced a new boolean flag `require_visit_price` in the `EntityInsurancePricing` to enforce visit price for appointments.
- Updated the appointment creation endpoints to validate `visit_price_rials` based on the new flag.
- Added `visit_price_rials` field to the `Appointment` entity to store the visit price.
- Enhanced the `PatientService` to validate visit price during session creation.
- Updated API documentation to reflect changes in appointment and insurance pricing.
- Implemented a new service `VisitPriceRequirementResolver` to determine if a visit price is required for a doctor based on their pricing settings.
- Added migrations to update the database schema for the new fields.
2026-07-16 19:44:30 +03:30
hamedandClaude Opus 4.8 d7cb9ea5a3 feat(insurance): redesign insurance management page to match Figma
Rebuild the /admin/insurance-pricing contracts UI to the Figma "مدیریت بیمه"
design and inject the coverage/franchise/ceiling fields the design omitted.

Backend:
- Add contract-level `kind` column to TenantInsurance (basic|supplementary),
  defaulting to the catalog type; migration Version20260715093358.
- POST/PATCH /billing/tenant-insurances now accept effective_from,
  effective_to, kind; PATCH also toggles is_active without clobbering the
  user-set effective_to (unlike DELETE/deactivate).
- List returns the latest version of every insurance (active + inactive) via
  TenantInsuranceRepository::findLatestByTenant, for the فعال/غیرفعال toggle.

Frontend:
- New InsuranceModal (ui/Modal + SearchableSelect + PersianDateInput) with the
  seven fields; submit "ثبت بیمه".
- TenantInsuranceContracts rebuilt: header + search box, desktop table
  (ردیف/نام/کد/نوع/وضعیت/عملیات) and mobile cards, status toggle -> PATCH.
- utils: isoToUnix/unixToIso helpers for contract dates.

Tests: TenantInsuranceContractApiTest (create/edit/toggle/list, 5 cases),
InsuranceModal + TenantInsuranceContracts vitest suites, docs/api updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 13:23:38 +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 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
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
hamed 69beb7b944 feat(insurance): add insurance coverage flag to selected services and update coverage logic 2026-06-24 06:09:05 +03:30
hamed 27840da78d feat: integrate insurance coverage management for clinic services
- Updated NewSessionPage to calculate patient share based on insurance coverage rules.
- Refactored billing calculations to utilize new patientShareOf function for service items.
- Enhanced API documentation to reflect changes in service coverage structure.
- Implemented ServiceInsuranceModal for managing insurance coverage per service.
- Added UI components for displaying and editing insurance coverage details.
- Removed obsolete toggle switch styles and adjusted CSS for new components.
- Ensured backend endpoints support both service_item_id and service_item_uuid for flexibility.
2026-06-24 04:23:50 +03:30
hamedandClaude Opus 4.8 89191eee57 feat: insurance & medical billing system (6 phases)
Multi-tenant insurance contracts, service coverage, versioned tariffs,
invoice calculation, and insurance claims with debt reporting.

- TenantInsurance: per-tenant insurance contracts (coverage/franchise/ceiling,
  versioning, soft-deactivate) + active guard
- ServiceItem.insuranceCovered + TenantServiceCoverage per-service overrides
- Tariff: versioned yearly tariffs with fallback to ServiceItem price
- Billing domain: Money/ShareBreakdown VOs, BillingCalculator (unit-tested),
  Invoice/InvoiceItem aggregate, InvoiceService.createFromSession
- Claim/ClaimItem with state machine (pending->submitted->approved/rejected->paid),
  ClaimService, insurance-debt report
- ClaimSubmitterInterface + ManualClaimSubmitter (future insurance API ready)
- Admin UI: insurance-pricing page, claims page, service tariff modal,
  service insurance toggle; routes + sidebar entries
- Architecture doc + billing/insurance/clinic-services API docs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 15:05:24 +03:30
hamed cced85456a Add API documentation for Representation, Secretary, Settlement, SMS, Specialty, Tag, and User Profile endpoints 2026-06-11 10:27:27 +03:30