# ShiftOps Quick Reference Guide


**Last Updated:** 2025-11-20

## File Locations

### Core API Files

- Main API: `v2/api/shiftops.php` (6084 lines, contains ShiftOpsAnalyzer class)
- Cost Calculator: `v2/api/shiftops-cost-calculator.php` (922 lines)
- Competitive Analyzer: `v2/api/shiftops-competitive-analyzer.php` (910 lines)
- Recommendations: `v2/api/shiftops-recommendations-engine.php` (947 lines)
- User Explanations: `v2/api/shiftops-user-explanations.php` (126 lines)
- Customer Matcher: `v2/api/shiftops-customer-matcher.php` (918 lines)
- HubSpot: `v2/api/shiftops-hubspot.php` (325 lines)
- NPS Survey: `v2/api/shiftops-nps.php` (238 lines)
- HubSpot Sync: `v2/api/shiftops-hubspot-customers.php` (547 lines)
- Health Check: `v2/api/shiftops-health-check.php` (123 lines)
- Test Matching: `v2/api/shiftops-test-matching.php` (172 lines)

### Frontend

- Entry Page: `v2/pages/shiftops.php` (4416 lines)
- Report Page: `v2/pages/shiftops-report.php` (18310 lines)
- PDF Generator: `v2/js/shiftops-pdf-generator.js` (1468 lines)

### Data & Config

- Benchmarks: `v2/data/industry_benchmarks.php`
- Examples: `v2/data/shiftops-examples.json` (314 lines)
- Config: `v2/config/shiftops-customers.php`
- Cache: `v2/cache/systems/shiftops/`
- Logs: `logs/shiftops-*.log`

## API Endpoints

### POST `/v2/api/shiftops.php`

**Required:** `place_id`, `name`  
**Optional:** `mode` (essential|enhanced), all Google Places fields  
**Response:** `{success: true, analysis: {...}, mode: "...", timestamp: "...", request_id: "..."}`

**Performance:**

- Essential mode: < 2 seconds
- Enhanced mode: 3-5 seconds
- Cache hits: < 100ms

### POST `/v2/api/shiftops-hubspot.php`

**Required:** `email`  
**Optional:** All ShiftOps data fields, UTM parameters  
**Response:** `{success: true, message: "...", lead_data: {...}}`

**Configuration:**

- Portal ID: `145133546`
- Form ID: `41d07332-6697-4daa-b27e-dd60515f9c0f`
- Rate limit: 0.6s delay between requests

### GET `/v2/api/shiftops-health-check.php`

**No parameters**  
**Response:** `{success: true, checks: {...}, customer_count: 3018, php_config: {...}}`

**Use:** Verify customer matcher status, file existence, customer count

### GET `/v2/api/shiftops-test-matching.php`

**Required:** `name` (query parameter)  
**Optional:** `website`, `address`  
**Response:** `{success: true, match_result: {...}, matching_details: {...}}`

**Use:** Debug customer matching for specific businesses

## Scoring System

### 5 Pillars (0-20 each)

1. **Scheduling Efficiency** - Digital maturity + operational complexity
2. **Absence Stability** - Review sentiment + seasonal factors
3. **Time Tracking Hygiene** - Hours complexity analysis
4. **Compliance Docs** - Industry-specific requirements
5. **Payroll Readiness** - DATEV integration indicators

### Total Score Calculation

1. Raw pillar scores (floats)
2. Sum raw scores
3. Apply data completeness multiplier (0.50-1.0)
4. Apply customer cap (max 95)
5. Round total score
6. Adjust pillar scores proportionally
7. Assign grade (A+, A, A-, B+, B, B-, C+, C, C-, D+, D, D-, F)

