# ShiftOps Team Estimation - Changelog


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

Complete changelog of all team size estimation logic changes, improvements, and fixes.

## January 2025 - Validation Bounds & Realism Fixes

### Problem Identified

Restaurant team size estimates were showing unrealistic values (50+ employees) for single-location restaurants. Investigation revealed:

1. **Validation bounds inconsistencies**: PHP backend had no cap (could reach 334+), PHP API and JavaScript capped at 50, all should cap at 25 for restaurants
2. **Unrealistic values**: Restaurants showing 50+ employees (should be max 25 for realistic single-location operations)
3. **Volume factor inflation**: 6.0x cap too high for restaurants with 2000+ reviews
4. **Data consistency**: Loading screen and report page used different data source priorities
5. **Missing safety checks**: Location multipliers could push values beyond realistic limits
6. **No validation logging**: Difficult to debug calculation issues

### Changes Made

#### 1. Validation Bounds Fixes

**Before:**

- PHP Backend (`shiftops-cost-calculator.php`): No maximum cap (could reach 334+ employees)
- PHP API (`shiftops.php`): Restaurant cap at 50
- JavaScript Report (`shiftops-report.php`): Restaurant cap at 50
- JavaScript Loading (`shiftops.php`): Restaurant cap at 50

**After:**

- **All implementations**: Restaurant cap set to **25** (realistic maximum for single-location restaurants)
- **All business types**: Added realistic caps:
  - Restaurant: 25
  - Cafe: 15
  - Bar: 25
  - Store: 30
  - Hospital: 60
  - Pharmacy: 20
  - General: 30

**Files Modified:**

- `v2/api/shiftops-cost-calculator.php` (line 425-456): `getValidationBoundsForTeamSize()` method
- `v2/api/shiftops.php` (line 2377-2408): `getValidationBoundsForTeamSize()` method
- `v2/pages/shiftops-report.php` (line 7400-7431): `getValidationBounds()` function
- `v2/pages/shiftops.php` (line 2020-2051): `getValidationBounds()` function

**Example:**

```php
// Before (PHP Backend)
'restaurant' => [
    'min' => 5,
    'max' => max(5, ceil($reviewCount / 15))  // Could reach 334+ for 5000 reviews
]

// After (All implementations)
'restaurant' => [
    'min' => 5,
    'max' => min(25, max(5, ceil($reviewCount / 15)))  // Capped at 25
]
```

#### 2. Volume Factor Cap Reduction

**Before:**

- All businesses: 6.0x volume factor cap
- Restaurants with 5000+ reviews could inflate estimates unrealistically

**After:**

- **Restaurants with 2000+ reviews**: Cap reduced from 6.0x to **4.0x**
- **Other businesses**: Remain at 6.0x cap

**Files Modified:**

- `v2/api/shiftops-cost-calculator.php` (line 125): Volume factor cap logic
- `v2/api/shiftops.php` (line 2120): Volume factor cap logic
- `v2/pages/shiftops-report.php` (line 7320): Volume factor cap logic
- `v2/pages/shiftops.php` (line 1990): Volume factor cap logic

**Example:**

```php
// Before
$maxVolumeCap = 6.0;
$volumeFactor = max(0.3, min($maxVolumeCap, $volumeFactor));

// After
$maxVolumeCap = ($reviewCount > 2000 && $primaryType === 'restaurant') ? 4.0 : 6.0;
$volumeFactor = max(0.3, min($maxVolumeCap, $volumeFactor));
```

#### 3. Safety Checks

**Added:** Additional validation after location multipliers to ensure restaurants don't exceed 25, even if location multipliers push values higher.

**Files Modified:**

- `v2/api/shiftops-cost-calculator.php` (line 246-251): Safety check after bounds validation
- `v2/api/shiftops.php` (line 2193-2198): Safety check after bounds validation
- `v2/pages/shiftops-report.php` (line 7540-7543): Safety check after bounds validation
- `v2/pages/shiftops.php` (line 2070-2073): Safety check after bounds validation

**Example:**

```php
// Additional safety check: Ensure location multipliers don't push values beyond realistic limits
// This is especially important for restaurants where max is 25
if ($primaryType === 'restaurant' && $estimatedTeam > 25) {
    $estimatedTeam = 25;
    $appliedMax = true;
}
```

#### 4. Data Consistency

**Before:**

- Loading screen: Prioritized `online_presence.team_size_estimate` first
- Report page: Prioritized `cost_savings.team_size_estimate` first
- **Result**: Different values displayed on loading screen vs report page

**After:**

- **Both pages**: Now use same priority order:
  1. `cost_savings.team_size_estimate` (from API)
  2. `online_presence.team_size_estimate` (from API)
  3. Fallback calculation (same function with same parameters)

**Files Modified:**

- `v2/pages/shiftops.php` (line 3145-3159): Updated `generateIndustryInsights()` to prioritize `cost_savings.team_size_estimate` first

**Example:**

```javascript
// Before (Loading Screen)
const teamSize = onlinePresence.team_size_estimate ||
                estimateTeamSizeEnhanced(...);

// After (Both Pages)
const teamSize = costSavings.team_size_estimate ||
                onlinePresence.team_size_estimate ||
                estimateTeamSizeEnhanced(...);
```

#### 5. Validation Logging

**Added:** Console logging when validation bounds are applied to aid debugging.

**Files Modified:**

- `v2/pages/shiftops-report.php` (line 7545-7548): Added validation logging
- `v2/pages/shiftops.php` (line 2075-2078): Added validation logging

**Example:**

