# ShiftOps Technical Implementation

**Last Updated:** 2026-01-09

Complete technical documentation for ShiftOps implementation, including file structure, JavaScript modules, API endpoints, data flow, and code organization.

## File Structure

### PHP Files

- **`v2/pages/shiftops.php`** (4,416 lines)

  - Main entry page with search interface
  - Google Places autocomplete initialization
  - Chat-style loading sequence
  - Essential/enhanced data fetching
  - Redirect to report page
  - Key functions: `initAutocomplete()`, `handlePlaceSelection()`, `runChatSequence()`, `fetchEssentialData()`, `fetchEnhancedData()`

- **`v2/pages/shiftops-report.php`** (18,310 lines)
  - Report display page with comprehensive analysis
  - Progressive rendering logic
  - Email gating and unlock functionality
  - PDF export integration
  - NPS survey display
  - Key functions: `progressiveDataLoad()`, `renderPrioritySections()`, `handleEmailUnlock()`, `loadEnhancedDataInBackground()`

### JavaScript Files

- **`v2/js/shiftops-pdf-generator.js`** (1,468 lines)

  - PDF export functionality using jsPDF and html2canvas
  - Multi-page PDF generation
  - Ordio branding and layout
  - Key functions: `generatePDF()`, `extractExportData()`, `shouldIncludeSection()`

- **Minified JavaScript Modules** (13+ modules for report functionality):
  - `shiftops-report-main.min.js` - Main initialization and coordination
  - `shiftops-report-rendering.min.js` - UI rendering logic
  - `shiftops-report-population.min.js` - Data population into UI
  - `shiftops-report-display.min.js` - Display logic and animations
  - `shiftops-report-gating.min.js` - Email gating and unlock logic
  - `shiftops-report-export.min.js` - Export functionality
  - `shiftops-report-helpers.min.js` - Helper functions
  - `shiftops-report-utils.min.js` - Utility functions
  - `shiftops-report-calculations.min.js` - Calculation helpers
  - `shiftops-report-analysis.min.js` - Analysis display logic
  - `shiftops-report-carousels.min.js` - Carousel functionality
  - `shiftops-report-generation.min.js` - Report generation logic

### CSS

- **Inline styles** in PHP files (no separate CSS file)
- CSS variables defined in `:root` for consistent theming
- Responsive design with mobile-first approach
- Breakpoints: 768px (tablet), 480px (mobile)

## API Endpoints

### Main Analysis Endpoint

**`/v2/api/shiftops.php`** (6,084 lines)

- **Method:** POST
- **Modes:** `essential` (default) or `enhanced`
- **Request Body:** JSON with Google Places data
- **Response:** JSON with complete analysis
- **Caching:** 1-hour TTL based on business data hash
- **Error Handling:** Comprehensive fallback mechanisms

**Key Classes:**

- `ShiftOpsAnalyzer` (lines 786-6084) - Main analysis class

### Supporting Endpoints

1. **`/v2/api/shiftops-cost-calculator.php`** (922 lines)

   - Cost savings calculations
   - Team size estimation
   - ROI analysis
   - Break-even calculations

2. **`/v2/api/shiftops-competitive-analyzer.php`** (910 lines)

   - Market positioning analysis
   - Competitor analysis using Google Places Nearby Search
   - Growth potential assessment

3. **`/v2/api/shiftops-recommendations-engine.php`** (947 lines)

   - Priority-ranked recommendations
   - Implementation roadmap generation
   - Pillar-specific recommendations

4. **`/v2/api/shiftops-user-explanations.php`** (126 lines)

   - User-friendly score explanations
   - Pillar-specific explanations
   - Grade interpretation

5. **`/v2/api/shiftops-customer-matcher.php`** (918 lines)

   - Ordio customer identification
   - Multi-strategy matching (domain, exact, prefix, fuzzy, address)
   - Lazy loading of customer list (3018+ customers)

6. **`/v2/api/shiftops-hubspot.php`** (325 lines)

   - HubSpot lead submission
   - Form ID: `41d07332-6697-4daa-b27e-dd60515f9c0f`
   - Portal ID: `145133546`

7. **`/v2/api/shiftops-nps.php`** (238 lines)

   - NPS survey submission
   - Form ID: `804459f7-c18d-4da6-8a0b-a81f44bb8275`
   - Validates NPS score (0-10 integer)

8. **`/v2/api/shiftops-hubspot-customers.php`** (547 lines)

   - Customer list sync from HubSpot
   - Stores in `v2/data/ordio-customers.json`

