# Full Resync Implementation Summary

## Overview
This document describes the implementation of full resync functionality for the reports sync system. The client now properly handles server responses indicating that a full resync is needed.

## Problem Statement
When sending a request to sync reports to the server and asking for the latest sync received, the server may answer that it is in need of a full resync because it doesn't have any record for this client. Additionally, the server can respond with null values for the last sync ID. In both cases, the client should start a full resync with the server.

## Implementation Details

### 1. Modified `query_server_last_sync` Method
**File:** `mbetterclient/api_client/client.py` (lines 1431-1481)

**Changes:**
- Added detection of `needs_full_resync` flag in server response
- Added detection of `null` values for `last_sync_id`
- When either condition is detected, the response is marked with `needs_full_resync: True`
- For 404 responses (no record for client), returns a dict indicating full resync is needed

**Key Logic:**
```python
if needs_full_resync or last_sync_id is None:
    logger.warning(f"Server indicates full resync is needed (needs_full_resync={needs_full_resync}, last_sync_id={last_sync_id})")
    data['needs_full_resync'] = True
    return data
```

### 2. Modified `needs_recovery` Method
**File:** `mbetterclient/api_client/client.py` (lines 1531-1574)

**Changes:**
- Added check for `needs_full_resync` flag in server info
- Added check for `null` `last_sync_id` value
- When either condition is detected, calls `_clear_local_tracking()` to force full resync
- Returns `True` to indicate recovery is needed

**Key Logic:**
```python
needs_full_resync = server_info.get('needs_full_resync', False)
last_sync_id = server_info.get('last_sync_id')

if needs_full_resync or last_sync_id is None:
    logger.warning(f"Server indicates full resync is needed (needs_full_resync={needs_full_resync}, last_sync_id={last_sync_id}) - clearing local tracking")
    self._clear_local_tracking()
    return True
```

### 3. Added `_clear_local_tracking` Method
**File:** `mbetterclient/api_client/client.py` (lines 1575-1592)

**Purpose:**
- Clears all local sync tracking records from the database
- Forces the next sync to be a full sync instead of incremental

**Implementation:**
```python
def _clear_local_tracking(self) -> bool:
    """Clear all local sync tracking records to force full resync"""
    try:
        session = self.db_manager.get_session()
        try:
            deleted_count = session.query(self.ReportsSyncTrackingModel).delete()
            session.commit()
            logger.info(f"Cleared {deleted_count} local sync tracking records to force full resync")
            return True
        except Exception as e:
            logger.error(f"Failed to clear local tracking: {e}")
            session.rollback()
            return False
        finally:
            session.close()
    except Exception as e:
        logger.error(f"Error clearing local tracking: {e}")
        return False
```

### 4. Modified `collect_report_data` Method
**File:** `mbetterclient/api_client/client.py` (lines 1014-1035)

**Changes:**
- Added check for `needs_full_resync` flag after recovery check
- When full resync is needed, forces `date_range = 'all'` to collect all data
- Logs warning message indicating full sync is being performed

**Key Logic:**
```python
needs_full_resync = server_info and server_info.get('needs_full_resync', False)
if needs_full_resync:
    logger.warning("Server indicated full resync is needed - performing full sync")
    date_range = 'all'
```

## Server Response Format

The server should respond to the `/api/reports/last-sync` endpoint with the following format:

### Normal Sync Response
```json
{
  "success": true,
  "needs_full_resync": false,
  "last_sync_id": "sync_20240101_120000_abc123",
  "last_sync_timestamp": "2024-01-01T12:00:00Z",
  "total_syncs": 10
}
```

### Full Resync Response (No Record)
```json
{
  "success": true,
  "needs_full_resync": true,
  "last_sync_id": null,
  "last_sync_timestamp": null,
  "total_syncs": 0
}
```

### Full Resync Response (Null Last Sync ID)
```json
{
  "success": true,
  "needs_full_resync": false,
  "last_sync_id": null,
  "last_sync_timestamp": "2024-01-01T12:00:00Z",
  "total_syncs": 5
}
```

## Test Coverage

Created comprehensive test suite in `test_full_resync.py`:

1. **test_server_indicates_full_resync** - Verifies `needs_full_resync=True` triggers full resync
2. **test_server_null_last_sync_id** - Verifies null `last_sync_id` triggers full resync
3. **test_server_404_response** - Verifies 404 response triggers full resync
4. **test_clear_local_tracking** - Verifies local tracking is cleared
5. **test_normal_sync_no_full_resync** - Verifies normal sync doesn't trigger full resync
6. **test_collect_report_data_with_full_resync** - Verifies full sync is forced when needed

All tests pass successfully.

## Behavior Flow

### Scenario 1: Server Indicates Full Resync
1. Client queries server for last sync info
2. Server responds with `needs_full_resync: true`
3. `needs_recovery()` detects the flag and returns `True`
4. `_clear_local_tracking()` is called to clear all local tracking
5. `collect_report_data()` forces `date_range = 'all'`
6. Full sync is performed with all data

### Scenario 2: Server Returns Null Last Sync ID
1. Client queries server for last sync info
2. Server responds with `last_sync_id: null`
3. `needs_recovery()` detects the null value and returns `True`
4. `_clear_local_tracking()` is called to clear all local tracking
5. `collect_report_data()` forces `date_range = 'all'`
6. Full sync is performed with all data

### Scenario 3: Server Returns 404 (No Record)
1. Client queries server for last sync info
2. Server responds with 404 status code
3. `query_server_last_sync()` returns dict with `needs_full_resync: true`
4. `needs_recovery()` detects the flag and returns `True`
5. `_clear_local_tracking()` is called to clear all local tracking
6. `collect_report_data()` forces `date_range = 'all'`
7. Full sync is performed with all data

## Logging

The implementation includes comprehensive logging:

- `Server indicates full resync is needed (needs_full_resync={value}, last_sync_id={value}) - clearing local tracking`
- `Cleared {count} local sync tracking records to force full resync`
- `Server indicated full resync is needed - performing full sync`

## Benefits

1. **Automatic Recovery**: Client automatically detects when full resync is needed
2. **Data Consistency**: Ensures client and server are synchronized
3. **Robust Error Handling**: Handles multiple scenarios where full resync is needed
4. **Clear Logging**: Provides clear visibility into resync operations
5. **Test Coverage**: Comprehensive test suite ensures reliability

## Files Modified

1. `mbetterclient/api_client/client.py` - Core implementation
2. `test_full_resync.py` - Test suite (new file)

## Backward Compatibility

The implementation is backward compatible:
- Existing sync behavior is preserved when server doesn't indicate full resync
- Only triggers full resync when explicitly needed
- No changes to database schema or API contracts