```javascript
// Log validation for debugging
if (beforeBounds !== estimatedTeam) {
  console.log(
    `🔧 Team size validation applied: ${beforeBounds.toFixed(
      1
    )} → ${estimatedTeam} (bounds: ${bounds.min}-${
      bounds.max
    }, type: ${primaryType}, reviews: ${reviewCount})`
  );
}
```

### Impact

**Before Fixes:**

- Restaurant with 5018 reviews: Estimated 50+ employees (unrealistic)
- Inconsistent values between loading screen and report
- No visibility into when validation bounds were applied

**After Fixes:**

- Restaurant with 5018 reviews: Estimated 25 employees (realistic cap)
- Consistent values between loading screen and report
- Console logging shows when and why validation bounds are applied

### Testing

**Test Cases:**

- ✅ Very high review counts (5000+): Values capped at 25 for restaurants
- ✅ Very low review counts (<10): Minimum bounds applied correctly
- ✅ Missing data scenarios: Fallback calculations work correctly
- ✅ Different business types: All caps applied correctly
- ✅ Loading screen vs report: Values match consistently
- ✅ Console logs: Validation messages appear when bounds applied

### Code Locations

**Current Line Numbers (January 2025):**

- PHP Backend: `v2/api/shiftops-cost-calculator.php` line 110 (`estimateTeamSize()`)
- PHP API: `v2/api/shiftops.php` line 2047 (`estimateTeamSize()`)
- JavaScript Report: `v2/pages/shiftops-report.php` line 7288 (`estimateTeamSizeFromReviews()`)
- JavaScript Loading: `v2/pages/shiftops.php` line 1949 (`estimateTeamSizeEnhanced()`)

**Validation Bounds Methods:**

- PHP Backend: `v2/api/shiftops-cost-calculator.php` line 425 (`getValidationBoundsForTeamSize()`)
- PHP API: `v2/api/shiftops.php` line 2377 (`getValidationBoundsForTeamSize()`)
- JavaScript Report: `v2/pages/shiftops-report.php` line 7400 (`getValidationBounds()`)
- JavaScript Loading: `v2/pages/shiftops.php` line 2020 (`getValidationBounds()`)

---

## Previous Changes

### Enhanced Multi-Factor Model (Earlier)

**Date:** Prior to January 2025

**Changes:**

- Implemented multi-factor weighted approach (35% volume, 25% hours, 20% complexity, 15% quality, 5% velocity)
- Added location-based multipliers
- Improved business age estimation
- Enhanced confidence calculation
- Added scaled base staffing ranges

**Documentation:** See `TEAM_ESTIMATION_IMPROVEMENTS_APPLIED.md` for details.

---

## Validation Bounds Reference

### Current Validation Bounds (January 2025)

| Business Type | Min | Max Formula                           | Max Cap |
| ------------- | --- | ------------------------------------- | ------- |
| Restaurant    | 5   | `min(25, max(5, ceil(reviews / 15)))` | 25      |
| Cafe          | 3   | `min(15, max(3, ceil(reviews / 20)))` | 15      |
| Bar           | 3   | `min(25, max(3, ceil(reviews / 18)))` | 25      |
| Store         | 2   | `min(30, max(2, ceil(reviews / 25)))` | 30      |
| Hospital      | 8   | `min(60, max(8, ceil(reviews / 10)))` | 60      |
| Pharmacy      | 3   | `min(20, max(3, ceil(reviews / 15)))` | 20      |
| General       | 3   | `min(30, max(3, ceil(reviews / 20)))` | 30      |

### Volume Factor Caps

| Business Type | Review Count | Max Volume Factor |
| ------------- | ------------ | ----------------- |
| Restaurant    | > 2000       | 4.0x              |
| Restaurant    | ≤ 2000       | 6.0x              |
| All Others    | Any          | 6.0x              |

---

## Best Practices

### When Modifying Team Estimation Logic

1. **Update all implementations**: Changes must be made in all 4 locations (PHP backend, PHP API, JavaScript report, JavaScript loading)
2. **Maintain consistency**: All implementations must use same formulas, bounds, and caps
3. **Test edge cases**: Verify with very high/low review counts, missing data, different business types
4. **Update documentation**: Update this changelog and all related documentation files
5. **Add logging**: Include console logging for debugging when validation bounds are applied
6. **Verify data consistency**: Ensure loading screen and report page show same values

### Validation Bounds Guidelines

- **Restaurants**: Maximum 25 employees (realistic for single-location operations)
- **Cafes**: Maximum 15 employees (smaller operations)
- **Bars**: Maximum 25 employees (similar to restaurants)
- **Stores**: Maximum 30 employees (can scale larger)
- **Hospitals**: Maximum 60 employees (larger operations)
- **Pharmacies**: Maximum 20 employees (moderate size)

### Volume Factor Guidelines

- **High review counts**: Reduce cap for restaurants with 2000+ reviews to prevent unrealistic inflation
- **Other businesses**: Can use higher cap (6.0x) as they may scale differently
- **Always validate**: Apply safety checks after location multipliers to ensure final values are realistic

---

## Related Documentation

- `TEAM_ESTIMATION_CURRENT_LOGIC.md` - Current implementation details
- `TEAM_ESTIMATION_ENHANCED_MODEL.md` - Enhanced model design
- `TEAM_ESTIMATION_IMPROVEMENTS_APPLIED.md` - Previous improvements
- `TEAM_ESTIMATION_ai/QUICK_REFERENCE.md` - Quick reference guide
- `TEAM_ESTIMATION_SUMMARY.md` - High-level summary
