System
Unified timeline of data changes (saves, imports, deletes) and backend errors. Filter by type, area, severity, or search.
275,429 results · Page 5504 of 5509
{"document_type":"upload"}
{"backend_document_id":"19","document_type":"upload","title":"Change Hours","slug":"change-hours","summary_text":"Change Business Hours","content_markdown":"https://business.apple.com/companies/1508340657688417792/maps/locations/1554057468158415192/info\r\nWebsite\r\nfacebook\r\ntwitter\r\nnextdoor\r\napple\r\nyelp","content_html":"<p>https://business.apple.com/companies/1508340657688417792/maps/locations/1554057468158415192/info</p>\n<p>Website</p>\n<p>facebook</p>\n<p>twitter</p>\n<p>nextdoor</p>\n<p>apple</p>\n<p>yelp</p>","file_name":"REPORTING_MODULE_UPDATES_2026-04-15.md","stored_name":"20260416-182120-cf1442b8.md","mime_type":"application/octet-stream","file_size_bytes":"8228","storage_path":"/mnt/drive1/customerdb/backend/documents_storage/20260416-182120-cf1442b8.md","is_deleted":"0","created_at":"2026-04-16 14:21:20","updated_at":"2026-04-17 12:01:43","editor_content":"https://business.apple.com/companies/1508340657688417792/maps/locations/1554057468158415192/info\r\nWebsite\r\nfacebook\r\ntwitter\r\nnextdoor\r\napple\r\nyelp","is_text_editable":1,"can_edit_inline":1}
{"backend_document_id":"19","document_type":"upload","title":"Change Hours","slug":"change-hours","summary_text":"Change Business Hours","content_markdown":"# **Places to change hours**\r\n*** https://business.apple.com/companies/1508340657688417792/maps/locations/1554057468158415192/info\r\n* Website\r\n* facebook\r\n* twitter\r\n* nextdoor\r\n* apple\r\n* yelp**","content_html":"<h1>**Places to change hours**</h1>\n<p><em>*</em> https://business.apple.com/companies/1508340657688417792/maps/locations/1554057468158415192/info</p>\n<ul>\n<li>Website</li>\n<li>facebook</li>\n<li>twitter</li>\n<li>nextdoor</li>\n<li>apple</li>\n<li>yelp**</li>\n</ul>","file_name":"REPORTING_MODULE_UPDATES_2026-04-15.md","stored_name":"20260416-182120-cf1442b8.md","mime_type":"application/octet-stream","file_size_bytes":"8228","storage_path":"/mnt/drive1/customerdb/backend/documents_storage/20260416-182120-cf1442b8.md","is_deleted":"0","created_at":"2026-04-16 14:21:20","updated_at":"2026-04-17 12:02:14","editor_content":"# **Places to change hours**\r\n*** https://business.apple.com/companies/1508340657688417792/maps/locations/1554057468158415192/info\r\n* Website\r\n* facebook\r\n* twitter\r\n* nextdoor\r\n* apple\r\n* yelp**","is_text_editable":1,"can_edit_inline":1}
{"document_type":"upload"}
{"backend_document_id":"19","document_type":"upload","title":"Claude and Curser Reporting Changes 04-16","slug":"claude-and-curser-reporting-changes-04-16","summary_text":"Claude and Curser Reporting Changes 04-16","content_markdown":null,"content_html":null,"file_name":"REPORTING_MODULE_UPDATES_2026-04-15.md","stored_name":"20260416-182120-cf1442b8.md","mime_type":"application/octet-stream","file_size_bytes":"8228","storage_path":"/mnt/drive1/customerdb/backend/documents_storage/20260416-182120-cf1442b8.md","is_deleted":"0","created_at":"2026-04-16 14:21:20","updated_at":"2026-04-16 14:21:20","editor_content":"# Reporting Module Updates Log\n\nDate: 2026-04-15 \nOwner: Codex (implementation) \nScope: Backend reporting module (`backend/reporting_module.php`, `backend/api/reporting_module.php`, `backend/reporting_module_service.php`)\n\n## Purpose\n\nThis document tracks:\n\n- Updates completed\n- Areas implemented vs planned\n- Data sources used by each report\n- Corrections and refactors made\n- API/UI calls and usage patterns\n- Completion timeline\n\n## Completion Timeline\n\n### 2026-04-15 (Initial build)\n\n- Added backend report engine:\n - `backend/reporting_module_service.php`\n- Added API endpoint:\n - `backend/api/reporting_module.php`\n- Added backend themed page:\n - `backend/reporting_module.php`\n- Linked module into existing reporting surfaces:\n - `backend/module_service.php`\n - `backend/reports.php`\n\n### 2026-04-15 (Coverage expansion)\n\n- Expanded report families for:\n - Sales\n - Cost / P&L / Balance Sheet / Cash Flow\n - Customer service and quality\n - Labor/time and trend analysis\n - Compliance and insurance\n - Marketing/sales\n- Added planned placeholders for unsupported schema areas:\n - Inventory\n - Employee performance\n - Goals vs actuals\n - Referral source tracking\n - Missed fitting and seamstress productivity\n\n### 2026-04-15 (Legend + documentation controls)\n\n- Added report metadata registry:\n - status\n - completed date\n - data sources\n - report logic notes\n- Added in-app \"Data Source Legend\" panel in:\n - `backend/reporting_module.php`\n- Added catalog column for completion date in UI.\n\n### 2026-04-15 (Settings integration for backend theming)\n\n- Aligned frontend settings APIs with backend/webui theme controls so backend modules can use centralized style settings:\n - `frontend/api/settings_save.php`\n - `frontend/api/settings_get.php`\n - `frontend/api/settings_css.php`\n- Added missing persistence + exposure for:\n - backend-specific theme keys (`backend_theme_*`)\n - advanced typography and sizing keys (`theme_heading_font`, `theme_border_width`, `theme_radius_*`, `theme_panel_padding`, `theme_button_padding_*`)\n - today-pill color keys and extended button label/color keys\n- Result: settings entered in Settings module now propagate to backend pages that consume `/api/settings_css.php` and CSS variables from `page_helpers.php`.\n\n## Report Areas: Status and Data Uses\n\n| Report Key | Status | Completed On | Data Sources | Notes |\n|---|---|---|---|---|\n| `sales_reports` | Implemented | 2026-04-15 | `payments`, `orders`, `visits` | Sales trend rollup |\n| `sales_revenue_by_category` | Implemented | 2026-04-15 | `order_items`, `item_types`, `orders`, `visits` | Revenue by service/category |\n| `sales_trends` | Implemented | 2026-04-15 | `payments`, `orders`, `visits` | Day/month/quarter/year buckets |\n| `top_selling_services` | Implemented | 2026-04-15 | `order_items`, `item_types`, `orders`, `visits` | Quantity and gross sales |\n| `sales_by_customer` | Implemented | 2026-04-15 | `customers`, `orders`, `visits`, `payments` | Customer revenue ranking |\n| `sales_goals_vs_actuals` | Planned | - | Requires goals table/config | Pending schema |\n| `cost_reports` | Implemented | 2026-04-15 | `bills_entry`, `bills_item` | Materials/labor/overhead split |\n| `inventory_reports` | Planned | - | Requires inventory schema | Pending schema |\n| `profit_and_loss_statement` | Implemented | 2026-04-15 | `payments`, `bills_entry`, `bills_item` | Revenue minus expenses |\n| `balance_sheet` | Implemented | 2026-04-15 | `bills_balance`, `orders`, `order_items`, `payments`, `bills_entry` | Assets/liabilities/equity snapshot |\n| `cash_flow_statement` | Implemented | 2026-04-15 | `payments`, `bills_entry`, `tax_payments` | Inflows/outflows/net |\n| `customer_service_reports` | Implemented | 2026-04-15 | `visits`, `orders` | Overdue/aging/volume indicators |\n| `time_and_labor_reports` | Implemented | 2026-04-15 | `visits`, `orders` | Billed labor trend proxy |\n| `trends_and_analysis_reports` | Implemented | 2026-04-15 | `payments`, `orders`, `visits` | Monthly KPI trend |\n| `compliance_reports` | Implemented | 2026-04-15 | `payments`, `tax_payments` | Sales/tax snapshot |\n| `insurance_reports` | Implemented | 2026-04-15 | `bills_entry`, `bills_item` | Insurance bill tracking |\n| `quality_control_reports` | Implemented | 2026-04-15 | `visits`, `orders` | Open/overdue quality indicators |\n| `marketing_and_sales_reports` | Implemented | 2026-04-15 | `customers`, `orders`, `visits`, `payments` | Top customer activity |\n| `employee_performance_reports` | Planned | - | Requires worker attribution | Pending schema |\n| `workroom_queue` | Implemented | 2026-04-15 | `visits`, `customers`, `orders` | Queue + rush/stage |\n| `missed_fitting_alert` | Planned | - | Requires fitting milestones | Pending schema |\n| `ready_for_pickup_aging` | Implemented | 2026-04-15 | `visits`, `customers`, `orders`, `order_items` | 14+ day pickup aging |\n| `revenue_by_category` | Implemented | 2026-04-15 | `order_items`, `item_types`, `orders`, `visits` | Alias report |\n| `average_order_value` | Implemented | 2026-04-15 | `orders`, `visits`, `payments` | AOV |\n| `outstanding_balances` | Implemented | 2026-04-15 | `orders`, `customers`, `visits`, `order_items`, `payments` | WIP balances |\n| `customer_lifetime_value` | Implemented | 2026-04-15 | `customers`, `orders`, `payments` | Top 20% CLV |\n| `referral_source_tracking` | Planned | - | Requires referral source | Pending schema |\n| `dormant_clients` | Implemented | 2026-04-15 | `customers`, `visits`, `orders`, `payments` | 12+ month inactive clients |\n| `seamstress_productivity` | Planned | - | Requires worker time logs | Pending schema |\n| `garment_type_frequency` | Implemented | 2026-04-15 | `order_items`, `item_types`, `orders`, `visits` | Garment/service frequency |\n| `projected_completion_vs_deadline` | Implemented | 2026-04-15 | `visits`, `customers`, `orders` | Deadline risk status |\n\n## Corrections and Refactors Applied\n\n- Standardized report availability through metadata-based support checks:\n - `app_reporting_module_is_supported()`\n- Introduced single report metadata registry:\n - `app_reporting_module_definitions()`\n- Added metadata accessor:\n - `app_reporting_module_metadata()`\n- Updated UI catalog to include completion dates.\n- Added in-page data-source legend to reduce ambiguity during audits and reconciliation reviews.\n\n## Calls and Usage\n\n### Backend UI Calls\n\n- Open reporting module page:\n - `/backend/reporting_module.php`\n- Run report in browser:\n - `/backend/reporting_module.php?report=sales_trends&start_date=2026-01-01&end_date=2026-04-15&group_by=month&limit=25`\n\n### API Calls\n\n- Catalog:\n - `/backend/api/reporting_module.php?report=catalog`\n- Sales by customer:\n - `/backend/api/reporting_module.php?report=sales_by_customer&start_date=2026-01-01&end_date=2026-04-15&limit=100`\n- P&L:\n - `/backend/api/reporting_module.php?report=profit_and_loss_statement&start_date=2026-01-01&end_date=2026-04-15`\n- Balance sheet:\n - `/backend/api/reporting_module.php?report=balance_sheet&end_date=2026-04-15`\n\n### Internal Function Calls (Core)\n\n- Catalog and metadata:\n - `app_reporting_module_catalog()`\n - `app_reporting_module_metadata()`\n- Dispatcher:\n - `app_reporting_module_run()`\n- Service/report functions:\n - `app_reporting_module_sales_trends()`\n - `app_reporting_module_profit_and_loss()`\n - `app_reporting_module_balance_sheet()`\n - `app_reporting_module_cash_flow()`\n - `app_reporting_module_cost_reports()`\n - plus additional report-specific handlers\n\n## Pending Gaps / Next Corrections\n\n1. Add dedicated inventory schema (stock ledger, reorder points, usage) and implement `inventory_reports`.\n2. Add referral source persistence (`customers.referral_source` or linked table) and implement `referral_source_tracking`.\n3. Add employee/time attribution tables and implement:\n - `employee_performance_reports`\n - `seamstress_productivity`\n4. Add sales goals table to enable `sales_goals_vs_actuals`.\n5. Add fitting milestone fields/events to enable `missed_fitting_alert`.\n\n## Change Control Notes\n\n- All new report logic was added non-destructively.\n- Existing reporting endpoints were not removed.\n- The module keeps planned reports visible for roadmap tracking.\n","is_text_editable":1,"can_edit_inline":1}
{"backend_document_id":"19","document_type":"upload","title":"Change Hours","slug":"change-hours","summary_text":"Change Business Hours","content_markdown":"https://business.apple.com/companies/1508340657688417792/maps/locations/1554057468158415192/info\r\nWebsite\r\nfacebook\r\ntwitter\r\nnextdoor\r\napple\r\nyelp","content_html":"<p>https://business.apple.com/companies/1508340657688417792/maps/locations/1554057468158415192/info</p>\n<p>Website</p>\n<p>facebook</p>\n<p>twitter</p>\n<p>nextdoor</p>\n<p>apple</p>\n<p>yelp</p>","file_name":"REPORTING_MODULE_UPDATES_2026-04-15.md","stored_name":"20260416-182120-cf1442b8.md","mime_type":"application/octet-stream","file_size_bytes":"8228","storage_path":"/mnt/drive1/customerdb/backend/documents_storage/20260416-182120-cf1442b8.md","is_deleted":"0","created_at":"2026-04-16 14:21:20","updated_at":"2026-04-17 12:01:43","editor_content":"https://business.apple.com/companies/1508340657688417792/maps/locations/1554057468158415192/info\r\nWebsite\r\nfacebook\r\ntwitter\r\nnextdoor\r\napple\r\nyelp","is_text_editable":1,"can_edit_inline":1}
[]
{"customer_id":"489082","legacy_customer_id":null,"created_at":"2026-04-17 11:20:50","full_name":"Wanda Laezza","phone":"8139972753","email":"lasagnas@aol.com","pickup_due_at":null,"description":null,"notes":"","is_new_customer":"1","setmore_customer_key":null}
{"customer_id":"489082","legacy_customer_id":null,"created_at":"2026-04-17 11:20:00","full_name":"Wanda Laezza","phone":"8139972753","email":"lasagnas@aol.com","pickup_due_at":"2026-05-04 09:29:00","description":null,"notes":"3 Skirts @ 20\r\n2 pants @ 22\r\nPaid Square 111.28","is_new_customer":"1","setmore_customer_key":null}
{"type":"mysqli_sql_exception","file":"/mnt/drive1/customerdb/backend/jobs/delete_add_name_records.php","line":53,"trace":"#0 /mnt/drive1/customerdb/backend/jobs/delete_add_name_records.php(53): mysqli->query()\n#1 /mnt/drive1/customerdb/backend/jobs/delete_add_name_records.php(206): app_delete_if_exists()\n#2 {main}"}
{"file_name":"REPORTING_MODULE_UPDATES_2026-04-15.md","mime_type":"application/octet-stream"}
[]
{"backend_document_id":"19","document_type":"upload","title":"Claude and Curser Reporting Changes 04-16","slug":"claude-and-curser-reporting-changes-04-16","summary_text":"Claude and Curser Reporting Changes 04-16","content_markdown":null,"content_html":null,"file_name":"REPORTING_MODULE_UPDATES_2026-04-15.md","stored_name":"20260416-182120-cf1442b8.md","mime_type":"application/octet-stream","file_size_bytes":"8228","storage_path":"/mnt/drive1/customerdb/backend/documents_storage/20260416-182120-cf1442b8.md","is_deleted":"0","created_at":"2026-04-16 14:21:20","updated_at":"2026-04-16 14:21:20","editor_content":"# Reporting Module Updates Log\n\nDate: 2026-04-15 \nOwner: Codex (implementation) \nScope: Backend reporting module (`backend/reporting_module.php`, `backend/api/reporting_module.php`, `backend/reporting_module_service.php`)\n\n## Purpose\n\nThis document tracks:\n\n- Updates completed\n- Areas implemented vs planned\n- Data sources used by each report\n- Corrections and refactors made\n- API/UI calls and usage patterns\n- Completion timeline\n\n## Completion Timeline\n\n### 2026-04-15 (Initial build)\n\n- Added backend report engine:\n - `backend/reporting_module_service.php`\n- Added API endpoint:\n - `backend/api/reporting_module.php`\n- Added backend themed page:\n - `backend/reporting_module.php`\n- Linked module into existing reporting surfaces:\n - `backend/module_service.php`\n - `backend/reports.php`\n\n### 2026-04-15 (Coverage expansion)\n\n- Expanded report families for:\n - Sales\n - Cost / P&L / Balance Sheet / Cash Flow\n - Customer service and quality\n - Labor/time and trend analysis\n - Compliance and insurance\n - Marketing/sales\n- Added planned placeholders for unsupported schema areas:\n - Inventory\n - Employee performance\n - Goals vs actuals\n - Referral source tracking\n - Missed fitting and seamstress productivity\n\n### 2026-04-15 (Legend + documentation controls)\n\n- Added report metadata registry:\n - status\n - completed date\n - data sources\n - report logic notes\n- Added in-app \"Data Source Legend\" panel in:\n - `backend/reporting_module.php`\n- Added catalog column for completion date in UI.\n\n### 2026-04-15 (Settings integration for backend theming)\n\n- Aligned frontend settings APIs with backend/webui theme controls so backend modules can use centralized style settings:\n - `frontend/api/settings_save.php`\n - `frontend/api/settings_get.php`\n - `frontend/api/settings_css.php`\n- Added missing persistence + exposure for:\n - backend-specific theme keys (`backend_theme_*`)\n - advanced typography and sizing keys (`theme_heading_font`, `theme_border_width`, `theme_radius_*`, `theme_panel_padding`, `theme_button_padding_*`)\n - today-pill color keys and extended button label/color keys\n- Result: settings entered in Settings module now propagate to backend pages that consume `/api/settings_css.php` and CSS variables from `page_helpers.php`.\n\n## Report Areas: Status and Data Uses\n\n| Report Key | Status | Completed On | Data Sources | Notes |\n|---|---|---|---|---|\n| `sales_reports` | Implemented | 2026-04-15 | `payments`, `orders`, `visits` | Sales trend rollup |\n| `sales_revenue_by_category` | Implemented | 2026-04-15 | `order_items`, `item_types`, `orders`, `visits` | Revenue by service/category |\n| `sales_trends` | Implemented | 2026-04-15 | `payments`, `orders`, `visits` | Day/month/quarter/year buckets |\n| `top_selling_services` | Implemented | 2026-04-15 | `order_items`, `item_types`, `orders`, `visits` | Quantity and gross sales |\n| `sales_by_customer` | Implemented | 2026-04-15 | `customers`, `orders`, `visits`, `payments` | Customer revenue ranking |\n| `sales_goals_vs_actuals` | Planned | - | Requires goals table/config | Pending schema |\n| `cost_reports` | Implemented | 2026-04-15 | `bills_entry`, `bills_item` | Materials/labor/overhead split |\n| `inventory_reports` | Planned | - | Requires inventory schema | Pending schema |\n| `profit_and_loss_statement` | Implemented | 2026-04-15 | `payments`, `bills_entry`, `bills_item` | Revenue minus expenses |\n| `balance_sheet` | Implemented | 2026-04-15 | `bills_balance`, `orders`, `order_items`, `payments`, `bills_entry` | Assets/liabilities/equity snapshot |\n| `cash_flow_statement` | Implemented | 2026-04-15 | `payments`, `bills_entry`, `tax_payments` | Inflows/outflows/net |\n| `customer_service_reports` | Implemented | 2026-04-15 | `visits`, `orders` | Overdue/aging/volume indicators |\n| `time_and_labor_reports` | Implemented | 2026-04-15 | `visits`, `orders` | Billed labor trend proxy |\n| `trends_and_analysis_reports` | Implemented | 2026-04-15 | `payments`, `orders`, `visits` | Monthly KPI trend |\n| `compliance_reports` | Implemented | 2026-04-15 | `payments`, `tax_payments` | Sales/tax snapshot |\n| `insurance_reports` | Implemented | 2026-04-15 | `bills_entry`, `bills_item` | Insurance bill tracking |\n| `quality_control_reports` | Implemented | 2026-04-15 | `visits`, `orders` | Open/overdue quality indicators |\n| `marketing_and_sales_reports` | Implemented | 2026-04-15 | `customers`, `orders`, `visits`, `payments` | Top customer activity |\n| `employee_performance_reports` | Planned | - | Requires worker attribution | Pending schema |\n| `workroom_queue` | Implemented | 2026-04-15 | `visits`, `customers`, `orders` | Queue + rush/stage |\n| `missed_fitting_alert` | Planned | - | Requires fitting milestones | Pending schema |\n| `ready_for_pickup_aging` | Implemented | 2026-04-15 | `visits`, `customers`, `orders`, `order_items` | 14+ day pickup aging |\n| `revenue_by_category` | Implemented | 2026-04-15 | `order_items`, `item_types`, `orders`, `visits` | Alias report |\n| `average_order_value` | Implemented | 2026-04-15 | `orders`, `visits`, `payments` | AOV |\n| `outstanding_balances` | Implemented | 2026-04-15 | `orders`, `customers`, `visits`, `order_items`, `payments` | WIP balances |\n| `customer_lifetime_value` | Implemented | 2026-04-15 | `customers`, `orders`, `payments` | Top 20% CLV |\n| `referral_source_tracking` | Planned | - | Requires referral source | Pending schema |\n| `dormant_clients` | Implemented | 2026-04-15 | `customers`, `visits`, `orders`, `payments` | 12+ month inactive clients |\n| `seamstress_productivity` | Planned | - | Requires worker time logs | Pending schema |\n| `garment_type_frequency` | Implemented | 2026-04-15 | `order_items`, `item_types`, `orders`, `visits` | Garment/service frequency |\n| `projected_completion_vs_deadline` | Implemented | 2026-04-15 | `visits`, `customers`, `orders` | Deadline risk status |\n\n## Corrections and Refactors Applied\n\n- Standardized report availability through metadata-based support checks:\n - `app_reporting_module_is_supported()`\n- Introduced single report metadata registry:\n - `app_reporting_module_definitions()`\n- Added metadata accessor:\n - `app_reporting_module_metadata()`\n- Updated UI catalog to include completion dates.\n- Added in-page data-source legend to reduce ambiguity during audits and reconciliation reviews.\n\n## Calls and Usage\n\n### Backend UI Calls\n\n- Open reporting module page:\n - `/backend/reporting_module.php`\n- Run report in browser:\n - `/backend/reporting_module.php?report=sales_trends&start_date=2026-01-01&end_date=2026-04-15&group_by=month&limit=25`\n\n### API Calls\n\n- Catalog:\n - `/backend/api/reporting_module.php?report=catalog`\n- Sales by customer:\n - `/backend/api/reporting_module.php?report=sales_by_customer&start_date=2026-01-01&end_date=2026-04-15&limit=100`\n- P&L:\n - `/backend/api/reporting_module.php?report=profit_and_loss_statement&start_date=2026-01-01&end_date=2026-04-15`\n- Balance sheet:\n - `/backend/api/reporting_module.php?report=balance_sheet&end_date=2026-04-15`\n\n### Internal Function Calls (Core)\n\n- Catalog and metadata:\n - `app_reporting_module_catalog()`\n - `app_reporting_module_metadata()`\n- Dispatcher:\n - `app_reporting_module_run()`\n- Service/report functions:\n - `app_reporting_module_sales_trends()`\n - `app_reporting_module_profit_and_loss()`\n - `app_reporting_module_balance_sheet()`\n - `app_reporting_module_cash_flow()`\n - `app_reporting_module_cost_reports()`\n - plus additional report-specific handlers\n\n## Pending Gaps / Next Corrections\n\n1. Add dedicated inventory schema (stock ledger, reorder points, usage) and implement `inventory_reports`.\n2. Add referral source persistence (`customers.referral_source` or linked table) and implement `referral_source_tracking`.\n3. Add employee/time attribution tables and implement:\n - `employee_performance_reports`\n - `seamstress_productivity`\n4. Add sales goals table to enable `sales_goals_vs_actuals`.\n5. Add fitting milestone fields/events to enable `missed_fitting_alert`.\n\n## Change Control Notes\n\n- All new report logic was added non-destructively.\n- Existing reporting endpoints were not removed.\n- The module keeps planned reports visible for roadmap tracking.\n","is_text_editable":1,"can_edit_inline":1}
{"file_name":"PAY_BILLS_ENHANCED_FEATURES.md","mime_type":"application/octet-stream"}
[]
{"backend_document_id":"18","document_type":"upload","title":"Open Code 04-16 Pay Bills changes","slug":"open-code-04-16-pay-bills-changes","summary_text":"Open Code 04-16 Pay Bills changes","content_markdown":null,"content_html":null,"file_name":"PAY_BILLS_ENHANCED_FEATURES.md","stored_name":"20260416-182019-18adea90.md","mime_type":"application/octet-stream","file_size_bytes":"8500","storage_path":"/mnt/drive1/customerdb/backend/documents_storage/20260416-182019-18adea90.md","is_deleted":"0","created_at":"2026-04-16 14:20:19","updated_at":"2026-04-16 14:20:19","editor_content":"# Pay Bills - Enhanced Features Documentation\n\n**Last Updated:** April 16, 2026 \n**File:** `/backend/bills.php` \n**Server:** `kefa@192.168.7.202` \n**Data Location:** `/mnt/drive1/customerdb/`\n\n---\n\n## Overview\n\nThe Pay Bills page has been enhanced with new features for better bank account management and payment tracking visibility.\n\n---\n\n## New Features\n\n### 1. Bank Account Types\n\nEach bank account now has a **type classification**:\n\n| Type | Icon | Description |\n|------|------|-------------|\n| **Pay Bill** | 💳 | Used for paying bills - appears in bank dropdown |\n| **Show Balance** | 👁 | Track only - excluded from bill payment dropdowns |\n\n**Why this matters:** Accounts marked as \"Show Balance\" won't clutter the bill payment dropdown but still track their running balance.\n\n### 2. Bank URL (Popup Window)\n\nEach account can have a **Bank URL** that opens in a popup window.\n\n- Click the \"🌐 Bank\" button next to any account\n- Opens the URL in a 1200x800 popup window\n- Useful for quick access to bank login without leaving the bills page\n\n### 3. Bal After Pills (Status Badges)\n\nThe \"Bal After\" column now shows **color-coded pills**:\n\n| Status | Appearance | Meaning |\n|--------|------------|---------|\n| **Paid** | Green pill with ✓ | Bill amount has been paid |\n| **Due** | Red pill with ! | Still needs to be paid |\n| **—** | Gray pill | No amount entered |\n\n### 4. Save All Buttons\n\nTwo save buttons added for convenience:\n\n1. **Save All Balances** - In the bank accounts section\n2. **Save All Bills** - At the bottom of the bills table\n\nBoth show \"Saving…\" → \"Saved ✓\" feedback.\n\n### 5. Auto-Update\n\nAll changes auto-save after 600ms of inactivity (debounced).\n\n---\n\n## Database Schema Changes\n\n### New Columns in `bills_accounts` Table\n\n```sql\n-- MySQL / MariaDB\nALTER TABLE bills_accounts\nADD COLUMN account_type ENUM('pay_bill', 'show_balance') DEFAULT 'pay_bill' AFTER name,\nADD COLUMN bank_url TEXT DEFAULT '' AFTER account_type;\n\n-- SQLite\nALTER TABLE bills_accounts ADD COLUMN account_type TEXT DEFAULT 'pay_bill';\nALTER TABLE bills_accounts ADD COLUMN bank_url TEXT DEFAULT '';\n```\n\n### New Tables Created\n\nIf tables don't exist, the following are auto-created:\n\n```sql\nCREATE TABLE bills_accounts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n account_type TEXT DEFAULT 'pay_bill',\n bank_url TEXT DEFAULT '',\n sort_order INTEGER DEFAULT 0,\n created_at TEXT DEFAULT CURRENT_TIMESTAMP\n);\n\nCREATE TABLE bills_monthly (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n year INTEGER NOT NULL,\n month INTEGER NOT NULL,\n bills_account_id INTEGER,\n opening_balance REAL DEFAULT 0,\n UNIQUE(year, month, bills_account_id)\n);\n\nCREATE TABLE bills_items (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n default_due REAL DEFAULT 0,\n notes TEXT DEFAULT '',\n sort_order INTEGER DEFAULT 0,\n created_at TEXT DEFAULT CURRENT_TIMESTAMP\n);\n\nCREATE TABLE bills_entries (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n year INTEGER NOT NULL,\n month INTEGER NOT NULL,\n bills_item_id INTEGER NOT NULL,\n bills_account_id INTEGER DEFAULT 0,\n payment_due REAL DEFAULT 0,\n amount_paid REAL DEFAULT 0,\n is_paid INTEGER DEFAULT 0,\n paid_date TEXT DEFAULT '',\n UNIQUE(year, month, bills_item_id)\n);\n\nCREATE TABLE bills_copy_log (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n year INTEGER NOT NULL,\n month INTEGER NOT NULL,\n copied_from_year INTEGER NOT NULL,\n copied_from_month INTEGER NOT NULL,\n copied_at TEXT DEFAULT CURRENT_TIMESTAMP\n);\n```\n\n---\n\n## Deployment Instructions\n\n### Step 1: Upload the File\n\n**Option A: Direct Copy (if file is on local machine)**\n\n```bash\n# From local machine to server\nscp bills.php kefa@192.168.7.202:/var/www/floridaalterations.com/backend/bills.php\n```\n\n**Option B: If editing on server directly**\n\n```bash\nssh kefa@192.168.7.202\n# Then edit the file at:\n# /var/www/floridaalterations.com/backend/bills.php\n```\n\n### Step 2: Set Permissions\n\n```bash\nssh kefa@192.168.202\nchmod 644 /var/www/floridaalterations.com/backend/bills.php\nchown www-data:www-data /var/www/floridaalterations.com/backend/bills.php\n```\n\n### Step 3: Clear Cache (Optional)\n\n```bash\n# If using OPcache\nssh kefa@192.168.7.202\nphp -r \"opcache_get_status();\" 2>/dev/null && echo \"Consider: php-fpm restart\"\n```\n\n### Step 4: Access the Page\n\n```\nhttps://ella.floridaalterations.com/backend/bills.php\n```\n\n---\n\n## How to Use\n\n### Adding a New Account with Bank URL\n\n1. Click **\"+ Add Account\"** button\n2. Enter account name (e.g., \"Chase Checking\")\n3. Select account type:\n - **Pay Bill** - For accounts you'll pay bills from\n - **Show Balance** - For tracking only\n4. Enter Bank URL (e.g., `https://www.chase.com/login`)\n5. Click **\"Add Account\"**\n6. Enter the opening balance and click **\"Save Balances\"**\n\n### Editing an Existing Account\n\n1. Click **\"Edit\"** next to the account\n2. Update name, type, or URL\n3. Click **\"Save Changes\"**\n\n### Switching Account Type\n\n1. Edit the account\n2. Change the radio button selection\n3. Click **\"Save Changes\"**\n\n### Opening Bank in Popup\n\n1. Click the **\"🌐 Bank\"** button next to an account\n2. The bank URL opens in a new popup window\n\n### Marking a Bill as Paid\n\n1. Enter the **Paid ($)** amount (or it auto-calculates)\n2. The **Bal After** pill turns **green** with a ✓ checkmark\n3. Row background turns light blue to indicate paid status\n\n### Viewing Running Balance\n\n- The sidebar shows **Running Totals** for each pay-bill account\n- Updates automatically as you enter payments\n\n---\n\n## File Location Reference\n\n| Item | Server Path |\n|------|-------------|\n| bills.php | `/var/www/floridaalterations.com/backend/bills.php` |\n| Data directory | `/mnt/drive1/customerdb/` |\n| Database | `/mnt/drive1/customerdb/customer.db` |\n| Backup | `/mnt/drive1/customerdb/backup/` |\n| Logs | `/mnt/drive1/customerdb/logs/` |\n\n---\n\n## Troubleshooting\n\n### Database Connection Error\n\n```\nError: Connection failed\n```\n\n**Solution:**\n```bash\n# Check if MySQL is running\nssh kefa@192.168.7.202\nsudo systemctl status mysql\n# or\nsudo systemctl status mariadb\n```\n\n### Table Doesn't Exist\n\nIf you see errors about missing tables:\n\n```bash\n# The tables are auto-created on first page load\n# Just refresh the page once\n```\n\n### Bank URL Not Opening\n\n- Verify the URL includes `https://` or `http://`\n- Check browser popup blocker settings\n- Some banking sites block popup windows\n\n### Bal After Shows \"—\"\n\n**Causes:**\n1. No bank account selected for the bill\n2. Opening balance not saved for the account\n3. Account is marked as \"Show Balance\" type\n\n**Solution:**\n1. Select a bank account from the dropdown\n2. Save the opening balance for that account\n\n### Changes Not Saving\n\n1. Check browser console for JavaScript errors\n2. Verify network tab shows POST requests completing\n3. Clear browser cache and retry\n\n---\n\n## Quick Commands Reference\n\n```bash\n# Connect to server\nssh kefa@192.168.7.202\n\n# View current bills.php\ncat /var/www/floridaalterations.com/backend/bills.php | head -50\n\n# Backup bills.php before updating\ncp /var/www/floridaalterations.com/backend/bills.php /mnt/drive1/customerdb/backup/bills.php.$(date +%Y%m%d)\n\n# Upload new file\nscp bills.php kefa@192.168.7.202:/var/www/floridaalterations.com/backend/bills.php\n\n# Set correct permissions\nchmod 644 /var/www/floridaalterations.com/backend/bills.php\nchown www-data:www-data /var/www/floridaalterations.com/backend/bills.php\n\n# Check PHP error logs\nssh kefa@192.168.7.202 \"tail -50 /var/log/php*-fpm.log\"\n\n# Restart PHP-FPM if needed\nssh kefa@192.168.7.202 \"sudo systemctl restart php*-fpm\"\n```\n\n---\n\n## Security Notes\n\n- Bank URLs are stored as-is - ensure only trusted users can edit accounts\n- No sensitive data encrypted in the database\n- Consider HTTPS-only for all bank URLs\n- Session-based access control should be configured at the application level\n\n---\n\n## Future Enhancements (Suggested)\n\n1. **Auto-fetch balance** - API integration with banks (requires bank credentials)\n2. **Email notifications** - Remind when bills are due\n3. **Export to CSV** - Download bill history\n4. **Recurring bills** - Auto-create monthly bills\n5. **Budget tracking** - Set monthly budget limits per category\n\n---\n\n## Version History\n\n| Version | Date | Changes |\n|---------|------|---------|\n| 1.0 | April 16, 2026 | Initial release with account types, bank URLs, status pills |\n| - | - | Auto-save functionality |\n| - | - | Save All buttons added |\n\n---\n\n*End of Documentation*\n","is_text_editable":1,"can_edit_inline":1}
[]
{"target_database":"ellas_alterations_backup","tables":[{"source_table":"customers","backup_table":"customers__snapshot_20260411_151957_before_final_input","row_count":3177},{"source_table":"order_items","backup_table":"order_items__snapshot_20260411_151957_before_final_input","row_count":108},{"source_table":"orders","backup_table":"orders__snapshot_20260411_151957_before_final_input","row_count":992},{"source_table":"payments","backup_table":"payments__snapshot_20260411_151957_before_final_input","row_count":1275},{"source_table":"visits","backup_table":"visits__snapshot_20260411_151957_before_final_input","row_count":992}]}
[]
[]
{"target_database":"ellas_alterations_backup","tables":[{"source_table":"customers","backup_table":"customers__snapshot_20260410_171516","row_count":3174},{"source_table":"order_items","backup_table":"order_items__snapshot_20260410_171516","row_count":90},{"source_table":"orders","backup_table":"orders__snapshot_20260410_171516","row_count":979},{"source_table":"payments","backup_table":"payments__snapshot_20260410_171516","row_count":1260},{"source_table":"visits","backup_table":"visits__snapshot_20260410_171516","row_count":979}]}
[]
[]
[]
{"target_database":"ellas_alterations_backup","tables":[{"source_table":"customers","backup_table":"customers__snapshot_20260414_204542","row_count":3243},{"source_table":"visits","backup_table":"visits__snapshot_20260414_204542","row_count":1232},{"source_table":"orders","backup_table":"orders__snapshot_20260414_204542","row_count":1232},{"source_table":"order_items","backup_table":"order_items__snapshot_20260414_204542","row_count":394},{"source_table":"payments","backup_table":"payments__snapshot_20260414_204542","row_count":1315},{"source_table":"customer_totals","backup_table":"customer_totals__snapshot_20260414_204542","row_count":5668},{"source_table":"daily_customer_totals","backup_table":"daily_customer_totals__snapshot_20260414_204542","row_count":546},{"source_table":"customer_payment_transactions","backup_table":"customer_payment_transactions__snapshot_20260414_204542","row_count":2844},{"source_table":"customer_reports","backup_table":"customer_reports__snapshot_20260414_204542","row_count":10943},{"source_table":"visit_signatures","backup_table":"visit_signatures__snapshot_20260414_204542","row_count":70},{"source_table":"visit_activity_log","backup_table":"visit_activity_log__snapshot_20260414_204542","row_count":515},{"source_table":"setmore_appointments","backup_table":"setmore_appointments__snapshot_20260414_204542","row_count":145},{"source_table":"backend_no_show_log","backup_table":"backend_no_show_log__snapshot_20260414_204542","row_count":119},{"source_table":"square_customer_log","backup_table":"square_customer_log__snapshot_20260414_204542","row_count":31},{"source_table":"backend_job_runs","backup_table":"backend_job_runs__snapshot_20260414_204542","row_count":26}]}
[]
{"customer_payment_transaction_id":"5426","payment_id":"63373","order_id":"103787","visit_id":"129034","customer_id":"200483","customer_name":"Christian Sistoso","transaction_date":"2026-04-09 16:59:00","payment_method":"Square","payment_type":"Tip","bucket":"tip","amount":"0.55","tip_amount":"0.55","is_new_customer":"0","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
{"customer_payment_transaction_id":"5412","payment_id":"63336","order_id":"103780","visit_id":"129027","customer_id":"488990","customer_name":"Angela Dixon","transaction_date":"2026-04-07 16:49:00","payment_method":"Square","payment_type":"Full Payment","bucket":"credit","amount":"0.98","tip_amount":"0.00","is_new_customer":"1","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
{"customer_payment_transaction_id":"5413","payment_id":"63337","order_id":"103777","visit_id":"129024","customer_id":"200484","customer_name":"Angela Dixon","transaction_date":"2026-04-07 16:52:00","payment_method":"Square","payment_type":"Full Payment","bucket":"credit","amount":"0.70","tip_amount":"0.00","is_new_customer":"0","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
{"customer_payment_transaction_id":"5414","payment_id":"63338","order_id":"103777","visit_id":"129024","customer_id":"200484","customer_name":"Angela Dixon","transaction_date":"2026-04-07 16:52:00","payment_method":"Square","payment_type":"Tip","bucket":"tip","amount":"0.00","tip_amount":"0.00","is_new_customer":"0","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
{"customer_payment_transaction_id":"5415","payment_id":"63340","order_id":"103758","visit_id":"129005","customer_id":"200483","customer_name":"Christian Sistoso","transaction_date":"2026-04-07 10:44:00","payment_method":"Square","payment_type":"Deposit","bucket":"credit","amount":"0.59","tip_amount":"0.00","is_new_customer":"0","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
{"customer_payment_transaction_id":"5416","payment_id":"63341","order_id":"103758","visit_id":"129005","customer_id":"200483","customer_name":"Christian Sistoso","transaction_date":"2026-04-07 16:58:00","payment_method":"Square","payment_type":"Tip","bucket":"tip","amount":"0.59","tip_amount":"0.59","is_new_customer":"0","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
{"customer_payment_transaction_id":"5417","payment_id":"63350","order_id":"103779","visit_id":"129026","customer_id":"488989","customer_name":"Julie Sahagun","transaction_date":"2026-04-07 11:04:00","payment_method":"Cash","payment_type":"Deposit","bucket":"cash","amount":"100.00","tip_amount":"0.00","is_new_customer":"1","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
{"customer_payment_transaction_id":"5419","payment_id":"63356","order_id":"103785","visit_id":"129032","customer_id":"200483","customer_name":"Christian Sistoso","transaction_date":"2026-04-09 16:19:00","payment_method":"Square","payment_type":"Full Payment","bucket":"credit","amount":"6.41","tip_amount":"0.00","is_new_customer":"0","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
{"customer_payment_transaction_id":"5420","payment_id":"63357","order_id":"103785","visit_id":"129032","customer_id":"200483","customer_name":"Christian Sistoso","transaction_date":"2026-04-09 16:19:00","payment_method":"Square","payment_type":"Tip","bucket":"tip","amount":"0.00","tip_amount":"0.00","is_new_customer":"0","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
{"customer_payment_transaction_id":"5421","payment_id":"63360","order_id":"103784","visit_id":"129031","customer_id":"488991","customer_name":"Angela Dixon","transaction_date":"2026-04-09 16:40:00","payment_method":"Square","payment_type":"Full Payment","bucket":"credit","amount":"3.20","tip_amount":"0.00","is_new_customer":"1","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
{"customer_payment_transaction_id":"5422","payment_id":"63361","order_id":"103784","visit_id":"129031","customer_id":"488991","customer_name":"Angela Dixon","transaction_date":"2026-04-09 16:40:00","payment_method":"Square","payment_type":"Tip","bucket":"tip","amount":"0.00","tip_amount":"0.00","is_new_customer":"1","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
{"customer_payment_transaction_id":"5423","payment_id":"63366","order_id":"103781","visit_id":"129028","customer_id":"488991","customer_name":"Angela Dixon","transaction_date":"2026-04-09 16:53:00","payment_method":"Square","payment_type":"Full Payment","bucket":"credit","amount":"3.34","tip_amount":"0.00","is_new_customer":"1","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
{"customer_payment_transaction_id":"5424","payment_id":"63367","order_id":"103781","visit_id":"129028","customer_id":"488991","customer_name":"Angela Dixon","transaction_date":"2026-04-09 16:53:00","payment_method":"Square","payment_type":"Tip","bucket":"tip","amount":"0.00","tip_amount":"0.00","is_new_customer":"1","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
{"customer_payment_transaction_id":"5425","payment_id":"63372","order_id":"103787","visit_id":"129034","customer_id":"200483","customer_name":"Christian Sistoso","transaction_date":"2026-04-09 16:59:00","payment_method":"Square","payment_type":"Full Payment","bucket":"credit","amount":"2.73","tip_amount":"0.00","is_new_customer":"0","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
[]
{"target_database":"ellas_alterations_backup","tables":[{"source_table":"customers","backup_table":"customers__snapshot_20260414_191633","row_count":3243},{"source_table":"visits","backup_table":"visits__snapshot_20260414_191633","row_count":1232},{"source_table":"orders","backup_table":"orders__snapshot_20260414_191633","row_count":1232},{"source_table":"order_items","backup_table":"order_items__snapshot_20260414_191633","row_count":394},{"source_table":"payments","backup_table":"payments__snapshot_20260414_191633","row_count":1315}]}
[]
{"customer_payment_transaction_id":"5418","payment_id":"63351","order_id":"103779","visit_id":"129026","customer_id":"488989","customer_name":"Julie Sahagun","transaction_date":"2026-04-07 11:04:00","payment_method":"Cash","payment_type":"Full Payment","bucket":"cash","amount":"32.68","tip_amount":"0.00","is_new_customer":"1","source":"payments","created_at":"2026-04-14 15:13:42","updated_at":"2026-04-14 15:13:42"}
{"deleted":true}
[]
[]
{"customer_date":"2026-04-07T19:12","customer_name":"Manual Entry Testing Square","dopu_can":"Pick Up","edwards":0,"edwards_type":"","update_flag":""}
[]
[]
{"customer_date":"2026-04-09T19:11","customer_name":"Edwards Delivery","dopu_can":"Edwards","edwards":150,"edwards_type":"other","update_flag":""}
{"type":"TypeError","file":"/mnt/drive1/customerdb/backend/payment_ledger_service.php","line":103,"trace":"#0 /mnt/drive1/customerdb/backend/jobs/rebuild_payment_ledger.php(26): app_payment_ledger_rebuild_range()\n#1 {main}"}
{"file":"/mnt/drive1/customerdb/backend/jobs/rebuild_payment_ledger.php","line":26,"severity_code":2}
[]
[]
[]
[]
{"customer_payment_transaction_id":"4958","payment_id":"63756","order_id":"104088","visit_id":"129335","customer_id":"489028","customer_name":"Tessa Sa","transaction_date":"2026-04-12 00:00:00","payment_method":"Square","payment_type":"Tip","bucket":"tip","amount":"25.06","tip_amount":"25.06","is_new_customer":"0","source":"payments","created_at":"2026-04-14 14:02:33","updated_at":"2026-04-14 14:02:33"}
{"customer_payment_transaction_id":"4958","payment_id":"63756","order_id":"104088","visit_id":"129335","customer_id":"489028","customer_name":"Tessa Sa","transaction_date":"2026-04-12 00:00:00","payment_method":"Square","payment_type":"Tip","bucket":"tip","amount":"25.06","tip_amount":"0.00","is_new_customer":"0","source":"payments","created_at":"2026-04-14 14:02:00","updated_at":"2026-04-14 14:02:00"}
[]
{"content_item_id":"122","legacy_access_id":"65","slug":"headtotoesuitoverview","title":"A Tailor’s Guide: What Is The Head to Toe Suit Overview.","canonical_url":"link","short_url":null,"speakable_url":null,"status":"draft","workflow_state":"pending","review_count":"0","is_web_complete":"0","is_social_complete":"0","is_complete":"0","legacy_short_name":"HeadtoToeSuitOverview","legacy_short_name_1":"continue section \"Introduction: A Suit Is Not Just Clothing, It’s A System\" do not include the title, Provide a comprehensive 500-600 word overview \" , leaving no stone unturned and illuminating even the subtlest nuances, remember do not use the em-dash","legacy_short_name_2":"Introduction: A Suit Is Not Just Clothing, It’s A System\n\nSection 1: What Head to Toe Suit Fit Really Means\n\nSection 2: Why Tailors Look at the Whole Suit, Not One Wrinkle\n\nSection 3: Shoulders and Chest Are the Foundation of Structure\n\nSection 4: Waist","legacy_short_name_3":null,"source_batch_id":"4","source_row_number":"61","created_at":"2026-03-20 12:11:11","updated_at":"2026-03-24 09:18:36"}
{"content_item_id":"122","legacy_access_id":"65","slug":"headtotoesuitoverview","title":"A Tailor's Guide: What Is The Head to Toe Suit Overview.","canonical_url":"link","short_url":null,"speakable_url":null,"status":"draft","workflow_state":"pending","review_count":"0","is_web_complete":"0","is_social_complete":"0","is_complete":"0","legacy_short_name":"HeadtoToeSuitOverview","legacy_short_name_1":"continue section \"Introduction: A Suit Is Not Just Clothing, It’s A System\" do not include the title, Provide a comprehensive 500-600 word overview \" , leaving no stone unturned and illuminating even the subtlest nuances, remember do not use the em-dash","legacy_short_name_2":"Introduction: A Suit Is Not Just Clothing, It’s A System\n\nSection 1: What Head to Toe Suit Fit Really Means\n\nSection 2: Why Tailors Look at the Whole Suit, Not One Wrinkle\n\nSection 3: Shoulders and Chest Are the Foundation of Structure\n\nSection 4: Waist","legacy_short_name_3":null,"source_batch_id":"4","source_row_number":"61","created_at":"2026-03-20 12:11:11","updated_at":"2026-04-13 16:09:52"}
{"file_name":"END_OF_DAY_2026-04-13.md","mime_type":"application/octet-stream"}
[]
{"backend_document_id":"17","document_type":"upload","title":"Codex - End of day documentation 04-13-26","slug":"codex-end-of-day-documentation-04-13-26","summary_text":"Codex - End of day documentation 04-13-26","content_markdown":null,"content_html":null,"file_name":"END_OF_DAY_2026-04-13.md","stored_name":"20260413-200137-4e26a8e2.md","mime_type":"application/octet-stream","file_size_bytes":"11054","storage_path":"/mnt/drive1/customerdb/backend/documents_storage/20260413-200137-4e26a8e2.md","is_deleted":"0","created_at":"2026-04-13 16:01:37","updated_at":"2026-04-13 16:01:37","editor_content":"# End Of Day Documentation - April 13, 2026\n\n## Session Scope\nThis document captures the production fixes and feature work completed on **Monday, April 13, 2026** for Florida Alterations CustomerDB, focused on:\n\n- totals correctness (today, month, and year comparison)\n- rebuild operations from backend UI\n- visit save stability and data sync\n- range-to-unit pricing behavior\n- Square payment traceability and reporting\n- next-day email cron stability\n\nThis is the end-of-day technical handoff and restart guide for tomorrow.\n\n---\n\n## Executive Summary\nToday we stabilized and aligned core reporting with business rules:\n\n1. **Year Comparison fixed** to use full prior month totals (not prior-year MTD comparable day).\n2. **Today totals fixed** to use strict `payments.payment_date` logic for today pills.\n3. **Totals rebuild UI added** so customer/daily rebuild can be run from backend (no SSH needed).\n4. **Range pricing behavior fixed** so range text parses last amount into unit price only on blur (no typing interruption).\n5. **Square customer history implemented** (new table + logging + customer history page + visit button integration).\n6. **Next-day emails cron fixed** for schema variance (`status` column missing in `setmore_appointments`).\n\n---\n\n## Business Rules Locked In Today\n\n## 1) Year Comparison\n- Prior implementation used prior-year MTD comparable day and showed values like `3858.83` for April 2025 MTD.\n- New behavior for year comparison uses **full prior month** range (example: `2025-04-01` through `2025-04-30`), showing `10215.20` for April 2025 when daily totals table contains that total.\n- Comparable-day value is still provided in API as `last_year_mtd` for any future UI that still needs it.\n\n## 2) Today totals\n- `today_totals` now use **strict payment-date window**:\n - `payment_date >= today 00:00:00`\n - `payment_date < tomorrow 00:00:00`\n- This avoids inflated totals from `COALESCE(payment_date, NOW())` when historical rows have NULL payment_date.\n\n## 3) Range field behavior\n- Range text accepts values such as `100-250` or `$100 - $250`.\n- Last numeric value (`250`) is applied to `unit_price`.\n- Auto-fill now occurs only **on field blur** (loss of focus), not on every keystroke.\n\n## 4) Square logging (go-forward model)\n- No historical backfill was forced today.\n- Going forward, each Square save writes structured rows to a new log table.\n- Front desk can open customer-specific Square history from visit screen.\n\n---\n\n## Implemented Changes (Detailed)\n\n## A. Totals + Reporting API changes\n\n### Files updated\n- `frontend/api/totals_snapshot.php`\n- `frontend/api/totals_snapshot_live.php`\n- `webui/api/totals_snapshot.php`\n- `webui/api/totals_snapshot_live.php`\n\n### What changed\n1. Year comparison `last_year` switched from prior-year comparable-day MTD to prior-year **full month**.\n2. Added `last_year_mtd` payload key for optional MTD comparisons.\n3. Added strict today payment aggregation function for `today_totals` to avoid NULL-date inflation.\n\n### Outcome\n- Year comparison now aligns with accounting expectation for full month.\n- Today pills align with strict payment rows and expected values (example target discussed: cash `32.06`, credit including tips `424.25`).\n\n---\n\n## B. Backend rebuild tooling\n\n### File added\n- `backend/totals_rebuild.php`\n\n### File updated\n- `backend/index.php` (link added to Totals Rebuild page)\n\n### Mirror route added\n- `webui/backend/totals_rebuild.php` (thin loader to canonical backend page)\n\n### What changed\n- Added backend UI to run:\n - customer totals rebuild for date range\n - daily totals rebuild for date range\n- Added quick compare widget showing today payments vs daily table buckets.\n\n### Outcome\n- Rebuild operations no longer require SSH for normal operations.\n\n---\n\n## C. Customer totals date attribution correction\n\n### Files updated\n- `backend/customer_totals_sync_service.php`\n- `frontend/api/visit_save.php` (local totals sync path)\n\n### What changed\n- Removed logic that shifted `customer_totals.customer_date` to latest payment date.\n- Restored visit-date attribution to prevent old deposits being dragged into today.\n\n### Outcome\n- Eliminated recurring `$30` day-shift drift pattern in daily totals.\n\n---\n\n## D. Visit save and frontend stability improvements\n\n### Files updated\n- `frontend/api/visit_save.php`\n- `frontend/api/visit_delete.php`\n- `frontend/visit.html`\n\n### What changed\n- Added local totals sync helper flow in visit save to avoid include/redeclare fatal paths.\n- Ensured save updates:\n - payment ledger sync\n - `customer_totals` upsert for visit\n - daily totals rebuild for affected date\n- Fixed deposit behavior edge in visit form load/save path.\n\n### Outcome\n- Visit save is stable and returns valid JSON in known fatal edge paths previously reported.\n\n---\n\n## E. Next-day customer emails cron fix\n\n### File updated\n- `backend/jobs/send_nextday_customer_emails.php`\n\n### Problem\n- Cron failed with:\n - `Unknown column 'sa.status' in 'WHERE'`\n\n### Fix\n- Added schema-aware status resolution:\n - prefers `status` if present\n - falls back to `label` or `status_label` when available\n - if none present, job still runs without status predicate\n\n### Outcome\n- Job no longer hard-fails on column mismatch.\n\n---\n\n## F. Range parsing -> unit price behavior\n\n### Files updated\n- `frontend/visit.html`\n- `frontend/api/visit_save.php`\n- `backend/visit.php`\n- `backend/visit_service.php`\n\n### What changed\n- Implemented parser to extract last numeric token from range label.\n- Applies value to `unit_price`.\n- UI only triggers on blur to avoid interrupting typing.\n- Server-side also enforces same rule for consistency.\n\n### Outcome\n- Staff can enter flexible range text while keeping reliable unit pricing for repeat visits.\n\n---\n\n## G. Square reporting and customer history\n\n### Files added\n- `backend/square_payments_report.php`\n- `webui/backend/square_payments_report.php` (mirror route)\n- `frontend/api/square_customer_log.php`\n- `frontend/square_customer.html`\n\n### Files updated\n- `backend/index.php` (Square Details link)\n- `frontend/visit.html` (Square Customer button behavior)\n- `frontend/api/visit_save.php` (log writes + table creation + duplicate guard)\n\n### New table\n- `square_customer_log` (auto-created in visit save path)\n\n### Captured fields\n- customer/visit/order identifiers\n- customer name/phone/email snapshots\n- event_type/message\n- Square reference fields:\n - payment_id\n - receipt_number\n - checkout_id\n - card_brand\n - last_4\n- payment method/type\n- amount/tip/total\n- structured details JSON\n- created_at timestamp\n\n### Behavior\n- On Square save, log entries are written for customer.\n- Duplicate guard prevents repeated identical inserts from repeated save clicks.\n- Visit screen `Square Customer` button now opens local customer history page pre-filtered by current visit customer.\n- Customer page includes quick external Square Directory open button.\n\n### Outcome\n- Front desk has immediate traceability for Square transactions/messages per customer going forward.\n\n---\n\n## Verification Performed\n\n## Syntax checks completed\nUsing `C:\\php\\php.exe -l` on all modified/added PHP files in this session:\n\n- `backend/customer_totals_sync_service.php`\n- `frontend/api/visit_save.php`\n- `backend/index.php`\n- `webui/backend/totals_rebuild.php`\n- `frontend/api/totals_snapshot.php`\n- `frontend/api/totals_snapshot_live.php`\n- `webui/api/totals_snapshot.php`\n- `webui/api/totals_snapshot_live.php`\n- `backend/jobs/send_nextday_customer_emails.php`\n- `backend/visit_service.php`\n- `backend/square_payments_report.php`\n- `webui/backend/square_payments_report.php`\n- `backend/visit.php`\n- `frontend/api/square_customer_log.php`\n\nAll lint checks passed with no syntax errors.\n\n## Data validation evidence reviewed\n- Workbook validation confirmed:\n - strict today rows matched expected payment set\n - prior-year MTD (`3858.83`) vs full-month (`10215.20`) mismatch source identified\n- Query results validated that full-month April 2025 totals are correct in both:\n - `daily_customer_totals`\n - `customer_totals`\n\n---\n\n## Operational Runbook (Current)\n\n## Rebuild UI\n- URL: `/backend/totals_rebuild.php`\n- Recommended range for live rebuild window:\n - `2026-04-10` to current date\n\n## Next-day emails dry-run\n```bash\nphp8.3 /mnt/drive1/customerdb/backend/jobs/send_nextday_customer_emails.php --dry-run\n```\n\n## Square detail report\n- URL: `/backend/square_payments_report.php`\n\n## Customer-specific Square history from visit\n- Visit page button: `Square Customer`\n- Opens local page:\n - `/square_customer.html?...`\n\n---\n\n## Open Items / Pending (Next Session)\n\n1. Confirm production deployment of all new files and mirror routes.\n2. Validate next-day cron in production after schema-aware status fix.\n3. Add optional backend module card for direct access to customer Square history page.\n4. Add optional import/backfill utility for `square_customer_log` from existing `visit_activity_log` for partial historical visibility (if desired).\n5. Monitor today/tomorrow totals for drift and confirm no reintroduction of payment-date shifting.\n6. Validate front-desk workflow on range blur behavior across both frontend and backend visit editors.\n\n---\n\n## Risks / Notes\n\n- Existing repository is heavily dirty with many unrelated changes; work was targeted to requested paths only.\n- Some backend pages are mirrored through `webui/backend` thin loaders; ensure deployment copies both canonical and mirror files where required.\n- Square log is go-forward by design; historical completeness is not guaranteed unless a dedicated backfill is added.\n\n---\n\n## Quick Diff Focus (Today’s primary touched paths)\n\n- `frontend/api/totals_snapshot.php`\n- `frontend/api/totals_snapshot_live.php`\n- `webui/api/totals_snapshot.php`\n- `webui/api/totals_snapshot_live.php`\n- `backend/totals_rebuild.php`\n- `webui/backend/totals_rebuild.php`\n- `backend/index.php`\n- `backend/customer_totals_sync_service.php`\n- `frontend/api/visit_save.php`\n- `frontend/api/visit_delete.php`\n- `frontend/visit.html`\n- `backend/visit.php`\n- `backend/visit_service.php`\n- `backend/jobs/send_nextday_customer_emails.php`\n- `backend/square_payments_report.php`\n- `webui/backend/square_payments_report.php`\n- `frontend/api/square_customer_log.php`\n- `frontend/square_customer.html`\n\n---\n\n## Status Summary\n\n- **DONE**\n - Year comparison full-month fix\n - Today strict payment-date totals fix\n - Backend totals rebuild UI + link + mirror route\n - Range blur-only auto-fill and parser\n - Next-day email schema mismatch fix\n - Square details report page\n - Square go-forward per-customer log (table + writes + API + page + visit button integration)\n\n- **VERIFIED**\n - Syntax checks pass on all changed PHP paths\n - Workbook query analysis validated root causes and corrected logic direction\n - Year comparison now aligned to full-month model\n\n- **BLOCKED / NOT COMPLETED TODAY**\n - Historical Square backfill into new log table (not done by design; go-forward only)\n - Broader production smoke test across all modules after deployment\n\n","is_text_editable":1,"can_edit_inline":1}
{"file_name":"TOTALS_CUTOFF_2026-04-12.odt","mime_type":"application/vnd.oasis.opendocument.text"}
[]
{"backend_document_id":"16","document_type":"upload","title":"Codex - 04-13 All Customer Totals Tables and Logic","slug":"codex-04-13-all-customer-totals-tables-and-logic","summary_text":"Codex - 04-13 All Customer Totals Tables and Logic","content_markdown":null,"content_html":null,"file_name":"TOTALS_CUTOFF_2026-04-12.odt","stored_name":"20260412-190147-cdbfac59.odt","mime_type":"application/vnd.oasis.opendocument.text","file_size_bytes":"31229","storage_path":"/mnt/drive1/customerdb/backend/documents_storage/20260412-190147-cdbfac59.odt","is_deleted":"0","created_at":"2026-04-12 15:01:47","updated_at":"2026-04-12 15:01:47","editor_content":"Totals Cutover Documentation Date: 2026-04-12 Cutover Date: 2026-04-10 Purpose This documents the totals logic now used by the dashboard snapshot endpoints after go-live. Rule: Through 2026-04-09 : use imported totals from customer_totals Starting 2026-04-10 : use live payment data from payments This change was applied to: frontend/api/totals_snapshot.php frontend/api/totals_snapshot_live.php webui/api/totals_snapshot.php webui/api/totals_snapshot_live.php Current Logic The application now uses this date split: If the requested range ends before 2026-04-10 Read totals from customer_totals Fallback to CustomerTotals only if customer_totals has no rows for that range If the requested range starts on or after 2026-04-10 Read totals from live payments joined to orders , visits , and customers If the requested range crosses the cutoff Sum customer_totals for the pre-cutover side Sum live payments for the post-cutover side Add the two result sets together Fallback behavior If neither side returns data, the code can still fall back to: customer_payment_transactions daily_customer_totals customer_totals CustomerTotals Those are safety fallbacks only, not the intended source-of-truth for this cutover rule Tables Used Primary tables: customer_totals Imported totals table Source of truth for dates through 2026-04-09 payments Live payment rows Source of truth for dates on and after 2026-04-10 orders Used to connect payments to visits visits Used for visit date and customer linkage customers Used for customer counts and is_new_customer Fallback and audit tables: CustomerTotals Legacy Access-style table name Fallback only daily_customer_totals Stored daily rollups Fallback/audit only customer_payment_transactions Ledger table Useful for reconciliation and auditing Not the primary source for the current dashboard cutover logic Totals Columns Imported totals columns: total_customers new_customers cash_sales check_sales credit_card_sales edwards total_sales total_sales_no_edwards Live payment totals are calculated into these output buckets: total_customers new_customers cash check credit tips edwards total_sales total_sales_no_edwards Notes: customer_totals does not have a dedicated tips column For imported totals, tips are effectively included wherever they were represented in the import values In live totals, tips are broken out separately and also still contribute to total_sales In live totals, credit excludes cash , check , and edwards No Application DB View Required The application does not currently require a database view for this logic. It is implemented directly in PHP in the four snapshot endpoints listed above. If you want a database-level validation helper, use the optional views below. Optional Validation Views These views are for manual validation only. They are not required by the app. 1. Imported totals through 2026-04-09 CREATE OR REPLACE VIEW vw_totals_import_pre_2026_04_10 AS SELECT DATE(customer_date) AS totals_date, SUM(COALESCE(total_customers, 0)) AS total_customers, SUM(COALESCE(new_customers, 0)) AS new_customers, ROUND(SUM(COALESCE(cash_sales, 0)), 2) AS cash, ROUND(SUM(COALESCE(check_sales, 0)), 2) AS `check`, ROUND(SUM(COALESCE(credit_card_sales, 0)), 2) AS credit, 0.00 AS tips, ROUND(SUM(COALESCE(edwards, 0)), 2) AS edwards, ROUND(SUM(COALESCE(total_sales, COALESCE(cash_sales,0)+COALESCE(check_sales,0)+COALESCE(credit_card_sales,0)+COALESCE(edwards,0))), 2) AS total_sales, ROUND(SUM(COALESCE(total_sales_no_edwards, COALESCE(cash_sales,0)+COALESCE(check_sales,0)+COALESCE(credit_card_sales,0))), 2) AS total_sales_no_edwards FROM customer_totals WHERE DATE(customer_date) <= '2026-04-09' GROUP BY DATE(customer_date); 2. Live totals from 2026-04-10 forward CREATE OR REPLACE VIEW vw_totals_live_post_2026_04_09 AS SELECT DATE(COALESCE(p.payment_date, o.created_at, v.visit_date)) AS totals_date, COUNT(DISTINCT c.customer_id) AS total_customers, COUNT(DISTINCT CASE WHEN COALESCE(c.is_new_customer, 0) = 1 THEN c.customer_id END) AS new_customers, ROUND(SUM(CASE WHEN (LOWER(COALESCE(p.payment_method, '')) LIKE '%cash%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%cash%') AND NOT ( LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' ) THEN p.amount ELSE 0 END), 2) AS cash, ROUND(SUM(CASE WHEN (LOWER(COALESCE(p.payment_method, '')) LIKE '%check%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%check%') AND NOT ( LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' ) THEN p.amount ELSE 0 END), 2) AS `check`, ROUND(SUM(CASE WHEN LOWER(COALESCE(p.payment_type, '')) LIKE '%tip%' THEN p.amount ELSE 0 END), 2) AS tips, ROUND(SUM(CASE WHEN (LOWER(COALESCE(p.payment_method, '')) LIKE '%cash%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%cash%') OR (LOWER(COALESCE(p.payment_method, '')) LIKE '%check%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%check%') OR LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' THEN 0 ELSE p.amount END), 2) AS credit, ROUND(SUM(CASE WHEN LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' THEN p.amount ELSE 0 END), 2) AS edwards, ROUND(SUM(COALESCE(p.amount, 0)), 2) AS total_sales, ROUND(SUM(CASE WHEN LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' THEN 0 ELSE COALESCE(p.amount, 0) END), 2) AS total_sales_no_edwards FROM payments p LEFT JOIN orders o ON o.order_id = p.order_id LEFT JOIN visits v ON v.visit_id = o.visit_id LEFT JOIN customers c ON c.customer_id = v.customer_id WHERE DATE(COALESCE(p.payment_date, o.created_at, v.visit_date)) >= '2026-04-10' GROUP BY DATE(COALESCE(p.payment_date, o.created_at, v.visit_date)); 3. Combined validation view CREATE OR REPLACE VIEW vw_totals_cutover_2026_04_10 AS SELECT * FROM vw_totals_import_pre_2026_04_10 UNION ALL SELECT * FROM vw_totals_live_post_2026_04_09; Copy/Paste Validation Queries A. Check imported totals only for 2026-04-09 and earlier SELECT ROUND(SUM(COALESCE(total_sales, COALESCE(cash_sales,0)+COALESCE(check_sales,0)+COALESCE(credit_card_sales,0)+COALESCE(edwards,0))), 2) AS total_sales, ROUND(SUM(COALESCE(total_sales_no_edwards, COALESCE(cash_sales,0)+COALESCE(check_sales,0)+COALESCE(credit_card_sales,0))), 2) AS total_sales_no_edwards, ROUND(SUM(COALESCE(cash_sales, 0)), 2) AS cash, ROUND(SUM(COALESCE(check_sales, 0)), 2) AS `check`, ROUND(SUM(COALESCE(credit_card_sales, 0)), 2) AS credit, ROUND(SUM(COALESCE(edwards, 0)), 2) AS edwards, SUM(COALESCE(total_customers, 0)) AS total_customers, SUM(COALESCE(new_customers, 0)) AS new_customers FROM customer_totals WHERE DATE(customer_date) BETWEEN '2026-04-01' AND '2026-04-09'; B. Check live totals only for 2026-04-10 and later SELECT ROUND(SUM(CASE WHEN (LOWER(COALESCE(p.payment_method, '')) LIKE '%cash%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%cash%') AND NOT ( LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' ) THEN p.amount ELSE 0 END), 2) AS cash, ROUND(SUM(CASE WHEN (LOWER(COALESCE(p.payment_method, '')) LIKE '%check%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%check%') AND NOT ( LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' ) THEN p.amount ELSE 0 END), 2) AS `check`, ROUND(SUM(CASE WHEN LOWER(COALESCE(p.payment_type, '')) LIKE '%tip%' THEN p.amount ELSE 0 END), 2) AS tips, ROUND(SUM(CASE WHEN (LOWER(COALESCE(p.payment_method, '')) LIKE '%cash%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%cash%') OR (LOWER(COALESCE(p.payment_method, '')) LIKE '%check%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%check%') OR LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' THEN 0 ELSE p.amount END), 2) AS credit, ROUND(SUM(CASE WHEN LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' THEN p.amount ELSE 0 END), 2) AS edwards, ROUND(SUM(COALESCE(p.amount, 0)), 2) AS total_sales, ROUND(SUM(CASE WHEN LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' THEN 0 ELSE COALESCE(p.amount, 0) END), 2) AS total_sales_no_edwards, COUNT(DISTINCT c.customer_id) AS total_customers, COUNT(DISTINCT CASE WHEN COALESCE(c.is_new_customer, 0) = 1 THEN c.customer_id END) AS new_customers FROM payments p LEFT JOIN orders o ON o.order_id = p.order_id LEFT JOIN visits v ON v.visit_id = o.visit_id LEFT JOIN customers c ON c.customer_id = v.customer_id WHERE DATE(COALESCE(p.payment_date, o.created_at, v.visit_date)) BETWEEN '2026-04-10' AND '2026-04-12'; C. Check month total using the same cutover logic as the app SELECT ROUND(SUM(total_sales), 2) AS total_sales, ROUND(SUM(total_sales_no_edwards), 2) AS total_sales_no_edwards, ROUND(SUM(cash), 2) AS cash, ROUND(SUM(`check`), 2) AS `check`, ROUND(SUM(credit), 2) AS credit, ROUND(SUM(tips), 2) AS tips, ROUND(SUM(edwards), 2) AS edwards, SUM(total_customers) AS total_customers, SUM(new_customers) AS new_customers FROM ( SELECT ROUND(SUM(COALESCE(total_sales, COALESCE(cash_sales,0)+COALESCE(check_sales,0)+COALESCE(credit_card_sales,0)+COALESCE(edwards,0))), 2) AS total_sales, ROUND(SUM(COALESCE(total_sales_no_edwards, COALESCE(cash_sales,0)+COALESCE(check_sales,0)+COALESCE(credit_card_sales,0))), 2) AS total_sales_no_edwards, ROUND(SUM(COALESCE(cash_sales, 0)), 2) AS cash, ROUND(SUM(COALESCE(check_sales, 0)), 2) AS `check`, ROUND(SUM(COALESCE(credit_card_sales, 0)), 2) AS credit, 0.00 AS tips, ROUND(SUM(COALESCE(edwards, 0)), 2) AS edwards, SUM(COALESCE(total_customers, 0)) AS total_customers, SUM(COALESCE(new_customers, 0)) AS new_customers FROM customer_totals WHERE DATE(customer_date) BETWEEN '2026-04-01' AND '2026-04-09' UNION ALL SELECT ROUND(SUM(COALESCE(p.amount, 0)), 2) AS total_sales, ROUND(SUM(CASE WHEN LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' THEN 0 ELSE COALESCE(p.amount, 0) END), 2) AS total_sales_no_edwards, ROUND(SUM(CASE WHEN (LOWER(COALESCE(p.payment_method, '')) LIKE '%cash%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%cash%') AND NOT ( LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' ) THEN p.amount ELSE 0 END), 2) AS cash, ROUND(SUM(CASE WHEN (LOWER(COALESCE(p.payment_method, '')) LIKE '%check%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%check%') AND NOT ( LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' ) THEN p.amount ELSE 0 END), 2) AS `check`, ROUND(SUM(CASE WHEN (LOWER(COALESCE(p.payment_method, '')) LIKE '%cash%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%cash%') OR (LOWER(COALESCE(p.payment_method, '')) LIKE '%check%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%check%') OR LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' THEN 0 ELSE p.amount END), 2) AS credit, ROUND(SUM(CASE WHEN LOWER(COALESCE(p.payment_type, '')) LIKE '%tip%' THEN p.amount ELSE 0 END), 2) AS tips, ROUND(SUM(CASE WHEN LOWER(COALESCE(p.payment_method, '')) LIKE '%edward%' OR LOWER(COALESCE(p.payment_type, '')) LIKE '%edward%' OR LOWER(COALESCE(o.order_status, '')) LIKE '%edward%' OR LOWER(COALESCE(v.visit_type, '')) LIKE '%edward%' OR LOWER(COALESCE(NULLIF(c.full_name, ''), v.customer_name_snapshot, '')) LIKE '%edward%' THEN p.amount ELSE 0 END), 2) AS edwards, COUNT(DISTINCT c.customer_id) AS total_customers, COUNT(DISTINCT CASE WHEN COALESCE(c.is_new_customer, 0) = 1 THEN c.customer_id END) AS new_customers FROM payments p LEFT JOIN orders o ON o.order_id = p.order_id LEFT JOIN visits v ON v.visit_id = o.visit_id LEFT JOIN customers c ON c.customer_id = v.customer_id WHERE DATE(COALESCE(p.payment_date, o.created_at, v.visit_date)) BETWEEN '2026-04-10' AND '2026-04-12' ) t; Quick Daily Checks Check one day from imported totals: SELECT * FROM customer_totals WHERE DATE(customer_date) = '2026-04-09'; Check one day from live payments: SELECT p.payment_id, p.order_id, v.visit_id, c.customer_id, c.full_name, p.payment_date, p.payment_method, p.payment_type, p.amount FROM payments p LEFT JOIN orders o ON o.order_id = p.order_id LEFT JOIN visits v ON v.visit_id = o.visit_id LEFT JOIN customers c ON c.customer_id = v.customer_id WHERE DATE(COALESCE(p.payment_date, o.created_at, v.visit_date)) = '2026-04-10' ORDER BY COALESCE(p.payment_date, o.created_at, v.visit_date), p.payment_id; Related Files totals_snapshot.php totals_snapshot_live.php totals_snapshot.php totals_snapshot_live.php totals_service.php report_totals_audit.php","is_text_editable":1,"can_edit_inline":0}
[]
{"customer_payment_transaction_id":"4499","payment_id":"63617","order_id":"104082","visit_id":"129329","customer_id":"3534","customer_name":"Zuheily Castaneda","transaction_date":"2026-04-12 10:30:00","payment_method":"Credit Card","payment_type":"Deposit","bucket":"credit","amount":"100.00","tip_amount":"0.00","is_new_customer":"0","source":"payments","created_at":"2026-04-12 13:45:19","updated_at":"2026-04-12 13:45:19"}
{"customer_payment_transaction_id":"4499","payment_id":"63617","order_id":"104082","visit_id":"129329","customer_id":"3534","customer_name":"Zuheily Castaneda","transaction_date":"2026-03-29 10:30:00","payment_method":"Credit Card","payment_type":"Deposit","bucket":"credit","amount":"100.00","tip_amount":"0.00","is_new_customer":"0","source":"payments","created_at":"2026-04-12 13:45:00","updated_at":"2026-04-12 13:45:00"}
[]
{"customer_payment_transaction_id":"4500","payment_id":"63618","order_id":"104082","visit_id":"129329","customer_id":"3534","customer_name":"Zuheily Castaneda","transaction_date":"2026-04-12 10:30:00","payment_method":"Credit Card","payment_type":"Balance","bucket":"credit","amount":"104.93","tip_amount":"0.00","is_new_customer":"0","source":"payments","created_at":"2026-04-12 13:45:19","updated_at":"2026-04-12 13:45:19"}
{"customer_payment_transaction_id":"4500","payment_id":"63618","order_id":"104082","visit_id":"129329","customer_id":"3534","customer_name":"Zuheily Castaneda","transaction_date":"2026-03-29 10:30:00","payment_method":"Credit Card","payment_type":"Balance","bucket":"credit","amount":"104.93","tip_amount":"0.00","is_new_customer":"0","source":"payments","created_at":"2026-04-12 13:45:00","updated_at":"2026-04-12 13:45:00"}
[]
{"payment_id":"63617","order_id":"104082","payment_date":"2026-04-12 00:00:00","payment_type":"Deposit","payment_method":"Credit Card","amount":"100.00","notes":null,"legacy_payment_id":null,"source_payment_key":null}
{"payment_id":"63617","order_id":"104082","payment_date":"2026-03-29 00:00:00","payment_type":"Deposit","payment_method":"Credit Card","amount":"100.00","notes":null,"legacy_payment_id":null,"source_payment_key":null}
[]
{"payment_id":"63618","order_id":"104082","payment_date":"2026-04-12 00:00:00","payment_type":"Balance","payment_method":"Credit Card","amount":"104.93","notes":null,"legacy_payment_id":null,"source_payment_key":null}
{"payment_id":"63618","order_id":"104082","payment_date":"2026-03-29 00:00:00","payment_type":"Balance","payment_method":"Credit Card","amount":"104.93","notes":null,"legacy_payment_id":null,"source_payment_key":null}
{"file_name":"IMPLEMENTATION_STATUS_2026-04-12.md","mime_type":"application/octet-stream"}
[]
{"backend_document_id":"15","document_type":"upload","title":"Codes - 04-13-2026 DONE / VERIFIED / BLOCKED","slug":"codes-04-13-2026-done-verified-blocked","summary_text":"Codes - 04-13-2026 DONE / VERIFIED / BLOCKED","content_markdown":null,"content_html":null,"file_name":"IMPLEMENTATION_STATUS_2026-04-12.md","stored_name":"20260412-164417-5a72fe80.md","mime_type":"application/octet-stream","file_size_bytes":"5341","storage_path":"/mnt/drive1/customerdb/backend/documents_storage/20260412-164417-5a72fe80.md","is_deleted":"0","created_at":"2026-04-12 12:44:17","updated_at":"2026-04-12 12:44:17","editor_content":"# CustomerDB Implementation Status\n\nDate: 2026-04-12\nOwner: Codex + Front Desk Team\nFormat: DONE / VERIFIED / BLOCKED\n\n## DONE\n\n- Added cron smoke-test preflight for morning jobs:\n - `backend/jobs/smoke_morning_jobs.php`\n - Wired in cron manager command chain:\n - `backend/cron_manager.php`\n - `backend/README.md`\n\n- Fixed unified appointments SQL ambiguity (`customer_id`) and stabilized combined feed:\n - `backend/appointment_service.php`\n\n- Implemented Setmore import lock + booking source + stronger note extraction:\n - `backend/setmore_service.php`\n - `backend/morning_jobs_service.php`\n - `backend/install_schema.php`\n\n- Added single transaction ledger foundation (`customer_payment_transactions`) and tip support:\n - `backend/install_schema.php`\n - `backend/payment_ledger_service.php`\n - `backend/payment_ledger.php`\n - `backend/live_table_manager_service.php`\n\n- Added ledger rebuild and legacy CSV import tooling:\n - `backend/jobs/rebuild_payment_ledger.php`\n - `backend/jobs/import_customer_totals_csv_to_ledger.php`\n\n- Added reconciliation and audit backend modules:\n - `backend/report_reconciliation.php`\n - `backend/report_totals_audit.php`\n - `backend/report_unmatched.php`\n - Linked in:\n - `backend/reports.php`\n - `backend/index.php`\n\n- Switched report/snapshot paths to ledger-first behavior with fallbacks:\n - `backend/report_service.php`\n - `frontend/api/totals_snapshot.php`\n - `frontend/api/totals_snapshot_live.php`\n - `webui/api/totals_snapshot.php`\n - `webui/api/totals_snapshot_live.php`\n\n- Stabilized visit save and item type persistence:\n - `frontend/api/visit_save.php`\n - `frontend/api/visit_get.php`\n - `frontend/api/visit_report_generate.php`\n - `backend/visit_service.php`\n - migration:\n - `migrations/20260411_order_items_item_type_name_no_fk.sql`\n - schema:\n - `mariadb_core_schema.sql`\n\n- Updated receipt/work-order logic to prefer ledger totals:\n - `frontend/receipt.html`\n - `frontend/work_order.html`\n - `frontend/api/visit_get.php`\n - `frontend/api/visit_report_generate.php`\n\n- Updated visit email receipt generation to use live visit data and ledger-aware totals:\n - `frontend/visit.html`\n\n- Payroll robustness updates (Yana/Jana alias handling, paste parser hardening, clearer import diagnostics):\n - `backend/payroll_service.php`\n - `backend/payroll.php`\n\n- Added frontend activity monitor for backend checks:\n - `backend/frontend_activity.php`\n\n- Added frontend item type management page and APIs:\n - `frontend/item_types.html`\n - `frontend/api/item_type_update.php`\n - `frontend/api/item_type_delete.php`\n\n- Fixed front desk title/refresh weird text artifacts:\n - `frontend/index.html`\n\n- Introduced backend canonical loaders under `webui/backend/*` to reduce drift:\n - Example files:\n - `webui/backend/bootstrap.php`\n - `webui/backend/payment_ledger.php`\n - `webui/backend/report_reconciliation.php`\n\n## VERIFIED\n\n- Morning cron smoke chain is working from user-provided run output:\n - smoke test passes\n - morning jobs run completes with `Exit Code: 0`\n\n- Legacy import command executed successfully by user:\n - imported rows: `2757`\n - date range imported: `2023-12-24` to `2026-04-06`\n - forward resync rows: `55`\n\n- PHP syntax check passed for critical modules:\n - `backend/payment_ledger.php`\n - `backend/payment_ledger_service.php`\n - `backend/report_reconciliation.php`\n - `backend/report_totals_audit.php`\n - `backend/jobs/import_customer_totals_csv_to_ledger.php`\n - `backend/jobs/rebuild_payment_ledger.php`\n - `backend/jobs/smoke_morning_jobs.php`\n - `backend/morning_jobs_service.php`\n - `backend/appointment_service.php`\n - `frontend/api/visit_get.php`\n - `frontend/api/visit_save.php`\n - `frontend/api/visit_report_generate.php`\n - `backend/payroll_service.php`\n - `backend/payroll.php`\n\n## BLOCKED\n\n- Month-end totals still not fully matched to expected Access truth for selected periods:\n - April 2025 mismatch remains\n - April 2026 daily range mismatch remains for at least one target comparison\n - Edwards bucket attribution still has unresolved edge cases on some records\n\n- Full parity confirmation still needed for all frontend totals surfaces:\n - `reports.html`\n - dashboard `index.html`\n - `webui.html`\n - Goal: all must reconcile against `customer_payment_transactions` outputs\n\n- Receipt parity final QA still pending:\n - Need side-by-side validation on known problematic visits:\n - print receipt\n - email receipt\n - backend generated receipt report\n\n- Payroll API alias parity incomplete:\n - `backend/api/payroll_import.php` still strictly accepts only `Yana` or `Lola`\n - Should be aligned with alias handling in `backend/payroll_service.php`\n\n- Release hygiene blocked by broad workspace churn:\n - Many unrelated changed/deleted files exist in current worktree\n - Needs isolation/staging before safe production commit/deploy\n\n## Next Actions\n\n1. Run reconciliation for April 2025 and April 2026 target windows and fix row-level ledger bucket/date mismatches.\n2. Confirm dashboard and report UI totals are reading ledger-backed endpoints only.\n3. Execute receipt parity QA on named customer/visit samples and sign off.\n4. Align payroll import API alias handling with payroll service.\n5. Prepare a clean staged commit containing only intended production files.\n","is_text_editable":1,"can_edit_inline":1}
{"file_name":"Codex-Update-04-12-2026.odt","mime_type":"application/vnd.oasis.opendocument.text"}
[]
{"backend_document_id":"14","document_type":"upload","title":"Codex - Updates Fixes Issues 04-13-2026","slug":"codex-updates-fixes-issues-04-13-2026","summary_text":"Codex - Updates Fixes Issues 04-13-2026 Detailed Documentation","content_markdown":null,"content_html":null,"file_name":"Codex-Update-04-12-2026.odt","stored_name":"20260412-164224-b4b11b83.odt","mime_type":"application/vnd.oasis.opendocument.text","file_size_bytes":"49423","storage_path":"/mnt/drive1/customerdb/backend/documents_storage/20260412-164224-b4b11b83.odt","is_deleted":"0","created_at":"2026-04-12 12:42:24","updated_at":"2026-04-12 12:42:24","editor_content":"Comprehensive implementation log (through April 12, 2026 ) and remaining work: Scope Snapshot The branch currently has very large churn ( 242 files changed ), including canonical backend work plus broad webui/backend/* compatibility-loader rewiring. Core functional work for your issues is concentrated in backend/frontend reporting, Setmore import, visit save/receipt logic, payroll import, and payment ledger. I also validated syntax for key new/modified PHP modules (all clean). What Was Implemented Cron hardening + morning smoke test Added cron-safe preflight script to fail fast when runtime prerequisites are missing: backend/jobs/smoke_morning_jobs.php Smoke test now explicitly checks mysqli extension and required functions (including app_unified_appointments ). Wired cron “Morning Import” and “Morning Jobs” commands to run smoke test first: backend/cron_manager.php Documented smoke command chain in backend docs: backend/README.md Fixed unified appointments SQL ambiguity / cron fatal Added/updated centralized unified appointment query service: backend/appointment_service.php Fixed ambiguous customer_id in union query by qualifying Setmore side as setmore_appointments.customer_id . Included setmore_import_locked in unified rows (used by workflow/import safeguards). Setmore import improvements (notes + booking source + lock flag) Implemented robust note extraction from multiple payload fields and flattened additional fields: backend/setmore_service.php Added booking source extraction ( booking_source / booked_from / parsed note line “Booked from ...”) and write-through to visits when column exists. Added import lock behavior ( setmore_import_locked ) so re-import does not overwrite locked visits. Added lock column bootstrap/ensure + bulk lock helper: backend/morning_jobs_service.php Added schema evolution for lock and ledger fields in installer: backend/install_schema.php Visit save 500 fix + item type reliability Added item_type_name persistence to order_items and updated reads to prefer stored label (fallback to item_types ): frontend/api/visit_save.php , frontend/api/visit_get.php , frontend/api/visit_report_generate.php , backend/visit_service.php Added migration to backfill item_type_name and drop fragile FK dependency on type table: migrations/20260411_order_items_item_type_name_no_fk.sql Updated base schema accordingly: mariadb_core_schema.sql Payment ledger architecture (single transaction table with tips) Added/expanded canonical ledger table customer_payment_transactions with tip_amount and indexes: backend/install_schema.php Implemented sync/rebuild services from payments with bucket classification ( cash/check/credit/edwards/tip ): backend/payment_ledger_service.php Added ledger rebuild CLI: backend/jobs/rebuild_payment_ledger.php Added ledger UI/report page with filters and summary cards: backend/payment_ledger.php Added ledger table to Live Table Manager map: backend/live_table_manager_service.php Legacy CustomerTotals import into ledger + forward resync Added CLI import from Access CSV into ledger ( source=legacy_customer_totals ) and optional forward rebuild from next date: backend/jobs/import_customer_totals_csv_to_ledger.php Your run imported 2757 rows for 2023-12-24 to 2026-04-06 and resynced 55 rows forward ( 2026-04-07 to 2026-04-12 ). Report totals now ledger-first (with fallback strategy) Added ledger-driven daily/period/month/year aggregation paths, including Edwards handling and totals-no-Edwards logic: backend/report_service.php Updated dashboard snapshot APIs to use ledger when range rows exist (instead of always preferring legacy tables): frontend/api/totals_snapshot.php , frontend/api/totals_snapshot_live.php , webui/api/totals_snapshot.php , webui/api/totals_snapshot_live.php New reconciliation / audit backend modules Added totals reconciliation page (report total vs ledger total vs daily mismatch rows + exact ledger rows): backend/report_reconciliation.php Added daily source-vs-source totals audit page: backend/report_totals_audit.php Added unmatched report attachment helper page: backend/report_unmatched.php Added navigation links in backend home/reports: backend/index.php , backend/reports.php Receipts and work orders moved toward ledger truth visit_get now returns ledger payment rows/totals (deposit/tip/paid-toward-balance): frontend/api/visit_get.php PDF receipt/work-order generator uses ledger-first totals and item_type_name fallback: frontend/api/visit_report_generate.php Frontend receipt/work-order screens updated to prefer ledger_totals : frontend/receipt.html , frontend/work_order.html Save flow includes tip safety net so Square tip is persisted as a Tip payment row if missing in payload: frontend/api/visit_save.php , backend/visit_service.php Email receipt vs print receipt mismatch Reworked email receipt generation path in visit page to build from live visit_get + settings_get data and ledger-aware totals, replacing simplified/legacy divergence path: frontend/visit.html Payroll module fixes Added alias normalization and clause support ( Jana/Janna -> Yana ) so counts/reports don’t zero out due name variants: backend/payroll_service.php Improved pasted Excel parsing robustness (delimiter/header detection, fallback parsing, skip-reason diagnostics): backend/payroll_service.php UI now surfaces import diagnostics and styled KPI cards: backend/payroll.php Frontend activity monitor Added backend page to monitor frontend edits/signatures/status changes using backend_change_log : backend/frontend_activity.php UI cleanup for weird characters Frontdesk title and refresh text normalized to plain readable values: frontend/index.html Item types management module Added standalone item type manager page and update/delete APIs: frontend/item_types.html , frontend/api/item_type_update.php , frontend/api/item_type_delete.php Backend/WebUI canonicalization Large set of webui/backend/* files converted to thin loaders pointing to canonical /backend/* files to reduce drift; examples: webui/backend/bootstrap.php , webui/backend/payment_ledger.php , webui/backend/report_reconciliation.php Validation Done Ran PHP lint on critical modules; all reported “No syntax errors detected”: backend/payment_ledger.php , backend/payment_ledger_service.php , backend/report_reconciliation.php , backend/report_totals_audit.php backend/jobs/import_customer_totals_csv_to_ledger.php , backend/jobs/rebuild_payment_ledger.php , backend/jobs/smoke_morning_jobs.php backend/morning_jobs_service.php , backend/appointment_service.php frontend/api/visit_get.php , frontend/api/visit_save.php , frontend/api/visit_report_generate.php backend/payroll_service.php , backend/payroll.php What Is Still Left To Do Finalize totals parity for April 2025 / April 2026 edge cases Remaining mismatch indicates ledger contents/classification still differ from your Access truth set for some rows (especially Edwards split + date bucketing). Action left: run reconciliation for target ranges and correct source rows/bucket rules until report total == ledger total == expected monthly total. Confirm all frontend totals pages are fully ledger-backed end-to-end You asked reports.html , dashboard , index.html , webui.html to use new table. Snapshot endpoints were updated, but full UI-path verification for each page still needs click-through + data diff. Receipt equivalence final QA Email receipt builder was unified in frontend/visit.html , but still needs real-record side-by-side test against print receipt on the problematic visits to confirm exact parity in totals/labels/lines. Payroll import API parity backend/api/payroll_import.php still hard-validates worker as only Yana/Lola (no alias normalization there). If that endpoint is used directly, aliases may still fail. Should align this API with service-layer alias logic. Ledger population completeness You imported Access CSV and forward-resynced, but full historical backfill strategy still needs final sign-off: Decide whether to trust imported Access rows as authoritative for all prior dates and keep live rebuild only forward. Run one full-range ledger audit after any additional historical imports. Potentially risky broad file churn review before release There are many unrelated changed/deleted files (including docs storage artifacts and backups). Needs staging/cleanup before commit/deploy so only intended production changes are shipped.","is_text_editable":1,"can_edit_inline":0}
[]
{"item_type_id":"238","type_name":"Dance costume"}
{"item_type_id":"238","type_name":"Dance costume"}
[]
{"item_type_id":"410","type_name":"tanktop"}
{"item_type_id":"410","type_name":"Tank Top"}
{"type":"mysqli_sql_exception","file":"/mnt/drive1/customerdb/backend/payment_ledger_service.php","line":75,"trace":"#0 /mnt/drive1/customerdb/backend/payment_ledger_service.php(75): mysqli->query()\n#1 /mnt/drive1/customerdb/backend/payment_ledger_service.php(102): app_payment_ledger_sync_order()\n#2 /mnt/drive1/customerdb/backend/payment_ledger.php(32): app_payment_ledger_rebuild_range()\n#3 /mnt/drive1/customerdb/webui/backend/payment_ledger.php(5): require('...')\n#4 {main}"}
[]
{"item_type_id":"5","type_name":"Formal Dress"}
{"deleted":true}
[]
{"item_type_id":"6","type_name":"Mother of the Bride"}
{"deleted":true}
[]
{"item_type_id":"7","type_name":"Mother of the Groom"}
{"deleted":true}
[]
{"item_type_id":"17","type_name":"Coat"}
{"deleted":true}
[]
{"item_type_id":"18","type_name":"Other Formal Wear"}
{"deleted":true}
[]
{"item_type_id":"19","type_name":"Other"}
{"deleted":true}
[]
{"item_type_id":"21","type_name":"Mother Of Bride Gown Top Shoulder Alterations"}
{"deleted":true}