# Online Clinic System Documentation

Generated from repository source for the Laravel backend, Vue web frontend, and Expo React Native mobile app. Environment secrets and `.env` values are intentionally excluded.

## System Overview

Online Clinic is a multi-tenant clinic management platform. Accounts own clinic branches, customers, patients, staff, services/products, schedules, consultations, diagnoses, prescriptions, invoices, receipts, POS sessions, inventory, reports, support tickets, public content, and subscription/payment settings. Access is controlled by login portal, roles, permissions, feature flags, platform feature flags, and subscription state.

| Layer | Implementation |
| --- | --- |
| Backend | Laravel 13 / PHP 8.3, Sanctum auth, Eloquent ORM, Dompdf, PhpSpreadsheet, PDF parser |
| Frontend | Vue 3, Vite, Vue Router, Vuestic UI, Axios, Toast UI Calendar, Leaflet, Quill |
| Mobile | Expo / React Native, React Navigation, Axios, SecureStore/AsyncStorage |
| Database | Laravel migrations define account-scoped clinic, clinical, POS, billing, reporting, support, and platform tables |

## Primary Modules

| Module | Purpose | Important Backend Entry Points |
| --- | --- | --- |
| Setup | Requirements, database setup, migrations, seeding, first account. | SetupController, InstallationService, AccountSetupService |
| Authentication and Profiles | Registration, verification, login, password reset, profile updates. | AuthController, ProfileController, UserPermissions |
| Clinic Core Records | Branches, customers, patients, staff, services/products, widgets, content CRUD. | GenericResourceController, RecordAuditor, AuditLogger |
| Scheduling and Booking | Private schedules and public/customer booking widgets. | ScheduleController, PublicBookingController, BookingAvailabilityService, ScheduleConflictService |
| Consultations | Daily queue, priority numbers, queue limits, served/cancelled flow. | ConsultationController, ConsultationService |
| Clinical Records | Diagnoses, prescriptions, medical certificate context, follow-up sync. | GenericResourceController, PrescriptionFollowUpSyncService |
| Billing and Payments | Invoices, official receipts, payment gateways, subscriptions, billing numbers. | InvoiceController, OfficialReceiptController, SubscriptionController, InvoiceService, BillingNumberService |
| POS and Inventory | POS sessions, sales, held sales, returns, voids, devices, stock movements. | PosController, InventoryController, PosService, InventoryService |
| Reports | Clinic and platform reporting plus exports/logs. | ReportController, SuperadminReportController, ClinicReportService, PlatformReportService |
| Ask Dr AI | Medical knowledge base, external AI/search, file/lab interpretation. | AskDrAiController, MedicalKnowledgeBaseService, ExternalMedicalAnswerService |
| Support | Tickets, messages, attachments, unread state. | SupportTicketController |
| Platform Admin | Accounts, users, roles, enum options, features, captcha, branding, legal, partners, backups. | SuperadminController and Superadmin* controllers |

## General Process Flowcharts

### Installation and Setup

```mermaid
flowchart TD
  A[Open /setup] --> B[Check setup/status]
  B --> C[Test database and requirements]
  C --> D[Install prepare]
  D --> E[Run migrations]
  E --> F[Seed baseline records]
  F --> G[Finalize owner account]
  G --> H[Redirect to login]
```

### Authentication and Session

```mermaid
flowchart TD
  A[Open web or mobile app] --> B{Public route?}
  B -- yes --> C[Render public page]
  B -- no --> D[Login, register, verify, or reset password]
  D --> E[AuthController validates request]
  E --> F[Issue Sanctum token and user/account metadata]
  F --> G[Client stores token/session]
  G --> H[Route guards check role, permissions, features, subscription]
  H --> I[Allowed module renders]
```

### Generic Resource CRUD

```mermaid
flowchart TD
  A[Open resource list] --> B[GET /api/{resource}]
  B --> C[GenericResourceController resolves model]
  C --> D[Apply account/customer scope, search, filters, trash]
  D --> E[Return paginated records]
  E --> F[Create, edit, delete, restore, or force delete]
  F --> G[Specialized behavior for staff, customer, product, patient, prescription]
  G --> H[RecordAuditor stamps metadata]
  H --> I[AuditLogger records action]
  I --> J[UI refreshes]
```

### Scheduling and Public Booking

```mermaid
flowchart TD
  A[Open booking widget] --> B[Resolve account and clinic codes]
  B --> C[Load branch, doctor, service, widget settings]
  C --> D[BookingAvailabilityService calculates slots]
  D --> E[Customer selects slot]
  E --> F[ScheduleConflictService checks business hours and overlap]
  F --> G[Schedule created]
  G --> H[Consultation and notification sync]
```

### Consultation Queue

```mermaid
flowchart TD
  A[Open consultations by date] --> B[Find or create daily consultation]
  B --> C[Load queue settings and patients]
  C --> D[Add patient]
  D --> E[Validate queue limit]
  E --> F[Assign next priority number]
  F --> G[Mark served or cancelled]
  G --> H[Diagnosis and invoice can follow]
```

### Diagnosis to Billing

```mermaid
flowchart TD
  A[Record diagnosis] --> B[Select billable service/product]
  B --> C[Generate invoice]
  C --> D[InvoiceService normalizes line items and totals]
  D --> E[Invoice issued to customer/patient]
  E --> F[Payment captured]
  F --> G[Official receipt generated when paid]
  G --> H[Reports aggregate revenue]
```

### POS Sale

```mermaid
flowchart TD
  A[Open POS session] --> B[Search product, barcode, patient, or prescription]
  B --> C[Add cart lines]
  C --> D[Preview totals and discounts]
  D --> E[Capture cash/card/e-wallet]
  E --> F[Create sales order, payments, transaction]
  F --> G[Inventory decrements stock]
  G --> H[Receipt shown, printed, or shared]
  H --> I[Session reconciliation and close]
```

### Inventory

```mermaid
flowchart TD
  A[Create or edit service/product] --> B{Product with inventory tracking?}
  B -- yes --> C[Inventory item exists]
  C --> D[Receive or adjust stock movement]
  D --> E[Low stock computed from reorder level]
  E --> F[POS sale decrements stock]
  B -- no --> G[Service remains billable without stock]
```

### Ask Dr AI

```mermaid
flowchart TD
  A[Submit question, symptoms, files] --> B[AskDrAiController receives payload]
  B --> C[Extract text/image context]
  C --> D[Match local medical knowledge base]
  D --> E{High confidence?}
  E -- yes --> F[Return ranked answers]
  E -- no --> G[Optional OpenAI/OpenRouter/search layer]
  G --> H[Normalize response]
  H --> I[Display educational answer]
```

### Subscription and Account Lock

```mermaid
flowchart TD
  A[Owner opens subscription settings] --> B[Build quote]
  B --> C[Create pending subscription checkout]
  C --> D[Gateway redirect or confirmation]
  D --> E[Confirm/webhook completes payment]
  E --> F[Update account subscription dates]
  F --> G[Route guards lift restrictions]
```

### Reports and Export

```mermaid
flowchart TD
  A[Open reports] --> B[Controller applies account/date scope]
  B --> C[Aggregate appointments, revenue, patients, clinical data]
  C --> D[Return dashboard JSON]
  D --> E[Export service builds report]
  E --> F[ReportLog records output]
```

### Support Tickets

```mermaid
flowchart TD
  A[Create support ticket] --> B[Store ticket and attachments]
  B --> C[Append messages]
  C --> D[Update read states and unread count]
  D --> E[Change status or assignment]
  E --> F[Delete, restore, or force delete]
```

### Public Content CMS

```mermaid
flowchart TD
  A[Superadmin manages guides, blog, FAQ, legal pages, partners] --> B[Normalize/store content blocks]
  B --> C[Public controllers expose published content]
  C --> D[Web and mobile screens fetch lists/details]
  D --> E[Visitors view content]
```

### Backup and Restore

```mermaid
flowchart TD
  A[Superadmin opens backup page] --> B[Create backup or edit schedule]
  B --> C[DatabaseBackupService exports data/files]
  C --> D[SystemBackup tracks status]
  D --> E[Download, restore, or delete backup]
```

## Database and Table Schedule

The database is defined by 77 migration files. The schedule below lists every table discovered from `Schema::create` or `Schema::table`, the migration source, current column inventory inferred from migrations, and known foreign-key-style fields.