9. **`/v2/api/shiftops-health-check.php`** (123 lines)

   - Diagnostic endpoint for customer matcher status

10. **`/v2/api/shiftops-test-matching.php`** (172 lines)
    - Test endpoint for customer matching debugging

## Data Flow

### Essential Mode Flow

```mermaid
flowchart LR
    User[User Selects Business] --> API[POST /v2/api/shiftops.php]
    API --> Cache{Cache Check}
    Cache -->|Hit| Return[Return Cached Data]
    Cache -->|Miss| Customer{Customer Match}
    Customer --> Scores[Calculate Scores]
    Scores --> Team[Estimate Team Size]
    Team --> Cost[Calculate Cost Savings]
    Cost --> Recs[Generate Recommendations]
    Recs --> Context[Get Context Data]
    Context --> Store[Store in Cache]
    Store --> Return
    Return --> Frontend[Frontend Stores in localStorage]
    Frontend --> Redirect[Redirect to Report]
```

### Enhanced Mode Flow

```mermaid
flowchart LR
    Essential[Essential Data Complete] --> Background[Background Fetch]
    Background --> Website{Website Exists?}
    Website -->|Yes| Analyze[Website Analysis]
    Website -->|No| Competitors[Competitor Analysis]
    Analyze --> Competitors
    Competitors --> Enhanced[Enhanced Recommendations]
    Enhanced --> Store[Store Enhanced Data]
    Store --> Update[Update UI Sections]
```

## State Management

### localStorage Keys

**Primary Data:**

- `shiftops_report_data`: Complete essential analysis object (JSON string)
  - Structure: `{business_info, shiftops_score, cost_savings, location_analysis, online_presence, context_data, competitive_positioning, recommendations, is_ordio_customer, customer_match_confidence, customer_match}`
- `shiftops_enhanced_data`: Enhanced analysis object (JSON string)
  - Structure: `{enhanced_analysis: {...}, timestamp: ISO string}`

**Status Keys:**

- `shiftops_report_unlocked`: Boolean flag ('true'/'false')
- `shiftops_email`: Email address used for unlock
- `shiftops_unlock_timestamp`: ISO timestamp of unlock
- `shiftops_nps_submitted`: Boolean flag ('true'/'false')
- `shiftops_nps_dismissed`: Boolean flag ('true'/'false')
- `ordio_original_referrer`: Original referrer before same-site redirect
  - Format: `{referrer: string, timestamp: number, page_url: string}`
  - Expiration: 30 days

**Legacy/Backup Keys:**

- `shiftops_data`: Old format (may exist in older sessions)
- `shiftops_analysis_data`: Fallback data structure

### Safe localStorage Functions

**Frontend Helper Functions:**

- `safeLocalStorageGet(key)`: Safe get with try-catch, returns null on error
- `safeLocalStorageSet(key, value)`: Safe set with try-catch, handles quota exceeded

**Code Location:** `v2/pages/shiftops-report.php` lines 5400+ (safe localStorage functions)

## Code Organization

### Modular Structure

**Search Page (`shiftops.php`):**

- Autocomplete initialization (lines 2106-2194)
- Business selection handling (lines 2196-2234)
- Chat sequence logic (lines 2414-2582)
- Data fetching functions (lines 4732-4877)
- Content generation functions (lines 3571-4284)

**Report Page (`shiftops-report.php`):**

- Data loading and validation (lines 5237-5583)
- Progressive rendering (lines 7914-8088)
- Email gating (lines 6400-6572)
- Enhanced data loading (lines 6574-6652)
- Section rendering (lines 6676-8000+)

### Code Patterns

- **Vanilla JavaScript:** No framework dependencies, pure JavaScript
- **Progressive Enhancement:** Essential data first, enhanced data updates UI
- **Error Handling:** Try-catch blocks throughout, fallback data structures
- **Request ID Tracking:** Unique request IDs for logging traceability
- **DOM Caching:** High-frequency elements cached to reduce queries
- **Safe DOM Operations:** Wrapper functions for safe DOM manipulation

## Functions & Methods

### Search Page Functions

**`initAutocomplete()`** (lines 2106-2194)

- Initializes Google Places autocomplete
- Configures DACH region focus
- Sets up event listeners

**`handlePlaceSelection(place)`** (lines 2196-2234)

- Validates business selection
- Shows loading state
- Triggers analysis

**`runChatSequence(place, analysisData)`** (lines 2414-2515)

