================================================================================
REPORTS SYNCHRONIZATION API SPECIFICATION
================================================================================

This document describes the API endpoint for synchronizing report data from the
MbetterClient application to the server. The implementation is designed to handle
unreliable and unstable network connections with automatic retry mechanisms.

================================================================================
ENDPOINT DETAILS
================================================================================

URL: /api/reports/sync
Method: POST
Authentication: Bearer Token (required)
Content-Type: application/json
Timeout: 60 seconds (recommended for large payloads)

================================================================================
REQUEST FORMAT
================================================================================

The client sends a POST request with the following JSON structure:

{
  "sync_id": "sync_20260201_082615_a1b2c3d4",
  "client_id": "abc123def456",
  "sync_timestamp": "2026-02-01T08:26:15.123456",
  "date_range": "today",
  "start_date": "2026-02-01T00:00:00",
  "end_date": "2026-02-01T08:26:15",
  "bets": [
    {
      "uuid": "550e8400-e29b-41d4-a716-446655440000",
      "fixture_id": "fixture_20260201_001",
      "bet_datetime": "2026-02-01T08:15:30.123456",
      "paid": false,
      "paid_out": false,
      "total_amount": 500.00,
      "bet_count": 3,
      "details": [
        {
          "match_id": 123,
          "match_number": 1,
          "outcome": "WIN1",
          "amount": 200.00,
          "win_amount": 0.00,
          "result": "pending"
        },
        {
          "match_id": 124,
          "match_number": 2,
          "outcome": "X1",
          "amount": 150.00,
          "win_amount": 0.00,
          "result": "pending"
        },
        {
          "match_id": 125,
          "match_number": 3,
          "outcome": "WIN2",
          "amount": 150.00,
          "win_amount": 0.00,
          "result": "pending"
        }
      ]
    }
  ],
  "extraction_stats": [
    {
      "match_id": 123,
      "fixture_id": "fixture_20260201_001",
      "match_datetime": "2026-02-01T08:00:00.123456",
      "total_bets": 45,
      "total_amount_collected": 15000.00,
      "total_redistributed": 10500.00,
      "actual_result": "WIN1",
      "extraction_result": "WIN1",
      "cap_applied": true,
      "cap_percentage": 70.0,
      "under_bets": 20,
      "under_amount": 6000.00,
      "over_bets": 25,
      "over_amount": 9000.00,
      "result_breakdown": {
        "WIN1": {"bets": 20, "amount": 6000.00, "coefficient": 2.5},
        "X1": {"bets": 10, "amount": 3000.00, "coefficient": 3.0},
        "WIN2": {"bets": 15, "amount": 6000.00, "coefficient": 2.0}
      }
    }
  ],
  "summary": {
    "total_payin": 15000.00,
    "total_payout": 10500.00,
    "net_profit": 4500.00,
    "total_bets": 45,
    "total_matches": 1
  }
}

================================================================================
REQUEST FIELDS DESCRIPTION
================================================================================

Top-Level Fields:
----------------
sync_id (string, required)
  - Unique identifier for this sync operation
  - Format: "sync_YYYYMMDD_HHMMSS_<random_8_chars>"
  - Used for tracking and deduplication on server side

client_id (string, required)
  - Unique identifier for the client machine
  - Generated from rustdesk_id or machine ID
  - Used to identify source of data

sync_timestamp (string, required)
  - ISO 8601 format timestamp when sync was initiated
  - Format: "YYYY-MM-DDTHH:MM:SS.ffffff"

date_range (string, required)
  - Time range for the report data
  - Values: "today", "yesterday", "week", "all"

start_date (string, required)
  - ISO 8601 format start of date range
  - Format: "YYYY-MM-DDTHH:MM:SS"

end_date (string, required)
  - ISO 8601 format end of date range
  - Format: "YYYY-MM-DDTHH:MM:SS"

bets (array, required)
  - Array of bet records for the specified date range
  - Excludes cancelled bets

extraction_stats (array, required)
  - Array of extraction statistics for matches
  - Contains redistribution and payout data

summary (object, required)
  - Summary statistics for the entire sync
  - Aggregated totals for quick reporting

Bet Object Fields:
-----------------
uuid (string, required)
  - Unique identifier for the bet
  - UUID v4 format

fixture_id (string, required)
  - Fixture identifier the bet belongs to
  - Links bet to specific fixture

bet_datetime (string, required)
  - ISO 8601 format timestamp when bet was placed
  - Format: "YYYY-MM-DDTHH:MM:SS.ffffff"

paid (boolean, required)
  - Whether the bet has been marked as paid
  - true = paid, false = unpaid