| Table | Created In | Modified In | Columns | Foreign Keys | Notes |
| --- | --- | --- | --- | --- | --- |
| account_billing_number_settings | 2026_05_29_110000_create_account_billing_number_settings_table.php<br>2026_05_30_000003_ensure_account_billing_number_settings_table.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; unique, foreign key<br>`invoice_segments` json<br>`receipt_segments` json<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, created_by, updated_by | - |
| account_consultation_settings | 2026_06_07_000001_add_consultation_queue_limits.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; unique, foreign key<br>`default_queue_limit` integer unsigned; nullable<br>`created_at` timestamp<br>`updated_at` timestamp | account_id | - |
| account_payment_settings | 2026_05_30_000002_create_account_payment_settings_table.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; unique, foreign key<br>`currency` varchar; default 'PHP'<br>`credit_card_enabled` boolean; default false<br>`paypal_enabled` boolean; default false<br>`ewallet_enabled` boolean; default false<br>`cash_enabled` boolean; default true<br>`credit_card_provider` varchar; default 'stripe'<br>`credit_card_public_key` text; nullable<br>`credit_card_secret_key` text; nullable<br>`credit_card_webhook_secret` text; nullable<br>`paypal_client_id` text; nullable<br>`paypal_client_secret` text; nullable<br>`paypal_mode` varchar; default 'sandbox'<br>`ewallet_provider` varchar; default 'stripe'<br>`ewallet_public_key` text; nullable<br>`ewallet_secret_key` text; nullable<br>`ewallet_webhook_secret` text; nullable<br>`ewallet_methods` text; nullable<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, created_by, updated_by | - |
| accounts | 0001_01_01_000000_create_users_table.php | 2026_05_23_000002_add_booking_codes_and_widget_expiry.php<br>2026_05_23_000002_add_booking_codes_and_widget_expiry.php<br>2026_05_30_000001_add_subscription_payment_fields.php<br>2026_05_30_000001_add_subscription_payment_fields.php<br>2026_06_06_000003_add_is_test_data_to_accounts_table.php<br>2026_06_06_000003_add_is_test_data_to_accounts_table.php | `id` bigint unsigned primary key<br>`clinic_name` varchar<br>`owner_name` varchar<br>`email` varchar; unique<br>`phone` varchar; nullable<br>`status` enum; default 'trial'<br>`payment_required` boolean; default true<br>`trial_ends_at` timestamp; nullable<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`code` dropColumn<br>`subscription_ends_at` dropColumn<br>`is_test_data` dropColumn | - | 2026_05_23_000002_add_booking_codes_and_widget_expiry.php: drops or renames columns; 2026_05_30_000001_add_subscription_payment_fields.php: drops or renames columns; 2026_06_06_000003_add_is_test_data_to_accounts_table.php: drops or renames columns |
| advertisements | 2026_05_21_000002_create_clinic_feature_tables.php | - | `id` bigint unsigned primary key<br>`title` varchar<br>`content` text<br>`image_url` varchar; nullable<br>`link_url` varchar; nullable<br>`placement` enum; default 'home'<br>`starts_on` date<br>`ends_on` date<br>`status` enum; default 'active'<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker | - | - |
| audit_logs | 2026_05_21_000002_create_clinic_feature_tables.php | - | `id` bigint unsigned primary key<br>`account_id` index<br>`user_id` bigint unsigned foreign key; nullable, foreign key<br>`event` varchar<br>`subject_type` varchar; nullable<br>`subject_id` bigint unsigned; nullable<br>`properties` json; nullable<br>`ip_address` varchar; nullable<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, user_id | - |
| backup_schedules | 2026_06_06_000002_create_backup_schedules_table.php | - | `id` bigint unsigned primary key<br>`is_enabled` boolean; default false<br>`frequency` varchar; default 'daily'<br>`run_at` time; default '02:00:00'<br>`day_of_week` unsignedTinyInteger; default 1<br>`day_of_month` unsignedTinyInteger; default 1<br>`retain_count` unsignedSmallInteger; default 10<br>`last_run_at` timestamp; nullable<br>`next_run_at` timestamp; nullable<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp | updated_by | - |
| blog_posts | 2026_05_31_000001_create_blog_posts_table.php | - | `id` bigint unsigned primary key<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`title` varchar<br>`slug` varchar; unique<br>`excerpt` varchar; nullable<br>`content` longtext; nullable<br>`content_blocks` json; nullable<br>`status` enum; default 'draft'<br>`published_at` timestamp; nullable<br>`featured_image` varchar; nullable<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker | created_by, updated_by | - |
| cache | 0001_01_01_000001_create_cache_table.php | - | `key` varchar<br>`value` mediumtext<br>`expiration` bigint | - | - |
| cache_locks | 0001_01_01_000001_create_cache_table.php | - | `key` varchar<br>`owner` varchar<br>`expiration` bigint | - | - |
| clinic_branches | 2026_05_21_000001_create_clinic_core_tables.php | 2026_05_23_000002_add_booking_codes_and_widget_expiry.php<br>2026_05_23_000002_add_booking_codes_and_widget_expiry.php<br>2026_05_29_000002_add_staff_and_branch_prescription_fields.php<br>2026_05_29_000002_add_staff_and_branch_prescription_fields.php | `id` bigint unsigned primary key<br>`account_id` unique<br>`name` varchar<br>`address` text<br>`google_map_url` varchar; nullable<br>`latitude` decimal; nullable<br>`longitude` decimal; nullable<br>`bir_tin` varchar; nullable<br>`business_hours` json; nullable<br>`status` enum; default 'active'<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`code` dropColumn<br>`clinic_branches_account_code_unique` dropUnique<br>`phone` dropColumn<br>`email` varchar; nullable<br>`emergency_info` text; nullable | account_id | 2026_05_23_000002_add_booking_codes_and_widget_expiry.php: drops or renames columns; 2026_05_29_000002_add_staff_and_branch_prescription_fields.php: drops or renames columns |
| consultations | 2026_05_24_000004_create_consultations_tables.php | 2026_06_07_000001_add_consultation_queue_limits.php<br>2026_06_07_000001_add_consultation_queue_limits.php | `id` bigint unsigned primary key<br>`account_id` unique<br>`date` date<br>`status` enum; default 'active'<br>`created_at` timestamp<br>`updated_at` timestamp<br>`queue_limit` dropColumn | account_id | 2026_06_07_000001_add_consultation_queue_limits.php: drops or renames columns |
| customers | 2026_05_21_000001_create_clinic_core_tables.php | 2026_05_23_000004_add_photo_fields_to_profiles.php<br>2026_05_23_000004_add_photo_fields_to_profiles.php<br>2026_06_03_000001_add_customer_code_to_customers.php<br>2026_06_03_000001_add_customer_code_to_customers.php | `id` bigint unsigned primary key<br>`account_id` unique<br>`user_id` bigint unsigned foreign key; nullable, foreign key<br>`first_name` varchar<br>`last_name` varchar<br>`address` text; nullable<br>`phone` varchar; nullable<br>`email` varchar; nullable<br>`status` enum; default 'active'<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`photo_path` dropColumn<br>`photo_filename` varchar; nullable<br>`customer_code` dropColumn<br>`customers_account_code_unique` dropUnique | account_id, user_id | 2026_05_23_000004_add_photo_fields_to_profiles.php: drops or renames columns; 2026_06_03_000001_add_customer_code_to_customers.php: drops or renames columns |
| daily_priority_patients | 2026_05_21_000002_create_clinic_feature_tables.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`patient_id` bigint unsigned foreign key; foreign key<br>`schedule_id` bigint unsigned foreign key; nullable, foreign key<br>`priority_date` date<br>`priority_number` integer<br>`status` enum; default 'waiting'<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker | account_id, patient_id, schedule_id | - |
| diagnoses | 2026_05_21_000002_create_clinic_feature_tables.php | 2026_05_22_000003_add_diagnosis_medical_history.php<br>2026_05_22_000003_add_diagnosis_medical_history.php<br>2026_05_22_121900_ensure_diagnoses_medical_history_column.php<br>2026_05_22_121900_ensure_diagnoses_medical_history_column.php<br>2026_05_22_170000_add_service_product_id_to_diagnoses.php<br>2026_05_22_170000_add_service_product_id_to_diagnoses.php<br>2026_05_28_000001_add_diagnosis_clinical_fields.php<br>2026_05_28_000001_add_diagnosis_clinical_fields.php | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`patient_id` bigint unsigned foreign key; foreign key<br>`created_by` bigint unsigned foreign key; foreign key<br>`notes` text<br>`attachments` json; nullable<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`medical_history` dropColumn<br>`service_product_id` dropConstrainedForeignId<br>`chief_complaint` text; nullable<br>`history_of_present_illness` text; nullable<br>`vital_signs` json; nullable<br>`primary_diagnosis` varchar; nullable<br>`secondary_diagnoses` json; nullable<br>`diagnosis_notes` text; nullable<br>`assessment` text; nullable<br>`plan` text; nullable<br>`visit_date` datetime; nullable<br>`attending_doctor_id` bigint unsigned; nullable | account_id, created_by, patient_id | 2026_05_22_000003_add_diagnosis_medical_history.php: drops or renames columns; 2026_05_22_121900_ensure_diagnoses_medical_history_column.php: drops or renames columns; 2026_05_28_000001_add_diagnosis_clinical_fields.php: drops or renames columns |
| document_design_settings | 2026_05_28_000002_create_document_design_settings_table.php | 2026_05_29_100000_add_medical_certificate_document_design_fields.php<br>2026_05_29_100000_add_medical_certificate_document_design_fields.php | `id` bigint unsigned primary key<br>`account_id` unique<br>`document_type` varchar<br>`header_background_color` varchar; default '#0d6efd'<br>`header_text_color` varchar; default '#ffffff'<br>`content_background_color` varchar; default '#ffffff'<br>`page_background_color` varchar; default '#f5f6f8'<br>`footer_background_color` varchar; default '#f0f2f5'<br>`footer_text_color` varchar; default '#667085'<br>`font_family` varchar; default 'Inter, Segoe UI, sans-serif'<br>`font_style` varchar; default 'normal'<br>`accent_color` varchar; default '#20c997'<br>`created_by` bigint unsigned; nullable<br>`updated_by` bigint unsigned; nullable<br>`created_at` timestamp<br>`updated_at` timestamp<br>`template_content` dropColumn<br>`content_text_color` varchar; default '#1d2939' | account_id | 2026_05_29_100000_add_medical_certificate_document_design_fields.php: drops or renames columns |
| documentation_pages | 2026_05_21_000004_add_documentation_pages_and_restore_support.php | 2026_05_26_000004_make_documentation_pages_platform_scoped.php<br>2026_05_26_000004_make_documentation_pages_platform_scoped.php<br>2026_05_26_000004_make_documentation_pages_platform_scoped.php<br>2026_05_26_000004_make_documentation_pages_platform_scoped.php<br>2026_05_26_000004_make_documentation_pages_platform_scoped.php<br>2026_05_27_000001_add_content_blocks_to_documentation_pages.php<br>2026_05_27_000001_add_content_blocks_to_documentation_pages.php | `id` bigint unsigned primary key<br>`account_id` foreign<br>`title` varchar<br>`slug` dropUnique<br>`content` longtext; nullable<br>`status` enum; default 'draft'<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`content_blocks` dropColumn | account_id | 2026_05_27_000001_add_content_blocks_to_documentation_pages.php: drops or renames columns |
| enum_options | 2026_06_04_000001_create_enum_options_table.php | 2026_06_04_000003_add_soft_deletes_to_enum_options_table.php<br>2026_06_04_000003_add_soft_deletes_to_enum_options_table.php | `id` bigint unsigned primary key<br>`type` index<br>`slug` varchar<br>`label` varchar; nullable<br>`sort_order` unsignedSmallInteger; default 0<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker | - | - |
| failed_jobs | 0001_01_01_000002_create_jobs_table.php | - | `id` bigint unsigned primary key<br>`uuid` varchar; unique<br>`connection` index<br>`queue` varchar<br>`payload` longtext<br>`exception` longtext<br>`failed_at` timestamp | - | - |
| faq_pages | 2026_05_31_000002_create_faq_pages_table.php | - | `id` bigint unsigned primary key<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`title` varchar<br>`slug` varchar; unique<br>`content` longtext; nullable<br>`content_blocks` json; nullable<br>`status` enum; default 'draft'<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker | created_by, updated_by | - |
| feature_settings | 2026_06_05_000002_create_feature_settings_table.php | - | `id` bigint unsigned primary key<br>`feature_id` unique<br>`account_id` bigint unsigned foreign key; nullable, foreign key<br>`enabled` boolean; default true<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, feature_id, updated_by | - |
| features | 2026_06_05_000001_create_features_table.php | - | `id` bigint unsigned primary key<br>`key` varchar; unique<br>`name` varchar<br>`description` text; nullable<br>`sort_order` unsignedSmallInteger; default 0<br>`default_enabled` boolean; default true<br>`created_at` timestamp<br>`updated_at` timestamp | - | - |
| inventory_items | 2026_05_28_100000_create_pos_and_inventory_tables.php | - | `id` bigint unsigned primary key<br>`account_id` unique<br>`service_product_id` bigint unsigned foreign key; foreign key<br>`clinic_branch_id` bigint unsigned foreign key; nullable, foreign key<br>`quantity_on_hand` integer; default 0<br>`reserved_quantity` integer; default 0<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, clinic_branch_id, service_product_id | - |
| inventory_movements | 2026_05_28_100000_create_pos_and_inventory_tables.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`service_product_id` bigint unsigned foreign key; foreign key<br>`clinic_branch_id` bigint unsigned foreign key; nullable, foreign key<br>`type` enum; default 'adjustment'<br>`quantity` integer<br>`quantity_before` integer<br>`quantity_after` integer<br>`reference_type` varchar; nullable<br>`reference_id` bigint unsigned; nullable<br>`notes` text; nullable<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, clinic_branch_id, created_by, service_product_id | - |
| invoice_line_items | 2026_05_28_100000_create_pos_and_inventory_tables.php | - | `id` bigint unsigned primary key<br>`invoice_id` bigint unsigned foreign key; foreign key<br>`service_product_id` bigint unsigned foreign key; nullable, foreign key<br>`name` varchar<br>`type` varchar; nullable<br>`unit_price` decimal<br>`quantity` integer unsigned; default 1<br>`line_total` decimal<br>`created_at` timestamp<br>`updated_at` timestamp | invoice_id, service_product_id | - |
| invoices | 2026_05_21_000002_create_clinic_feature_tables.php | 2026_05_22_180000_extend_invoices_and_create_official_receipts.php<br>2026_05_22_180000_extend_invoices_and_create_official_receipts.php<br>2026_05_28_100000_create_pos_and_inventory_tables.php<br>2026_05_28_100000_create_pos_and_inventory_tables.php<br>2026_06_02_000002_add_report_query_indexes.php<br>2026_06_02_000002_add_report_query_indexes.php | `id` bigint unsigned primary key<br>`account_id` dropIndex<br>`staff_user_id` bigint unsigned foreign key; nullable, foreign key<br>`customer_id` bigint unsigned foreign key; nullable, foreign key<br>`subtotal` decimal; default 0<br>`discount` decimal; default 0<br>`total` decimal; default 0<br>`status` enum; default 'draft'<br>`items` json; nullable<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`invoice_number` varchar; nullable<br>`patient_id` bigint unsigned foreign key; nullable, foreign key<br>`diagnosis_id` bigint unsigned foreign key; nullable, foreign key<br>`tax_rate` decimal; default 0<br>`tax_amount` decimal; default 0<br>`sales_order_id` dropConstrainedForeignId<br>`pos_session_id` dropConstrainedForeignId<br>`clinic_branch_id` dropConstrainedForeignId<br>`source` dropColumn | account_id, clinic_branch_id, customer_id, diagnosis_id, patient_id, pos_session_id, sales_order_id, staff_user_id | 2026_05_22_180000_extend_invoices_and_create_official_receipts.php: drops or renames columns; 2026_05_28_100000_create_pos_and_inventory_tables.php: drops or renames columns |
| job_batches | 0001_01_01_000002_create_jobs_table.php | - | `id` varchar<br>`name` varchar<br>`total_jobs` integer<br>`pending_jobs` integer<br>`failed_jobs` integer<br>`failed_job_ids` longtext<br>`options` mediumtext; nullable<br>`cancelled_at` integer; nullable<br>`created_at` integer<br>`finished_at` integer; nullable | - | - |
| jobs | 0001_01_01_000002_create_jobs_table.php | - | `id` bigint unsigned primary key<br>`queue` varchar<br>`payload` longtext<br>`attempts` unsignedSmallInteger<br>`reserved_at` integer unsigned; nullable<br>`available_at` integer unsigned<br>`created_at` integer unsigned | - | - |
| mass_message_campaigns | 2026_06_07_000002_create_mass_message_tables.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`channel` enum<br>`subject` varchar; nullable<br>`body` longtext<br>`customer_ids` json; nullable<br>`external_recipients` json; nullable<br>`sent_count` integer unsigned; default 0<br>`failed_count` integer unsigned; default 0<br>`skipped_count` integer unsigned; default 0<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, created_by | - |
| mass_message_email_designs | 2026_06_07_000002_create_mass_message_tables.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; unique, foreign key<br>`page_background_color` varchar; default '#f2f4f7'<br>`header_background_color` varchar; default '#ffffff'<br>`header_text_color` varchar; default '#101828'<br>`header_brand_text` varchar; nullable<br>`header_logo_url` varchar; nullable<br>`header_show_view_in_browser` boolean; default true<br>`header_view_in_browser_text` varchar; default 'View in browser'<br>`hero_enabled` boolean; default true<br>`hero_background_color` varchar; default '#eff8ff'<br>`hero_icon_url` varchar; nullable<br>`content_background_color` varchar; default '#ffffff'<br>`font_family` varchar; default 'Arial, Helvetica, sans-serif'<br>`body_font_size` varchar; default '16px'<br>`heading_font_size` varchar; default '18px'<br>`body_font_weight` varchar; default '400'<br>`heading_font_weight` varchar; default '600'<br>`body_font_style` varchar; default 'normal'<br>`heading_font_style` varchar; default 'normal'<br>`body_text_color` varchar; default '#475467'<br>`heading_text_color` varchar; default '#101828'<br>`body_intro_html` longtext; nullable<br>`body_outro_html` longtext; nullable<br>`cta_enabled` boolean; default false<br>`cta_text` varchar; nullable<br>`cta_url` varchar; nullable<br>`cta_background_color` varchar; default '#2563eb'<br>`cta_text_color` varchar; default '#ffffff'<br>`trust_note_enabled` boolean; default true<br>`trust_note_text` text; nullable<br>`footer_background_color` varchar; default '#ffffff'<br>`footer_text_color` varchar; default '#667085'<br>`footer_copyright_text` varchar; nullable<br>`footer_address_text` varchar; nullable<br>`footer_show_social` boolean; default true<br>`footer_facebook_url` varchar; nullable<br>`footer_twitter_url` varchar; nullable<br>`footer_linkedin_url` varchar; nullable<br>`footer_instagram_url` varchar; nullable<br>`footer_unsubscribe_text` varchar; default 'Unsubscribe'<br>`footer_unsubscribe_url` varchar; nullable<br>`footer_privacy_text` varchar; default 'Privacy Policy'<br>`footer_privacy_url` varchar; nullable<br>`footer_contact_text` varchar; default 'Contact Us'<br>`footer_contact_url` varchar; nullable<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, created_by, updated_by | - |
| medical_treatments | 2026_05_22_140000_add_patient_treatments_and_clinical_notes.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`patient_id` bigint unsigned foreign key; foreign key<br>`name` varchar; nullable<br>`dosage` varchar; nullable<br>`frequency` varchar; nullable<br>`purpose` varchar; nullable<br>`notes` text; nullable<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, patient_id | - |
| notification_email_designs | 2026_05_25_000004_create_notification_email_designs_table.php | 2026_05_26_000002_add_font_styles_to_notification_email_designs.php<br>2026_05_26_000002_add_font_styles_to_notification_email_designs.php | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; unique, foreign key<br>`notification_setting_id` bigint unsigned foreign key; unique, foreign key<br>`page_background_color` varchar; default '#f2f4f7'<br>`header_background_color` varchar; default '#ffffff'<br>`header_text_color` varchar; default '#101828'<br>`header_brand_text` varchar; nullable<br>`header_logo_url` varchar; nullable<br>`header_show_view_in_browser` boolean; default true<br>`header_view_in_browser_text` varchar; default 'View in browser'<br>`hero_enabled` boolean; default true<br>`hero_background_color` varchar; default '#eff8ff'<br>`hero_icon_url` varchar; nullable<br>`content_background_color` varchar; default '#ffffff'<br>`font_family` varchar; default 'Arial, Helvetica, sans-serif'<br>`body_text_color` varchar; default '#475467'<br>`heading_text_color` varchar; default '#101828'<br>`body_intro_html` longtext; nullable<br>`body_outro_html` longtext; nullable<br>`cta_enabled` boolean; default false<br>`cta_text` varchar; nullable<br>`cta_url` varchar; nullable<br>`cta_background_color` varchar; default '#2563eb'<br>`cta_text_color` varchar; default '#ffffff'<br>`trust_note_enabled` boolean; default true<br>`trust_note_text` text; nullable<br>`footer_background_color` varchar; default '#ffffff'<br>`footer_text_color` varchar; default '#667085'<br>`footer_copyright_text` varchar; nullable<br>`footer_address_text` varchar; nullable<br>`footer_show_social` boolean; default true<br>`footer_facebook_url` varchar; nullable<br>`footer_twitter_url` varchar; nullable<br>`footer_linkedin_url` varchar; nullable<br>`footer_instagram_url` varchar; nullable<br>`footer_unsubscribe_text` varchar; default 'Unsubscribe'<br>`footer_unsubscribe_url` varchar; nullable<br>`footer_privacy_text` varchar; default 'Privacy Policy'<br>`footer_privacy_url` varchar; nullable<br>`footer_contact_text` varchar; default 'Contact Us'<br>`footer_contact_url` varchar; nullable<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp<br>`body_font_size` varchar; default '16px'<br>`heading_font_size` varchar; default '18px'<br>`body_font_weight` varchar; default '400'<br>`heading_font_weight` varchar; default '600'<br>`body_font_style` varchar; default 'normal'<br>`heading_font_style` varchar; default 'normal' | account_id, created_by, notification_setting_id, updated_by | 2026_05_26_000002_add_font_styles_to_notification_email_designs.php: drops or renames columns |
| notification_settings | 2026_05_21_000002_create_clinic_feature_tables.php | 2026_05_24_000001_rebuild_notification_settings_tables.php<br>2026_05_24_000001_rebuild_notification_settings_tables.php | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`default_send_email_now` boolean; default true<br>`default_send_sms_now` boolean; default false<br>`default_reminder_minutes_before` integer; default 1440<br>`email_templates` json; nullable<br>`sms_templates` json; nullable<br>`created_at` timestamp<br>`updated_at` timestamp<br>`default_send_reminder_sms` boolean; default false<br>`default_send_reminder_email` boolean; default true<br>`default_send_invoice_email_now` boolean; default true<br>`default_send_invoice_sms_now` boolean; default false | account_id | 2026_05_24_000001_rebuild_notification_settings_tables.php: drops or renames columns; 2026_05_24_000001_rebuild_notification_settings_tables.php: drops or renames columns |
| notification_template_attachments | 2026_05_24_000001_rebuild_notification_settings_tables.php | - | `id` bigint unsigned primary key<br>`notification_template_id` bigint unsigned<br>`filename` varchar<br>`file_path` varchar<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker | created_by, updated_by | - |
| notification_template_settings | 2026_05_24_000001_rebuild_notification_settings_tables.php | 2026_05_24_000002_add_target_feature_to_notification_template_settings.php<br>2026_05_24_000002_add_target_feature_to_notification_template_settings.php<br>2026_05_24_000003_add_action_type_and_schedule_type_to_notification_templates.php<br>2026_05_24_000003_add_action_type_and_schedule_type_to_notification_templates.php | `id` bigint unsigned primary key<br>`account_id` unique<br>`notification_name` varchar<br>`notification_slug` varchar<br>`template_type` enum<br>`recipient_type` enum<br>`subject` varchar; nullable<br>`content` longtext; nullable<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`target_feature` dropColumn<br>`action_type` enum; default 'now'<br>`schedule_type` enum; nullable | account_id, created_by, updated_by | 2026_05_24_000002_add_target_feature_to_notification_template_settings.php: drops or renames columns; 2026_05_24_000003_add_action_type_and_schedule_type_to_notification_templates.php: drops or renames columns |
| official_receipt_line_items | 2026_05_22_190000_create_official_receipt_line_items_table.php | - | `id` bigint unsigned primary key<br>`official_receipt_id` bigint unsigned foreign key; foreign key<br>`service_product_id` bigint unsigned foreign key; nullable, foreign key<br>`name` varchar<br>`price` decimal; default 0<br>`tax_amount` decimal; default 0<br>`discount_rate` decimal; default 0<br>`discount_amount` decimal; default 0<br>`quantity` integer unsigned; default 1<br>`created_at` timestamp<br>`updated_at` timestamp | official_receipt_id, service_product_id | - |
| official_receipts | 2026_05_22_180000_extend_invoices_and_create_official_receipts.php | 2026_05_22_190000_create_official_receipt_line_items_table.php<br>2026_05_22_190000_create_official_receipt_line_items_table.php<br>2026_06_02_000002_add_report_query_indexes.php<br>2026_06_02_000002_add_report_query_indexes.php | `id` bigint unsigned primary key<br>`account_id` dropIndex<br>`invoice_id` bigint unsigned foreign key; unique, foreign key<br>`receipt_number` varchar; nullable<br>`customer_id` bigint unsigned foreign key; nullable, foreign key<br>`patient_id` bigint unsigned foreign key; nullable, foreign key<br>`subtotal` decimal; default 0<br>`discount` decimal; default 0<br>`tax_rate` decimal; default 0<br>`tax_amount` decimal; default 0<br>`total` decimal; default 0<br>`items` json; nullable<br>`paid_at` timestamp; nullable<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker | account_id, created_by, customer_id, invoice_id, patient_id, updated_by | 2026_05_22_190000_create_official_receipt_line_items_table.php: drops or renames columns |
| partners | 2026_05_27_000002_create_partners_table.php | - | `id` bigint unsigned primary key<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`name` varchar<br>`logo_url` varchar; nullable<br>`website_url` varchar; nullable<br>`description` text; nullable<br>`sort_order` integer unsigned; default 0<br>`is_visible` boolean; default true<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker | created_by, updated_by | - |
| password_reset_tokens | 0001_01_01_000000_create_users_table.php | - | `email` varchar<br>`token` varchar<br>`created_at` timestamp; nullable | - | - |
| patient_consultations | 2026_05_24_000004_create_consultations_tables.php | - | `id` bigint unsigned primary key<br>`consultation_id` unique<br>`patient_id` bigint unsigned foreign key; foreign key<br>`schedule_id` bigint unsigned foreign key; nullable, foreign key<br>`priority_number` integer unsigned<br>`status` enum; default 'waiting'<br>`created_at` timestamp<br>`updated_at` timestamp | consultation_id, patient_id, schedule_id | - |
| patient_emergency_contacts | 2026_05_22_123700_add_patient_gender_contacts_and_insurance.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`patient_id` unique<br>`name` varchar; nullable<br>`relationship` varchar; nullable<br>`phone` varchar; nullable<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, patient_id | - |
| patient_family_history | 2026_05_22_150000_create_patient_family_history.php | - | `id` bigint unsigned primary key<br>`patient_id` unique<br>`sickness_id` bigint unsigned foreign key; foreign key<br>`created_at` timestamp<br>`updated_at` timestamp | patient_id, sickness_id | - |
| patient_insurance | 2026_05_22_123700_add_patient_gender_contacts_and_insurance.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`patient_id` unique<br>`provider` varchar; nullable<br>`policy_number` varchar; nullable<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, patient_id | - |
| patient_sickness_history | 2026_05_22_130000_create_sickness_and_patient_sickness_history.php | - | `id` bigint unsigned primary key<br>`patient_id` unique<br>`sickness_id` bigint unsigned foreign key; foreign key<br>`created_at` timestamp<br>`updated_at` timestamp | patient_id, sickness_id | - |
| patients | 2026_05_21_000001_create_clinic_core_tables.php | 2026_05_21_000007_add_patient_profile_fields.php<br>2026_05_21_000007_add_patient_profile_fields.php<br>2026_05_22_123700_add_patient_gender_contacts_and_insurance.php<br>2026_05_22_123700_add_patient_gender_contacts_and_insurance.php<br>2026_05_22_140000_add_patient_treatments_and_clinical_notes.php<br>2026_05_22_140000_add_patient_treatments_and_clinical_notes.php<br>2026_05_23_000004_add_photo_fields_to_profiles.php<br>2026_05_23_000004_add_photo_fields_to_profiles.php<br>... +2 more | `id` bigint unsigned primary key<br>`account_id` dropIndex<br>`customer_id` bigint unsigned foreign key; nullable, foreign key<br>`first_name` varchar<br>`last_name` varchar<br>`date_of_birth` date; nullable<br>`address` text; nullable<br>`phone` varchar; nullable<br>`email` varchar; nullable<br>`status` enum; default 'active'<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`blood_type` varchar; nullable<br>`mother_name` varchar; nullable<br>`father_name` varchar; nullable<br>`company_affiliated` varchar; nullable<br>`job_position` varchar; nullable<br>`job_industry` varchar; nullable<br>`gender` dropColumn<br>`surgeries` dropColumn<br>`allergies` dropColumn<br>`photo_path` dropColumn<br>`photo_filename` varchar; nullable | account_id, customer_id | 2026_05_21_000007_add_patient_profile_fields.php: drops or renames columns; 2026_05_22_123700_add_patient_gender_contacts_and_insurance.php: drops or renames columns; 2026_05_22_140000_add_patient_treatments_and_clinical_notes.php: drops or renames columns; 2026_05_23_000004_add_photo_fields_to_profiles.php: drops or renames columns |
| personal_access_tokens | 2026_05_21_000003_create_personal_access_tokens_table.php | - | `id` bigint unsigned primary key<br>`tokenable` morphs<br>`name` text<br>`token` varchar; unique<br>`abilities` text; nullable<br>`last_used_at` timestamp; nullable<br>`expires_at` timestamp; nullable<br>`created_at` timestamp<br>`updated_at` timestamp | - | - |
| platform_feature_settings | 2026_05_28_200000_create_platform_features_tables.php | - | `id` bigint unsigned primary key<br>`platform_feature_id` unique<br>`enabled` boolean; default true<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp | platform_feature_id, updated_by | - |
| platform_features | 2026_05_28_200000_create_platform_features_tables.php | - | `id` bigint unsigned primary key<br>`key` varchar; unique<br>`name` varchar<br>`description` text; nullable<br>`sort_order` integer unsigned; default 0<br>`default_enabled` boolean; default true<br>`created_at` timestamp<br>`updated_at` timestamp | - | - |
| platform_settings | 2026_05_27_000001_create_platform_settings_table.php | - | `id` bigint unsigned primary key<br>`key` varchar; unique<br>`value` json<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp | updated_by | - |
| pos_cash_drawer_events | 2026_05_30_120000_add_pos_extended_features.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`pos_session_id` bigint unsigned foreign key; nullable, foreign key<br>`sales_order_id` bigint unsigned foreign key; nullable, foreign key<br>`triggered_by` bigint unsigned foreign key; nullable, foreign key<br>`event_type` varchar; default 'manual'<br>`notes` text; nullable<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, pos_session_id, sales_order_id, triggered_by | - |
| pos_held_sales | 2026_05_31_120000_create_pos_held_sales_table.php | - | `id` bigint unsigned primary key<br>`account_id` unique<br>`pos_session_id` index<br>`clinic_branch_id` bigint unsigned foreign key; nullable, foreign key<br>`hold_reference` varchar<br>`label` varchar; nullable<br>`item_count` unsignedSmallInteger; default 0<br>`total` decimal; default 0<br>`payload` json<br>`status` enum; default 'on_hold'<br>`held_by` bigint unsigned foreign key; foreign key<br>`resumed_by` bigint unsigned foreign key; nullable, foreign key<br>`resumed_at` timestamp; nullable<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, clinic_branch_id, held_by, pos_session_id, resumed_by | - |
| pos_payment_devices | 2026_06_06_000001_add_pos_payments_devices_and_sale_actions.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`pos_register_id` bigint unsigned foreign key; nullable, foreign key<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`name` varchar<br>`device_type` varchar; default 'card_terminal'<br>`provider` varchar; nullable<br>`serial_number` varchar; nullable<br>`connection_status` enum; default 'disconnected'<br>`last_synced_at` timestamp; nullable<br>`metadata` json; nullable<br>`status` enum; default 'active'<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, created_by, pos_register_id, updated_by | - |
| pos_registers | 2026_05_28_100000_create_pos_and_inventory_tables.php | - | `id` bigint unsigned primary key<br>`account_id` unique<br>`clinic_branch_id` bigint unsigned foreign key; nullable, foreign key<br>`name` varchar<br>`code` varchar<br>`status` enum; default 'active'<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, clinic_branch_id | - |
| pos_sessions | 2026_05_28_100000_create_pos_and_inventory_tables.php | 2026_05_30_120000_add_pos_extended_features.php<br>2026_05_30_120000_add_pos_extended_features.php<br>2026_06_06_000001_add_pos_payments_devices_and_sale_actions.php<br>2026_06_06_000001_add_pos_payments_devices_and_sale_actions.php | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`pos_register_id` bigint unsigned foreign key; foreign key<br>`clinic_branch_id` bigint unsigned foreign key; nullable, foreign key<br>`opened_by` bigint unsigned foreign key; foreign key<br>`closed_by` bigint unsigned foreign key; nullable, foreign key<br>`opening_float` decimal; default 0<br>`closing_cash` decimal; nullable<br>`expected_cash` decimal; nullable<br>`status` enum; default 'open'<br>`opened_at` timestamp<br>`closed_at` timestamp; nullable<br>`notes` text; nullable<br>`created_at` timestamp<br>`updated_at` timestamp<br>`cash_variance` dropColumn<br>`card_sales_total` decimal; nullable<br>`ewallet_sales_total` decimal; nullable<br>`connected_device_id` dropConstrainedForeignId | account_id, clinic_branch_id, closed_by, opened_by, pos_register_id | 2026_05_30_120000_add_pos_extended_features.php: drops or renames columns |
| prescription_items | 2026_05_29_000001_add_prescription_template_fields.php | - | `id` bigint unsigned primary key<br>`prescription_id` bigint unsigned foreign key; foreign key<br>`sort_order` unsignedSmallInteger; default 0<br>`medicine_strength` varchar<br>`dosage_instructions` text; nullable<br>`quantity` varchar; nullable<br>`duration` varchar; nullable<br>`created_at` timestamp<br>`updated_at` timestamp | prescription_id | - |
| prescriptions | 2026_05_21_000002_create_clinic_feature_tables.php | 2026_05_22_000002_add_prescription_notes_attachments.php<br>2026_05_22_000002_add_prescription_notes_attachments.php<br>2026_05_25_000003_add_diagnosis_id_to_prescriptions.php<br>2026_05_25_000003_add_diagnosis_id_to_prescriptions.php<br>2026_05_29_000001_add_prescription_template_fields.php<br>2026_05_29_000001_add_prescription_template_fields.php | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`patient_id` bigint unsigned foreign key; foreign key<br>`doctor_user_id` bigint unsigned foreign key; foreign key<br>`medicines` text<br>`instructions` text; nullable<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`notes` dropColumn<br>`attachments` json; nullable<br>`diagnosis_id` dropConstrainedForeignId<br>`follow_up_date` dropColumn<br>`clinic_branch_id` dropConstrainedForeignId | account_id, clinic_branch_id, doctor_user_id, patient_id | 2026_05_22_000002_add_prescription_notes_attachments.php: drops or renames columns; 2026_05_29_000001_add_prescription_template_fields.php: drops or renames columns |
| report_logs | 2026_06_02_000001_create_report_logs_table.php | - | `id` bigint unsigned primary key<br>`account_id` index<br>`user_id` bigint unsigned foreign key; foreign key<br>`report_key` varchar<br>`scope` index<br>`filters` json; nullable<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, user_id | - |
| role_user | 2026_05_25_000002_create_role_user_table.php | - | `id` bigint unsigned primary key<br>`user_id` unique<br>`role_id` bigint unsigned foreign key; foreign key<br>`assigned_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp | assigned_by, role_id, user_id | - |
| roles | 2026_05_25_000001_create_roles_table.php | - | `id` bigint unsigned primary key<br>`name` varchar<br>`slug` varchar; unique<br>`description` text; nullable<br>`permissions` json; nullable<br>`is_system` boolean; default false<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker | - | - |
| sales_order_adjustments | 2026_06_06_000001_add_pos_payments_devices_and_sale_actions.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`sales_order_id` bigint unsigned foreign key; foreign key<br>`performed_by` bigint unsigned foreign key; foreign key<br>`action` enum<br>`reason` text<br>`before_snapshot` json; nullable<br>`after_snapshot` json; nullable<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, performed_by, sales_order_id | - |
| sales_order_lines | 2026_05_28_100000_create_pos_and_inventory_tables.php | 2026_05_30_120000_add_pos_extended_features.php<br>2026_05_30_120000_add_pos_extended_features.php | `id` bigint unsigned primary key<br>`sales_order_id` bigint unsigned foreign key; foreign key<br>`service_product_id` bigint unsigned foreign key; nullable, foreign key<br>`name` varchar<br>`type` varchar; nullable<br>`unit_price` decimal<br>`quantity` integer unsigned; default 1<br>`line_total` decimal<br>`created_at` timestamp<br>`updated_at` timestamp<br>`quantity_returned` dropColumn | sales_order_id, service_product_id | 2026_05_30_120000_add_pos_extended_features.php: drops or renames columns |
| sales_order_payments | 2026_06_06_000001_add_pos_payments_devices_and_sale_actions.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`sales_order_id` bigint unsigned foreign key; foreign key<br>`pos_payment_device_id` bigint unsigned foreign key; nullable, foreign key<br>`payment_mode` enum<br>`amount` decimal<br>`capture_mode` enum; default 'manual'<br>`card_brand` varchar; nullable<br>`card_last4` varchar; nullable<br>`authorization_code` varchar; nullable<br>`reference_number` varchar; nullable<br>`ewallet_provider` varchar; nullable<br>`ewallet_account` varchar; nullable<br>`device_transaction_id` varchar; nullable<br>`payment_notes` text; nullable<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, pos_payment_device_id, sales_order_id | - |
| sales_order_return_lines | 2026_05_30_120000_add_pos_extended_features.php | - | `id` bigint unsigned primary key<br>`sales_order_return_id` bigint unsigned foreign key; foreign key<br>`sales_order_line_id` bigint unsigned foreign key; foreign key<br>`quantity` integer unsigned<br>`line_refund` decimal<br>`created_at` timestamp<br>`updated_at` timestamp | sales_order_line_id, sales_order_return_id | - |
| sales_order_returns | 2026_05_30_120000_add_pos_extended_features.php | - | `id` bigint unsigned primary key<br>`account_id` unique<br>`sales_order_id` bigint unsigned foreign key; foreign key<br>`pos_session_id` bigint unsigned foreign key; nullable, foreign key<br>`performed_by` bigint unsigned foreign key; foreign key<br>`return_number` varchar<br>`refund_amount` decimal<br>`reason` text<br>`created_at` timestamp<br>`updated_at` timestamp | account_id, performed_by, pos_session_id, sales_order_id | - |
| sales_orders | 2026_05_28_100000_create_pos_and_inventory_tables.php | 2026_05_30_120000_add_pos_extended_features.php<br>2026_05_30_120000_add_pos_extended_features.php<br>2026_06_06_000001_add_pos_payments_devices_and_sale_actions.php<br>2026_06_06_000001_add_pos_payments_devices_and_sale_actions.php | `id` bigint unsigned primary key<br>`account_id` unique<br>`pos_session_id` bigint unsigned foreign key; nullable, foreign key<br>`clinic_branch_id` bigint unsigned foreign key; nullable, foreign key<br>`order_number` varchar<br>`customer_id` bigint unsigned foreign key; nullable, foreign key<br>`patient_id` bigint unsigned foreign key; nullable, foreign key<br>`staff_user_id` bigint unsigned foreign key; nullable, foreign key<br>`subtotal` decimal; default 0<br>`discount` decimal; default 0<br>`tax_rate` decimal; default 0<br>`tax_amount` decimal; default 0<br>`total` decimal; default 0<br>`status` enum; default 'completed'<br>`payment_method` varchar; default 'cash'<br>`amount_tendered` decimal; nullable<br>`change_amount` decimal; default 0<br>`notes` text; nullable<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`discount_type` varchar; default 'none'<br>`discount_percent` decimal; nullable<br>`sc_pwd_type` varchar; nullable<br>`sc_pwd_id_number` varchar; nullable<br>`total_refunded` decimal; default 0<br>`prescription_id` dropConstrainedForeignId<br>`void_reason` text; nullable<br>`voided_by` dropConstrainedForeignId<br>`voided_at` timestamp; nullable<br>`last_adjustment_reason` text; nullable<br>`last_adjusted_by` dropConstrainedForeignId<br>`last_adjusted_at` timestamp; nullable | account_id, clinic_branch_id, created_by, customer_id, last_adjusted_by, patient_id, pos_session_id, staff_user_id, updated_by, voided_by | 2026_05_30_120000_add_pos_extended_features.php: drops or renames columns; 2026_06_06_000001_add_pos_payments_devices_and_sale_actions.php: drops or renames columns |
| schedules | 2026_05_21_000001_create_clinic_core_tables.php | 2026_05_21_000006_add_schedule_type.php<br>2026_05_21_000006_add_schedule_type.php<br>2026_05_26_000003_add_reminder_sent_tracking_columns.php<br>2026_05_26_000003_add_reminder_sent_tracking_columns.php<br>2026_06_02_000002_add_report_query_indexes.php<br>2026_06_02_000002_add_report_query_indexes.php | `id` bigint unsigned primary key<br>`account_id` dropIndex<br>`clinic_branch_id` bigint unsigned foreign key; nullable, foreign key<br>`staff_user_id` bigint unsigned foreign key; nullable, foreign key<br>`doctor_user_id` bigint unsigned foreign key; nullable, foreign key<br>`customer_id` bigint unsigned foreign key; nullable, foreign key<br>`patient_id` bigint unsigned foreign key; nullable, foreign key<br>`service_product_id` bigint unsigned foreign key; nullable, foreign key<br>`title` varchar<br>`starts_at` datetime<br>`ends_at` datetime<br>`status` enum; default 'booked'<br>`send_now_email` boolean; default false<br>`send_now_sms` boolean; default false<br>`reminder_minutes_before` integer; nullable<br>`notes` text; nullable<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`schedule_type` dropColumn<br>`reminder_email_sent_at` dropColumn<br>`reminder_sms_sent_at` timestamp; nullable | account_id, clinic_branch_id, customer_id, doctor_user_id, patient_id, service_product_id, staff_user_id | 2026_05_21_000006_add_schedule_type.php: drops or renames columns; 2026_05_26_000003_add_reminder_sent_tracking_columns.php: drops or renames columns |
| service_product_staff | 2026_05_23_000001_create_widget_types_and_booking_tables.php | - | `id` bigint unsigned primary key<br>`service_product_id` unique<br>`staff_profile_id` bigint unsigned foreign key; foreign key<br>`created_at` timestamp<br>`updated_at` timestamp | service_product_id, staff_profile_id | - |
| service_products | 2026_05_21_000001_create_clinic_core_tables.php | 2026_05_23_000004_add_photo_fields_to_profiles.php<br>2026_05_23_000004_add_photo_fields_to_profiles.php<br>2026_05_28_100000_create_pos_and_inventory_tables.php<br>2026_05_28_100000_create_pos_and_inventory_tables.php | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`type` enum; default 'service'<br>`name` varchar<br>`description` text; nullable<br>`price` decimal; default 0<br>`duration_minutes` integer; nullable<br>`status` enum; default 'active'<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`image_path` dropColumn<br>`image_filename` varchar; nullable<br>`sku` dropColumn<br>`barcode` varchar; nullable<br>`cost_price` decimal; default 0<br>`track_inventory` boolean; default false<br>`reorder_level` integer unsigned; default 0<br>`unit_of_measure` varchar; default 'pcs' | account_id | 2026_05_23_000004_add_photo_fields_to_profiles.php: drops or renames columns; 2026_05_28_100000_create_pos_and_inventory_tables.php: drops or renames columns |
| sessions | 0001_01_01_000000_create_users_table.php | - | `id` varchar<br>`user_id` bigint unsigned foreign key; nullable, foreign key<br>`ip_address` varchar; nullable<br>`user_agent` text; nullable<br>`payload` longtext<br>`last_activity` integer | user_id | - |
| sickness | 2026_05_22_130000_create_sickness_and_patient_sickness_history.php | - | `id` bigint unsigned primary key<br>`sick_name` varchar<br>`detail_name` text; nullable<br>`heridetary` boolean; default false<br>`status` varchar; default 'active'<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker | - | - |
| staff_profiles | 2026_05_21_000001_create_clinic_core_tables.php | 2026_05_22_000001_add_staff_identity_fields.php<br>2026_05_22_000001_add_staff_identity_fields.php<br>2026_05_23_000004_add_photo_fields_to_profiles.php<br>2026_05_23_000004_add_photo_fields_to_profiles.php<br>2026_05_29_000002_add_staff_and_branch_prescription_fields.php<br>2026_05_29_000002_add_staff_and_branch_prescription_fields.php | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`user_id` bigint unsigned foreign key; foreign key<br>`position` varchar; default 'staff'<br>`availability` json; nullable<br>`permissions` json; nullable<br>`status` enum; default 'active'<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`first_name` dropColumn<br>`last_name` varchar; nullable<br>`email` varchar; nullable<br>`user_role` enum; default 'staff'<br>`photo_path` dropColumn<br>`photo_filename` varchar; nullable<br>`license_number` dropColumn<br>`specialty` varchar; nullable<br>`phone` varchar; nullable<br>`signature_path` varchar; nullable<br>`signature_filename` varchar; nullable | account_id, user_id | 2026_05_22_000001_add_staff_identity_fields.php: drops or renames columns; 2026_05_23_000004_add_photo_fields_to_profiles.php: drops or renames columns; 2026_05_29_000002_add_staff_and_branch_prescription_fields.php: drops or renames columns |
| subscriptions | 2026_05_21_000002_create_clinic_feature_tables.php | 2026_05_30_000001_add_subscription_payment_fields.php<br>2026_05_30_000001_add_subscription_payment_fields.php<br>2026_06_02_000002_add_report_query_indexes.php<br>2026_06_02_000002_add_report_query_indexes.php | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`billing_period` enum; default 'monthly'<br>`base_amount_per_staff` decimal; default 0<br>`active_staff_count` integer; default 0<br>`discount_percent` decimal; default 0<br>`amount_due` decimal; default 0<br>`starts_at` date; nullable<br>`ends_at` date; nullable<br>`status` dropIndex<br>`created_at` timestamp<br>`updated_at` timestamp<br>`currency` varchar; default 'USD'<br>`payment_method` enum; nullable<br>`payment_status` dropIndex<br>`gateway_provider` varchar; nullable<br>`gateway_reference` varchar; nullable<br>`gateway_payment_id` varchar; nullable<br>`paid_at` timestamp; nullable | account_id | 2026_05_30_000001_add_subscription_payment_fields.php: drops or renames columns |
| support_ticket_attachments | 2026_06_01_000003_create_support_ticket_attachments_table.php | - | `id` bigint unsigned primary key<br>`support_ticket_id` bigint unsigned foreign key; foreign key<br>`support_ticket_message_id` bigint unsigned foreign key; nullable, foreign key<br>`type` enum; default 'upload'<br>`url` varchar<br>`label` varchar; nullable<br>`sort_order` integer unsigned; default 0<br>`created_at` timestamp<br>`updated_at` timestamp | support_ticket_id, support_ticket_message_id | - |
| support_ticket_messages | 2026_06_01_000001_create_support_ticket_tables.php | - | `id` bigint unsigned primary key<br>`support_ticket_id` bigint unsigned foreign key; foreign key<br>`parent_id` bigint unsigned foreign key; nullable, foreign key<br>`user_id` bigint unsigned foreign key; foreign key<br>`body` text<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker | parent_id, support_ticket_id, user_id | - |
| support_ticket_read_states | 2026_06_01_000001_create_support_ticket_tables.php | - | `id` bigint unsigned primary key<br>`support_ticket_id` unique<br>`user_id` bigint unsigned foreign key; foreign key<br>`last_read_at` timestamp; nullable<br>`last_read_message_id` bigint unsigned; nullable<br>`created_at` timestamp<br>`updated_at` timestamp | support_ticket_id, user_id | - |
| support_tickets | 2026_06_01_000001_create_support_ticket_tables.php | 2026_06_01_000004_add_report_type_to_support_tickets_table.php<br>2026_06_01_000004_add_report_type_to_support_tickets_table.php | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; nullable, foreign key<br>`reporter_user_id` bigint unsigned foreign key; foreign key<br>`assigned_user_id` bigint unsigned foreign key; nullable, foreign key<br>`feature_reported` varchar<br>`subject` varchar<br>`description` text<br>`importance` enum; default 'medium'<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`report_type` dropColumn | account_id, assigned_user_id, created_by, reporter_user_id, updated_by | 2026_06_01_000004_add_report_type_to_support_tickets_table.php: drops or renames columns |
| system_backups | 2026_06_06_000001_create_system_backups_table.php | - | `id` bigint unsigned primary key<br>`filename` varchar<br>`disk_path` varchar<br>`size_bytes` bigint unsigned; default 0<br>`trigger` varchar; default 'manual'<br>`status` varchar; default 'pending'<br>`error_message` text; nullable<br>`table_count` integer unsigned; default 0<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`completed_at` timestamp; nullable<br>`created_at` timestamp<br>`updated_at` timestamp | created_by | - |
| transactions | 2026_05_21_000002_create_clinic_feature_tables.php | 2026_05_28_100000_create_pos_and_inventory_tables.php<br>2026_05_28_100000_create_pos_and_inventory_tables.php<br>2026_05_30_000002_create_account_payment_settings_table.php<br>2026_05_30_000002_create_account_payment_settings_table.php<br>2026_06_06_000001_add_pos_payments_devices_and_sale_actions.php<br>2026_06_06_000001_add_pos_payments_devices_and_sale_actions.php | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; foreign key<br>`invoice_id` bigint unsigned foreign key; nullable, foreign key<br>`method` enum; default 'cash'<br>`amount` decimal<br>`reference_number` varchar; nullable<br>`status` enum; default 'pending'<br>`paid_at` timestamp; nullable<br>`created_at` timestamp<br>`updated_at` timestamp<br>`pos_session_id` dropConstrainedForeignId<br>`sales_order_id` dropConstrainedForeignId<br>`gateway_provider` varchar; nullable<br>`gateway_reference` varchar; nullable<br>`gateway_payment_id` varchar; nullable<br>`payment_notes` text; nullable<br>`sales_order_payment_id` dropConstrainedForeignId | account_id, invoice_id, pos_session_id, sales_order_id | 2026_05_30_000002_create_account_payment_settings_table.php: drops or renames columns |
| upcoming_consultations | 2026_05_26_000001_create_upcoming_consultations_table.php | 2026_05_26_000003_add_reminder_sent_tracking_columns.php<br>2026_05_26_000003_add_reminder_sent_tracking_columns.php | `id` bigint unsigned primary key<br>`account_id` index<br>`patient_id` bigint unsigned foreign key; foreign key<br>`diagnosis_id` index<br>`consultation_date` date<br>`reminder_date` date<br>`status` enum; default 'pending'<br>`created_by` bigint unsigned foreign key; nullable, foreign key<br>`updated_by` bigint unsigned foreign key; nullable, foreign key<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker<br>`reminder_email_sent_at` dropColumn<br>`reminder_sms_sent_at` timestamp; nullable | account_id, created_by, diagnosis_id, patient_id, updated_by | 2026_05_26_000003_add_reminder_sent_tracking_columns.php: drops or renames columns |
| users | 0001_01_01_000000_create_users_table.php | - | `id` bigint unsigned primary key<br>`account_id` bigint unsigned foreign key; nullable, foreign key<br>`name` varchar<br>`email` varchar; unique<br>`role` enum; default 'customer'<br>`status` enum; default 'pending'<br>`verification_code` varchar; nullable<br>`verification_code_expires_at` timestamp; nullable<br>`email_verified_at` timestamp; nullable<br>`password` varchar; nullable<br>`remember_token` varchar; nullable<br>`created_at` timestamp<br>`updated_at` timestamp<br>`deleted_at` timestamp; soft delete marker | account_id | - |
| widget_settings | 2026_05_21_000002_create_clinic_feature_tables.php | 2026_05_23_000001_create_widget_types_and_booking_tables.php<br>2026_05_23_000001_create_widget_types_and_booking_tables.php<br>2026_05_23_000001_create_widget_types_and_booking_tables.php<br>2026_05_23_000002_add_booking_codes_and_widget_expiry.php<br>2026_05_23_000002_add_booking_codes_and_widget_expiry.php<br>2026_05_23_000003_update_widget_settings_styling_fields.php<br>2026_05_23_000003_update_widget_settings_styling_fields.php | `id` bigint unsigned primary key<br>`account_id` unique<br>`primary_color` varchar; default '#2563eb'<br>`button_text` varchar; default 'Book Appointment'<br>`intro_content` text; nullable<br>`time_buttons` json; nullable<br>`allow_reschedule` boolean; default true<br>`allow_cancel` boolean; default true<br>`created_at` timestamp<br>`updated_at` timestamp<br>`widget_type_id` dropColumn<br>`clinic_branch_id` dropForeign<br>`time_range` unsignedSmallInteger; default 30<br>`widget_settings_account_branch_type_unique` dropUnique<br>`expires_at` dropColumn<br>`header_footer_bg` dropColumn<br>`header_footer_font_color` varchar; default '#101828'<br>`font_style` varchar; default 'Inter, system-ui, sans-serif' | account_id, clinic_branch_id, widget_type_id | 2026_05_23_000001_create_widget_types_and_booking_tables.php: drops or renames columns; 2026_05_23_000001_create_widget_types_and_booking_tables.php: drops or renames columns; 2026_05_23_000002_add_booking_codes_and_widget_expiry.php: drops or renames columns; 2026_05_23_000003_update_widget_settings_styling_fields.php: drops or renames columns; 2026_05_23_000003_update_widget_settings_styling_fields.php: drops or renames columns |
| widget_types | 2026_05_23_000001_create_widget_types_and_booking_tables.php | - | `id` bigint unsigned primary key<br>`name` varchar<br>`slug` varchar; unique<br>`created_at` timestamp<br>`updated_at` timestamp | - | - |

## Backend API Routes

Protected routes are wrapped by Sanctum authentication, account feature checks, and subscription middleware unless specifically public. Account-owner and superadmin sections add narrower authorization rules.

| Method | URI | Controller | Function |
| --- | --- | --- | --- |
| GET | /api/setup/status | SetupController | status |
| GET | /api/network-hints | SetupController | networkHints |
| GET | /api/requirements | SetupController | requirements |
| POST | /api/test-database | SetupController | testDatabase |
| POST | /api/install/prepare | SetupController | installPrepare |
| POST | /api/install/migrate | SetupController | installMigrate |
| POST | /api/install/seed | SetupController | installSeed |
| POST | /api/install/finalize | SetupController | installFinalize |
| POST | /api/install | SetupController | install |
| GET | /api/public/app-config | PublicAppConfigController | show |
| GET | /api/public/contact | PublicContactController | show |
| POST | /api/public/contact | PublicContactController | submit |
| GET | /api/public/pages/{page} | PublicLegalPageController | show |
| GET | /api/public/partners | PublicPartnersController | index |
| GET | /api/captcha | CaptchaController | show |
| POST | /api/register | AuthController | register |
| POST | /api/verify | AuthController | verify |
| POST | /api/customer-onboard | AuthController | customerOnboard |
| POST | /api/login | AuthController | login |
| POST | /api/forgot-password | AuthController | forgotPassword |
| POST | /api/reset-password | AuthController | resetPassword |
| GET | /api/config | PublicBookingController | config |
| GET | /api/availability | PublicBookingController | availability |
| POST | /api/schedule | PublicBookingController | book |
| GET | /api// | DocumentationController | index |
| GET | /api/{slug} | DocumentationController | show |
| GET | /api// | BlogPublicController | index |
| GET | /api/{slug} | BlogPublicController | show |
| GET | /api// | FaqPublicController | index |
| GET | /api/{slug} | FaqPublicController | show |
| POST | /api/webhooks/payments/{provider} | PaymentWebhookController | handle |
| GET | /api/me | AuthController | me |
| GET | /api/profile | ProfileController | show |
| PUT | /api/profile/user | ProfileController | updateUser |
| PUT | /api/profile/password | ProfileController | updatePassword |
| PUT | /api/profile/staff | ProfileController | updateStaff |
| POST | /api/logout | AuthController | logout |
| GET | /api/dashboard/summary | DashboardController | summary |
| GET | /api/dashboard/analytics | DashboardController | analytics |
| GET | /api/dashboard/weather | DashboardController | weather |
| GET | /api/dashboard/health-news | DashboardController | healthNews |
| GET | /api/dashboard/map | DashboardController | map |
| GET | /api/dashboard/panels/activity | DashboardController | panelActivity |
| GET | /api/dashboard/panels/recent-accounts | DashboardController | panelRecentAccounts |
| GET | /api/dashboard/panels/sales-growth | DashboardController | panelSalesGrowth |
| GET | /api/dashboard/panels/incoming-appointments | DashboardController | panelIncomingAppointments |
| GET | /api/dashboard/panels/recent-appointments | DashboardController | panelRecentAppointments |
| GET | /api/dashboard/panels/recent-invoices | DashboardController | panelRecentInvoices |
| POST | /api/uploads | UploadController | store |
| GET | /api/codes/generate | CodeGenerationController | generate |
| GET | /api/select-options/{source} | SelectOptionController | index |
| GET | /api/enum-options/{type} | EnumOptionController | index |
| GET | /api/sickness | SicknessController | index |
| POST | /api/ask-dr-ai | AskDrAiController | ask |
| GET | /api/consultations | ConsultationController | index |
| GET | /api/consultations/settings | ConsultationController | settings |
| PUT | /api/consultations/settings | ConsultationController | updateSettings |
| PUT | /api/consultations/limit | ConsultationController | updateDateLimit |
| GET | /api/consultations/download | ConsultationController | download |
| GET | /api/consultations/diagnosis | ConsultationController | diagnosisForPatient |
| POST | /api/consultations/patients | ConsultationController | storePatient |
| PUT | /api/consultations/patients/{id} | ConsultationController | updatePatient |
| POST | /api/consultations/patients/{id}/served | ConsultationController | markServed |
| POST | /api/consultations/patients/{id}/cancel | ConsultationController | markCancelled |
| POST | /api/consultations/patients/{id}/generate-invoice | ConsultationController | generateInvoice |
| GET | /api/customer/booking/widgets | CustomerBookingController | widgets |
| GET | /api/schedules | ScheduleController | index |
| POST | /api/schedules | ScheduleController | store |
| GET | /api/schedules/{schedule}/reschedule-slots | ScheduleController | rescheduleSlots |
| POST | /api/schedules/{schedule}/reschedule | ScheduleController | reschedule |
| GET | /api/schedules/{schedule} | ScheduleController | show |
| PUT | /api/schedules/{schedule} | ScheduleController | update |
| POST | /api/schedules/{schedule}/cancel | ScheduleController | cancel |
| POST | /api/staff/{staff}/send-access | StaffAccessController | send |
| POST | /api/customers/{customer}/send-access | CustomerAccessController | send |
| GET | /api/subscriptions/current | SubscriptionController | current |
| POST | /api/subscriptions/quote | SubscriptionController | quote |
| POST | /api/subscriptions/checkout | SubscriptionController | checkout |
| POST | /api/subscriptions/{subscription}/confirm | SubscriptionController | confirm |
| GET | /api/payment-gateway-settings | PaymentGatewaySettingsController | show |
| PUT | /api/payment-gateway-settings | PaymentGatewaySettingsController | update |
| GET | /api/billing-number-settings | BillingNumberSettingsController | show |
| PUT | /api/billing-number-settings | BillingNumberSettingsController | update |
| POST | /api/billing-number-settings/preview | BillingNumberSettingsController | preview |
| GET | /api/billing-number-settings/next | BillingNumberSettingsController | next |
| GET | /api/mass-messages/recipients | MassMessageController | recipients |
| GET | /api/mass-messages/campaigns | MassMessageController | indexCampaigns |
| POST | /api/mass-messages/send | MassMessageController | send |
| GET | /api/mass-messages/email-design | MassMessageController | showEmailDesign |
| PUT | /api/mass-messages/email-design | MassMessageController | updateEmailDesign |
| POST | /api/mass-messages/email-design/preview | MassMessageController | previewEmailDesign |
| GET | /api/state | PosController | state |
| GET | /api/dashboard | PosController | dashboard |
| GET | /api/reconciliation | PosController | reconciliation |
| GET | /api/products/search | PosController | searchProducts |
| GET | /api/patients/search | PosController | searchPatients |
| GET | /api/prescriptions/{id}/cart | PosController | prescriptionCart |
| POST | /api/totals/preview | PosController | previewTotals |
| POST | /api/cash-drawer/open | PosController | openCashDrawer |
| GET | /api/holds | PosController | listHeldSales |
| POST | /api/holds | PosController | holdSale |
| POST | /api/holds/{id}/resume | PosController | resumeHeldSale |
| DELETE | /api/holds/{id} | PosController | discardHeldSale |
| POST | /api/sessions/open | PosController | openSession |
| POST | /api/sessions/close | PosController | closeSession |
| POST | /api/sales | PosController | completeSale |
| GET | /api/sales | PosController | salesHistory |
| GET | /api/sales/{id} | PosController | showSale |
| GET | /api/sales/{id}/receipt | PosController | saleReceipt |
| POST | /api/sales/{id}/return | PosController | returnSale |
| POST | /api/sales/{id}/void | PosController | voidSale |
| PUT | /api/sales/{id} | PosController | editSale |
| GET | /api/devices | PosController | listDevices |
| POST | /api/devices | PosController | registerDevice |
| POST | /api/devices/{id}/connect | PosController | connectDevice |
| POST | /api/devices/disconnect | PosController | disconnectDevice |
| POST | /api/devices/{id}/sync | PosController | syncDevice |
| POST | /api/devices/{id}/capture | PosController | capturePayment |
| GET | /api// | InventoryController | index |
| GET | /api/movements | InventoryController | movements |
| POST | /api/adjust | InventoryController | adjust |
| GET | /api/invoice-payments/methods | InvoicePaymentController | methods |
| POST | /api/invoices/{invoice}/pay | InvoicePaymentController | pay |
| POST | /api/invoice-payments/{transaction}/confirm | InvoicePaymentController | confirm |
| GET | /api/reports/summary | ReportController | summary |
| GET | /api/reports/revenue | ReportController | revenue |
| GET | /api/reports/appointments | ReportController | appointments |
| GET | /api/reports/patients | ReportController | patients |
| GET | /api/reports/clinical | ReportController | clinical |
| GET | /api/reports/customer-invoices | ReportController | customerInvoices |
| GET | /api/reports/outstanding-invoices | ReportController | outstandingInvoices |
| GET | /api/reports/{reportKey}/export | ReportController | export |
| GET | /api/{resource}/import-export/fields | ResourceImportExportController | fields |
| POST | /api/{resource}/import/preview | ResourceImportExportController | importPreview |
| POST | /api/{resource}/import | ResourceImportExportController | import |
| POST | /api/{resource}/export | ResourceImportExportController | export |
| GET | /api/superadmin/reports/summary | SuperadminReportController | summary |
| GET | /api/superadmin/reports/subscription-sales | SuperadminReportController | subscriptionSales |
| GET | /api/superadmin/reports/accounts-by-billing | SuperadminReportController | accountsByBilling |
| GET | /api/superadmin/reports/accounts | SuperadminReportController | accounts |
| GET | /api/superadmin/reports/accounts/{account} | SuperadminReportController | accountDetail |
| GET | /api/superadmin/reports/{reportKey}/export | SuperadminReportController | export |
| GET | /api/superadmin/accounts | SuperadminController | accounts |
| PATCH | /api/superadmin/accounts/{account} | SuperadminController | updateAccount |
| GET | /api/superadmin/accounts/{account}/logs | SuperadminController | accountLogs |
| GET | /api/superadmin/roles | SuperadminController | roles |
| POST | /api/superadmin/roles | SuperadminController | storeRole |
| PUT | /api/superadmin/roles/{role} | SuperadminController | updateRole |
| DELETE | /api/superadmin/roles/{role} | SuperadminController | destroyRole |
| GET | /api/superadmin/users | SuperadminController | users |
| POST | /api/superadmin/users | SuperadminController | storeUser |
| PUT | /api/superadmin/users/{user} | SuperadminController | updateUser |
| DELETE | /api/superadmin/users/{user} | SuperadminController | destroyUser |
| POST | /api/superadmin/users/{user}/restore | SuperadminController | restoreUser |
| DELETE | /api/superadmin/users/{user}/force | SuperadminController | forceDestroyUser |
| PUT | /api/superadmin/users/{user}/roles | SuperadminController | syncUserRoles |
| GET | /api/superadmin/enum-options | SuperadminEnumOptionController | index |
| POST | /api/superadmin/enum-options | SuperadminEnumOptionController | store |
| POST | /api/superadmin/enum-options/reorder | SuperadminEnumOptionController | reorder |
| PUT | /api/superadmin/enum-options/{id} | SuperadminEnumOptionController | update |
| DELETE | /api/superadmin/enum-options/{id} | SuperadminEnumOptionController | destroy |
| POST | /api/superadmin/enum-options/{id}/restore | SuperadminEnumOptionController | restore |
| DELETE | /api/superadmin/enum-options/{id}/force | SuperadminEnumOptionController | forceDestroy |
| GET | /api/superadmin/feature-settings | SuperadminFeatureSettingsController | index |
| PUT | /api/superadmin/feature-settings/{feature} | SuperadminFeatureSettingsController | update |
| GET | /api/superadmin/platform-feature-settings/definitions | SuperadminPlatformFeatureSettingsController | definitions |
| GET | /api/superadmin/platform-feature-settings | SuperadminPlatformFeatureSettingsController | index |
| PUT | /api/superadmin/platform-feature-settings/{platformFeature} | SuperadminPlatformFeatureSettingsController | update |
| GET | /api/superadmin/captcha-settings | SuperadminCaptchaSettingsController | show |
| PUT | /api/superadmin/captcha-settings | SuperadminCaptchaSettingsController | update |
| GET | /api/superadmin/subscription-payment-settings | SuperadminSubscriptionPaymentSettingsController | show |
| PUT | /api/superadmin/subscription-payment-settings | SuperadminSubscriptionPaymentSettingsController | update |
| GET | /api/superadmin/branding-settings | SuperadminBrandingSettingsController | show |
| PUT | /api/superadmin/branding-settings | SuperadminBrandingSettingsController | update |
| GET | /api/superadmin/contact-settings | SuperadminContactSettingsController | show |
| PUT | /api/superadmin/contact-settings | SuperadminContactSettingsController | update |
| GET | /api/superadmin/legal-pages | SuperadminLegalPagesController | show |
| PUT | /api/superadmin/legal-pages | SuperadminLegalPagesController | update |
| GET | /api/superadmin/partners | SuperadminPartnersController | index |
| PUT | /api/superadmin/partners/page-settings | SuperadminPartnersController | updatePageSettings |
| POST | /api/superadmin/partners | SuperadminPartnersController | store |
| PUT | /api/superadmin/partners/{partner} | SuperadminPartnersController | update |
| DELETE | /api/superadmin/partners/{partner} | SuperadminPartnersController | destroy |
| POST | /api/superadmin/partners/{partner}/restore | SuperadminPartnersController | restore |
| DELETE | /api/superadmin/partners/{partner}/force | SuperadminPartnersController | forceDestroy |
| GET | /api/superadmin/backups | SuperadminBackupController | index |
| POST | /api/superadmin/backups | SuperadminBackupController | store |
| GET | /api/superadmin/backups/schedule | SuperadminBackupController | showSchedule |
| PUT | /api/superadmin/backups/schedule | SuperadminBackupController | updateSchedule |
| GET | /api/superadmin/backups/{backup}/download | SuperadminBackupController | download |
| POST | /api/superadmin/backups/{backup}/restore | SuperadminBackupController | restore |
| DELETE | /api/superadmin/backups/{backup} | SuperadminBackupController | destroy |
| GET | /api/support-tickets/unread-count | SupportTicketController | unreadCount |
| GET | /api/support-tickets/assignable-users | SupportTicketController | assignableUsers |
| GET | /api/support-tickets | SupportTicketController | index |
| POST | /api/support-tickets | SupportTicketController | store |
| GET | /api/support-tickets/{supportTicket} | SupportTicketController | show |
| PUT | /api/support-tickets/{supportTicket} | SupportTicketController | update |
| DELETE | /api/support-tickets/{supportTicket} | SupportTicketController | destroy |
| POST | /api/support-tickets/{supportTicket}/restore | SupportTicketController | restore |
| DELETE | /api/support-tickets/{supportTicket}/force | SupportTicketController | forceDestroy |
| POST | /api/support-tickets/{supportTicket}/messages | SupportTicketController | storeMessage |
| POST | /api/support-tickets/{supportTicket}/read | SupportTicketController | markRead |
| GET | /api/invoices | InvoiceController | index |
| POST | /api/invoices | InvoiceController | store |
| GET | /api/invoices/{id} | InvoiceController | show |
| PUT | /api/invoices/{id} | InvoiceController | update |
| DELETE | /api/invoices/{id} | InvoiceController | destroy |
| DELETE | /api/invoices/{id}/force | InvoiceController | forceDestroy |
| POST | /api/invoices/{id}/restore | InvoiceController | restore |
| POST | /api/diagnoses/{diagnosis}/generate-invoice | InvoiceController | generateFromDiagnosis |
| GET | /api/official-receipts | OfficialReceiptController | index |
| GET | /api/official-receipts/{id} | OfficialReceiptController | show |
| PUT | /api/official-receipts/{id} | OfficialReceiptController | update |
| DELETE | /api/official-receipts/{id} | OfficialReceiptController | destroy |
| DELETE | /api/official-receipts/{id}/force | OfficialReceiptController | forceDestroy |
| POST | /api/official-receipts/{id}/restore | OfficialReceiptController | restore |
| GET | /api/upcoming-consultations | UpcomingConsultationController | index |
| POST | /api/upcoming-consultations | UpcomingConsultationController | store |
| PUT | /api/upcoming-consultations/{id} | UpcomingConsultationController | update |
| DELETE | /api/upcoming-consultations/{id} | UpcomingConsultationController | destroy |
| GET | /api/document-design/{type} | DocumentDesignController | show |
| PUT | /api/document-design/{type} | DocumentDesignController | update |
| GET | /api/notification-email-design | NotificationController | showEmailDesign |
| PUT | /api/notification-email-design | NotificationController | updateEmailDesign |
| POST | /api/notification-email-design/preview | NotificationController | previewEmailDesign |
| GET | /api/notification-settings | NotificationController | showSettings |
| PUT | /api/notification-settings | NotificationController | updateSettings |
| GET | /api/notification-templates/defaults | NotificationController | defaultTemplates |
| GET | /api/notification-templates | NotificationController | indexTemplates |
| POST | /api/notification-templates | NotificationController | storeTemplate |
| GET | /api/notification-templates/{id} | NotificationController | showTemplate |
| PUT | /api/notification-templates/{id} | NotificationController | updateTemplate |
| DELETE | /api/notification-templates/{id} | NotificationController | destroyTemplate |
| GET | /api/{resource} | GenericResourceController | index |
| POST | /api/{resource} | GenericResourceController | store |
| GET | /api/{resource}/{id} | GenericResourceController | show |
| PUT | /api/{resource}/{id} | GenericResourceController | update |
| DELETE | /api/{resource}/{id} | GenericResourceController | destroy |
| DELETE | /api/{resource}/{id}/force | GenericResourceController | forceDestroy |
| POST | /api/{resource}/{id}/restore | GenericResourceController | restore |

## Backend Classes and Functions

The backend is organized into Eloquent models, API controllers, domain services, support classes, providers, middleware, and console/bootstrap code. The inventory below lists discovered classes and functions.

### Models

| File | Class | Functions |
| --- | --- | --- |
| backend/app/Models/Account.php | Account | `subscriptions()`, `enumColumns()` |
| backend/app/Models/AccountBillingNumberSetting.php | AccountBillingNumberSetting | `casts()`, `account()` |
| backend/app/Models/AccountConsultationSetting.php | AccountConsultationSetting | `casts()`, `account()` |
| backend/app/Models/AccountPaymentSetting.php | AccountPaymentSetting | `account()`, `isMethodEnabled()`, `credentialsForMethod()`, `enumColumns()` |
| backend/app/Models/Advertisement.php | Advertisement | `enumColumns()` |
| backend/app/Models/AuditLog.php | AuditLog | `user()` |
| backend/app/Models/BackupSchedule.php | BackupSchedule | `updatedByUser()`, `current()` |
| backend/app/Models/BlogPost.php | BlogPost | `booted()`, `enumColumns()` |
| backend/app/Models/ClinicBranch.php | ClinicBranch | `enumColumns()` |
| backend/app/Models/Concerns/HasContentBlocks.php | HasContentBlocks | `bootHasContentBlocks()`, `scopePublished()`, `resolvedBlocks()` |
| backend/app/Models/Concerns/HasEnumOptions.php | HasEnumOptions | `enumColumns()`, `enumIdColumn()`, `enumCasts()`, `initializeHasEnumOptions()`, `scopeWhereEnum()`, `scopeWhereEnumNot()`, `scopeOrWhereEnumLike()`, `scopeOrderByEnum()` |
| backend/app/Models/Consultation.php | Consultation | `patientConsultations()`, `enumColumns()` |
| backend/app/Models/Customer.php | Customer | `account()`, `user()`, `patients()`, `schedules()`, `invoices()`, `displayName()`, `enumColumns()` |
| backend/app/Models/DailyPriorityPatient.php | DailyPriorityPatient | `enumColumns()` |
| backend/app/Models/Diagnosis.php | Diagnosis | `patient()`, `serviceProduct()`, `invoices()`, `activeInvoice()`, `prescriptions()`, `upcomingConsultations()`, `latestUpcomingConsultation()` |
| backend/app/Models/DocumentationPage.php | DocumentationPage | `account()`, `enumColumns()` |
| backend/app/Models/DocumentDesignSetting.php | DocumentDesignSetting | `account()`, `enumColumns()` |
| backend/app/Models/EnumOption.php | EnumOption | `idFor()`, `slugForId()`, `slugsFor()`, `optionsFor()`, `flushCache()`, `booted()`, `cachedMap()`, `cachedReverseMap()` |
| backend/app/Models/FaqPage.php | FaqPage | `enumColumns()` |
| backend/app/Models/Feature.php | Feature | `settings()` |
| backend/app/Models/FeatureSetting.php | FeatureSetting | `feature()`, `account()`, `updatedByUser()` |
| backend/app/Models/InventoryItem.php | InventoryItem | `casts()`, `serviceProduct()`, `clinicBranch()` |
| backend/app/Models/InventoryMovement.php | InventoryMovement | `serviceProduct()` |
| backend/app/Models/Invoice.php | Invoice | `customer()`, `patient()`, `diagnosis()`, `officialReceipt()`, `salesOrder()`, `lineItems()`, `enumColumns()` |
| backend/app/Models/InvoiceLineItem.php | InvoiceLineItem | `casts()`, `invoice()` |
| backend/app/Models/MassMessageCampaign.php | MassMessageCampaign | `casts()`, `account()`, `creator()` |
| backend/app/Models/MassMessageEmailDesign.php | MassMessageEmailDesign | `casts()`, `account()` |
| backend/app/Models/MedicalTreatment.php | MedicalTreatment | - |
| backend/app/Models/NotificationEmailDesign.php | NotificationEmailDesign | `account()`, `notificationSetting()`, `enumColumns()` |
| backend/app/Models/NotificationSetting.php | NotificationSetting | `emailDesign()` |
| backend/app/Models/NotificationTemplateAttachment.php | NotificationTemplateAttachment | `template()` |
| backend/app/Models/NotificationTemplateSetting.php | NotificationTemplateSetting | `attachments()`, `enumColumns()` |
| backend/app/Models/OfficialReceipt.php | OfficialReceipt | `lineItems()`, `invoice()`, `customer()`, `patient()` |
| backend/app/Models/OfficialReceiptLineItem.php | OfficialReceiptLineItem | `officialReceipt()`, `serviceProduct()` |
| backend/app/Models/Partner.php | Partner | `casts()`, `scopeVisible()`, `createdByUser()`, `updatedByUser()` |
| backend/app/Models/Patient.php | Patient | `emergencyContact()`, `insurance()`, `sicknessHistory()`, `familySicknessHistory()`, `medicalTreatments()`, `getEmergencyContactNameAttribute()`, `getEmergencyContactRelationshipAttribute()`, `getEmergencyContactPhoneAttribute()`, `getInsuranceProviderAttribute()`, `getInsurancePolicyNumberAttribute()`, `getPatientSicknessIdsAttribute()`, `getPersonalHistoryAttribute()`, `getPatientFamilySicknessIdsAttribute()`, `getFamilyHistoryAttribute()`, `enumColumns()` |
| backend/app/Models/PatientConsultation.php | PatientConsultation | `consultation()`, `patient()`, `schedule()`, `enumColumns()` |
| backend/app/Models/PatientEmergencyContact.php | PatientEmergencyContact | - |
| backend/app/Models/PatientFamilyHistory.php | PatientFamilyHistory | `sickness()` |
| backend/app/Models/PatientInsurance.php | PatientInsurance | - |
| backend/app/Models/PatientSicknessHistory.php | PatientSicknessHistory | `sickness()` |
| backend/app/Models/PlatformFeature.php | PlatformFeature | `casts()`, `globalSetting()` |
| backend/app/Models/PlatformFeatureSetting.php | PlatformFeatureSetting | `casts()`, `platformFeature()`, `updatedByUser()` |
| backend/app/Models/PlatformSetting.php | PlatformSetting | `casts()`, `updatedByUser()` |
| backend/app/Models/PosCashDrawerEvent.php | PosCashDrawerEvent | `session()` |
| backend/app/Models/PosHeldSale.php | PosHeldSale | `casts()`, `session()`, `holder()`, `toPosArray()` |
| backend/app/Models/PosPaymentDevice.php | PosPaymentDevice | `casts()`, `account()`, `register()`, `payments()` |
| backend/app/Models/PosRegister.php | PosRegister | `account()`, `clinicBranch()`, `sessions()` |
| backend/app/Models/PosSession.php | PosSession | `casts()`, `register()`, `connectedDevice()`, `salesOrders()`, `scopeOpen()` |
| backend/app/Models/Prescription.php | Prescription | `patient()`, `diagnosis()`, `clinicBranch()`, `doctorStaff()`, `items()` |
| backend/app/Models/PrescriptionItem.php | PrescriptionItem | `prescription()` |
| backend/app/Models/ReportLog.php | ReportLog | `account()`, `user()`, `enumColumns()` |
| backend/app/Models/Role.php | Role | `casts()`, `users()` |
| backend/app/Models/SalesOrder.php | SalesOrder | `casts()`, `payments()`, `adjustments()`, `lines()`, `invoice()`, `customer()`, `patient()`, `returns()`, `customerType()`, `customerDisplayLabel()`, `patientDisplayLabel()`, `toPosArray()`, `session()` |
| backend/app/Models/SalesOrderAdjustment.php | SalesOrderAdjustment | `casts()`, `salesOrder()`, `performer()` |
| backend/app/Models/SalesOrderLine.php | SalesOrderLine | `casts()`, `salesOrder()`, `serviceProduct()` |
| backend/app/Models/SalesOrderPayment.php | SalesOrderPayment | `casts()`, `salesOrder()`, `device()`, `transaction()` |
| backend/app/Models/SalesOrderReturn.php | SalesOrderReturn | `casts()`, `salesOrder()`, `lines()`, `performer()` |
| backend/app/Models/SalesOrderReturnLine.php | SalesOrderReturnLine | `casts()`, `salesOrderLine()`, `salesOrderReturn()` |
| backend/app/Models/Schedule.php | Schedule | `customer()`, `patient()`, `account()`, `clinicBranch()`, `serviceProduct()`, `enumColumns()`, `booted()` |
| backend/app/Models/ServiceProduct.php | ServiceProduct | `casts()`, `staffProfiles()`, `enumColumns()`, `requiresInventoryTracking()`, `toArray()` |
| backend/app/Models/Sickness.php | Sickness | `enumColumns()` |
| backend/app/Models/StaffProfile.php | StaffProfile | `user()`, `serviceProducts()`, `getNameAttribute()`, `getFullAddressAttribute()`, `getPermissionsAttribute()`, `enumColumns()` |
| backend/app/Models/Subscription.php | Subscription | `account()`, `enumColumns()` |
| backend/app/Models/SupportTicket.php | SupportTicket | `account()`, `reporter()`, `assignee()`, `messages()`, `readStates()`, `attachments()`, `enumColumns()` |
| backend/app/Models/SupportTicketAttachment.php | SupportTicketAttachment | `ticket()`, `message()`, `enumColumns()` |
| backend/app/Models/SupportTicketMessage.php | SupportTicketMessage | `ticket()`, `parent()`, `user()`, `replies()` |
| backend/app/Models/SupportTicketReadState.php | SupportTicketReadState | `ticket()`, `user()` |
| backend/app/Models/SystemBackup.php | SystemBackup | `creator()`, `absolutePath()` |
| backend/app/Models/Transaction.php | Transaction | `invoice()`, `salesOrderPayment()`, `account()`, `enumColumns()` |
| backend/app/Models/UpcomingConsultation.php | UpcomingConsultation | `patient()`, `diagnosis()`, `creator()`, `updater()`, `enumColumns()` |
| backend/app/Models/User.php | User | `isVerified()`, `staffProfile()`, `account()`, `roleRecord()`, `roles()`, `hasRole()`, `roleSlugs()`, `syncAssignedRoles()`, `role()`, `scopeWhereRoleSlug()`, `enumColumns()` |
| backend/app/Models/WidgetSetting.php | WidgetSetting | `widgetType()`, `clinicBranch()`, `account()`, `widgetStatusLabel()` |
| backend/app/Models/WidgetType.php | WidgetType | `widgetSettings()` |

### API Controllers

| File | Class | Functions |
| --- | --- | --- |
| backend/app/Http/Controllers/Api/AskDrAiController.php | AskDrAiController | `__construct()`, `ask()`, `databaseAnswers()`, `globalReferenceAnswers()`, `aiGeneratedAnswer()`, `isLabInterpretationRequest()`, `educationalAnswerForQuestion()`, `deduplicateAnswers()`, `answerDedupeKey()`, `isDefinitionalQuestion()`, `hasDistinctiveMatch()`, `dropPlaceholdersWhenSpecificAnswersExist()`, `isSpecificConditionAnswer()`, `isLowValuePlaceholderAnswer()`, `extractEducationalTopic()`, `isDiseaseNotFoundAnswer()`, `buildDiseaseNotFoundAnswer()`, `extractMatchedTerms()`, `extractKeywordsFromQuestion()`, `fitPercentage()`, `enrichWithCareGuidance()`, `normalizeEmptyAnswerFields()` |
| backend/app/Http/Controllers/Api/AuthController.php | AuthController | `register()`, `verify()`, `customerOnboard()`, `login()`, `subscriptionRestrictedForUser()`, `defaultRedirect()`, `forgotPassword()`, `resetPassword()`, `me()`, `logout()` |
| backend/app/Http/Controllers/Api/BillingNumberSettingsController.php | BillingNumberSettingsController | `__construct()`, `show()`, `update()`, `preview()`, `next()`, `transform()`, `assertOwner()`, `assertBillingSettingsTable()` |
| backend/app/Http/Controllers/Api/BlogPublicController.php | BlogPublicController | `__construct()`, `index()`, `show()`, `transformPage()`, `transformListItem()` |
| backend/app/Http/Controllers/Api/CaptchaController.php | CaptchaController | `show()` |
| backend/app/Http/Controllers/Api/CodeGenerationController.php | CodeGenerationController | `generate()` |
| backend/app/Http/Controllers/Api/ConsultationController.php | ConsultationController | `index()`, `settings()`, `updateSettings()`, `updateDateLimit()`, `download()`, `storePatient()`, `updatePatient()`, `markServed()`, `markCancelled()`, `generateInvoice()`, `diagnosisForPatient()`, `findScoped()`, `formatRecord()` |
| backend/app/Http/Controllers/Api/CustomerAccessController.php | CustomerAccessController | `send()`, `sendLoginAccess()`, `fallbackLoginAccessBody()` |
| backend/app/Http/Controllers/Api/CustomerBookingController.php | CustomerBookingController | `widgets()`, `formatWidget()` |
| backend/app/Http/Controllers/Api/DashboardController.php | DashboardController | `summary()`, `analytics()`, `weather()`, `healthNews()`, `map()`, `panelActivity()`, `panelRecentAccounts()`, `panelSalesGrowth()`, `panelIncomingAppointments()`, `panelRecentAppointments()`, `panelRecentInvoices()`, `assertCustomerDashboard()`, `superadminSummary()`, `featuresFor()`, `normalizePeriod()`, `periodRange()`, `salesGrowthForSuperadmin()`, `presentationFor()`, `statsFor()`, `stat()`, `can()` |
| backend/app/Http/Controllers/Api/DocumentationController.php | DocumentationController | `__construct()`, `index()`, `show()`, `transformPage()`, `transformListItem()`, `resolveCategory()` |
| backend/app/Http/Controllers/Api/DocumentDesignController.php | DocumentDesignController | `show()`, `update()`, `designForAccount()`, `assertType()` |
| backend/app/Http/Controllers/Api/EnumOptionController.php | EnumOptionController | `index()` |
| backend/app/Http/Controllers/Api/FaqPublicController.php | FaqPublicController | `__construct()`, `index()`, `show()`, `transformPage()`, `transformListItem()` |
| backend/app/Http/Controllers/Api/GenericResourceController.php | GenericResourceController | `index()`, `store()`, `show()`, `update()`, `destroy()`, `restore()`, `forceDestroy()`, `ensureDocumentationSuperadmin()`, `abortIfProtectedDefault()`, `model()`, `findScoped()`, `applyResourceRelations()`, `transformResourceRecord()`, `createStaff()`, `updateStaff()`, `createCustomer()`, `updateCustomer()`, `createServiceProduct()`, `updateServiceProduct()`, `normalizeServiceProductPayload()`, `syncProductQuantity()`, `createWidgetSetting()`, `updateWidgetSetting()`, `syncStaffServices()`, `syncServiceStaff()`, `assertUniqueWidgetSetting()`, `createPatient()`, `updatePatient()`, `extractPatientRelatedPayload()`, `syncPatientRelatedRecords()`, `payload()`, `hydrateLegacyAddress()`, `createPrescription()`, `updatePrescription()`, `normalizePrescriptionItems()`, `syncPrescriptionItems()`, `buildPrescriptionMedicinesSummary()`, `validatePrescriptionDiagnosis()`, `scope()`, `scopedToAccount()`, `applyTrashFilter()`, `applyTrashScopeForFind()`, `usesSoftDeletes()`, `search()`, `filters()` |
| backend/app/Http/Controllers/Api/InventoryController.php | InventoryController | `__construct()`, `index()`, `movements()`, `adjust()` |
| backend/app/Http/Controllers/Api/InvoiceController.php | InvoiceController | `index()`, `store()`, `show()`, `update()`, `destroy()`, `restore()`, `forceDestroy()`, `generateFromDiagnosis()`, `scopedQuery()`, `findScoped()`, `ensureInvoiceEditable()`, `applySearch()`, `applySort()` |
| backend/app/Http/Controllers/Api/InvoicePaymentController.php | InvoicePaymentController | `methods()`, `pay()`, `confirm()`, `findInvoice()` |
| backend/app/Http/Controllers/Api/MassMessageController.php | MassMessageController | `recipients()`, `indexCampaigns()`, `send()`, `showEmailDesign()`, `updateEmailDesign()`, `previewEmailDesign()`, `emailDesignForAccount()`, `transformEmailDesign()`, `validateEmailDesign()`, `availableVariables()`, `assertOwner()` |
| backend/app/Http/Controllers/Api/NotificationController.php | NotificationController | `showSettings()`, `updateSettings()`, `indexTemplates()`, `defaultTemplates()`, `showTemplate()`, `storeTemplate()`, `updateTemplate()`, `destroyTemplate()`, `showEmailDesign()`, `updateEmailDesign()`, `previewEmailDesign()`, `emailDesignForAccount()`, `validateEmailDesign()`, `transformEmailDesign()`, `settingsForAccount()`, `findTemplate()`, `validateTemplate()`, `buildNotificationSlug()`, `ensureUniqueSlug()`, `syncAttachments()`, `transformTemplate()`, `normalizeTemplateData()` |
| backend/app/Http/Controllers/Api/OfficialReceiptController.php | OfficialReceiptController | `index()`, `show()`, `update()`, `destroy()`, `restore()`, `forceDestroy()`, `scopedQuery()`, `findScoped()`, `applySearch()`, `applySort()`, `mapLineItems()` |
| backend/app/Http/Controllers/Api/PaymentGatewaySettingsController.php | PaymentGatewaySettingsController | `show()`, `update()`, `mergeSecretFields()` |
| backend/app/Http/Controllers/Api/PaymentWebhookController.php | PaymentWebhookController | `handle()` |
| backend/app/Http/Controllers/Api/PosController.php | PosController | `__construct()`, `state()`, `listHeldSales()`, `holdSale()`, `resumeHeldSale()`, `discardHeldSale()`, `openSession()`, `closeSession()`, `reconciliation()`, `dashboard()`, `searchProducts()`, `searchPatients()`, `prescriptionCart()`, `previewTotals()`, `saleReceipt()`, `returnSale()`, `openCashDrawer()`, `completeSale()`, `salesHistory()`, `showSale()`, `voidSale()`, `editSale()`, `listDevices()`, `registerDevice()`, `connectDevice()`, `disconnectDevice()`, `syncDevice()`, `capturePayment()`, `currentSession()`, `findSale()`, `findDevice()`, `findHeldSale()`, `assertCanManagePosTransaction()` |
| backend/app/Http/Controllers/Api/ProfileController.php | ProfileController | `show()`, `updateUser()`, `updatePassword()`, `updateStaff()`, `profilePayload()`, `syncUserFromStaff()`, `syncStaffFromUser()`, `ensureStaffEmailAvailable()`, `syncStaffServices()` |
| backend/app/Http/Controllers/Api/PublicAppConfigController.php | PublicAppConfigController | `show()`, `fallbackConfig()` |
| backend/app/Http/Controllers/Api/PublicBookingController.php | PublicBookingController | `config()`, `availability()`, `book()`, `customerSession()`, `authenticatedCustomer()`, `resolveCustomerPatient()`, `createPatientFromPayload()`, `assertDoctorAssignedToService()`, `findOrCreateCustomer()` |
| backend/app/Http/Controllers/Api/PublicContactController.php | PublicContactController | `show()`, `submit()` |
| backend/app/Http/Controllers/Api/PublicLegalPageController.php | PublicLegalPageController | `show()` |
| backend/app/Http/Controllers/Api/PublicPartnersController.php | PublicPartnersController | `index()`, `transform()` |
| backend/app/Http/Controllers/Api/ReportController.php | ReportController | `__construct()`, `summary()`, `revenue()`, `appointments()`, `patients()`, `clinical()`, `outstandingInvoices()`, `export()`, `customerInvoices()`, `buildReportPayload()`, `summaryPayload()`, `filterSummaryData()`, `dateRange()`, `datedPayload()`, `authorizeReportExport()`, `authorizeReports()`, `authorizeCustomerReports()`, `normalizeGranularity()` |
| backend/app/Http/Controllers/Api/ResourceImportExportController.php | ResourceImportExportController | `__construct()`, `fields()`, `importPreview()`, `import()`, `export()`, `authorizeImport()`, `authorizeExport()`, `authorizeAccess()` |
| backend/app/Http/Controllers/Api/ScheduleController.php | ScheduleController | `index()`, `show()`, `rescheduleSlots()`, `reschedule()`, `store()`, `update()`, `cancel()`, `validated()`, `authorizeAccount()` |
| backend/app/Http/Controllers/Api/SelectOptionController.php | SelectOptionController | `index()`, `users()`, `usersFromRole()`, `usersFromStaffProfiles()`, `attendingDoctors()`, `attendingDoctorLabel()` |
| backend/app/Http/Controllers/Api/SetupController.php | SetupController | `__construct()`, `status()`, `networkHints()`, `requirements()`, `testDatabase()`, `install()`, `installPrepare()`, `installMigrate()`, `installSeed()`, `installFinalize()`, `runInstallStep()`, `validateDatabase()`, `validateInstall()` |
| backend/app/Http/Controllers/Api/SicknessController.php | SicknessController | `index()` |
| backend/app/Http/Controllers/Api/StaffAccessController.php | StaffAccessController | `send()`, `sendLoginAccess()`, `fallbackLoginAccessBody()` |
| backend/app/Http/Controllers/Api/SubscriptionController.php | SubscriptionController | `current()`, `quote()`, `checkout()`, `confirm()` |
| backend/app/Http/Controllers/Api/SuperadminBackupController.php | SuperadminBackupController | `__construct()`, `index()`, `store()`, `download()`, `destroy()`, `restore()`, `showSchedule()`, `updateSchedule()`, `assertSuperadmin()` |
| backend/app/Http/Controllers/Api/SuperadminBrandingSettingsController.php | SuperadminBrandingSettingsController | `__construct()`, `show()`, `update()`, `assertSuperadmin()` |
| backend/app/Http/Controllers/Api/SuperadminCaptchaSettingsController.php | SuperadminCaptchaSettingsController | `__construct()`, `show()`, `update()`, `assertSuperadmin()` |
| backend/app/Http/Controllers/Api/SuperadminContactSettingsController.php | SuperadminContactSettingsController | `__construct()`, `show()`, `update()`, `assertSuperadmin()` |
| backend/app/Http/Controllers/Api/SuperadminController.php | SuperadminController | `accounts()`, `updateAccount()`, `accountLogs()`, `roles()`, `storeRole()`, `updateRole()`, `destroyRole()`, `users()`, `storeUser()`, `updateUser()`, `destroyUser()`, `restoreUser()`, `forceDestroyUser()`, `syncUserRoles()`, `transformUser()`, `isProtectedFromPermanentDelete()`, `applyKeywordSearch()` |
| backend/app/Http/Controllers/Api/SuperadminEnumOptionController.php | SuperadminEnumOptionController | `index()`, `store()`, `update()`, `destroy()`, `restore()`, `forceDestroy()`, `reorder()`, `filterTypesForSearch()`, `validated()`, `assertSuperadmin()` |
| backend/app/Http/Controllers/Api/SuperadminFeatureSettingsController.php | SuperadminFeatureSettingsController | `__construct()`, `index()`, `update()`, `assertSuperadmin()` |
| backend/app/Http/Controllers/Api/SuperadminLegalPagesController.php | SuperadminLegalPagesController | `__construct()`, `show()`, `update()`, `assertSuperadmin()` |
| backend/app/Http/Controllers/Api/SuperadminPartnersController.php | SuperadminPartnersController | `__construct()`, `index()`, `updatePageSettings()`, `store()`, `update()`, `destroy()`, `restore()`, `forceDestroy()`, `validated()`, `transform()`, `assertSuperadmin()` |
| backend/app/Http/Controllers/Api/SuperadminPlatformFeatureSettingsController.php | SuperadminPlatformFeatureSettingsController | `__construct()`, `index()`, `definitions()`, `update()`, `assertSuperadmin()` |
| backend/app/Http/Controllers/Api/SuperadminReportController.php | SuperadminReportController | `__construct()`, `summary()`, `subscriptionSales()`, `accountsByBilling()`, `accounts()`, `accountDetail()`, `export()`, `buildReportPayload()`, `dateRange()`, `datedPayload()`, `normalizeGranularity()` |
| backend/app/Http/Controllers/Api/SuperadminSubscriptionPaymentSettingsController.php | SuperadminSubscriptionPaymentSettingsController | `__construct()`, `show()`, `update()`, `assertSuperadmin()` |
| backend/app/Http/Controllers/Api/SupportTicketController.php | SupportTicketController | `unreadCount()`, `assignableUsers()`, `index()`, `store()`, `show()`, `update()`, `destroy()`, `restore()`, `forceDestroy()`, `storeMessage()`, `markRead()`, `unreadQuery()`, `syncTicketReadState()`, `transformTicket()`, `transformMessage()`, `syncAttachments()`, `transformAttachment()` |
| backend/app/Http/Controllers/Api/UpcomingConsultationController.php | UpcomingConsultationController | `index()`, `store()`, `update()`, `destroy()`, `validatePayload()`, `findScoped()`, `transform()` |
| backend/app/Http/Controllers/Api/UploadController.php | UploadController | `store()` |

### Services

| File | Class | Functions |
| --- | --- | --- |
| backend/app/Services/AccountSetupService.php | AccountSetupService | `__construct()`, `provision()`, `createMainBranch()`, `createOwnerStaffProfile()`, `createDefaultWidgetSetting()`, `splitName()` |
| backend/app/Services/AppBrandingSettingsService.php | AppBrandingSettingsService | `getSettings()`, `getPublicBranding()`, `updateSettings()`, `forgetCache()`, `defaultSettings()` |
| backend/app/Services/AskDrAi/ExternalMedicalAnswerService.php | ExternalMedicalAnswerService | `__construct()`, `aiAnswers()`, `aiAnswersFromUploadedImages()`, `searchLayerAnswer()`, `searchSnippets()`, `buildMessages()`, `parseStructuredResponse()`, `normalizeStringList()`, `extractKeywords()` |
| backend/app/Services/AskDrAi/MedicalAnswerSymptomsResolver.php | MedicalAnswerSymptomsResolver | `resolve()`, `attach()`, `extractFromClinicalText()`, `splitSymptomPhrase()`, `normalizeList()` |
| backend/app/Services/AskDrAi/MedicalAttachmentContentService.php | MedicalAttachmentContentService | `__construct()`, `extractFromUrls()`, `extractSingle()`, `fileResult()` |
| backend/app/Services/AskDrAi/MedicalAttachmentDisplayFormatter.php | MedicalAttachmentDisplayFormatter | `format()`, `normalizeLines()`, `extractPatientFields()`, `extractTestRows()`, `flagNearTest()`, `referenceNearTest()`, `groupTestsBySection()`, `buildFormattedText()`, `buildSummary()` |
| backend/app/Services/AskDrAi/MedicalAttachmentStorageResolver.php | MedicalAttachmentStorageResolver | `resolveAbsolutePath()`, `resolveRelativePath()`, `originalFilename()`, `extension()`, `isAllowedAttachmentPath()` |
| backend/app/Services/AskDrAi/MedicalAttachmentTextExtractor.php | MedicalAttachmentTextExtractor | `__construct()`, `extract()`, `readPlainText()`, `readPdf()`, `readDocx()`, `readLegacyDoc()`, `readSpreadsheet()`, `normalizeText()` |
| backend/app/Services/AskDrAi/MedicalAttachmentVisionExtractor.php | MedicalAttachmentVisionExtractor | `__construct()`, `extractText()`, `extractWithTesseract()`, `locateTesseractBinary()`, `defaultTesseractCandidates()` |
| backend/app/Services/AskDrAi/MedicalAuthorityDataService.php | MedicalAuthorityDataService | `referencesFor()`, `lookup()`, `fetchPayload()`, `lookupMedlinePlus()`, `bestMedlineDocument()`, `parseMedlineDocument()`, `lookupScientificName()`, `buildReferences()`, `splitSections()`, `resolveDefinition()`, `sectionKey()`, `listFromSection()`, `htmlToPlainText()`, `plainText()`, `normalizeLabel()`, `medlineSearchTerm()`, `preferredScientificName()`, `emptyPayload()` |
| backend/app/Services/AskDrAi/MedicalDiseaseContentEnricher.php | MedicalDiseaseContentEnricher | `enrich()`, `baseDiseaseKey()` |
| backend/app/Services/AskDrAi/MedicalDiseaseContentLibrary.php | MedicalDiseaseContentLibrary | `get()`, `aliasMap()`, `topicForKey()`, `entries()`, `entry()` |
| backend/app/Services/AskDrAi/MedicalKnowledgeBaseBuilder.php | MedicalKnowledgeBaseBuilder | `__construct()`, `buildToDirectory()`, `recordIterator()`, `makeRecord()`, `applyAuthorityData()`, `finalizeRecord()` |
| backend/app/Services/AskDrAi/MedicalKnowledgeBaseCatalog.php | MedicalKnowledgeBaseCatalog | `presentationVariants()`, `baseDiseasesByCategory()`, `rareDiseases()`, `clinVarDiseaseEntries()`, `commonDiseases()`, `epidemicDiseases()`, `endemicDiseases()`, `fatalDiseases()`, `hereditaryDiseases()`, `mapNames()` |
| backend/app/Services/AskDrAi/MedicalKnowledgeBaseRareDiseases.php | MedicalKnowledgeBaseRareDiseases | `names()` |
| backend/app/Services/AskDrAi/MedicalKnowledgeBaseService.php | MedicalKnowledgeBaseService | `__construct()`, `matchNamedDisease()`, `matchAnswers()`, `totalRecords()`, `categoryIndex()`, `rankCategoryIndex()`, `findRecord()`, `answerFromContentLibrary()`, `expandSymptomSearchText()`, `detectCategoryHint()`, `matchedTerms()`, `searchTermsForEntry()`, `fitScore()`, `isPresentationVariantTitle()` |
| backend/app/Services/AskDrAi/MedicalLabReportInterpreter.php | MedicalLabReportInterpreter | `__construct()`, `interpret()`, `parseFindings()`, `buildInterpretationAnswer()`, `buildTextualLabSummary()`, `buildExtractionFailedAnswer()`, `detectFlag()`, `flagHemoglobin()`, `clinicalImplications()`, `matchedTermsFromFindings()` |
| backend/app/Services/AskDrAi/MedicalQuestionMatcher.php | MedicalQuestionMatcher | `isGenericTerm()`, `significantTerms()`, `isMostlyGenericTopic()`, `hasDistinctiveDiseaseTerms()`, `extractTopic()`, `normalizedSearchText()`, `normalizePhrase()`, `wordCount()`, `preservedSymptomPhrases()`, `buildSearchContext()`, `findCatalogDiseaseName()`, `tokenize()`, `catalogDiseaseNames()` |
| backend/app/Services/AskDrAi/MedicalSourceReferenceService.php | MedicalSourceReferenceService | `attach()`, `buildReferences()`, `referenceLabel()`, `normalizeReferences()` |
| backend/app/Services/AskDrAi/SymptomConditionMatcher.php | SymptomConditionMatcher | `rules()`, `isSymptomPresentation()`, `match()`, `phraseMatchesKeyword()` |
| backend/app/Services/AuditLogFormatter.php | AuditLogFormatter | `format()`, `formatMany()`, `subjectName()`, `resolveName()`, `resolveFeature()`, `resolveAction()`, `formatDateTime()`, `formatDateTimeParts()`, `resolveActorName()`, `buildDisplaySentence()`, `actionSentence()`, `findSubject()`, `nameFromModel()`, `fullName()`, `findPatientById()`, `fallbackName()` |
| backend/app/Services/AuditLogger.php | AuditLogger | `log()` |
| backend/app/Services/BillingNumberService.php | BillingNumberService | `tableExists()`, `settingsForAccount()`, `invoiceSegments()`, `receiptSegments()`, `defaultSettingsModel()`, `nextInvoiceNumber()`, `nextReceiptNumber()`, `preview()`, `formatSample()`, `nextNumber()`, `buildPrefix()`, `formatNumber()`, `renderSegment()`, `sequenceSegment()`, `assertValidSegments()`, `normalizeSegments()` |
| backend/app/Services/BookingAvailabilityService.php | BookingAvailabilityService | `availableSlots()`, `resolveAvailabilityWindows()`, `rangeToWindow()`, `overlapsBooked()` |
| backend/app/Services/BookingWidgetResolver.php | BookingWidgetResolver | `resolve()` |
| backend/app/Services/CaptchaService.php | CaptchaService | `__construct()`, `isEnabled()`, `isRecaptchaEnabled()`, `provider()`, `issueChallenge()`, `validateRequest()`, `hasRecaptchaSubmission()`, `validateRecaptcha()`, `validateLocal()`, `generateLocalChallenge()`, `mathChallenge()`, `imageMatchChallenge()`, `randomQuestionChallenge()`, `normalizeAnswer()`, `cacheKey()`, `captchaCache()`, `normalizeContext()` |
| backend/app/Services/CaptchaSettingsService.php | CaptchaSettingsService | `pageKeys()`, `isValidPage()`, `getSettings()`, `isMasterEnabled()`, `isEnabledForPage()`, `updateSettings()`, `forgetCache()`, `defaultSettings()` |
| backend/app/Services/ClinicReportService.php | ClinicReportService | `summary()`, `revenue()`, `appointments()`, `patients()`, `clinical()`, `outstandingInvoices()`, `customerInvoices()`, `revenueSummary()`, `appointmentSummary()`, `patientSummary()`, `scopedScheduleQuery()` |
| backend/app/Services/Consultations/ConsultationDocumentBuilder.php | ConsultationDocumentBuilder | `build()`, `computeStats()`, `patientName()`, `formatAge()`, `statusLabel()` |
| backend/app/Services/ConsultationService.php | ConsultationService | `findOrCreateForDate()`, `settingsForAccount()`, `effectiveQueueLimit()`, `activeQueueCount()`, `queueMeta()`, `assertCanAddPatient()`, `addPatient()`, `nextPriorityNumber()`, `findDiagnosisForDate()`, `assertPatientBelongsToAccount()` |
| backend/app/Services/ContactFormMailService.php | ContactFormMailService | `__construct()`, `send()` |
| backend/app/Services/ContactSettingsService.php | ContactSettingsService | `getSettings()`, `getPublicContact()`, `updateSettings()`, `notificationEmail()`, `forgetCache()`, `formatAddress()`, `defaultSettings()` |
| backend/app/Services/CustomerPortalScope.php | CustomerPortalScope | `isCustomerPortal()`, `customerId()`, `customer()`, `affiliatedCustomers()`, `customerForAccount()`, `requireCustomerForAccount()`, `requireCustomerId()`, `allowedResources()`, `assertResourceAllowed()`, `assertCanMutate()`, `applyToQuery()` |
| backend/app/Services/DashboardLocationService.php | DashboardLocationService | `__construct()`, `resolveAccountLocation()`, `resolveUserLocation()`, `resolveUserPlace()`, `mapMarkers()`, `collectLocationEntries()`, `entityKey()`, `resolveEntityLocation()`, `bookedEntityKeys()` |
| backend/app/Services/DatabaseBackupService.php | DatabaseBackupService | `createBackup()`, `restoreBackup()`, `deleteBackup()`, `runScheduledBackupIfDue()`, `updateSchedule()`, `calculateNextRunAt()`, `nextWeeklyRun()`, `nextMonthlyRun()`, `exportDatabase()`, `importDatabase()`, `shouldUseMysqldump()`, `exportWithMysqldump()`, `importWithMysql()`, `exportWithPhp()`, `importWithPhp()`, `dumpTableSchema()`, `dumpTableData()`, `quoteValue()`, `listTables()`, `countTables()`, `createZipArchive()`, `pruneOldBackups()`, `commandExists()` |
| backend/app/Services/DocumentationContentService.php | DocumentationContentService | `normalizeBlocks()`, `blocksFromLegacyContent()`, `compileBlocksToContent()`, `excerptFromBlocks()`, `normalizeStoragePath()`, `extractScreenshotFromHtml()`, `stripScreenshotFigures()`, `screenshotFigure()` |
| backend/app/Services/EmailNotificationLayoutRenderer.php | EmailNotificationLayoutRenderer | `defaults()`, `designPayload()`, `normalizeDesign()`, `wrap()`, `previewVariables()`, `heroIconMarkup()`, `socialLinksMarkup()`, `backgroundInlineStyle()`, `backgroundFallbackColor()`, `fontInlineStyle()`, `replaceTokens()`, `escapeHtml()`, `escapeAttr()` |
| backend/app/Services/FeatureSettingsService.php | FeatureSettingsService | `syncDefinitions()`, `isEnabled()`, `resolvedMap()`, `listForScope()`, `updateSetting()`, `flushCache()` |
| backend/app/Services/HealthNewsClient.php | HealthNewsClient | `localNews()`, `internationalNews()`, `parseRssFeed()`, `fetchRssItems()`, `localFeedForCountry()`, `extractSource()` |
| backend/app/Services/InstallationService.php | InstallationService | `isInstalled()`, `clearStaleInstallationMarkers()`, `resetEnvironmentUrlDefaults()`, `applyEnvDefaults()`, `hasStaleInstallationMarkers()`, `isDatabaseReady()`, `hasExistingInstallation()`, `status()`, `requirements()`, `testDatabaseConnection()`, `networkHints()`, `installPrepare()`, `installMigrate()`, `installSeed()`, `installFinalize()`, `install()`, `assertInstallable()`, `readInstallPayload()`, `payloadPath()`, `writeEnvironmentFiles()`, `prepareApplicationForMigrations()`, `runInstallationSeeders()`, `provisionClinicAccounts()`, `runMigrations()`, `reloadAppKeyFromEnv()`, `refreshRuntimeConfig()`, `pdo()`, `resolveFrontendApiUrl()`, `markInstalled()`, `lockPath()`, `readLock()`, `checkPhpVersion()`, `checkExtensions()`, `checkWritable()`, `checkComposerVendor()`, `detectLanIpv4Addresses()`, `isPrivateLanIp()`, `collectStatefulHosts()`, `intranetAccessNotes()` |
| backend/app/Services/InstallationUserCreator.php | InstallationUserCreator | `createSuperadmin()`, `createClinicOwner()` |
| backend/app/Services/InventoryService.php | InventoryService | `getOrCreateItem()`, `availableQuantity()`, `adjust()`, `deductForSale()`, `restoreForVoid()` |
| backend/app/Services/InvoiceNotificationService.php | InvoiceNotificationService | `__construct()`, `dispatchForInvoice()`, `sendEmail()`, `sendSms()`, `recipientEmail()`, `recipientPhone()` |
| backend/app/Services/InvoicePaymentService.php | InvoicePaymentService | `__construct()`, `settingsForAccount()`, `availableMethods()`, `canPayInvoice()`, `payInvoice()`, `completePayment()`, `transformSettings()`, `recordManualPayment()`, `initiateOnlinePayment()`, `transformTransaction()` |
| backend/app/Services/InvoiceService.php | InvoiceService | `__construct()`, `normalizeItems()`, `computeTotals()`, `normalizeReceiptLineItems()`, `computeReceiptTotals()`, `syncReceiptLineItems()`, `invoiceItemsToReceiptLineItems()`, `nextInvoiceNumber()`, `nextReceiptNumber()`, `buildPayload()`, `createFromDiagnosis()`, `findActiveInvoiceForDiagnosis()`, `syncOfficialReceipt()`, `hydrateLineItems()` |
| backend/app/Services/LegalPagesSettingsService.php | LegalPagesSettingsService | `getPages()`, `getPublicPage()`, `updatePages()`, `forgetCache()`, `defaultPages()` |
| backend/app/Services/MassMessageMailSender.php | MassMessageMailSender | `__construct()`, `send()` |
| backend/app/Services/MassMessageService.php | MassMessageService | `__construct()`, `recipientOptions()`, `send()`, `buildTargets()`, `variablesForCustomer()`, `baseVariables()`, `replaceTokens()` |
| backend/app/Services/NotificationMailSender.php | NotificationMailSender | `__construct()`, `send()` |
| backend/app/Services/NotificationSettingResolver.php | NotificationSettingResolver | `forAccount()`, `applyScheduleDefaults()` |
| backend/app/Services/NotificationTemplateRenderer.php | NotificationTemplateRenderer | `render()`, `variablesForSchedule()`, `variablesForUpcomingConsultation()`, `variablesForInvoice()`, `replaceTokens()` |
| backend/app/Services/NotificationTemplateResolver.php | NotificationTemplateResolver | `forSchedule()`, `forInvoice()`, `bySlug()`, `defaultTemplate()` |
| backend/app/Services/OpenMeteoClient.php | OpenMeteoClient | `geocode()`, `currentWeather()`, `weatherLabel()` |
| backend/app/Services/PartnersPageSettingsService.php | PartnersPageSettingsService | `getSettings()`, `getPublicSettings()`, `updateSettings()`, `forgetCache()`, `defaultSettings()` |
| backend/app/Services/Payment/AccountPaymentGatewayManager.php | AccountPaymentGatewayManager | `forAccountMethod()` |
| backend/app/Services/Payment/Gateways/MockPaymentGateway.php | MockPaymentGateway | `provider()`, `supportsMethod()`, `createCheckout()`, `verifyReturn()`, `handleWebhook()`, `checkoutForSubscription()`, `checkoutForTransaction()` |
| backend/app/Services/Payment/Gateways/PayPalPaymentGateway.php | PayPalPaymentGateway | `provider()`, `supportsMethod()`, `createCheckout()`, `verifyReturn()`, `handleWebhook()`, `accessToken()`, `baseUrl()` |
| backend/app/Services/Payment/Gateways/StripePaymentGateway.php | StripePaymentGateway | `provider()`, `supportsMethod()`, `createCheckout()`, `verifyReturn()`, `handleWebhook()`, `assertStripeSignature()` |
| backend/app/Services/Payment/PaymentGatewayManager.php | PaymentGatewayManager | `__construct()`, `forMethod()`, `forProvider()`, `resolvePayPalGateway()`, `resolveCardGateway()` |
| backend/app/Services/PlatformFeatureSettingsService.php | PlatformFeatureSettingsService | `syncDefinitions()`, `isEnabled()`, `resolvedMap()`, `listForScope()`, `updateSetting()`, `permissionDefinitions()` |
| backend/app/Services/PlatformReportService.php | PlatformReportService | `__construct()`, `summary()`, `billingBreakdown()`, `subscriptionSales()`, `accountsOverview()`, `accountDetail()`, `resolveBillingType()` |
| backend/app/Services/PosDiscountService.php | PosDiscountService | `__construct()`, `computeTotals()`, `scPwdDiscount()`, `percentDiscount()` |
| backend/app/Services/PosService.php | PosService | `__construct()`, `ensureDefaultRegister()`, `openSession()`, `closeSession()`, `sessionReconciliation()`, `dashboard()`, `searchProducts()`, `searchPatients()`, `prescriptionCartItems()`, `previewTotals()`, `saleReceipt()`, `openCashDrawer()`, `returnSaleItems()`, `nextReturnNumber()`, `sessionPaymentBreakdown()`, `customerOptions()`, `catalog()`, `listDevices()`, `registerDevice()`, `connectDevice()`, `disconnectDevice()`, `syncDevice()`, `captureFromDevice()`, `completeSale()`, `voidSale()`, `editSale()`, `normalizePayments()`, `paymentAttributes()`, `summarizePaymentMethod()`, `transactionMethodForPayment()`, `updateSalePayments()`, `saleSnapshot()`, `enrichSaleItems()`, `nextOrderNumber()`, `listHeldSales()`, `holdTransaction()`, `resumeHeldSale()`, `discardHeldSale()`, `nextHoldReference()` |
| backend/app/Services/PrescriptionFollowUpSyncService.php | PrescriptionFollowUpSyncService | `__construct()`, `reminderDateForFollowUp()`, `syncUpcomingFromPrescription()`, `syncPrescriptionFromUpcoming()`, `applyUpcomingConsultationDates()`, `findLinkedUpcomingConsultation()`, `datesChanged()` |
| backend/app/Services/RecordAuditor.php | RecordAuditor | `stampForCreate()`, `stampForUpdate()`, `stamp()`, `resolveTable()` |
| backend/app/Services/ReminderSchedulerService.php | ReminderSchedulerService | `__construct()`, `dispatchDueReminders()`, `isDueInWindow()`, `isOverdueButUnsent()`, `dispatchScheduleReminder()`, `dispatchUpcomingConsultationReminder()`, `shouldDispatch()` |
| backend/app/Services/ReportDateRange.php | ReportDateRange | `resolve()`, `bucketSeries()` |
| backend/app/Services/ReportLogger.php | ReportLogger | `log()` |
| backend/app/Services/Reports/ClinicReportDocumentBuilder.php | ClinicReportDocumentBuilder | `build()`, `periodMeta()`, `buildSummary()`, `buildRevenue()`, `buildAppointments()`, `buildPatients()`, `buildClinical()`, `buildOutstandingInvoices()`, `money()` |
| backend/app/Services/Reports/PlatformReportDocumentBuilder.php | PlatformReportDocumentBuilder | `build()`, `periodMeta()`, `buildSummary()`, `buildSubscriptionSales()`, `buildAccountsByBilling()`, `buildAccounts()`, `buildAccountDetail()`, `money()` |
| backend/app/Services/Reports/ReportDocument.php | ReportDocument | `__construct()` |
| backend/app/Services/Reports/ReportExportService.php | ReportExportService | `download()`, `normalizeFormat()`, `buildFilename()`, `downloadSpreadsheet()`, `downloadPdf()`, `downloadDoc()`, `renderHtml()` |
| backend/app/Services/ResourceImportExport/ResourceExporter.php | ResourceExporter | `__construct()`, `download()`, `fetchRecords()`, `serviceProductExportQuery()`, `fetchConsultationRecords()`, `consultationRowValues()`, `computeAge()`, `rowValues()`, `headerLabels()`, `streamXlsx()`, `streamCsv()` |
| backend/app/Services/ResourceImportExport/ResourceFieldRegistry.php | ResourceFieldRegistry | `supports()`, `permissionFor()`, `definition()`, `fields()`, `requiredKeys()`, `exportOnly()` |
| backend/app/Services/ResourceImportExport/ResourceImporter.php | ResourceImporter | `__construct()`, `import()`, `buildPayload()`, `castValue()`, `normalizeDateTime()`, `validateRequired()`, `createRecord()`, `createPatient()`, `createStaff()`, `prepareBranchPayload()` |
| backend/app/Services/ResourceImportExport/SpreadsheetParser.php | SpreadsheetParser | `preview()`, `readMatrix()`, `readCsv()`, `normalizeHeaderRow()`, `alignRow()`, `rowHasContent()`, `stringValue()` |
| backend/app/Services/ScheduleConflictService.php | ScheduleConflictService | `assertAvailable()`, `isInsideBusinessHours()` |
| backend/app/Services/ScheduleNotificationService.php | ScheduleNotificationService | `__construct()`, `dispatchForSchedule()`, `sendScheduleReminderEmail()`, `sendScheduleReminderSms()`, `dispatchCustomerPortalAction()`, `sendCustomerActionEmail()`, `sendCustomerActionSms()`, `customerActionMessage()`, `sendEmail()`, `sendSms()`, `recipientEmail()`, `recipientPhone()` |
| backend/app/Services/ScheduleWidgetPolicyService.php | ScheduleWidgetPolicyService | `settingForSchedule()`, `flagsForSchedule()`, `assertCustomerAction()` |
| backend/app/Services/ServiceProductListQuery.php | ServiceProductListQuery | `__construct()`, `applyFilters()`, `enrich()`, `requestWantsLowStockOnly()`, `applyLowStockScope()` |
| backend/app/Services/SubscriptionBillingService.php | SubscriptionBillingService | `__construct()`, `buildQuote()`, `currentSummary()`, `initiateCheckout()`, `completePayment()`, `markPaymentFailed()`, `countBillableStaff()`, `transformSubscription()`, `calculateEndsAt()`, `accountFeaturesRestricted()`, `accountIsExpired()`, `trialHasEnded()`, `subscriptionHasEnded()` |
| backend/app/Services/SubscriptionPaymentSettingsService.php | SubscriptionPaymentSettingsService | `getSettings()`, `getSettingsForAdmin()`, `envFallbackSummary()`, `updateSettings()`, `forgetCache()`, `isMockAllowed()`, `isStripeConfigured()`, `isPayPalConfigured()`, `stripeSecret()`, `stripeWebhookSecret()`, `stripeEwalletMethods()`, `paypalCredentials()`, `availablePaymentMethods()`, `isMethodAvailable()`, `assertMethodAvailable()`, `credentialsForMethod()`, `primaryGatewayProvider()`, `defaultSettings()`, `normalizeStored()` |
| backend/app/Services/TestAccountProvisioner.php | TestAccountProvisioner | `__construct()`, `generate()`, `delete()`, `createTestAccount()`, `createStaffMembers()`, `createServiceProducts()`, `assignDoctorsToServices()`, `createCustomers()`, `createPatients()`, `createInvoices()`, `createSchedules()`, `createDiagnoses()`, `createPrescriptions()`, `samplePrescriptionItems()`, `buildPrescriptionMedicinesSummary()`, `purgeAccount()` |
| backend/app/Services/UpcomingConsultationNotificationService.php | UpcomingConsultationNotificationService | `__construct()`, `sendReminderEmail()`, `sendReminderSms()`, `resolveReminderTemplate()` |
| backend/app/Services/UpcomingConsultationService.php | UpcomingConsultationService | `syncStatuses()`, `resolveLatestDiagnosisId()`, `assertDiagnosisBelongsToPatient()`, `wasRendered()` |
| backend/app/Services/UserPermissions.php | UserPermissions | `for()`, `platformPermissions()`, `permissionsFromAssignedRoles()` |
| backend/app/Services/WidgetShareUrlService.php | WidgetShareUrlService | `generate()`, `embedHtml()` |

### Support, Providers, and Other Backend Classes

| File | Class | Functions |
| --- | --- | --- |
| backend/app/Casts/EnumSlugCast.php | EnumSlugCast | `__construct()`, `get()`, `set()` |
| backend/app/Concerns/HasAuditUsers.php | HasAuditUsers | `createdByUser()`, `updatedByUser()` |
| backend/app/Console/Commands/CaptureDocumentationScreenshots.php | CaptureDocumentationScreenshots | `__construct()`, `handle()`, `migrateLegacyBlocks()`, `captureScreenshots()`, `disableCaptchaForCapture()`, `embedScreenshots()`, `attachScreenshot()`, `findBlockIndexForScreenshot()` |
| backend/app/Console/Commands/DispatchRemindersCommand.php | DispatchRemindersCommand | `handle()` |
| backend/app/Console/Commands/GenerateAskDrAiKnowledgeBase.php | GenerateAskDrAiKnowledgeBase | `handle()` |
| backend/app/Console/Commands/ManageTestAccountsCommand.php | ManageTestAccountsCommand | `handle()`, `handleGenerate()`, `handleDelete()`, `invalidAction()` |
| backend/app/Console/Commands/MarkClinicInstalledCommand.php | MarkClinicInstalledCommand | `handle()` |
| backend/app/Console/Commands/ResetClinicInstallationCommand.php | ResetClinicInstallationCommand | `handle()` |
| backend/app/Console/Commands/RunSystemBackupCommand.php | RunSystemBackupCommand | `handle()` |
| backend/app/Console/Commands/SyncAskDrAiClinVarCatalog.php | SyncAskDrAiClinVarCatalog | `handle()` |
| backend/app/Contracts/PaymentGatewayInterface.php | PaymentGatewayInterface | `provider()`, `supportsMethod()`, `createCheckout()`, `verifyReturn()`, `handleWebhook()` |
| backend/app/Http/Controllers/Controller.php | Controller | - |
| backend/app/Http/Middleware/EnsureAccountFeatureAccess.php | EnsureAccountFeatureAccess | `__construct()`, `handle()` |
| backend/app/Http/Middleware/EnsureAccountOwner.php | EnsureAccountOwner | `handle()` |
| backend/app/Http/Middleware/EnsureActiveSubscription.php | EnsureActiveSubscription | `__construct()`, `handle()`, `allowsRestrictedAccess()` |
| backend/app/Http/Middleware/EnsureNotInstalled.php | EnsureNotInstalled | `__construct()`, `handle()` |
| backend/app/Http/Middleware/OptionalSanctumAuth.php | OptionalSanctumAuth | `handle()` |
| backend/app/Providers/AppServiceProvider.php | AppServiceProvider | `register()`, `boot()` |
| backend/app/Support/BlogPostImageCatalog.php | BlogPostImageCatalog | `focusScreenshotSlugs()`, `imagesForPost()`, `availableVariants()`, `blockVariantSet()`, `screenshotUrl()`, `screenshotExists()`, `fallbackUrl()` |
| backend/app/Support/ClinicCodeGenerator.php | ClinicCodeGenerator | `forAccount()`, `forBranch()`, `forCustomer()`, `forSku()`, `forBarcode()`, `forSlug()`, `slugModelForResource()`, `uniqueAccountCode()`, `uniqueBranchCode()`, `uniqueCustomerCode()`, `skuPrefixFromSeed()`, `uniqueRandomServiceProductCode()`, `randomAlphanumeric()` |
| backend/app/Support/DocumentationScreenshotCatalog.php | DocumentationScreenshotCatalog | `url()`, `block()`, `exists()` |
| backend/app/Support/EnumColumnMigrator.php | EnumColumnMigrator | `idColumnFor()`, `migrateToEnumOption()`, `migrateUserRoleToForeignKey()`, `backfillMissingIds()`, `sanitizeForeignKeyRefs()`, `ensureForeignKey()` |
| backend/app/Support/EnumTypeRegistry.php | EnumTypeRegistry | `definitionTypes()`, `typeLabel()`, `typeUsage()`, `typeLabels()`, `sections()`, `sectionForType()`, `groupedSections()`, `meta()` |
| backend/app/Support/EnvFileWriter.php | EnvFileWriter | `__construct()`, `forBackend()`, `forFrontend()`, `forMobileApp()`, `set()`, `formatValue()` |
| backend/app/Support/FeatureRouteMap.php | FeatureRouteMap | `featureForPath()`, `resourceImportFeature()` |
| backend/app/Support/LoginPortal.php | LoginPortal | `fromRequest()`, `fromUser()`, `isSuperadmin()` |
| backend/app/Support/PlatformAccess.php | PlatformAccess | `canViewPlatformReports()`, `abortUnlessPlatformReports()` |
| backend/app/Support/SupportAccess.php | SupportAccess | `isPlatformStaff()`, `canAccessPlatformPanel()`, `canManageTickets()`, `scopedTicketsQuery()`, `canViewTicket()`, `assignableUsersQuery()` |

## Generic Resource Map

| API Resource | Model/Class | Behavior |
| --- | --- | --- |
| branches | ClinicBranch | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |
| customers | Customer | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |
| patients | Patient | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |
| staff | StaffProfile | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |
| services | ServiceProduct | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |
| priority-patients | DailyPriorityPatient | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |
| diagnoses | Diagnosis | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |
| prescriptions | Prescription | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |
| invoices | Invoice | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |
| transactions | Transaction | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |
| widget-settings | WidgetSetting | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |
| advertisements | Advertisement | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |
| documentation-pages | DocumentationPage | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |
| blog-posts | BlogPost | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |
| faq-pages | FaqPage | Handled by GenericResourceController with account/customer scope, search, trash handling, auditing, and specialized save logic when needed. |

## Import and Export Resources

| Resource | Permission | Mode |
| --- | --- | --- |
| branches | settings | import/export |
| customers | customers | import/export |
| patients | patients | import/export |
| staff | staff | import/export |
| services | services | import/export |
| diagnoses | diagnoses | import/export |
| prescriptions | prescriptions | import/export |
| schedules | calendar | import/export |
| consultations | consultations | export only |

## Frontend Classes and Functions

The web frontend is a Vue 3 SPA initialized in `frontend/src/main.js`. Its router handles setup completion, auth redirects, guest-only pages, subscription restrictions, account features, platform features, permissions, public-shell styling, and page title synchronization.

| Path | Component |
| --- | --- |
| /setup | SetupWizardPage |
| / | HomePage |
| /login | LoginPage |
| /register | RegisterPage |
| /verify | VerifyPage |
| /customer/onboard | CustomerOnboardPage |
| /forgot-password | ForgotPasswordPage |
| /reset-password | ResetPasswordPage |
| /contact | ContactPage |
| /terms | LegalPublicPage |
| /privacy | LegalPublicPage |
| /about | LegalPublicPage |
| /partners | PartnersPublicPage |
| /dashboard | DashboardPage |
| /calendar | CalendarPage |
| /mass-messages | () => import('./pages/MassMessagesPage.vue') |
| /customer/booking | CustomerBookingPage |
| /consultations | ConsultationsPage |
| /profile | ProfilePage |
| /settings | SettingsPage |
| /account-locked | AccountLockedPage |
| /pos | PosRegisterPage |
| /inventory | InventoryPage |
| /reports | ReportsPage |
| /ask-dr-ai | AskDrAiPage |
| /patients/:id | PatientViewPage |
| /resources/:resource | ResourcePage |
| /superadmin/accounts | SuperadminAccountsPage |
| /superadmin/reports | SuperadminReportsPage |
| /superadmin/roles | SuperadminRolesPage |
| /superadmin/enum-options | SuperadminEnumOptionsPage |
| /superadmin/feature-settings | SuperadminFeatureSettingsPage |
| /superadmin/subscription-payment-settings | SuperadminSubscriptionPaymentSettingsPage |
| /superadmin/captcha-settings | SuperadminCaptchaSettingsPage |
| /superadmin/branding-settings | SuperadminBrandingSettingsPage |
| /superadmin/contact-settings | SuperadminContactSettingsPage |
| /superadmin/legal-pages | SuperadminLegalPagesSettingsPage |
| /superadmin/partners | SuperadminPartnersAdminPage |
| /superadmin/backups | SuperadminBackupRestorePage |
| /superadmin/users | SuperadminUsersPage |
| /superadmin/guides | FaqPagesAdminPage |
| /superadmin/guides/new | FaqPageEditorPage |
| /superadmin/guides/:id/edit | FaqPageEditorPage |
| /superadmin/guides/:id/preview | GuidePreviewPage |
| /superadmin/blog | BlogAdminPage |
| /superadmin/blog/new | BlogEditorPage |
| /superadmin/blog/:id/edit | BlogEditorPage |
| /superadmin/blog/:id/preview | BlogPreviewPage |
| /superadmin/faq | FaqCmsAdminPage |
| /superadmin/faq/new | FaqCmsEditorPage |
| /superadmin/faq/:id/edit | FaqCmsEditorPage |
| /superadmin/faq/:id/preview | FaqCmsPreviewPage |
| /help-support | HelpSupportPage |
| /superadmin/help | SuperadminHelpSupportPage |
| /guide | FaqEntryPage |
| /guide/pages/:slug | FaqViewPage |
| /blog | BlogPublicIndexPage |
| /blog/:slug | BlogPublicViewPage |
| /faq | FaqPublicIndexPage |
| /faq/pages/:slug | FaqPublicViewPage |

### Frontend Function Inventory

- `frontend/src/App.vue`: `logout()`
- `frontend/src/booking/bookingApi.js`: `isCustomerPortalBooking()`, `bookingResourcePath()`
- `frontend/src/components/askDrAi/DocumentDisplayPanel.vue`: `flagClass()`
- `frontend/src/components/askDrAi/MatchedAnswerCard.vue`: `fitPercentage()`, `displayText()`
- `frontend/src/components/auth/CaptchaField.vue`: `isRequestAborted()`, `isLocallyComplete()`, `emitState()`, `applyDisabledState()`, `syncLocalPayload()`, `syncRecaptchaPayload()`, `selectOption()`, `resetRecaptchaWidget()`, `fetchAppConfig()`, `loadRecaptchaScript()`, `renderRecaptcha()`, `applyLocalChallenge()`, `applyChallengeResponse()`, `fetchChallenge()`, `loadChallenge()`, `refresh()`, `validateForSubmit()`, `applyValidationErrors()`, `finish()`
- `frontend/src/components/billing/AdminLteInvoiceView.vue`: `formatMoney()`, `formatCell()`
- `frontend/src/components/billing/NumberFormatBuilder.vue`: `emitSegments()`, `updateSegment()`, `removeSegment()`, `addTextSegment()`, `addSequence()`
- `frontend/src/components/booking/BookingWizard.vue`: `stepState()`
- `frontend/src/components/calendar/CustomerScheduleManageModal.vue`: `formatDateTime()`, `loadSchedule()`, `startReschedule()`, `loadSlots()`, `submitReschedule()`, `cancelAppointment()`
- `frontend/src/components/calendar/ToastScheduleCalendar.vue`: `formatPeriodLabel()`, `shortDate()`, `startOfWeek()`, `toEventDateTime()`, `toLocalParts()`, `addMinutesToTime()`, `snapTimeToHalfHour()`, `handleSelectDateTime()`, `scheduleToEvent()`, `syncEvents()`, `syncAnchorDate()`, `goPrev()`, `goNext()`, `goToday()`, `changeView()`, `initCalendar()`, `total()`
- `frontend/src/components/content/ContentBlockComposer.vue`: `uploadScreenshot()`
- `frontend/src/components/dashboard/DashboardActivityPanel.vue`: `loadActivity()`
- `frontend/src/components/dashboard/DashboardAnalyticsPanel.vue`: `formatCurrency()`
- `frontend/src/components/dashboard/DashboardHealthNewsPanel.vue`: `loadHealthNews()`, `hasNews()`, `formatNewsMeta()`
- `frontend/src/components/dashboard/DashboardIncomingAppointmentsPanel.vue`: `loadAppointments()`, `formatDateTime()`
- `frontend/src/components/dashboard/DashboardMapPanel.vue`: `loadMap()`, `renderMap()`
- `frontend/src/components/dashboard/DashboardRecentAccountsPanel.vue`: `loadAccounts()`, `formatDate()`
- `frontend/src/components/dashboard/DashboardRecentAppointmentsPanel.vue`: `loadAppointments()`, `formatDateTime()`
- `frontend/src/components/dashboard/DashboardRecentInvoicesPanel.vue`: `loadInvoices()`, `formatDate()`, `formatMoney()`
- `frontend/src/components/dashboard/DashboardSalesGrowthPanel.vue`: `loadSalesGrowth()`, `formatCurrency()`, `salesBarWidth()`
- `frontend/src/components/dashboard/DashboardStatCards.vue`: `iconFor()`, `formatValue()`
- `frontend/src/components/dashboard/DashboardWeatherPanel.vue`: `weatherIconClass()`, `weatherTone()`, `formatTemperature()`
- `frontend/src/components/dashboard/LazyPanel.vue`: `load()`, `observe()`
- `frontend/src/components/diagnosis/DiagnosisForm.vue`: `fieldsForTab()`
- `frontend/src/components/faq/FaqBlockRenderer.vue`: `markImageError()`
- `frontend/src/components/import-export/ResourceExportModal.vue`: `selectAll()`, `clearAll()`, `runExport()`
- `frontend/src/components/import-export/ResourceImportModal.vue`: `onFileChange()`, `previewFile()`, `runImport()`, `buildMappingPayload()`
- `frontend/src/components/invoices/InvoicePayModal.vue`: `emitClose()`, `formatMoney()`, `submitPayment()`
- `frontend/src/components/mass-messages/MassMessageSendSection.vue`: `isSelected()`, `toggleRecipient()`, `selectAllRecipients()`, `clearRecipients()`, `recipientContact()`, `formatDate()`, `loadRecipients()`, `loadRecentCampaigns()`, `onChannelChange()`, `openConfirm()`, `sendMessage()`
- `frontend/src/components/medical-certificate/MedicalCertificateModal.vue`: `onFieldChange()`, `loadContext()`, `handlePrint()`, `handleDownload()`
- `frontend/src/components/notifications/EmailBackgroundField.vue`: `emitValue()`
- `frontend/src/components/notifications/EmailNotificationDesignSection.vue`: `normalizeDesignValue()`, `applyDesign()`, `loadDesign()`, `saveDesign()`, `triggerLogoUpload()`, `triggerHeroUpload()`, `uploadImage()`, `uploadLogo()`, `uploadHeroIcon()`
- `frontend/src/components/patients/PatientForm.vue`: `formatSicknessLabel()`, `blankTreatment()`, `addTreatmentRow()`, `removeTreatmentRow()`, `loadSicknesses()`
- `frontend/src/components/pos/PosDiscountPanel.vue`: `selectType()`, `onDiscountValueInput()`, `onScPwdIdInput()`
- `frontend/src/components/pos/PosHeldSalesModal.vue`: `formatMoney()`, `formatHeldTime()`
- `frontend/src/components/pos/PosPatientLookup.vue`: `search()`, `select()`, `clear()`
- `frontend/src/components/pos/PosPaymentLines.vue`: `isElectronic()`
- `frontend/src/components/pos/PosPrescriptionModal.vue`: `load()`
- `frontend/src/components/pos/PosReceiptModal.vue`: `printReceipt()`
- `frontend/src/components/pos/PosReconciliationModal.vue`: `formatMoney()`, `closeSession()`
- `frontend/src/components/pos/PosReturnModal.vue`: `submit()`
- `frontend/src/components/pos/PosSessionDashboard.vue`: `formatMoney()`
- `frontend/src/components/prescription/PrescriptionForm.vue`: `fieldsForTab()`
- `frontend/src/components/services/ServicesListingToolbar.vue`: `applyFilters()`, `clearFilters()`
- `frontend/src/components/settings/BillingNumberSettingsSection.vue`: `loadSettings()`, `resetToDefaults()`, `saveSettings()`, `updateInvoicePreview()`, `updateReceiptPreview()`, `schedulePreview()`
- `frontend/src/components/settings/DiagnosisDesignSection.vue`: `loadDesign()`, `saveDesign()`
- `frontend/src/components/settings/MedicalCertificateDesignSection.vue`: `resetTemplate()`, `loadDesign()`, `saveDesign()`
- `frontend/src/components/settings/PaymentGatewaySettingsSection.vue`: `loadSettings()`, `saveSettings()`
- `frontend/src/components/settings/PrescriptionDesignSection.vue`: `loadDesign()`, `saveDesign()`
- `frontend/src/components/settings/SubscriptionSection.vue`: `refreshAuthSession()`, `readStoredBillingPeriod()`, `persistBillingPeriod()`, `syncBillingPeriodFromSummary()`, `loadSummary()`, `startPayment()`, `handleReturnPayment()`, `formatMoney()`, `formatDate()`
- `frontend/src/components/superadmin/SubscriptionPaymentGatewaySection.vue`: `formatUpdatedAt()`, `applySettings()`, `loadSettings()`, `saveSettings()`
- `frontend/src/components/support/SupportTicketAttachmentsField.vue`: `createKey()`, `syncFromModel()`, `emitValue()`, `openFilePicker()`, `onFilesSelected()`, `addLinkRow()`, `removeLinkRow()`, `removeUploadItem()`
- `frontend/src/components/support/SupportTicketManager.vue`: `loadAssignableUsers()`, `openForm()`, `closeForm()`, `saveTicket()`, `confirmDelete()`, `confirmRestore()`, `confirmForceDelete()`, `performConfirm()`
- `frontend/src/components/support/SupportTicketPanel.vue`: `loadTickets()`, `loadAssignableUsers()`, `toggleExpanded()`, `loadThread()`, `submitReply()`, `ticketActions()`, `toggleTrash()`, `openForm()`, `formatDate()`, `body()`, `latestMessage()`
- `frontend/src/components/ui/AttachmentUpload.vue`: `openFilePicker()`, `onDragLeave()`, `onDrop()`, `onFileInput()`, `handleFiles()`, `removeFile()`
- `frontend/src/components/ui/BaseModal.vue`: `handleClose()`
- `frontend/src/components/ui/DataTable.vue`: `rowActions()`, `handleRowAction()`, `isRichTextColumn()`, `displayValue()`, `formatTimeRange()`, `formatBadge()`, `badgeClass()`
- `frontend/src/components/ui/DatePickerField.vue`: `onInput()`, `openPicker()`
- `frontend/src/components/ui/FormField.vue`: `copyReadonlyValue()`, `generateCode()`, `updatePhotoFilename()`, `parseDate()`, `dayHours()`, `isOpen()`, `toggleDay()`, `updateDay()`, `emitUpdate()`, `isSwitchEnabled()`, `toggleSwitch()`, `loadLocationApi()`, `refreshStates()`, `refreshCities()`, `displayTime()`
- `frontend/src/components/ui/ImageUrlField.vue`: `openFilePicker()`, `onFileChange()`
- `frontend/src/components/ui/ListingSearchBar.vue`: `emitSearch()`, `emitClear()`
- `frontend/src/components/ui/PhotoUpload.vue`: `applyUploadedFile()`, `onFileSelected()`, `openNativeCameraCapture()`, `openCamera()`, `closeCamera()`, `capturePhoto()`, `clearPhoto()`
- `frontend/src/components/ui/PrescriptionMedicationField.vue`: `emitUpdate()`, `addRow()`, `removeRow()`
- `frontend/src/components/ui/RichTextEditor.vue`: `onImageSelected()`, `insertText()`, `setEditorHtml()`
- `frontend/src/components/ui/TabbedFormShell.vue`: `fieldsForTab()`
- `frontend/src/components/ui/TableActionsDropdown.vue`: `destroyPopper()`, `positionMenu()`, `scheduleMenuPosition()`, `toggleMenu()`, `closeMenu()`, `handleSelect()`, `onDocumentClick()`, `onDocumentKeydown()`, `onViewportChange()`
- `frontend/src/components/ui/TagListField.vue`: `addTag()`, `removeTag()`
- `frontend/src/components/ui/VitalSignsField.vue`: `emitUpdate()`
- `frontend/src/composables/useContentBlocks.js`: `createContentBlock()`, `normalizeBlocksFromApi()`, `useContentBlocks()`, `createBlockId()`, `setBlocks()`, `addBlock()`, `removeBlock()`, `duplicateBlock()`, `moveBlock()`, `ensureAtLeastOneBlock()`
- `frontend/src/composables/useLiveClock.js`: `formatLiveDateTime()`, `useLiveClock()`
- `frontend/src/composables/useResourceCrud.js`: `useResourceCrud()`, `load()`, `save()`, `remove()`, `restore()`, `forceRemove()`, `changePage()`, `toggleTrashView()`, `reset()`
- `frontend/src/composables/useSelectOptions.js`: `useSelectOptions()`, `sourceKey()`, `loadSources()`, `loadSource()`, `getOptions()`
- `frontend/src/composables/useSubscriptionRestriction.js`: `useSubscriptionRestriction()`, `runIfAllowed()`
- `frontend/src/config/billingNumberDefaults.js`: `defaultInvoiceSegments()`, `defaultReceiptSegments()`, `billingSegmentTypes()`
- `frontend/src/config/defaultDocumentDesign.js`: `defaultDiagnosisDesign()`, `defaultMedicalCertificateDesign()`, `defaultPrescriptionDesign()`, `documentFontOptions()`, `documentFontStyleOptions()`
- `frontend/src/config/defaultEmailNotificationDesign.js`: `defaultEmailNotificationDesign()`, `emailDesignPreviewSample()`, `emailDesignPreviewVariables()`, `emailDesignFontOptions()`
- `frontend/src/config/defaultMedicalCertificateTemplate.js`: `defaultMedicalCertificateTemplate()`, `medicalCertificateVariables()`
- `frontend/src/config/defaultNotificationTemplates.js`: `defaultNotificationTemplates()`
- `frontend/src/config/diagnosisFormConfig.js`: `createDiagnosisFormDefaults()`, `diagnosisFormFieldDefinitions()`, `diagnosisFieldsForTab()`, `normalizeVitalSigns()`, `normalizeSecondaryDiagnoses()`, `diagnosisToForm()`, `formToDiagnosisPayload()`, `emptyVitalSigns()`, `diagnosisFormTabs()`
- `frontend/src/config/formTabsConfig.js`: `resolveFormTabs()`, `fieldsForTab()`, `FORM_TAB_THRESHOLD()`, `FORM_TAB_FIELD_LIMIT()`, `resourceFormTabs()`
- `frontend/src/config/notificationTemplateVariables.js`: `buildNotificationSlug()`, `minutesToReminderDisplay()`, `reminderDisplayToMinutes()`, `formatTemplateType()`, `formatRecipientType()`, `formatTargetFeature()`, `formatActionType()`, `formatScheduleType()`, `findMatchingDefaultTemplate()`, `defaultTemplateGroupLabel()`, `groupDefaultTemplates()`, `suggestedRecipientType()`, `notificationTemplateVariableGroups()`
- `frontend/src/config/platformPageConfigs.js`: `guidePageConfig()`, `blogPageConfig()`, `faqPageConfig()`, `platformPageConfigs()`
- `frontend/src/config/prescriptionFormConfig.js`: `createPrescriptionFormDefaults()`, `prescriptionFormFieldDefinitions()`, `prescriptionFieldsForTab()`, `normalizeMedicationItems()`, `prescriptionToForm()`, `formToPrescriptionPayload()`, `emptyMedicationItem()`, `prescriptionFormTabs()`
- `frontend/src/config/resourceConfigs.js`: `photoField()`, `signatureField()`, `productImageField()`, `personFields()`, `addressFields()`, `resourceConfigs()`
- `frontend/src/config/resourceImportExport.js`: `supportsImportExport()`, `importExportResources()`
- `frontend/src/config/supportTicketConfig.js`: `labelForImportance()`, `labelForReportType()`, `labelForStatus()`, `importanceBadgeClass()`, `reportTypeBadgeClass()`, `canAccessPlatformHelp()`, `supportReportTypeOptions()`, `supportImportanceOptions()`, `supportStatusOptions()`, `supportFeatureOptions()`, `platformSupportRoles()`
- `frontend/src/layouts/AdminLayout.vue`: `navIcon()`, `isNavActive()`, `isHelpNavItem()`, `loadSupportUnreadCount()`, `syncSidebarState()`, `enforceFeatureAccess()`
- `frontend/src/layouts/PublicSiteLayout.vue`: `toggleAccountMenu()`, `closeAccountMenu()`, `handleLogout()`, `handleDocumentClick()`, `refreshTheme()`
- `frontend/src/main.js`: `registerSubscriptionRequiredHandler()`, `bootstrap()`
- `frontend/src/pages/AskDrAiPage.vue`: `toggleSymptomInput()`, `appendSymptom()`, `removeSymptom()`, `fitPercentage()`, `answerDedupeKey()`, `isLowValuePlaceholder()`, `dedupeAnswers()`, `submitQuestion()`, `resetForm()`
- `frontend/src/pages/BookingWidgetPage.vue`: `blankPerson()`, `blankPatient()`, `goToStep()`, `handleBack()`, `handleNext()`, `selectService()`, `selectDoctor()`, `selectExistingPatient()`, `formatSlot()`, `loadConfig()`, `loadSlots()`, `confirmBooking()`
- `frontend/src/pages/CalendarPage.vue`: `loadNotificationDefaults()`, `load()`, `save()`, `handleSelectSchedule()`, `closeManageModal()`, `handleScheduleChanged()`, `cancelSchedule()`, `defaultReminderAt()`, `defaultSlotTimes()`, `addMinutesWithinRange()`, `openEditor()`, `closeEditor()`, `setScheduleType()`, `appointmentTitle()`, `schedulePayload()`, `buildTimeOptions()`, `withSelectedTimes()`, `businessHourRange()`, `normalizeTime()`, `minutesFromTime()`, `timeFromMinutes()`, `displayTime()`, `totalMinutes()`
- `frontend/src/pages/ConsultationsPage.vue`: `patientName()`, `computedAge()`, `rowClass()`, `statusLabel()`, `statusBadgeClass()`, `consultationActions()`, `viewPatient()`, `loadPatients()`, `loadConsultations()`, `downloadQueue()`, `printQueue()`, `shiftSelectedDate()`, `goToToday()`, `openForm()`, `closeForm()`, `openPatientForm()`, `closePatientForm()`, `openQueueLimitModal()`, `closeQueueLimitModal()`, `parseLimitInput()`, `saveQueueLimits()`, `updatePatientFormField()`, `savePatient()`, `selectPatient()`, `saveRecord()`, `generateInvoice()`, `generateInvoiceFromModal()`, `markServed()`, `markCancelled()`, `markServedFromModal()`, `markCancelledFromModal()`, `handleDocumentClick()`
- `frontend/src/pages/ContactPage.vue`: `loadContact()`, `submitForm()`
- `frontend/src/pages/content/PlatformPageAdminList.vue`: `loadPages()`, `toggleTrash()`, `updateStatus()`, `pageActions()`, `confirmDelete()`, `forceDeleteRecord()`, `restoreRecord()`, `performConfirm()`
- `frontend/src/pages/content/PlatformPageEditor.vue`: `generateSlug()`, `openPreview()`, `loadPage()`, `savePage()`
- `frontend/src/pages/content/PlatformPreviewPage.vue`: `loadPage()`
- `frontend/src/pages/content/PlatformPublicIndexPage.vue`: `loadPages()`
- `frontend/src/pages/content/PlatformPublicViewPage.vue`: `loadPage()`
- `frontend/src/pages/CustomerBookingPage.vue`: `onClinicChange()`, `load()`, `branches()`
- `frontend/src/pages/CustomerOnboardPage.vue`: `submitCode()`
- `frontend/src/pages/CustomerReportsPage.vue`: `loadReport()`, `formatMoney()`
- `frontend/src/pages/DashboardPage.vue`: `loadSummary()`, `loadAnalytics()`, `loadWeather()`
- `frontend/src/pages/DiagnosisResourcePage.vue`: `load()`, `loadDiagnoses()`, `reloadDiagnoses()`, `diagnosesByPatient()`, `togglePatient()`, `removePatient()`, `diagnosisActions()`, `openForm()`, `closeForm()`, `saveDiagnosis()`, `openDelete()`, `deleteDiagnosis()`, `updateDiagnosisService()`, `generateInvoice()`, `canGenerateInvoice()`, `generateInvoiceTitle()`, `patientName()`, `computedAge()`, `formatDateTime()`, `creatorName()`, `serviceLabel()`, `doctorNameForDiagnosis()`, `ensureDiagnosisDesign()`, `printDiagnosis()`, `downloadDiagnosisPdf()`, `printableHtml()`, `handleDocumentClick()`
- `frontend/src/pages/faq/FaqIndexPage.vue`: `loadPages()`
- `frontend/src/pages/faq/FaqLandingPage.vue`: `loadPages()`
- `frontend/src/pages/faq/FaqViewPage.vue`: `resolveCategory()`, `formatDate()`, `loadPage()`
- `frontend/src/pages/ForgotPasswordPage.vue`: `submit()`
- `frontend/src/pages/HomePage.vue`: `loadPartners()`
- `frontend/src/pages/LegalPublicPage.vue`: `loadPage()`
- `frontend/src/pages/LoginPage.vue`: `login()`
- `frontend/src/pages/NotificationSettingsPage.vue`: `applyDefaultTemplateByKey()`, `applyDefaultTemplate()`, `applyMatchingDefault()`, `syncDefaultTemplateSelection()`, `loadDefaultTemplates()`, `formatDateTime()`, `applySettings()`, `loadSettings()`, `loadTemplates()`, `searchTemplates()`, `clearTemplateSearch()`, `loadPage()`, `saveSettings()`, `resetTemplateForm()`, `templateActions()`, `openTemplateForm()`, `closeTemplateForm()`, `buildTemplatePayload()`, `saveTemplate()`, `openDeleteConfirm()`, `deleteTemplate()`, `insertVariable()`
- `frontend/src/pages/PartnersPublicPage.vue`: `loadPartners()`
- `frontend/src/pages/PatientViewPage.vue`: `serviceLabel()`, `openPatientForm()`, `closePatientForm()`, `savePatient()`, `load()`, `upcomingActions()`, `clinicalActions()`, `openClinicalForm()`, `closeClinicalForm()`, `saveClinicalRecord()`, `serializeClinicalPayload()`, `updateDiagnosisService()`, `generateInvoice()`, `canGenerateInvoice()`, `generateInvoiceTitle()`, `openDelete()`, `deleteClinicalRecord()`, `openUpcomingForm()`, `closeUpcomingForm()`, `saveUpcomingConsultation()`, `openUpcomingDelete()`, `deleteUpcomingConsultation()`, `formatNextConsultationDate()`, `formatConsultationDate()`, `upcomingStatusLabel()`, `upcomingStatusClass()`, `upcomingActorName()`, `diagnosisOptionLabel()`, `diagnosisLabel()`, `recordText()`, `normalizedAttachments()`, `creatorName()`, `formatDate()`, `computedAge()`, `doctorNameForDiagnosis()`, `ensureDiagnosisDesign()`, `ensurePrescriptionDesign()`, `printRecord()`, `downloadPdf()`, `printableHtml()`
- `frontend/src/pages/PaymentResourcePage.vue`: `emptyReceiptLineItem()`, `receiptLineItems()`, `receiptLineTotal()`, `emptyLineItem()`, `loadOptions()`, `openPayModal()`, `closePayModal()`, `handleInvoicePaid()`, `handlePaymentReturn()`, `loadActiveTab()`, `loadInvoices()`, `loadReceipts()`, `toggleInvoiceTrashView()`, `toggleReceiptTrashView()`, `canPayInvoice()`, `invoiceEditTitle()`, `invoiceActions()`, `canEditInvoice()`, `receiptActions()`, `setSort()`, `sortIndicator()`, `changePage()`, `openInvoiceForm()`, `regenerateInvoiceNumber()`, `regenerateReceiptNumber()`, `closeInvoiceForm()`, `addLineItem()`, `removeLineItem()`, `selectServiceProduct()`, `lineTotal()`, `updateLineTotal()`, `saveInvoice()`, `openInvoiceView()`, `openReceiptView()`, `openReceiptForm()`, `addReceiptLineItem()`, `removeReceiptLineItem()`, `selectReceiptServiceProduct()`, `closeReceiptForm()`, `saveReceipt()`, `openDelete()`, `confirmDelete()`, `restoreInvoice()`, `restoreReceipt()`, `openForceDelete()`, `closeForceDelete()`, `confirmForceDelete()`, `customerName()`, `userName()`, `formatMoney()`, `formatDate()`, `statusBadgeClass()`, `printReceipt()`, `printInvoice()`, `downloadReceiptPdf()`
- `frontend/src/pages/pos/InventoryPage.vue`: `loadItems()`, `adjustStock()`, `promptAdjust()`
- `frontend/src/pages/pos/PosRegisterPage.vue`: `createPaymentLine()`, `formatMoney()`, `setSaleCustomerType()`, `resetPaymentsForTotal()`, `addPaymentLine()`, `removePaymentLine()`, `loadState()`, `loadDashboard()`, `onBarcodeSearch()`, `openCashDrawer()`, `openReconciliation()`, `onSessionClosed()`, `onPrescriptionLoaded()`, `openReceipt()`, `openReturnSale()`, `onReturnProcessed()`, `saleStateHelpers()`, `refreshHeldSales()`, `openHeldSalesModal()`, `putSaleOnHold()`, `resumeHeldSale()`, `discardHeldSale()`, `openSession()`, `registerQuickDevice()`, `connectSelectedDevice()`, `disconnectDevice()`, `capturePaymentLine()`, `addToCart()`, `changeQty()`, `removeLine()`, `clearCart()`, `completeSale()`, `openSalesHistory()`, `openVoidSale()`, `openEditSale()`, `closeReasonModal()`, `submitReasonModal()`, `nextQty()`
- `frontend/src/pages/PrescriptionResourcePage.vue`: `loadDiagnosesForPatients()`, `diagnosisOptions()`, `diagnosisOptionLabel()`, `diagnosisLabel()`, `load()`, `reloadPrescriptions()`, `loadPrescriptions()`, `prescriptionsByPatient()`, `togglePatient()`, `removePatient()`, `prescriptionActions()`, `openForm()`, `closeForm()`, `savePrescription()`, `openDelete()`, `deletePrescription()`, `patientName()`, `computedAge()`, `formatDateTime()`, `creatorName()`, `prescriptionSummary()`, `ensurePrescriptionDesign()`, `printPrescription()`, `downloadPrescriptionPdf()`, `printableHtml()`, `handleDocumentClick()`
- `frontend/src/pages/ProfilePage.vue`: `defaultStaffValue()`, `normalizeBusinessHours()`, `normalizeSwitchList()`, `populateStaffForm()`, `applyProfile()`, `updateStaffField()`, `buildStaffPayload()`, `loadProfile()`, `saveUserInfo()`, `savePassword()`, `saveStaffInfo()`
- `frontend/src/pages/RegisterPage.vue`: `register()`
- `frontend/src/pages/ReportsPage.vue`: `exportParams()`, `downloadReport()`, `queryParams()`, `formatMoney()`, `setPeriod()`, `applyCustomRange()`, `setRevenueGranularity()`, `loadSummary()`, `loadRevenue()`, `loadAppointments()`, `loadPatients()`, `loadClinical()`, `loadOutstanding()`, `loadActiveTab()`, `loadAll()`
- `frontend/src/pages/ResetPasswordPage.vue`: `submit()`
- `frontend/src/pages/ResourcePage.vue`: `loadCurrent()`, `syncServiceFilters()`, `applyServiceFilters()`, `toggleTrashView()`, `saveRecord()`, `confirmChange()`, `sendLoginAccess()`, `viewPatient()`, `openMedicalCertificate()`, `openForm()`, `closeForm()`, `openConfirm()`, `closeConfirm()`, `changePage()`, `updateFormField()`, `serializeForm()`, `shouldSerializeEmptyField()`, `normalizeMedicalTreatments()`, `defaultValue()`, `normalizeSwitchList()`, `parseJsonObject()`, `normalizeBusinessHours()`, `normalizeTime()`, `formatDateTimeLocal()`, `normalizePatientSicknessIds()`, `normalizePatientFamilySicknessIds()`, `serviceRowClass()`, `blank()`
- `frontend/src/pages/SettingsPage.vue`: `setActiveTab()`
- `frontend/src/pages/setup/SetupWizardPage.vue`: `loadRequirements()`, `testDatabase()`, `loadNetworkHints()`, `applyIntranetUrls()`, `prevStep()`, `nextStep()`, `buildPayload()`, `runInstall()`
- `frontend/src/pages/superadmin/AccountsPage.vue`: `loadAccounts()`, `saveAccount()`, `viewLogs()`, `changePage()`, `applySearch()`, `clearSearch()`, `formatDate()`
- `frontend/src/pages/superadmin/BackupRestorePage.vue`: `formatDateTime()`, `formatSize()`, `statusClass()`, `loadBackups()`, `loadSchedule()`, `createBackup()`, `saveSchedule()`, `downloadBackup()`, `confirmRestore()`, `confirmDelete()`, `performConfirm()`
- `frontend/src/pages/superadmin/BrandingSettingsPage.vue`: `formatUpdatedAt()`, `applyForm()`, `loadSettings()`, `saveSettings()`
- `frontend/src/pages/superadmin/CaptchaSettingsPage.vue`: `formatUpdatedAt()`, `loadSettings()`, `applySettings()`, `saveSettings()`
- `frontend/src/pages/superadmin/ContactSettingsPage.vue`: `loadSettings()`, `saveSettings()`
- `frontend/src/pages/superadmin/EnumOptionsPage.vue`: `loadOptions()`, `formatTrashedAt()`, `optionActions()`, `openForm()`, `closeForm()`, `saveOption()`, `confirmDelete()`, `confirmRestore()`, `confirmForceDelete()`, `performConfirm()`, `toggleTrash()`, `clearSearch()`, `findGroup()`, `updateGroupOptions()`, `rowClasses()`, `onDragStart()`, `onDragEnd()`, `onDragOver()`, `onDragLeave()`, `onDrop()`, `persistOrder()`
- `frontend/src/pages/superadmin/FeatureSettingsPage.vue`: `formatUpdatedAt()`, `switchTab()`, `applyRouteTab()`, `loadAccounts()`, `loadClinicFeatures()`, `loadPlatformFeatures()`, `refreshSessionPlatformFeatures()`, `saveFeature()`, `applySearch()`, `clearSearch()`
- `frontend/src/pages/superadmin/HelpSupportPage.vue`: `notifyChanged()`
- `frontend/src/pages/superadmin/LegalPagesSettingsPage.vue`: `selectTab()`, `applyLoadedPages()`, `buildPayload()`, `validatePages()`, `loadSettings()`, `saveSettings()`
- `frontend/src/pages/superadmin/PartnersAdminPage.vue`: `resetForm()`, `loadPartners()`, `savePageSettings()`, `openCreate()`, `openEdit()`, `closeEditor()`, `savePartner()`, `toggleVisibility()`, `trashPartner()`, `restorePartner()`, `deletePartner()`
- `frontend/src/pages/superadmin/ReportsPage.vue`: `queryParams()`, `exportParams()`, `downloadReport()`, `formatMoney()`, `formatBillingLabel()`, `billingBadgeClass()`, `setPeriod()`, `applyCustomRange()`, `setGranularity()`, `selectAccount()`, `loadSummary()`, `loadSales()`, `loadBilling()`, `loadAccounts()`, `loadAccountDetail()`, `loadActiveTab()`, `loadAll()`
- `frontend/src/pages/superadmin/RolesPage.vue`: `loadRoles()`, `roleActions()`, `loadPlatformFeatureOptions()`, `openForm()`, `closeForm()`, `saveRole()`, `removeRole()`, `applySearch()`, `clearSearch()`
- `frontend/src/pages/superadmin/UsersPage.vue`: `loadUsers()`, `loadAllRoles()`, `loadAccounts()`, `userActions()`, `openForm()`, `closeForm()`, `saveUser()`, `confirmDelete()`, `confirmRestore()`, `confirmForceDelete()`, `performConfirm()`, `toggleTrash()`, `changePage()`, `applySearch()`, `clearSearch()`
- `frontend/src/pages/VerifyPage.vue`: `verify()`
- `frontend/src/services/askDrAi.js`: `normalizeText()`, `sourceLabel()`, `isLowValuePlaceholder()`, `filterLowValueAnswers()`, `preservedSymptomPhrases()`, `buildFallbackAnswers()`, `askDrAi()`, `longSymptoms()`, `fileHints()`
- `frontend/src/services/billingNumberSettings.js`: `fetchBillingNumberSettings()`, `saveBillingNumberSettings()`, `previewBillingNumber()`, `fetchNextBillingNumber()`
- `frontend/src/services/codeGeneration.js`: `autoGenerateSeedFields()`, `buildAutoGenerateSeed()`, `fetchGeneratedCode()`
- `frontend/src/services/consultations.js`: `downloadConsultationQueue()`
- `frontend/src/services/documentDesign.js`: `fetchDocumentDesign()`, `saveDocumentDesign()`
- `frontend/src/services/paymentGatewaySettings.js`: `fetchPaymentGatewaySettings()`, `savePaymentGatewaySettings()`, `fetchInvoicePaymentMethods()`, `payInvoice()`, `confirmInvoicePayment()`
- `frontend/src/services/publicApi.js`: `unwrapPublicList()`, `formatPublicApiError()`
- `frontend/src/services/reports.js`: `fetchClinicReportSummary()`, `fetchClinicRevenueReport()`, `fetchClinicAppointmentsReport()`, `fetchClinicPatientsReport()`, `fetchClinicClinicalReport()`, `fetchClinicOutstandingInvoices()`, `fetchPlatformReportSummary()`, `fetchPlatformSubscriptionSales()`, `fetchPlatformAccountsByBilling()`, `fetchPlatformAccounts()`, `fetchPlatformAccountDetail()`, `downloadClinicReport()`, `downloadPlatformReport()`
- `frontend/src/services/resourceImportExport.js`: `fetchImportExportFields()`, `previewResourceImport()`, `importResourceData()`, `exportResourceData()`
- `frontend/src/services/subscription.js`: `fetchSubscriptionSummary()`, `fetchSubscriptionQuote()`, `startSubscriptionCheckout()`, `confirmSubscriptionPayment()`
- `frontend/src/services/uploads.js`: `uploadFiles()`, `uploadPhoto()`
- `frontend/src/utils/apiBaseUrl.js`: `resolveApiBaseUrl()`, `configured()`
- `frontend/src/utils/appBranding.js`: `getAppTitle()`, `getAppInitials()`, `getLogoUrl()`, `getLogoIconUrl()`, `applyBrandingToDocument()`, `setAppBranding()`, `setContactInfo()`, `useAppBranding()`, `setPartnersPageSettings()`, `usePartnersPageSettings()`, `useContactInfo()`, `loadAppBranding()`
- `frontend/src/utils/attachments.js`: `normalizeAttachmentUrls()`, `attachmentFileName()`
- `frontend/src/utils/auditLogDisplay.js`: `formatAuditLogLine()`, `resolveFeature()`, `actionSentence()`, `splitFormattedAt()`, `formatFallbackDate()`, `feature()`, `name()`, `action()`, `actorName()`, `date()`, `time()`
- `frontend/src/utils/authErrors.js`: `firstAuthError()`
- `frontend/src/utils/authSession.js`: `extractLoginToken()`, `saveAuthSession()`, `saveSessionFromMe()`, `persistLoginSession()`, `clearAuthSession()`, `getAuthToken()`, `getAuthUserRole()`, `getAuthLoginPortal()`, `getAuthUserName()`, `getAuthPermissions()`, `getAuthUserRoles()`, `getAuthAccountFeatures()`, `getAuthPlatformFeatures()`, `setAuthSubscriptionRestricted()`, `getAuthSubscriptionRestricted()`, `getAuthAccountBilling()`, `safeSetItem()`, `isLoggedIn()`, `authUserName()`, `portal()`
- `frontend/src/utils/billingDocument.js`: `buildAdminLteInvoiceHtml()`, `printBillingDocument()`, `buildClinicParty()`, `buildOfficialReceiptDocument()`, `buildInvoiceDocument()`, `buildPosReceiptDocument()`, `money()`, `formatPaymentMode()`, `addressBlock()`, `cellValue()`, `buildMetaList()`, `receiptLineTotal()`, `ADMINLTE_INVOICE_STYLES()`, `BILLING_COLUMNS()`, `lineRows()`, `paymentLines()`, `lines()`
- `frontend/src/utils/cameraAccess.js`: `canAccessCamera()`, `isSecureCameraContext()`, `getCameraUnavailableReason()`, `ensureMediaDevicesShim()`, `getCameraStream()`
- `frontend/src/utils/captchaSubmit.js`: `isCaptchaSatisfied()`, `captchaPayload()`, `ensureCaptchaBeforeSubmit()`
- `frontend/src/utils/consultationPrintTemplate.js`: `buildConsultationQueuePrintHtml()`, `statusLabel()`, `patientName()`, `computedAge()`, `printConsultationQueue()`
- `frontend/src/utils/copyToClipboard.js`: `copyWithExecCommand()`, `copyFromElement()`, `copyToClipboard()`
- `frontend/src/utils/dateDisplay.js`: `toDateInputValue()`, `toDatetimeLocalValue()`, `addDaysToDateInput()`, `daysBetweenDateInputs()`, `parseDateOnly()`, `formatDisplayBirthdate()`, `formatDisplayDate()`, `reminderDateForFollowUp()`, `formatDisplayDateTime()`, `formatDisplayValue()`, `pad()`
- `frontend/src/utils/diagnosisPrintTemplate.js`: `buildDiagnosisDocumentHtml()`, `display()`, `formatBloodPressure()`, `formatVitalRow()`, `renderRichBlock()`, `renderPlanBlock()`, `renderSecondaryTags()`, `computeAge()`, `printDiagnosisDocument()`, `downloadDiagnosisDocumentPdf()`
- `frontend/src/utils/emailDesignStyle.js`: `isGradientBackground()`, `parseBackgroundValue()`, `buildBackgroundValue()`, `backgroundFallbackColor()`, `backgroundInlineStyle()`, `fontInlineStyle()`, `emailDesignGradientDirections()`, `emailDesignFontWeightOptions()`, `emailDesignFontStyleOptions()`, `emailDesignFontSizeOptions()`
- `frontend/src/utils/emailNotificationLayout.js`: `buildEmailNotificationLayoutHtml()`, `replaceTokens()`, `escapeHtml()`, `backgroundInlineStyle()`, `fontInlineStyle()`, `heroIconMarkup()`, `socialLinksMarkup()`
- `frontend/src/utils/ensureAuthSession.js`: `resetAuthSessionSync()`, `ensureAuthSessionSynced()`
- `frontend/src/utils/featureAccess.js`: `isPlatformPortal()`, `isFeatureEnabled()`, `featureKeyForPath()`, `isPathFeatureEnabled()`, `firstEnabledRoute()`, `redirectForDisabledFeature()`
- `frontend/src/utils/htmlContent.js`: `isRichTextField()`, `sanitizeHtml()`, `sanitizeDocumentationHtml()`, `prepareEditorContent()`, `normalizeEditorHtml()`, `htmlToPlainText()`, `truncateHtmlPreview()`, `escapeHtml()`, `buildPrintableDocument()`, `RICH_TEXT_FIELD_KEYS()`, `RICH_TEXT_CONTENT_STYLES()`, `trimmed()`
- `frontend/src/utils/initClinicTheme.js`: `initClinicTheme()`, `loadClinicAos()`, `toggleScrolled()`, `mobileNavToggle()`, `toggleScrollTop()`
- `frontend/src/utils/invoiceHelpers.js`: `computeReceiptTotals()`, `computeInvoiceTotals()`, `formatMoney()`, `normalizedItems()`
- `frontend/src/utils/medicalCertificateContext.js`: `buildMedicalCertificateVariables()`, `medicalCertificateFormFields()`, `syncLeavePeriod()`, `formatMedicalCertificateVariablesForDisplay()`, `display()`, `patientDisplayId()`, `certificateId()`, `diagnosisText()`, `doctorFromMe()`, `medicalCertificateDateKeys()`
- `frontend/src/utils/medicalCertificatePrintTemplate.js`: `applyMedicalCertificateVariables()`, `buildMedicalCertificateDocumentHtml()`, `printMedicalCertificateDocument()`, `downloadMedicalCertificatePdf()`
- `frontend/src/utils/pageTitle.js`: `resolvePageTitle()`, `applyDocumentTitle()`, `syncDocumentTitle()`, `APP_NAME()`
- `frontend/src/utils/patientFormHelpers.js`: `normalizePatientSicknessIds()`, `normalizePatientFamilySicknessIds()`, `normalizeMedicalTreatments()`, `populatePatientForm()`, `serializePatientPayload()`, `shouldSerializeEmptyPatientField()`, `defaultPatientFieldValue()`, `blank()`
- `frontend/src/utils/philippinesLocations.js`: `getPhilippinesCitiesForState()`, `deduplicateCitiesByName()`, `loadPhilippinesLocations()`, `normalizeLocationName()`, `formatPhCity()`
- `frontend/src/utils/platformFeatureAccess.js`: `isPlatformPortal()`, `isPlatformFeatureEnabled()`, `canAccessPlatformFeature()`, `platformFeatureKeyForPath()`, `redirectForDisabledPlatformFeature()`, `platformRouteFeatureMap()`
- `frontend/src/utils/posSaleState.js`: `createPaymentLine()`, `buildHoldPayload()`, `applyHoldPayload()`
- `frontend/src/utils/posStock.js`: `isServiceProduct()`, `productRequiresStock()`, `productStockAvailable()`, `canAddProductToCart()`
- `frontend/src/utils/posTotals.js`: `computePosTotals()`, `isScPwdDiscount()`, `getDiscountLabel()`, `round2()`, `DISCOUNT_TYPES()`
- `frontend/src/utils/prescriptionPrintTemplate.js`: `buildPrescriptionDocumentHtml()`, `display()`, `computeAge()`, `formatDisplayDate()`, `formatTimeLabel()`, `formatBusinessHoursSummary()`, `renderInstructionList()`, `resolveMedicationItems()`, `resolveDoctor()`, `resolveBranch()`, `printPrescriptionDocument()`, `downloadPrescriptionDocumentPdf()`
- `frontend/src/utils/publicShell.js`: `isPublicShellRoute()`, `isGuestOnlyPublicRoute()`, `shouldUsePublicSiteShell()`
- `frontend/src/utils/reportDownload.js`: `parseFilename()`, `triggerBlobDownload()`, `downloadReportBlob()`
- `frontend/src/utils/roleAccess.js`: `canAccessNavItem()`, `navItemsForRole()`, `roleLabel()`, `formatRoleList()`, `superadminNavDefinitions()`, `clinicNavDefinitions()`, `navDefinitions()`
- `frontend/src/utils/scheduleDateTime.js`: `parseStoredDateTime()`, `datePartFromStored()`, `timePartFromStored()`, `timeLabelFromStored()`, `storedDateKey()`, `combineDateTime()`, `reminderDateTimeFromStored()`, `reminderMinutesBeforeStored()`, `sortByStoredStartTime()`, `toMinuteStamp()`, `totalMinutes()`
- `frontend/src/utils/setupStatus.js`: `isSetupRoute()`, `clearSetupStatusCache()`, `fetchSetupStatus()`
- `frontend/src/utils/storageUrl.js`: `storageOrigin()`, `resolveStorageUrl()`, `normalizeStoragePath()`, `filenameFromStoragePath()`
- `frontend/src/utils/stringFormat.js`: `ucwords()`, `formatSelectOptionLabel()`, `normalizeSelectOption()`
- `frontend/src/utils/subscriptionAccess.js`: `isSubscriptionExemptPath()`, `computeSubscriptionRestrictedFromAccount()`, `isSubscriptionRestricted()`, `handleSubscriptionRequiredResponse()`, `isOwnerPortal()`, `isSubscriptionSettingsRoute()`, `shouldShowSubscriptionExpiredBanner()`, `redirectForSubscriptionRestriction()`, `defaultRouteWhenSubscriptionRestricted()`, `startOfDay()`, `SUBSCRIPTION_SETTINGS_PATH()`, `ACCOUNT_LOCKED_PATH()`, `SUBSCRIPTION_EXEMPT_PATH_PREFIXES()`
- `frontend/src/utils/vuesticNavIcons.js`: `vuesticNavIcon()`
- `frontend/src/utils/widgetFonts.js`: `fontStyleSelectOptions()`, `loadWidgetFont()`, `widgetFontFamily()`, `widgetFontOptions()`

## Mobile App Classes and Functions

The mobile app is an Expo React Native client. `RootNavigator` chooses authenticated or guest navigation; `MainShell` provides the authenticated shell; `AppStack` mirrors web features as native screens; `routeMap.ts` maps web paths to native screen names after login.

### Mobile Function Inventory

- `mobile-app/src/components/askDrAi/DocumentDisplayPanel.tsx`: `DocumentDisplayPanel()`, `flagStyle()`, `DocumentDisplayFieldRow()`, `DocumentDisplayTableRow()`, `DocumentDisplaySection()`, `DocumentDisplay()`
- `mobile-app/src/components/askDrAi/MatchedAnswerCard.tsx`: `MatchedAnswerCard()`, `fitPercentage()`, `BulletList()`, `NumberedList()`, `Section()`, `EmptyValue()`, `symptoms()`
- `mobile-app/src/components/askDrAi/UploadedFileAnalysisCard.tsx`: `UploadedFileAnalysisCard()`
- `mobile-app/src/components/auth/CaptchaField.tsx`: `CaptchaField()`, `selectOption()`, `onTextAnswer()`
- `mobile-app/src/components/navigation/AppMenuModal.tsx`: `AppMenuModal()`, `goTo()`
- `mobile-app/src/components/navigation/MenuHeaderButton.tsx`: `MenuHeaderButton()`
- `mobile-app/src/components/pos/PosCustomerLookup.tsx`: `PosCustomerLookup()`
- `mobile-app/src/components/pos/PosDiscountPanel.tsx`: `PosDiscountPanel()`, `selectType()`
- `mobile-app/src/components/pos/PosHeldSalesModal.tsx`: `PosHeldSalesModal()`
- `mobile-app/src/components/pos/PosPatientLookup.tsx`: `PosPatientLookup()`, `search()`, `select()`, `clear()`
- `mobile-app/src/components/pos/PosPaymentLines.tsx`: `PosPaymentLines()`
- `mobile-app/src/components/pos/PosPrescriptionModal.tsx`: `PosPrescriptionModal()`, `load()`, `PrescriptionCartPayload()`
- `mobile-app/src/components/pos/PosReceiptModal.tsx`: `PosReceiptModal()`, `shareReceipt()`, `copyReceipt()`
- `mobile-app/src/components/pos/PosReconciliationModal.tsx`: `PosReconciliationModal()`, `closeSession()`, `Row()`
- `mobile-app/src/components/pos/PosReturnModal.tsx`: `PosReturnModal()`, `submit()`
- `mobile-app/src/components/pos/PosSessionDashboard.tsx`: `PosSessionDashboard()`
- `mobile-app/src/components/services/ServicesFilterBar.tsx`: `ServicesFilterBar()`, `ServiceListFilters()`
- `mobile-app/src/components/subscription/SubscriptionExpiredBanner.tsx`: `SubscriptionExpiredBanner()`
- `mobile-app/src/components/ui/AppButton.tsx`: `AppButton()`
- `mobile-app/src/components/ui/BusinessHoursField.tsx`: `BusinessHoursField()`, `toggleDay()`, `updateDay()`
- `mobile-app/src/components/ui/EmptyState.tsx`: `EmptyState()`
- `mobile-app/src/components/ui/FormActionsFooter.tsx`: `FormActionsFooter()`
- `mobile-app/src/components/ui/FormField.tsx`: `FormField()`, `normalizeStaticOptions()`, `generateCode()`, `handleCopy()`, `FieldConfig()`
- `mobile-app/src/components/ui/FormSessionBar.tsx`: `FormSessionBar()`
- `mobile-app/src/components/ui/FormTabs.tsx`: `FormTabs()`, `FormTabPanel()`
- `mobile-app/src/components/ui/Icon.tsx`: `Icon()`
- `mobile-app/src/components/ui/RecordCard.tsx`: `RecordCard()`
- `mobile-app/src/components/ui/ScreenLayout.tsx`: `ScreenLayout()`
- `mobile-app/src/components/ui/SearchBar.tsx`: `SearchBar()`
- `mobile-app/src/components/ui/SwitchListField.tsx`: `SwitchListField()`, `isEnabled()`, `toggle()`
- `mobile-app/src/config/routeMap.ts`: `pathToScreen()`, `publicGuestScreens()`
- `mobile-app/src/constants/formTabsConfig.ts`: `resolveFormTabs()`, `formatLiveDateTime()`, `FORM_TAB_THRESHOLD()`, `FORM_TAB_FIELD_LIMIT()`, `FormTab()`
- `mobile-app/src/constants/resourceConfigs.js`: `fontStyleSelectOptions()`, `photoField()`, `signatureField()`, `productImageField()`, `personFields()`, `addressFields()`, `resourceConfigs()`
- `mobile-app/src/constants/theme.ts`: `colors()`, `spacing()`, `radii()`, `shadows()`
- `mobile-app/src/context/AuthContext.tsx`: `AuthProvider()`, `useAuth()`
- `mobile-app/src/context/MenuContext.tsx`: `MenuProvider()`, `useMenu()`, `useOptionalMenu()`
- `mobile-app/src/core/authSession.ts`: `extractLoginToken()`, `getAuthToken()`, `initAuthFromStorage()`, `saveAuthSession()`, `saveSessionFromMe()`, `persistLoginSession()`, `clearAuthSession()`, `setAuthSubscriptionRestricted()`, `getAuthSubscriptionRestricted()`, `getAuthAccountBilling()`, `getAuthLoginPortal()`, `getAuthUserName()`, `getAuthPermissions()`, `getAuthUserRoles()`, `getAuthAccountFeatures()`, `getAuthPlatformFeatures()`, `portal()`, `user()`
- `mobile-app/src/core/captcha.ts`: `captchaPayload()`, `isCaptchaReady()`, `CaptchaState()`
- `mobile-app/src/core/getApiBaseUrl.ts`: `getDevMachineHost()`, `getApiBaseUrl()`, `extractApiError()`, `formatNetworkError()`, `isLocalOnlyHost()`, `rewriteHostname()`
- `mobile-app/src/core/navIcons.ts`: `navIcon()`, `NavIconName()`
- `mobile-app/src/core/roleAccess.ts`: `canAccessPlatformHelp()`, `navItemsForRole()`, `firstEnabledRoute()`, `isPlatformFeatureEnabled()`, `canAccessNavItem()`, `NavItem()`
- `mobile-app/src/core/subscriptionAccess.ts`: `computeSubscriptionRestrictedFromAccount()`, `subscriptionRestrictedMessage()`, `isSubscriptionExemptPath()`, `homeRouteWhenRestricted()`, `startOfDay()`, `isSubscriptionRestricted()`, `isOwnerPortal()`, `handleSubscriptionRequiredResponse()`, `SUBSCRIPTION_EXEMPT_PATH_PREFIXES()`, `AccountBilling()`
- `mobile-app/src/hooks/useSelectOptions.ts`: `useSelectOptions()`, `sourceKey()`, `SelectOption()`
- `mobile-app/src/hooks/useSubscriptionRestriction.ts`: `useSubscriptionRestriction()`
- `mobile-app/src/navigation/appNavigation.ts`: `setAppNavigator()`, `navigateApp()`
- `mobile-app/src/navigation/AppStack.tsx`: `AppStack()`, `GuideViewScreen()`, `BlogViewScreen()`, `FaqViewScreen()`
- `mobile-app/src/navigation/GuestStack.tsx`: `GuestStack()`, `GuideViewScreen()`, `BlogViewScreen()`, `FaqViewScreen()`
- `mobile-app/src/navigation/MainShell.tsx`: `MainShell()`
- `mobile-app/src/navigation/RootNavigator.tsx`: `RootNavigator()`
- `mobile-app/src/navigation/types.ts`: `RootStackParamList()`, `GuestStackParamList()`, `MainDrawerParamList()`, `AppStackParamList()`
- `mobile-app/src/screens/auth/LoginScreen.tsx`: `LoginScreen()`, `submit()`
- `mobile-app/src/screens/auth/OtherAuthScreens.tsx`: `RegisterScreen()`, `ForgotPasswordScreen()`, `ResetPasswordScreen()`, `VerifyScreen()`, `CustomerOnboardScreen()`, `set()`, `submit()`
- `mobile-app/src/screens/guest/HomeScreen.tsx`: `HomeScreen()`
- `mobile-app/src/screens/guest/PublicContentScreens.tsx`: `ContactScreen()`, `LegalScreen()`, `PartnersScreen()`, `GuidePublicScreen()`, `BlogPublicScreen()`, `FaqPublicScreen()`, `ContentViewScreen()`, `ApiErrorText()`, `CmsListScreen()`, `submit()`
- `mobile-app/src/screens/main/AccountLockedScreen.tsx`: `AccountLockedScreen()`
- `mobile-app/src/screens/main/AskDrAiScreen.tsx`: `AskDrAiScreen()`, `message()`
- `mobile-app/src/screens/main/ClinicFeatureScreens.tsx`: `CalendarScreen()`, `ConsultationsScreen()`, `ProfileScreen()`, `SettingsScreen()`, `ReportsScreen()`, `InventoryScreen()`, `CustomerBookingScreen()`, `HelpSupportScreen()`, `PatientDetailScreen()`, `NotificationSettingsScreen()`, `SettingsLink()`, `markServed()`, `cancel()`
- `mobile-app/src/screens/main/DashboardScreen.tsx`: `DashboardScreen()`
- `mobile-app/src/screens/main/PosScreen.tsx`: `PosScreen()`, `saleStateHelpers()`, `refreshHeldSales()`, `openHeldSalesModal()`, `putSaleOnHold()`, `resumeHeldSale()`, `doResumeHeldSale()`, `discardHeldSale()`, `clearSaleContext()`, `fetchSaleDetail()`, `openReceipt()`, `openReturnSale()`, `openSession()`, `registerDevice()`, `connectDevice()`, `disconnectDevice()`, `capturePaymentLine()`, `addToCart()`, `nextQty()`, `barcodeSearch()`, `products()`, `onPrescriptionLoaded()`, `openCashDrawer()`, `changeQty()`, `updatePaymentLine()`, `addPaymentLine()`, `removePaymentLine()`, `completeSale()`, `openSalesHistory()`, `openVoidSale()`, `openEditSale()`, `submitReasonModal()`
- `mobile-app/src/screens/resources/ResourceFormScreen.tsx`: `ResourceFormScreen()`, `normalizeFormRecord()`, `defaultFieldValue()`, `save()`, `updateField()`, `renderFields()`
- `mobile-app/src/screens/resources/ResourceListScreen.tsx`: `ResourceListScreen()`, `ResourceListInner()`, `recordPresentation()`, `applyServiceFilters()`, `clearServiceFilters()`, `exportServices()`, `onDelete()`, `ResourceListInnerProps()`
- `mobile-app/src/screens/superadmin/SuperadminScreens.tsx`: `SuperadminGuidesScreen()`, `SuperadminBlogScreen()`, `SuperadminFaqScreen()`, `SuperadminAccountsScreen()`, `SuperadminUsersScreen()`, `SuperadminRolesScreen()`, `SuperadminEnumOptionsScreen()`, `SuperadminPartnersScreen()`, `SuperadminBackupsScreen()`, `SuperadminReportsScreen()`, `SuperadminFeatureSettingsScreen()`, `SuperadminCaptchaSettingsScreen()`, `SuperadminBrandingSettingsScreen()`, `SuperadminContactSettingsScreen()`, `SuperadminLegalPagesScreen()`, `PlatformHelpSupportScreen()`, `DiagnosisListScreen()`, `PrescriptionListScreen()`, `PaymentsListScreen()`, `ApiListScreen()`, `JsonSettingsScreen()`, `load()`, `rowTitle()`, `rowSubtitle()`
- `mobile-app/src/services/askDrAi.ts`: `displayAskDrAiText()`, `hasAskDrAiSourceUrl()`, `isAskDrAiNotFoundAnswer()`, `mapScalarField()`, `mapStringList()`, `mapReferences()`, `mapAnswer()`, `askDrAi()`, `AskDrAiReference()`, `AskDrAiAnswer()`, `DocumentDisplay()`, `UploadedFileContextItem()`, `AskDrAiPayload()`
- `mobile-app/src/services/codeGeneration.ts`: `autoGenerateSeedFields()`, `buildAutoGenerateSeed()`, `fetchGeneratedCode()`
- `mobile-app/src/services/resourceExport.ts`: `arrayBufferToBase64()`, `downloadResourceExport()`, `defaultServiceExportColumns()`
- `mobile-app/src/services/uploads.ts`: `uploadFiles()`, `UploadedFileMeta()`
- `mobile-app/src/types/pos.ts`: `createPaymentLine()`, `isElectronicPayment()`, `PosPaymentMode()`, `PosPaymentLine()`, `PosPaymentDevice()`, `PosSession()`, `PosSaleLine()`, `PosSalePayment()`, `PosCustomerOption()`, `PosPatientOption()`, `PosReconciliation()`, `PosSale()`, `PosReceiptData()`
- `mobile-app/src/types/posHeld.ts`: `PosHeldSale()`
- `mobile-app/src/utils/copyToClipboard.ts`: `copyToClipboard()`
- `mobile-app/src/utils/formValueHelpers.ts`: `normalizeBusinessHours()`, `normalizeSwitchList()`, `buildTimeOptions()`, `displayTime()`, `normalizeTime()`, `BusinessHours()`, `SwitchListValue()`
- `mobile-app/src/utils/posReceipt.ts`: `buildReceiptText()`
- `mobile-app/src/utils/posSaleState.ts`: `buildHoldPayload()`, `applyHoldPayload()`, `HoldPayloadInput()`, `HoldPayload()`, `SaleStateHelpers()`
- `mobile-app/src/utils/posStock.ts`: `isServiceProduct()`, `productRequiresStock()`, `productStockAvailable()`, `canAddProductToCart()`, `formatMoney()`, `PosCatalogItem()`, `PosCartLine()`
- `mobile-app/src/utils/posTotals.ts`: `computePosTotals()`, `isScPwdDiscount()`, `getDiscountLabel()`, `round2()`, `scPwdRequired()`, `DiscountType()`
- `mobile-app/src/utils/resourceListDisplay.ts`: `ucwords()`, `buildRecordPresentation()`, `formatColumnValue()`

## Key Data Relationships

| Area | Relationships |
| --- | --- |
| Tenancy | `accounts` own most clinic records through `account_id`; platform content/settings can be global or platform-scoped. |
| Users and Roles | `users` belong to accounts and can be assigned roles through `roles` and `role_user`; staff/customer profiles can create linked login users. |
| Patients | `patients` link to customers, emergency contacts, insurance, sickness history, family history, treatments, consultations, diagnoses, prescriptions, schedules, invoices, and POS sales. |
| Scheduling | `schedules` link to branches, customers, patients, doctors/staff, services, and can feed consultation queue records. |
| Clinical | `diagnoses` link patients and optional services/products; `prescriptions` link patients, diagnosis, clinic branch, doctor staff, and prescription items. |
| Billing | `invoices` link customers/patients/diagnoses/staff and line items; paid invoices synchronize official receipts and transactions. |
| POS | `pos_sessions` group register activity; `sales_orders` have lines, payments, adjustments, returns, and inventory movements. |
| Inventory | `service_products` of type product can have inventory items and movements; services are billable without stock tracking. |
| Support | `support_tickets` have messages, attachments, read states, status, priority, and assignment metadata. |

## Security and Access Control

- API authentication uses Laravel Sanctum tokens. Protected routes use `auth:sanctum`, `account.feature`, and `subscription.active` middleware.
- Account owners access billing, gateway, billing number, and mass messaging controls through `account.owner` middleware.
- Superadmin routes are protected by frontend route guards and backend controller assertions.
- `CustomerPortalScope` limits customer portal visibility and mutation.
- Role permissions are enforced for resource access, imports/exports, POS, reports, support, and settings areas.

## Operational Notes

- Generated files and uploads are stored through Laravel storage paths; upload endpoints return metadata for web and mobile forms.
- Backups are represented by `system_backups` and `backup_schedules`; restore, download, and delete are superadmin-only.
- Reports use date-range helpers and export builders, with generated output tracked in `report_logs`.
- Notification settings, templates, email designs, and mass message designs use resolver/renderer services.
- This document is based on static source inspection. Deployment-specific seeded values, database constraints, and gateway settings should be verified in the target environment.