- Orchestrates chat-style loading sequence
- Displays 6 analysis cards with delays
- Starts auto-redirect countdown

**`fetchEssentialData(place)`** (lines 4732-4877)

- POST to `/v2/api/shiftops.php` with `mode='essential'`
- 15-second timeout
- Returns fallback data on error

**`fetchEnhancedData(place)`** (lines 4838-4877)

- POST to `/v2/api/shiftops.php` with `mode='enhanced'`
- Background fetch, non-blocking
- Updates chat sections when available

### Report Page Functions

**`progressiveDataLoad(reportData)`** (lines 7914-8088)

- Orchestrates progressive rendering
- Phase 1: Priority sections (immediate)
- Phase 2: Secondary sections (100ms delay)
- Phase 3: Data-dependent sections (background)

**`loadEnhancedDataInBackground()`** (lines 6574-6642)

- Fetches enhanced data if not available
- Updates report sections with enhanced data
- Non-blocking, graceful error handling

**`handleEmailUnlock(email, name, phone)`** (lines 6400-6572)

- Validates email format
- Submits to HubSpot
- Unlocks report on success
- Handles errors gracefully

### API Functions

**`ShiftOpsAnalyzer::analyzeBusiness($businessData)`** (lines 1058-2145)

- Main analysis orchestration
- Coordinates all analysis components
- Returns complete analysis object

**`ShiftOpsAnalyzer::calculateShiftOpsScore($businessData, $isOrdioCustomer)`** (lines 3162-3314)

- Main scoring function
- Calculates 5 pillar scores
- Applies customer boost
- Applies data completeness multiplier

**Pillar Score Functions:**

- `calculateSchedulingScoreRaw()` (lines 3837-3981)
- `calculateAbsenceScoreRaw()` (lines 4014-4113)
- `calculateTimeTrackingScoreRaw()` (lines 4237-4317)
- `calculateComplianceScoreRaw()` (lines 4401-4500)
- `calculatePayrollScoreRaw()` (lines 4517-4631)

## Dependencies

### External Libraries

- **Google Places API:** Autocomplete, place details, nearby search, photos, static maps
- **jsPDF:** PDF generation (`https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js`)
- **html2canvas:** HTML to image conversion (`https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js`)

### External APIs

- **Google Places API:** Requires API key (from `v2/config/google-maps.php`)
- **HubSpot Forms API v3:** Requires API token (from `v2/config/hubspot.php`)
- **Open-Meteo API:** Weather forecast (no API key required)
- **Nager.Date API:** Public holidays (no API key required)

### Base Components

- `base/head.php` - Head section with meta tags
- `base/header.php` - Site header
- `base/footer.php` - Site footer

## Performance Optimizations

### Caching Strategy

- **API Response Caching:** 1-hour TTL based on business data hash
- **Cache Key Generation:** MD5 hash of business data + mode
- **Cache Location:** File-based cache in `v2/cache/shiftops/`
- **Cache Invalidation:** Automatic after 1 hour

### Progressive Rendering

- **Priority Sections:** Render immediately (score, pillars, cost savings)
- **Secondary Sections:** Render after 100ms delay
- **Data-Dependent Sections:** Render when data available
- **Skeleton Loaders:** Show loading states for sections waiting for enhanced data

### Code Optimization

- **DOM Caching:** High-frequency elements cached (6+ queries)
- **Batch DOM Updates:** DocumentFragment for batch operations
- **Lazy Loading:** Images loaded on demand
- **Minified JavaScript:** 13+ minified modules for report functionality

## Error Handling

### Frontend Error Handling

- **API Failures:** Fallback data used, error messages displayed
- **localStorage Errors:** Graceful degradation, continues without storage
- **Network Timeouts:** Retry mechanism, fallback to essential mode only
- **Invalid Data:** Validation errors shown inline, user can retry

### Backend Error Handling

- **Fatal Errors:** Shutdown handler returns valid JSON with fallback data
- **API Failures:** Try-catch blocks throughout, fallback responses
- **Missing Dependencies:** Graceful degradation, uses fallback implementations
- **Cache Failures:** Continues without cache, logs error

## Related Documentation

- [User Flow](02-user-flow.md) - Complete user journey
- [Scoring System](04-scoring-system.md) - Calculation formulas
- [API Endpoints](05-api-endpoints.md) - API reference
- [System Architecture](../../../systems/shiftops/SHIFTOPS_ARCHITECTURE.md) - Detailed architecture