paid_out (boolean, required)
  - Whether winnings have been paid out
  - true = paid out, false = not paid out

total_amount (float, required)
  - Total amount of all bet details in this bet
  - Sum of all detail amounts

bet_count (integer, required)
  - Number of bet details in this bet
  - Excludes cancelled details

details (array, required)
  - Array of individual bet details

Bet Detail Object Fields:
-------------------------
match_id (integer, required)
  - Database ID of the match
  - Foreign key reference

match_number (integer, required)
  - Match number from fixture
  - Human-readable match identifier

outcome (string, required)
  - Outcome type that was bet on
  - Examples: "WIN1", "X1", "WIN2", "UNDER", "OVER"

amount (float, required)
  - Amount bet on this outcome
  - Positive decimal value

win_amount (float, required)
  - Amount won for this bet detail
  - 0.00 if not won or pending

result (string, required)
  - Result status of the bet detail
  - Values: "pending", "won", "lost", "cancelled"

Extraction Stats Object Fields:
------------------------------
match_id (integer, required)
  - Database ID of the match
  - Foreign key reference

fixture_id (string, required)
  - Fixture identifier
  - Links stats to specific fixture

match_datetime (string, required)
  - ISO 8601 format timestamp of match
  - Format: "YYYY-MM-DDTHH:MM:SS.ffffff"

total_bets (integer, required)
  - Total number of bets placed on this match
  - Excludes cancelled bets

total_amount_collected (float, required)
  - Total amount collected from all bets
  - Sum of all bet amounts

total_redistributed (float, required)
  - Total amount redistributed to winners
  - Payout amount after CAP application

actual_result (string, required)
  - Actual match result
  - Examples: "WIN1", "X1", "WIN2", "RET1", "RET2"

extraction_result (string, required)
  - Result used for extraction calculations
  - May differ from actual_result in some cases

cap_applied (boolean, required)
  - Whether CAP percentage was applied
  - true = CAP applied, false = no CAP

cap_percentage (float, optional)
  - CAP percentage used for calculations
  - Example: 70.0 for 70% CAP

under_bets (integer, required)
  - Number of UNDER bets placed
  - Only applicable for UNDER/OVER matches

under_amount (float, required)
  - Total amount bet on UNDER
  - Only applicable for UNDER/OVER matches

over_bets (integer, required)
  - Number of OVER bets placed
  - Only applicable for UNDER/OVER matches

over_amount (float, required)
  - Total amount bet on OVER
  - Only applicable for UNDER/OVER matches

result_breakdown (object, required)
  - Detailed breakdown of bets by outcome
  - Structure: {"OUTCOME_NAME": {"bets": N, "amount": X.XX, "coefficient": Y.YY}}

Summary Object Fields:
---------------------
total_payin (float, required)
  - Total amount collected from all bets
  - Sum of all bet amounts

total_payout (float, required)
  - Total amount redistributed to winners
  - Sum of all extraction stats total_redistributed

net_profit (float, required)
  - Net profit for the period
  - Calculated as: total_payin - total_payout

total_bets (integer, required)
  - Total number of bet details
  - Excludes cancelled bets

total_matches (integer, required)
  - Number of matches with extraction stats
  - Count of extraction_stats array

================================================================================
SUCCESS RESPONSE FORMAT
================================================================================

HTTP Status: 200 OK
Content-Type: application/json

{
  "success": true,
  "synced_count": 45,
  "message": "Report data synchronized successfully",
  "requires_full_sync": false,
  "server_timestamp": "2026-02-01T08:26:20.123456"
}

Success Response Fields:
---------------------
success (boolean, required)
  - Always true for successful sync
  - Indicates operation completed successfully

synced_count (integer, required)
  - Number of items successfully synced
  - Total count of bets and stats processed

message (string, required)
  - Human-readable success message
  - Description of sync operation

requires_full_sync (boolean, required)
  - IMPORTANT: Indicates whether the server requires a full sync
  - Set to true when the server has NO records for this client across ALL report tables (bets, extraction_stats, match_reports)
  - Client should perform a full sync (send all historical data) when this is true
  - This handles scenarios where the server database was reset but client has local tracking
  - If ANY record exists for the client in ANY table, this flag will be false

server_timestamp (string, required)
  - ISO 8601 format timestamp on server
  - When the server processed the sync

================================================================================
ERROR RESPONSE FORMAT
================================================================================

HTTP Status: 400 Bad Request
Content-Type: application/json

{
  "success": false,
  "error": "Invalid request format",
  "details": "Missing required field: sync_id"
}

HTTP Status: 401 Unauthorized
Content-Type: application/json

{
  "success": false,
  "error": "Authentication required",
  "details": "Invalid or expired bearer token"
}

