API-KA — plateforme centrale : collecte quotidienne des 8 services KA, historisation append-only et API publique sur www.api-ka.com
1# API-Ka — L'API de données du Groupe Ka23**API-Ka** collecte, sauvegarde et centralise **chaque jour** les données des **8 plateformes** de l'écosystème **Groupe Ka** dans une base **PostgreSQL** unifiée, puis les expose via une API publique sur **www.api-ka.com** — avec en prime le **KA Agent** (assistant IA de l'écosystème) et le **hub SSO KA ID**.4567## Description89**API-Ka** est la **plateforme centrale** de l'écosystème **Groupe Ka** :1011- **8 collecteurs** quotidiens (**lou-ka, immo-ka, food-ka, auto-ka, fabri-ka, resto-ka, sorti-ka, crea-ka**) : fetch → validation → **checksum** → insertion → **backup** → journal de run, avec **retry 3×** (backoff **30 s → 2 min → 10 min**).12- Un **scheduler** (**APScheduler**) qui lance le job quotidien à **02:00**, collecteurs **en parallèle** et indépendants, plus un **backfill automatique** des dates manquées (**7 derniers jours**).13- Une **API FastAPI** publique (données paginées, historiques, stats, rapports **PDF**).14- Le **KA Agent** — assistant IA central du Groupe Ka (**Claude Haiku 4.5**) en **SSE**, avec une boucle de **12 outils** branchés sur les API publiques des plateformes (logements, propriétés, véhicules, emplois, épicerie, produits, restos, sorties, créateurs, web QC, stats live, état des services) et **CORS** ouvert aux **13 domaines** de l'écosystème.15- Le **hub SSO KA ID** (login **ka_id** partagé) + l'échange de jetons pour l'**app iOS native KA**.16- Des **backups quotidiens** horodatés par service (`data/backups/YYYY-MM-DD/`, rétention **90 jours**).1718## Endpoints1920### Données des plateformes2122- `GET /` — **statut** de la plateforme + version23- `GET /health` — nœud (**m3u96b**), état **DB**, dernière collecte par service24- `GET /api/v1/{service}` — données **paginées** (`?page=&limit=`, limit max **500**)25- `GET /api/v1/{service}/latest` — **dernière collecte**26- `GET /api/v1/{service}/date/{YYYY-MM-DD}` — données d'une **date précise**27- `GET /api/v1/{service}/stats` — enregistrements par jour, dernière réussite28- `GET /api/v1/runs` — **historique des collectes** (filtrable par service/statut)2930`{service}` ∈ **`louka`**, **`immoka`**, **`foodka`**, **`autoka`**, **`fabrika`**, **`restoka`**, **`sortika`**, **`creaka`**.3132### Stats & rapports3334- `GET /stats` — **tableau de bord analytique** de la plateforme (page web)35- `GET /api/stats/dashboard` — stats live de la plateforme36- `GET /api/stats/report` — rapport **PDF** de la plateforme37- `GET /api/stats/ecosystem-report` — **rapport PDF consolidé** des **12 plateformes** du Groupe Ka (nombre de plateformes **dynamique** via `ecosystem.json`)3839### KA Agent (IA)4041- `POST /api/agent/chat` — chat en **SSE** avec le **KA Agent** (boucle d'outils, prompt par site, cache système)42- `GET /ka-agent.js` — **widget de chat** embarquable sur les sites du Groupe Ka4344### Auth (KA ID / iOS)4546- `GET /api/auth/ka/login` + `GET /api/auth/ka/callback` — **SSO KA ID** (hub groupe-ka.com)47- `GET /api/auth/me`, `POST /api/auth/logout` — session48- `POST /api/ios/auth/exchange` — échange du **ka_token** (vérification **HS256**, `aud=ka-ios`) contre un **profil hub signé** pour l'**app iOS KA**4950Assets de partage servis à la racine : **`og.png`**, **`favicon.svg`**, **`apple-touch-icon.png`**, page **`/contact`**.5152## Stack5354- **Python 3** — **FastAPI** + **Uvicorn**55- **PostgreSQL** — **SQLAlchemy 2** + **Alembic** (migrations), `psycopg2`56- **APScheduler** — job quotidien + backfill57- **httpx** — collecteurs et outils de l'agent58- **fpdf2** — rapports PDF59- **PM2** + **ngrok** — exécution résiliente et exposition publique60- **pytest** — tests (`tests/`)6162## Structure6364```65/opt/api-ka66├── src/67│ ├── api/ # FastAPI : main, routes/ (health, services, runs, stats, agent, auth, iosauth), web/, PDF68│ ├── collectors/ # 8 collecteurs quotidiens (un par plateforme Ka)69│ ├── scheduler/ # daily_job.py (02:00) + backfill.py70│ ├── database/ # modèles + init DB71│ ├── utils/ # backup.py (dumps quotidiens, rétention 90 j)72│ └── config.py73├── scripts/ # deploy_m3u96b.sh, start_ngrok.sh…74├── systemd/ # unités historiques (le déploiement actuel utilise PM2)75├── tests/ # pytest76├── data/ # backups/YYYY-MM-DD/77├── logs/78├── alembic.ini · pyproject.toml · requirements.txt79└── docs/screenshot.png80```8182## Démarrage local8384```bash85python3 -m venv venv && source venv/bin/activate86pip install -r requirements.txt8788# Initialiser la base89python -m src.database.db --init9091# API en dev92uvicorn src.api.main:app --reload --port 80009394# Collecte manuelle immédiate (tous les services)95python -m src.scheduler.daily_job --now9697# Backfill d'une date manquée98python -m src.scheduler.backfill --date 2026-08-1599100# Vérifier la santé101curl http://127.0.0.1:8000/health102103# Tests104pytest tests/ -v105```106107## Déploiement108109- **Nœud** : **M3U96b** (Mac Studio, cluster MacLustr) — répertoire **`/opt/api-ka`**. Chaque service **vérifie le hostname** au démarrage et refuse de tourner ailleurs en production.110- **Port** : **8000** (API liée à `127.0.0.1`, exposée uniquement via le tunnel).111- **Domaine** : **https://www.api-ka.com** (tunnel **ngrok**).112- **PM2** (3 process, auto-restart) :113 - **`apika-api`** — l'API FastAPI/Uvicorn sur le port **8000**114 - **`apika-scheduler`** — le job quotidien **02:00** + backfill115 - **`apika-ngrok`** — le tunnel **www.api-ka.com**116117```bash118pm2 ls | grep apika # état des 3 process119pm2 restart apika-api # après un changement de code120pm2 logs apika-scheduler # suivre les collectes121```122123## Développement remote-first (IMPORTANT)124125La **source de vérité** est le **repo git sur le nœud M3U96b** (`/opt/api-ka`), **pas** une copie sur le laptop. Toute modification se fait **via SSH sur le nœud** : édition, test, `pm2 restart`, puis commit/push **depuis le nœud**.126127- Remote **`origin`** = **spbgit** (git perso **git.spboucher.ai**, bare repos sur M3U96a) — **pas GitHub**.128- **Agent forwarding** actif : le `git push origin main` fonctionne pendant une session SSH depuis le laptop.129130---131132Un service **Groupe Ka** — créé par **Simon-Pierre Boucher** (contact@spboucher.ai)133