SPB Git forge

spb/api-ka

Public

API-KA — plateforme centrale : collecte quotidienne des 8 services KA, historisation append-only et API publique sur www.api-ka.com

48commits 1branches 0releases
5.9 MBsize
maindefault branch
19 days agolast push
Python 60.9% HTML 21% TypeScript 7.3% JavaScript 5.2% CSS 4.8% Shell 0.8%
13.0 KB

# CLAUDE.md — Projet API-KA

# Vision du projet

API-KA est la plateforme centrale légendaire de l'écosystème KA. Elle collecte, sauvegarde et centralise chaque jour les données de tous les services KA (lou-ka, immo-ka, food-ka, auto-ka, fabri-ka, resto-ka, sorti-ka, crea-ka) dans une base de données unifiée, puis les expose via une API publique accessible sur www.api-ka.com (tunnel ngrok).

Tout le déploiement se fait sur le node m3u96b. Aucun service de production ne tourne ailleurs.

# Auteur — OBLIGATOIRE dans chaque fichier

Chaque fichier de code (Python, JS, SQL, shell, config, etc.) DOIT commencer par un en-tête d'auteur. Règle non négociable — aucun fichier sans en-tête.

Python / Shell / SQL / YAML :

text
# ============================================
# Projet   : API-KA
# Fichier  : <nom_du_fichier>
# Node     : m3u96b
# Author   : Simon-Pierre Boucher
# Contact  : contact@spboucher.ai
# Date     : <date de création>
# ============================================

JavaScript / TypeScript :

javascript
/**
 * ============================================
 * Projet   : API-KA
 * Fichier  : <nom_du_fichier>
 * Node     : m3u96b
 * Author   : Simon-Pierre Boucher
 * Contact  : contact@spboucher.ai
 * Date     : <date de création>
 * ============================================
 */