HTTP Status: 429 Too Many Requests
Content-Type: application/json

{
  "success": false,
  "error": "Rate limit exceeded",
  "details": "Too many sync requests. Please try again later.",
  "retry_after": 60
}

HTTP Status: 500 Internal Server Error
Content-Type: application/json

{
  "success": false,
  "error": "Internal server error",
  "details": "An unexpected error occurred while processing sync"
}

Error Response Fields:
--------------------
success (boolean, required)
  - Always false for errors
  - Indicates operation failed

error (string, required)
  - Error type or category
  - Human-readable error identifier

details (string, optional)
  - Detailed error description
  - Additional context about the error

retry_after (integer, optional)
  - Seconds to wait before retrying
  - Only present for rate limit errors

================================================================================
GET LAST SYNC INFORMATION
================================================================================

URL: /api/reports/last-sync
Method: GET
Authentication: Bearer Token (required)
Content-Type: application/json

Query Parameters:
----------------
client_id (string, optional)
  - Unique identifier for the client
  - If provided, retrieves sync information for a specific client
  - If not provided, returns information for all clients associated with the authenticated user's API token

Request Example (Single Client):
--------------------------------
GET /api/reports/last-sync?client_id=abc123def456

Authorization: Bearer your-api-token-here

Request Example (All Clients):
------------------------------
GET /api/reports/last-sync

Authorization: Bearer your-api-token-here

Success Response for Single Client (200 OK):
--------------------------------------------
{
  "success": true,
  "client_id": "abc123def456",
  "last_sync_id": "sync_20260201_082615_a1b2c3d4",
  "last_sync_timestamp": "2026-02-01T08:26:15.123456",
  "last_sync_type": "incremental",
  "last_date_range": "all",
  "last_start_date": "2026-01-01T00:00:00",
  "last_end_date": "2026-02-01T08:26:15",
  "total_syncs": 5,
  "requires_full_sync": false,
  "last_sync_summary": {
    "total_payin": 15000.00,
    "total_payout": 10500.00,
    "net_profit": 4500.00,
    "total_bets": 45,
    "total_matches": 1,
    "cap_compensation_balance": 5000.00
  },
  "server_timestamp": "2026-02-01T08:30:00.123456"
}

Success Response for All Clients (200 OK):
------------------------------------------
{
  "success": true,
  "message": "Found 2 client(s) for this user",
  "clients": [
    {
      "client_id": "abc123def456",
      "last_sync_id": "sync_20260201_082615_a1b2c3d4",
      "last_sync_timestamp": "2026-02-01T08:26:15.123456",
      "last_sync_type": "incremental",
      "total_syncs": 5,
      "requires_full_sync": false,
      "last_sync_summary": {
        "total_payin": 15000.00,
        "total_payout": 10500.00,
        "net_profit": 4500.00,
        "total_bets": 45,
        "total_matches": 1,
        "cap_compensation_balance": 5000.00
      }
    },
    {
      "client_id": "xyz789ghi012",
      "last_sync_id": null,
      "last_sync_timestamp": null,
      "last_sync_type": null,
      "total_syncs": 0,
      "requires_full_sync": true,
      "last_sync_summary": null
    }
  ],
  "server_timestamp": "2026-02-01T08:30:00.123456"
}

Response Fields (Single Client):
--------------------------------
success (boolean, required)
  - Always true for successful request

client_id (string, required)
  - Client identifier for which sync information was retrieved

last_sync_id (string, optional)
  - Sync ID of the most recent sync
  - null if no sync records exist

last_sync_timestamp (string, optional)
  - ISO 8601 format timestamp of the most recent sync
  - null if no sync records exist

last_sync_type (string, optional)
  - Type of the most recent sync ("full" or "incremental")
  - null if no sync records exist

last_date_range (string, optional)
  - Date range of the most recent sync
  - null if no sync records exist

last_start_date (string, optional)
  - Start date of the most recent sync
  - null if no sync records exist

last_end_date (string, optional)
  - End date of the most recent sync
  - null if no sync records exist

total_syncs (integer, required)
  - Total number of sync operations for this client

requires_full_sync (boolean, required)
  - IMPORTANT: Indicates whether the server requires a full sync for this client
  - Set to true when the server has NO records for this client across ALL report tables (bets, extraction_stats, match_reports)
  - Client should perform a full sync (send all historical data) when this is true
  - If ANY record exists for the client in ANY table, this flag will be false

last_sync_summary (object, optional)
  - Summary statistics from the most recent sync
  - null if no sync records exist

server_timestamp (string, required)
  - ISO 8601 format timestamp on server
  - When the server processed the request

