# API iOS TopStats

Base URL production prévue : `https://topstats.fr/api/v1`

Toutes les réponses JSON suivent ce format :

```json
{
  "ok": true,
  "data": {},
  "meta": {}
}
```

En erreur :

```json
{
  "ok": false,
  "error": {
    "code": "AUTH_REQUIRED",
    "message": "Connexion requise."
  }
}
```

## Authentification

Après connexion ou inscription, l’API retourne un token :

```json
{
  "auth": {
    "token": "neo_xxx",
    "token_type": "Bearer",
    "expires_at": "2026-12-13T12:00:00.000Z"
  }
}
```

L’app iOS doit ensuite envoyer :

```http
Authorization: Bearer neo_xxx
Content-Type: application/json
```

Endpoints :

- `POST /auth/register` : inscription email.
- `POST /auth/login` : connexion email.
- `GET /auth/me` : compte connecté.
- `POST /auth/logout` : révoque le token courant.
- `GET /auth/oauth/google/url` : URL OAuth Google mobile.
- `GET /auth/oauth/apple/url` : URL OAuth Apple mobile.
- `POST /auth/oauth/:provider/callback` : échange le callback OAuth contre un token API.

Pour l’app iOS, `GET /auth/oauth/:provider/url` génère un état mobile. Après validation chez Apple ou Google, le callback web `/auth/:provider/callback` redirige vers :

```text
askneo://oauth?provider=google&token=neo_xxx&expires_at=...
```

L’app stocke ensuite le token et appelle `GET /auth/me`.

Payload inscription :

```json
{
  "name": "Allan",
  "email": "allan@example.com",
  "password": "motdepasse8",
  "platform": "ios",
  "device_name": "iPhone"
}
```

Payload connexion :

```json
{
  "email": "allan@example.com",
  "password": "motdepasse8",
  "platform": "ios",
  "device_name": "iPhone"
}
```

## Public

- `GET /health` : statut API.
- `GET /config` : configuration app, limite gratuite, packs PRO, OAuth, liens légaux.
- `GET /landing` : analyse du jour pour l’accueil public.
- `GET /legal` : liste des pages légales.
- `GET /legal/:slug` : lien vers une page légale publique.

## App Connectée

- `GET /dashboard` : accueil app, 3 matchs à suivre, recommandations, historique court.
- `GET /matches` : matchs Coupe du Monde, UEFA et grands championnats européens.
- `GET /matches?live_only=true` : matchs live uniquement.
- `GET /matches?date=YYYY-MM-DD` : matchs d’une date.
- `GET /matches/:id` : détail match.
- `GET /matches/:id/analysis` : analyse pré-match complète.
- `GET /matches/:id/live` : score, stats live, événements et notifications d’un match.
- `GET /live` : page LIVE, matchs en direct avec statistiques et fil d’événements.
- `GET /recommendations` : recommandations du jour selon le pack.
- `GET /chat` : historique chat et quota.
- `POST /chat` : envoyer un message à TopStats.
- `GET /history?page=1&per_page=12` : historique paginé.
- `GET /profile` : compte et abonnement.
- `PATCH /profile/password` : changement mot de passe.
- `DELETE /profile` : suppression définitive du compte, confirmation `SUPPRIMER`.
- `POST /devices` : enregistrement token APNs iOS.
- `GET /pro/packs` : packs PRO.
- `POST /pro/checkout/:plan` : démarrage paiement.
- `POST /pro/cancel` : résiliation immédiate PRO.
- `POST /iap/apple/verify` : validation achat intégré Apple et activation PRO site + app.

## Règles Gratuit / PRO

- Gratuit : seules les recommandations dont la cote est `<= 1.45` sont visibles.
- PRO : toutes les recommandations fiables disponibles sont visibles.
- Si un match n’a aucun prono gratuit fiable mais possède des pronos PRO, `/matches/:id/analysis` retourne `hidden_recommendations_count > 0`, `locked: true` et `free_max_odds: 1.45`.

## Chat

Payload :

```json
{
  "message": "Donne-moi une cote à 2 aujourd’hui"
}
```

Réponse :

```json
{
  "ok": true,
  "data": {
    "reply": "Réponse de TopStats...",
    "quota": 5,
    "used_today": 2,
    "remaining_today": 3,
    "typing": {
      "recommended": true,
      "min_duration_ms": 900
    }
  }
}
```

L’app iOS doit afficher la réponse en mode typing côté interface.

## LIVE et Notifications

`GET /live` retourne uniquement les matchs en direct ciblés par TopStats : Coupe du Monde, compétitions UEFA et grands championnats européens configurés.

Chaque match live contient :

- `match` : équipes, logos, score, statut, compétition.
- `statistics` : stats live par équipe.
- `events` : buts, remplacements, cartons et temps forts.
- `lineups` : compositions officielles, formation, titulaires, remplaçants, coach.
- `player_stats` : stats joueurs disponibles, note, tirs, passes, duels, tacles, cartons.
- `odds` : cotes bookmaker groupées par marché.
- `recommendations` : conseils IA pré-match liés au match.
- `recent_form` : derniers matchs domicile/extérieur des deux équipes.
- `head_to_head` : confrontations récentes.
- `standings` : classements de la compétition quand l’API les fournit.
- `notifications` : notifications prêtes à afficher côté app.

Notifications prévues :

- `goal` : but en direct.
- `substitution` : changement joueur.
- `halftime` : mi-temps avec score.
- `fulltime` : fin du match avec score.
- `pick_validated` : un prono IA mémorisé du jour vient de passer.

Payload appareil :

```json
{
  "token": "apns_token",
  "platform": "ios",
  "device_name": "iPhone",
  "notifications_enabled": true
}
```

## Achats Intégrés Apple

Produits App Store Connect à créer :

- `askneo.pro.weekly` : PRO 1 semaine, 17,49€.
- `askneo.pro.monthly` : PRO 1 mois, 49,99€.
- `askneo.pro.sixmonths` : PRO 6 mois, 224,99€.

Payload de validation :

```json
{
  "product_id": "askneo.pro.monthly",
  "transaction_id": "200000000000000",
  "original_transaction_id": "200000000000000",
  "signed_transaction_info": "eyJhbGciOiJFUzI1NiIs...",
  "environment": "Production"
}
```

Le serveur vérifie le JWS StoreKit 2, contrôle le bundle `fr.askneo.app`, vérifie le produit et active l’abonnement dans la même table que le site. L’accès PRO est donc commun app + web.

Variable serveur à garder cohérente :

```bash
APPLE_BUNDLE_ID=fr.askneo.app
```

## Suppression De Compte

Payload :

```json
{
  "confirmation": "SUPPRIMER"
}
```

Réponse :

```json
{
  "deleted": true,
  "message": "Votre compte TopStats a été supprimé."
}
```

## Migrations SQL

Sur une base existante, importer au minimum :

```text
database/migrations/2026-06-16-api-tokens.sql
database/migrations/2026-06-16-ios-live-iap.sql
```