# Node de déploiement : m3u96b

  • Node cible unique : m3u96b. Tous les services (API, scheduler, base de données, tunnel ngrok) tournent sur ce node.
  • Répertoire de déploiement : /opt/api-ka/ sur m3u96b.
  • Données et backups : /opt/api-ka/data/ et /opt/api-ka/data/backups/.
  • Logs centralisés : /opt/api-ka/logs/.
  • Les services sont gérés par systemd sur m3u96b (voir section "Services systemd").
  • Toute commande de déploiement, cron ou service doit référencer explicitement m3u96b dans sa documentation et ses logs (hostname vérifié au démarrage : si le hostname n'est pas m3u96b, le service refuse de démarrer en mode production et log un avertissement).

# Vérification du node au démarrage (obligatoire dans chaque service)

python
import socket, os

REQUIRED_NODE = "m3u96b"

def verify_node():
    hostname = socket.gethostname()
    if os.getenv("APP_ENV") == "production" and hostname != REQUIRED_NODE:
        raise RuntimeError(f"API-KA doit tourner sur {REQUIRED_NODE}, node actuel : {hostname}")

# Sources de données (les 8 services KA)

Service Table Variable source Fréquence
lou-ka louka_data LOUKA_SOURCE_URL Quotidienne
immo-ka immoka_data IMMOKA_SOURCE_URL Quotidienne
food-ka foodka_data FOODKA_SOURCE_URL Quotidienne
auto-ka autoka_data AUTOKA_SOURCE_URL Quotidienne
fabri-ka fabrika_data FABRIKA_SOURCE_URL Quotidienne
resto-ka restoka_data RESTOKA_SOURCE_URL Quotidienne
sorti-ka sortika_data SORTIKA_SOURCE_URL Quotidienne
crea-ka creaka_data CREAKA_SOURCE_URL Quotidienne

RÈGLE CRITIQUE : les données de chaque service DOIVENT être sauvegardées tous les jours, sans exception.

  • Chaque exécution quotidienne est journalisée.
  • Tout échec de collecte est détecté, loggé et relancé automatiquement (3 tentatives, backoff exponentiel : 30s → 2min → 10min).
  • Si un service échoue après 3 tentatives, une entrée status=failed est écrite dans collection_runs et une alerte est ajoutée à logs/alerts.log. Le lendemain, le job tente automatiquement un rattrapage (backfill) des dates manquées.

# Architecture

text
/opt/api-ka/                      # sur le node m3u96b
├── CLAUDE.md
├── README.md
├── .env                          # jamais commité
├── .env.example
├── requirements.txt
├── src/
│   ├── config.py                 # chargement .env + vérification node m3u96b
│   ├── collectors/
│   │   ├── base_collector.py     # classe abstraite : fetch, validate, save, retry
│   │   ├── louka_collector.py
│   │   ├── immoka_collector.py
│   │   ├── foodka_collector.py
│   │   ├── autoka_collector.py
│   │   ├── fabrika_collector.py
│   │   ├── restoka_collector.py
│   │   ├── sortika_collector.py
│   │   └── creaka_collector.py
│   ├── database/
│   │   ├── models.py             # SQLAlchemy : 8 tables données + collection_runs
│   │   ├── db.py                 # engine, session, init, healthcheck
│   │   └── migrations/           # Alembic
│   ├── api/
│   │   ├── main.py               # FastAPI, monté derrière ngrok
│   │   ├── routes/
│   │   │   ├── services.py       # /api/v1/{service}...
│   │   │   ├── runs.py           # /api/v1/runs
│   │   │   └── health.py         # /health (inclut node, dernière collecte, db)
│   │   └── middleware/
│   │       ├── logging.py        # log de chaque requête
│   │       └── ratelimit.py      # protection basique de l'API publique
│   ├── scheduler/
│   │   ├── daily_job.py          # orchestre les 8 collecteurs
│   │   └── backfill.py           # rattrapage des dates manquées
│   └── utils/
│       ├── logger.py             # logs JSON structurés, rotation quotidienne
│       ├── retry.py              # décorateur retry avec backoff
│       └── backup.py             # dump quotidien horodaté
├── scripts/
│   ├── deploy_m3u96b.sh          # déploiement complet sur le node
│   ├── run_daily_backup.sh
│   ├── start_ngrok.sh            # tunnel www.api-ka.com avec auto-restart
│   └── healthcheck.sh            # utilisé par systemd / monitoring
├── systemd/
│   ├── apika-api.service
│   ├── apika-scheduler.service
│   └── apika-ngrok.service
├── data/
│   └── backups/YYYY-MM-DD/       # dumps quotidiens par service
├── logs/
└── tests/

# Base de données

  • Moteur : PostgreSQL 16 sur m3u96b (SQLite acceptable uniquement en dev local).
  • Base : apika, utilisateur dédié apika_user, accès restreint à localhost sur m3u96b.

# Schéma des tables de données (identique pour les 8 services)

Colonne Type Détail
id BIGSERIAL Clé primaire
payload JSONB Données brutes du service
source TEXT Nom du service (ex. louka)
collected_at TIMESTAMPTZ Horodatage exact de la collecte
date_key DATE Date logique de la collecte (index)
checksum TEXT SHA-256 du payload (déduplication)

Index : (date_key), (source, date_key), unique sur (source, date_key, checksum).

# Table collection_runs

id, service, date_key, status (success / failed / retried), records_count, duration_seconds, error_message, node (toujours m3u96b), started_at, finished_at.

# Règles

  • Append-only : aucune suppression destructive, l'historique complet est conservé.
  • Backup quotidien : pg_dump horodaté par service dans data/backups/YYYY-MM-DD/, compressé (.sql.gz), conservé 90 jours minimum.
  • Vérification d'intégrité hebdomadaire : comparaison du nombre de date_key distincts vs jours écoulés — toute journée manquante déclenche un backfill.

# Collecte quotidienne (scheduler)

  • Job planifié tous les jours à 02:00 (heure du node m3u96b) via apika-scheduler.service (APScheduler) — cron système en fallback.
  • Les 8 collecteurs s'exécutent en parallèle mais de façon indépendante : l'échec d'un service ne bloque jamais les autres.
  • Pipeline par collecteur : fetch → validate → checksum → insert → backup → log run.
  • À la fin du run global : résumé dans collection_runs + logs/daily_YYYY-MM-DD.log + mise à jour de /health.
  • backfill.py s'exécute juste après le job quotidien et rattrape automatiquement toute date manquée des 7 derniers jours.

# API publique (www.api-ka.com via ngrok)

  • Framework : FastAPI (docs auto sur /docs, OpenAPI sur /openapi.json).
  • Serveur : uvicorn sur 127.0.0.1:8000 (jamais exposé directement — seul ngrok est public).
  • Tunnel : ngrok http --domain=www.api-ka.com 8000 — le domaine doit être réservé dans le dashboard ngrok (compte payant requis pour un domaine personnalisé) et le NGROK_AUTHTOKEN configuré sur m3u96b.
  • apika-ngrok.service redémarre le tunnel automatiquement en cas de coupure (Restart=always).

# Endpoints

Méthode Route Description
GET / Statut de la plateforme + version
GET /health Node (m3u96b), état DB, dernière collecte par service
GET /api/v1/{service} Données paginées d'un service
GET /api/v1/{service}/latest Dernière collecte du service
GET /api/v1/{service}/date/{YYYY-MM-DD} Données d'une date précise
GET /api/v1/{service}/stats Nb d'enregistrements par jour, dernière réussite
GET /api/v1/runs Historique des collectes (filtrable par service/statut)
  • {service}louka, immoka, foodka, autoka, fabrika, restoka, sortika, creaka — toute autre valeur → 404.
  • Versionnement /api/v1/, pagination ?page=&limit= (limit max 500).
  • Format de réponse uniforme :
json
{ "success": true, "data": [...], "meta": { "page": 1, "limit": 100, "total": 4200, "node": "m3u96b" } }
  • Rate limiting basique (ex. 120 req/min/IP) car l'API est publique via ngrok.

# Services systemd (sur m3u96b)

Service Rôle Restart
apika-api.service uvicorn FastAPI :8000 always
apika-scheduler.service Job quotidien 02:00 + backfill always
apika-ngrok.service Tunnel www.api-ka.com always

Commandes : sudo systemctl enable --now apika-api apika-scheduler apika-ngrok, statut via systemctl status apika-*.

# Configuration (.env sur m3u96b)

text
APP_ENV=production
NODE_NAME=m3u96b
DATABASE_URL=postgresql://apika_user:***@localhost:5432/apika
NGROK_AUTHTOKEN=...
NGROK_DOMAIN=www.api-ka.com
API_PORT=8000
DAILY_RUN_HOUR=02
BACKUP_RETENTION_DAYS=90
LOUKA_SOURCE_URL=...
IMMOKA_SOURCE_URL=...
FOODKA_SOURCE_URL=...
AUTOKA_SOURCE_URL=...
FABRIKA_SOURCE_URL=...
RESTOKA_SOURCE_URL=...
SORTIKA_SOURCE_URL=...
CREAKA_SOURCE_URL=...

Ne jamais commiter .env — seulement .env.example avec des valeurs vides.

# Standards de code

  • Python 3.11+, type hints partout, black + ruff, docstrings sur toute fonction publique.
  • Logging structuré JSON via utils/logger.py avec rotation quotidienne — jamais de print() en production.
  • Tests pytest dans tests/ : chaque collecteur, chaque route API, la logique de retry et de backfill.
  • Gestion d'erreurs explicite : jamais de except: pass.
  • Commits descriptifs ; branche main = état déployé sur m3u96b.
  • Rappel : en-tête d'auteur (Simon-Pierre Boucher / contact@spboucher.ai / Node m3u96b) dans CHAQUE fichier.

# Commandes utiles

bash
# Déploiement complet sur m3u96b
bash scripts/deploy_m3u96b.sh

# Initialiser la base
python -m src.database.db --init

# Collecte manuelle immédiate (tous les services)
python -m src.scheduler.daily_job --now

# Backfill d'une date manquée
python -m src.scheduler.backfill --date 2026-08-15

# API en local (dev)
uvicorn src.api.main:app --reload --port 8000

# Tunnel public
bash scripts/start_ngrok.sh

# Vérifier la santé
curl http://127.0.0.1:8000/health

# Priorités absolues (dans l'ordre)

  1. Fiabilité de la sauvegarde quotidienne — aucune journée sans données pour aucun des 8 services.
  2. Intégrité de la base (append-only, checksums, backups horodatés, rétention 90 jours).
  3. Tout tourne sur le node m3u96b — vérification du hostname au démarrage.
  4. Disponibilité de l'API publique sur www.api-ka.com (auto-restart ngrok + uvicorn).
  5. En-tête d'auteur présent dans chaque fichier.
  6. Logs, alertes et traçabilité de chaque collecte et chaque requête.

Plateforme légendaire API-KA — Node m3u96b — créée par Simon-Pierre Boucher (contact@spboucher.ai)