Response Fields (All Clients):
-------------------------------
success (boolean, required)
  - Always true for successful request

message (string, required)
  - Human-readable message describing the result

clients (array, required)
  - Array of client objects, each containing the same fields as the single client response
  - Each client object includes: client_id, last_sync_id, last_sync_timestamp, last_sync_type, total_syncs, requires_full_sync, last_sync_summary

server_timestamp (string, required)
  - ISO 8601 format timestamp on server
  - When the server processed the request

Error Response (403 Forbidden):
--------------------------------
{
  "success": false,
  "error": "Access denied",
  "details": "You do not have access to this client"
}

================================================================================
CLIENT RETRY BEHAVIOR
================================================================================

The client implements robust retry mechanisms for unreliable connections:

1. Exponential Backoff:
   - Base backoff: 60 seconds
   - Formula: backoff_time = 60 * (2 ^ retry_count)
   - Example: 60s, 120s, 240s, 480s, 960s

2. Maximum Retries:
   - Per sync attempt: 3 retries
   - Per queued item: 5 retries total
   - After max retries: item marked as failed

3. Offline Queue:
   - Failed syncs are queued for retry
   - Queue stored in: <user_data_dir>/sync_queue/reports_sync_queue.json
   - Maximum queue size: 1000 items
   - Queue persists across application restarts

4. Connection Error Handling:
   - Timeout: Retry with backoff
   - Connection Error: Retry with backoff
   - HTTP 429: Wait retry_after seconds, then retry
   - HTTP 401: Stop retrying (authentication issue)
   - HTTP 5xx: Retry with backoff

5. Queue Processing:
   - Automatic processing on scheduled interval (default: 1 hour)
   - FIFO order (oldest items first)
   - Skips items waiting for backoff period
   - Removes completed/failed items after processing

================================================================================
SERVER IMPLEMENTATION REQUIREMENTS
================================================================================

1. Authentication:
   - Validate Bearer token from Authorization header
   - Return 401 if token is invalid or expired
   - Token should identify the client machine

2. Data Validation:
   - Validate all required fields are present
   - Validate data types match specifications
   - Validate date ranges are valid
   - Return 400 with specific error details on validation failure

3. Data Storage:
   - Store bets data with deduplication based on uuid
   - Store extraction stats with deduplication based on match_id
   - Use sync_id for tracking and audit trail
   - Store client_id for data source identification

4. Idempotency:
   - Handle duplicate sync requests gracefully
   - Use sync_id to detect duplicates
   - Return success for already-synced data

5. Rate Limiting:
   - Implement rate limiting to prevent abuse
   - Return 429 with retry_after header when limit exceeded
   - Recommended: 1 sync per minute per client

6. Response Format:
   - Always return JSON with success field
   - Include appropriate HTTP status codes
   - Provide helpful error messages for debugging

7. Data Integrity:
   - Validate numeric values are positive where required
   - Validate timestamps are in valid ISO 8601 format
   - Validate UUIDs are valid UUID v4 format
   - Validate result values are from allowed set

================================================================================
SECURITY CONSIDERATIONS
================================================================================

1. Authentication:
   - All requests must include valid Bearer token
   - Tokens should be cryptographically secure
   - Implement token expiration and refresh mechanism

2. Data Encryption:
   - Consider encrypting sensitive data in transit (HTTPS)
   - Validate SSL/TLS certificates
   - Use secure cipher suites

3. Input Validation:
   - Sanitize all input data
   - Prevent SQL injection
   - Validate data types and ranges
   - Limit payload size (recommended: 10MB max)

4. Audit Logging:
   - Log all sync requests with sync_id
   - Log client_id for tracking
   - Log timestamps for audit trail
   - Log errors for troubleshooting

================================================================================
TESTING RECOMMENDATIONS
================================================================================

1. Unit Tests:
   - Test with valid request data
   - Test with missing required fields
   - Test with invalid data types
   - Test with duplicate sync_id

2. Integration Tests:
   - Test with authentication
   - Test without authentication
   - Test with rate limiting
   - Test with large payloads

3. Network Tests:
   - Test with slow connections
   - Test with intermittent failures
   - Test with timeout scenarios
   - Test retry behavior

4. Load Tests:
   - Test with multiple concurrent clients
   - Test with large data volumes
   - Test with rapid sync requests
   - Test queue overflow scenarios

================================================================================
VERSION HISTORY
================================================================================

Version 1.0 - 2026-02-01
  - Initial specification
  - Basic sync functionality
  - Retry mechanisms
  - Offline queue support

================================================================================
CONTACT
================================================================================

For questions or issues regarding this API specification, please contact the
development team.

Document generated: 2026-02-01
Last updated: 2026-02-01