# api.bonusblog.bet — setup

Dedicated service that syncs SportMonks data into a separate `nodeposi_api`
database (same MySQL server as `nodeposi_betting_app`, same password) and
exposes JSON endpoints consumed by the main betting app.

## 1. Webroot layout

Point the vhost for `api.bonusblog.bet` to `api.bonusblog.bet/public/`.

```
api.bonusblog.bet/
├── .env                    # copy from .env.example, keep OUT of git
├── .env.example
├── config/
│   └── leagues.json
├── docs/
│   └── setup.md            # this file
├── jobs/                   # CLI only
│   ├── sync_sportmonks.php
│   ├── sync_odds.php
│   └── settle_bets.php
├── public/                 # webroot
│   ├── .htaccess
│   ├── _bootstrap.php
│   ├── lib/OddsService.php
│   └── v1/
│       ├── health.php
│       ├── matches.php
│       ├── match.php
│       ├── odds.php
│       └── settlements.php
└── sql/
    ├── 001_feed_schema.sql
    └── 002_main_db_patch.sql
```

## 2. Databases

```bash
# Feed DB (SportMonks mirror + odds caches + API clients)
mysql -u root -p < sql/001_feed_schema.sql

# Main DB (adds sportmonks_fixture_id to bets, widens match_id)
mysql -u root -p < sql/002_main_db_patch.sql
```

Both scripts are idempotent — re-running them is safe.

## 3. API key

`001_feed_schema.sql` seeds a client named `betting-web` with a PLACEHOLDER key
hash. Replace it:

```sql
UPDATE api_clients
SET api_key_hash = SHA2('YOUR_REAL_KEY_HERE', 256)
WHERE client_name = 'betting-web';
```

The main betting app must send it as `X-API-Key: YOUR_REAL_KEY_HERE`.

## 4. .env

Copy and fill:

```bash
cp .env.example .env
```

Required values:
- `FEED_DB_*` — connection to `nodeposi_api`.
- `MAIN_DB_*` — connection to `nodeposi_betting_app` (read + limited write,
  only bets + users tables touched).
- `SPORTMONKS_TOKEN` — SportMonks v3 API token.

## 5. Cron schedule (default)

```
*/10 * * * *   cd /path/to/api.bonusblog.bet && php jobs/sync_sportmonks.php  >> logs/sync.log 2>&1
*/5  * * * *   cd /path/to/api.bonusblog.bet && php jobs/sync_odds.php        >> logs/odds.log 2>&1
*/2  * * * *   cd /path/to/api.bonusblog.bet && php jobs/settle_bets.php      >> logs/settle.log 2>&1
```

Ensure `logs/` exists and is writable by the cron user.

## 6. Endpoints

Every request requires `X-API-Key`.

### `GET /v1/matches?date=YYYY-MM-DD[&league=<string>][&status=upcoming|finished]`

UI contract compatible with `assets/js/matches.js`.

```jsonc
{
  "success": true,
  "matches": [
    {
      "match_id": "sm:18535312",
      "sportmonks_fixture_id": 18535312,
      "formatted_date": "20.04.2026",      // dd.mm.yyyy
      "time": "20:00",                     // HH:MM Europe/Bucharest
      "date": "2026-04-20",                // yyyy-mm-dd
      "kickoff_utc": "2026-04-20 17:00:00",
      "match_status": "upcoming",
      "homeTeam": "Chelsea",               // legacy key
      "awayTeam": "Arsenal",
      "home_team": "Chelsea",
      "away_team": "Arsenal",
      "home_logo": "...", "away_logo": "...",
      "league": "England: Premier League",
      "league_id": 1,
      "sportmonks_league_id": 8,
      "score": { "home": null, "away": null, "ht_home": null, "ht_away": null },
      "odds": {
        "Match Winner": { "Home": "1.85", "Draw": "3.50", "Away": "4.20" },
        "Both Teams To Score": { "Yes": "1.65", "No": "2.20" },
        "Total Goals": { "Over:2.5": "1.95", "Under:2.5": "1.85" },
        "Total Goals 1st Half": { "Over:1.5": "2.80" },
        "Corners Over/Under": { "Over:8.5": "1.92", "Under:8.5": "1.88" }
      }
    }
  ],
  "leagues": ["England: Premier League", "..."]
}
```

### `GET /v1/match?id=sm:18535312` or `?fixture_id=18535312`

Returns the single match with `events`, `statistics`, `lineups`.

### `GET /v1/odds?fixture_id=18535312[&min_odds=1.8][&allow_api=1]`

Returns `best`, `filtered`, `ui` odds. `allow_api=1` is the only way to trigger
a live SportMonks call from this endpoint (normally responses come from the
feed DB cache populated by the cron jobs).

### `GET /v1/settlements[?since=YYYY-MM-DD][&fixture_id=...]`

Returns fixtures in a terminal state with their final and halftime scores.
Used by the betting UI to render recent settlements.

### `GET /v1/health`

Health check + last sync runs (for ops dashboards).

## 7. How the betting app consumes it

- **Match list**: `backend/api/matches.php` (or a new
  `backend/api/matches_v2.php`) proxies to `GET /v1/matches`.
- **Place bet**: the client POSTs `sportmonks_fixture_id` alongside
  `match_id = "sm:<fixtureId>"`; `backend/api/place_bet.php` persists it in
  the widened `bets` table.
- **Settlement**: this service's `settle_bets.php` processes only bets with
  `sportmonks_fixture_id IS NOT NULL`. Legacy Goalserve bets remain handled
  by `scripts/odds/validate_odds.php` until they drain out.

## 8. Troubleshooting

- `sync_runs` table records the status + counters of every job run.
- `request_logs` records every call to `/v1/*` with latency + status code.
- Odds caches (`fixture_odds_best`, `fixture_odds_filtered`,
  `fixture_odds_filtered_live`, `fixture_odds_ui`) expose `last_error` when
  SportMonks rejects a fixture (rate limit, forbidden, no odds available).