**For complete scoring documentation, see [Scoring System Documentation](SHIFTOPS_SCORING_SYSTEM.md) and [Scoring Quick Reference](SHIFTOPS_SCORING_ai//QUICK_REFERENCE.md)**

### Customer Boost

- Baseline: +3 points per pillar
- Percentage: 25-35% boost per pillar
- Max scores: 18-20 per pillar
- Total cap: 95

## Common Patterns

### Cache Check

```php
$cacheKey = $this->generateCacheKey($businessData);
$cachedResult = $this->getCachedAnalysis($cacheKey);
if ($cachedResult) return $cachedResult;
$this->cacheAnalysis($cacheKey, $analysis);
```

### Customer Matching

```php
$customerMatch = $this->customerMatcher->isOrdioCustomer($businessData);
if ($customerMatch) {
    $isOrdioCustomer = true;
    $confidence = $customerMatch['confidence'];
}
```

### Error Logging

```php
error_log('ShiftOps Error: ' . $e->getMessage());
error_log('Context: ' . json_encode($context));
```

## Data Structures

### Business Data (Input)

```php
[
    'place_id' => string,
    'name' => string,
    'formatted_address' => string,
    'website' => string,
    'types' => array,
    'rating' => float,
    'user_ratings_total' => int,
    'opening_hours' => array,
    'service_options' => array,
    'geometry' => ['location' => ['lat', 'lng']]
]
```

### ShiftOps Score

```php
[
    'total_score' => int (0-100),
    'pillar_scores' => [
        'scheduling_efficiency' => int (0-20),
        'absence_stability' => int (0-20),
        'time_tracking_hygiene' => int (0-20),
        'compliance_docs' => int (0-20),
        'payroll_readiness' => int (0-20)
    ],
    'grade' => string (A+, A, A-, B+, B, B-, C+, C, C-, D+, D, D-, F),
    'data_completeness' => array,
    'score_metadata' => array
]
```

## Configuration Constants

### Customer Matching

- `FUZZY_MATCH_THRESHOLD`: 85
- `EXACT_MATCH_CONFIDENCE`: 100
- `FUZZY_MATCH_CONFIDENCE`: 75
- `DOMAIN_MATCH_CONFIDENCE`: 95

### Score Boost

- `CUSTOMER_BASELINE_BONUS`: 3
- `BOOST_SCHEDULING_EFFICIENCY`: 35
- `BOOST_ABSENCE_STABILITY`: 25
- `BOOST_TIME_TRACKING`: 35
- `BOOST_COMPLIANCE_DOCS`: 30
- `BOOST_PAYROLL_READINESS`: 30
- `MAX_TOTAL_SCORE`: 95

## Cache

### Cache Key

- Format: `shiftops_analysis_{md5_hash}.json`
- Based on: place_id, name, rating, user_ratings_total, types, mode
- Location: `v2/cache/systems/shiftops/`
- TTL: 1 hour (3600 seconds)

## Log Files

- `logs/shiftops-debug.log` - PHP errors
- `logs/shiftops-hubspot.log` - HubSpot submissions
- `logs/shiftops-leads-full.log` - Rich lead data
- `logs/shiftops-benchmarks.log` - Benchmark data

## Testing

### Test Essential Mode

```bash
curl -X POST http://localhost:8003/v2/api/shiftops.php \
  -H "Content-Type: application/json" \
  -d '{"mode":"essential","place_id":"ChIJ...","name":"Test"}'
```

### Test Enhanced Mode

```bash
curl -X POST http://localhost:8003/v2/api/shiftops.php \
  -H "Content-Type: application/json" \
  -d '{"mode":"enhanced","place_id":"ChIJ...","name":"Test"}'
```

### Test HubSpot

```bash
curl -X POST http://localhost:8003/v2/api/shiftops-hubspot.php \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com","firstname":"Test","lastname":"User"}'
```

## Common Functions

### Get Primary Business Type

```php
private function getPrimaryBusinessType($types) {
    $priorityTypes = ['restaurant', 'hospital', 'store', 'cafe', 'pharmacy', 'bar'];
    foreach ($priorityTypes as $type) {
        if (in_array($type, $types)) return $type;
    }
    return 'general';
}
```

### Get Country From Address

```php
private function getCountryFromAddress($businessData) {
    $addressComponents = $businessData['address_components'] ?? [];
    foreach ($addressComponents as $component) {
        if (in_array('country', $component['types'] ?? [])) {
            return $component['short_name'] ?? 'DE';
        }
    }
    return 'DE';
}
```

## Performance Targets

- Essential mode: < 2 seconds
- Enhanced mode: 3-5 seconds
- Cache hits: < 100ms
- Page load: < 1 second

## External APIs

### Google Places

- Key: `AIzaSyAcmDVIEYDtmeXjKfIsqYxbNy2FFsluCdo`
- Quota: 1000 requests/day (free tier)

### Weather (Open-Meteo)

- URL: `https://api.open-meteo.com/v1/forecast`
- No API key required
- No rate limits

### Holidays (Nager.Date)

- URL: `https://date.nager.at/api/v3/PublicHolidays/{year}/{country}`
- No API key required
- No rate limits

### HubSpot

- Portal ID: `145133546`
- Form ID: `41d07332-6697-4daa-b27e-dd60515f9c0f`
- Rate limit: 100 requests per 10 seconds

## Quick Debugging

### Check Cache

```bash
ls -la v2/cache/systems/shiftops/
```

### Check Logs

```bash
tail -f logs/shiftops-debug.log
tail -f logs/shiftops-hubspot.log
```

### Clear Cache

```bash
rm -rf v2/cache/systems/shiftops/*
```

### Test Customer Match

**Using test endpoint:**

```bash
curl "https://www.ordio.com/v2/api/shiftops-test-matching.php?name=La+Fonda&website=https://lafonda.koeln"
```

**Using PHP:**

```php
$matcher = new ShiftOpsCustomerMatcher(null, $requestId);
$match = $matcher->isOrdioCustomer($businessData);
var_dump($match);
```

**Health check:**

```bash
curl https://www.ordio.com/v2/api/shiftops-health-check.php
```

## Common Issues

1. **Cache not working** → Check directory permissions (755)
2. **API errors** → Check log files
3. **Scores don't match** → Check pillar score adjustment logic
4. **Customer match fails** → Check customer list file exists
5. **HubSpot fails** → Check form ID and portal ID

## Reference Docs

- Architecture: `SHIFTOPS_ARCHITECTURE.md`
- API: `SHIFTOPS_API_DOCUMENTATION.md`
- Data Structures: `SHIFTOPS_DATA_STRUCTURES.md` (NEW)
- Components: `SHIFTOPS_COMPONENTS.md` (NEW)
- Troubleshooting: `SHIFTOPS_TROUBLESHOOTING.md`
- Cursor Rules: `.cursor/rules/shiftops-backend.mdc`, `.cursor/rules/shiftops-frontend.mdc`
