docs: README à jour avec screenshot
2 changed files +105 −40
modified
README.md
+105 −40
@@ -1,67 +1,132 @@ | |||||
| 1 | −# API-KA — Plateforme centrale de l'écosystème KA | 1 | +# API-Ka — L'API de données du Groupe Ka | ||
| 2 | 2 | ||||
| 3 | −API-KA collecte, sauvegarde et centralise **chaque jour** les données des 8 services KA | 3 | +**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**. | ||
| 4 | −(**lou-ka, immo-ka, food-ka, auto-ka, fabri-ka**) dans une base PostgreSQL unifiée, puis | ||||
| 5 | −les expose via une API publique sur **www.api-ka.com** (tunnel ngrok). | ||||
| 6 | 4 | ||||
| 7 | −**Tout le déploiement se fait sur le node `m3u96b`** (`/opt/api-ka/`). Chaque service | 5 | + | ||
| 8 | −vérifie le hostname au démarrage et refuse de tourner ailleurs en production. | ||||
| 9 | 6 | ||||
| 10 | −## Démarrage rapide | 7 | +## Description | ||
| 8 | + | ||||
| 9 | +**API-Ka** est la **plateforme centrale** de l'écosystème **Groupe Ka** : | ||||
| 10 | + | ||||
| 11 | +- **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**). | ||||
| 17 | + | ||||
| 18 | +## Endpoints | ||||
| 19 | + | ||||
| 20 | +### Données des plateformes | ||||
| 21 | + | ||||
| 22 | +- `GET /` — **statut** de la plateforme + version | ||||
| 23 | +- `GET /health` — nœud (**m3u96b**), état **DB**, dernière collecte par service | ||||
| 24 | +- `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éussite | ||||
| 28 | +- `GET /api/v1/runs` — **historique des collectes** (filtrable par service/statut) | ||||
| 29 | + | ||||
| 30 | +`{service}` ∈ **`louka`**, **`immoka`**, **`foodka`**, **`autoka`**, **`fabrika`**, **`restoka`**, **`sortika`**, **`creaka`**. | ||||
| 31 | + | ||||
| 32 | +### Stats & rapports | ||||
| 33 | + | ||||
| 34 | +- `GET /stats` — **tableau de bord analytique** de la plateforme (page web) | ||||
| 35 | +- `GET /api/stats/dashboard` — stats live de la plateforme | ||||
| 36 | +- `GET /api/stats/report` — rapport **PDF** de la plateforme | ||||
| 37 | +- `GET /api/stats/ecosystem-report` — **rapport PDF consolidé** des **12 plateformes** du Groupe Ka (nombre de plateformes **dynamique** via `ecosystem.json`) | ||||
| 38 | + | ||||
| 39 | +### KA Agent (IA) | ||||
| 40 | + | ||||
| 41 | +- `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 Ka | ||||
| 43 | + | ||||
| 44 | +### Auth (KA ID / iOS) | ||||
| 45 | + | ||||
| 46 | +- `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` — session | ||||
| 48 | +- `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** | ||||
| 49 | + | ||||
| 50 | +Assets de partage servis à la racine : **`og.png`**, **`favicon.svg`**, **`apple-touch-icon.png`**, page **`/contact`**. | ||||
| 51 | + | ||||
| 52 | +## Stack | ||||
| 53 | + | ||||
| 54 | +- **Python 3** — **FastAPI** + **Uvicorn** | ||||
| 55 | +- **PostgreSQL** — **SQLAlchemy 2** + **Alembic** (migrations), `psycopg2` | ||||
| 56 | +- **APScheduler** — job quotidien + backfill | ||||
| 57 | +- **httpx** — collecteurs et outils de l'agent | ||||
| 58 | +- **fpdf2** — rapports PDF | ||||
| 59 | +- **PM2** + **ngrok** — exécution résiliente et exposition publique | ||||
| 60 | +- **pytest** — tests (`tests/`) | ||||
| 61 | + | ||||
| 62 | +## Structure | ||||
| 63 | + | ||||
| 64 | +``` | ||||
| 65 | +/opt/api-ka | ||||
| 66 | +├── src/ | ||||
| 67 | +│ ├── api/ # FastAPI : main, routes/ (health, services, runs, stats, agent, auth, iosauth), web/, PDF | ||||
| 68 | +│ ├── collectors/ # 8 collecteurs quotidiens (un par plateforme Ka) | ||||
| 69 | +│ ├── scheduler/ # daily_job.py (02:00) + backfill.py | ||||
| 70 | +│ ├── database/ # modèles + init DB | ||||
| 71 | +│ ├── utils/ # backup.py (dumps quotidiens, rétention 90 j) | ||||
| 72 | +│ └── config.py | ||||
| 73 | +├── scripts/ # deploy_m3u96b.sh, start_ngrok.sh… | ||||
| 74 | +├── systemd/ # unités historiques (le déploiement actuel utilise PM2) | ||||
| 75 | +├── tests/ # pytest | ||||
| 76 | +├── data/ # backups/YYYY-MM-DD/ | ||||
| 77 | +├── logs/ | ||||
| 78 | +├── alembic.ini · pyproject.toml · requirements.txt | ||||
| 79 | +└── docs/screenshot.png | ||||
| 80 | +``` | ||||
| 81 | + | ||||
| 82 | +## Démarrage local | ||||
| 11 | 83 | ||||
| 12 | ```bash | 84 | ```bash | ||
| 13 | −# Déploiement complet sur m3u96b | 85 | +python3 -m venv venv && source venv/bin/activate | ||
| 14 | −bash scripts/deploy_m3u96b.sh | 86 | +pip install -r requirements.txt | ||
| 15 | 87 | ||||
| 16 | # Initialiser la base | 88 | # Initialiser la base | ||
| 17 | python -m src.database.db --init | 89 | python -m src.database.db --init | ||
| 18 | 90 | ||||
| 91 | +# API en dev | ||||
| 92 | +uvicorn src.api.main:app --reload --port 8000 | ||||
| 93 | + | ||||
| 19 | # Collecte manuelle immédiate (tous les services) | 94 | # Collecte manuelle immédiate (tous les services) | ||
| 20 | python -m src.scheduler.daily_job --now | 95 | python -m src.scheduler.daily_job --now | ||
| 21 | 96 | ||||
| 22 | # Backfill d'une date manquée | 97 | # Backfill d'une date manquée | ||
| 23 | python -m src.scheduler.backfill --date 2026-08-15 | 98 | python -m src.scheduler.backfill --date 2026-08-15 | ||
| 24 | 99 | ||||
| 25 | −# API en local (dev) | ||||
| 26 | −uvicorn src.api.main:app --reload --port 8000 | ||||
| 27 | − | ||||
| 28 | −# Tunnel public | ||||
| 29 | −bash scripts/start_ngrok.sh | ||||
| 30 | − | ||||
| 31 | # Vérifier la santé | 100 | # Vérifier la santé | ||
| 32 | curl http://127.0.0.1:8000/health | 101 | curl http://127.0.0.1:8000/health | ||
| 33 | −``` | ||||
| 34 | 102 | ||||
| 35 | −## Composants | 103 | +# Tests | ||
| 104 | +pytest tests/ -v | ||||
| 105 | +``` | ||||
| 36 | 106 | ||||
| 37 | −| Composant | Rôle | | 107 | +## Déploiement | ||
| 38 | −|-----------|------| | ||||
| 39 | −| `src/collectors/` | 8 collecteurs (fetch → validate → checksum → insert → backup → log run), retry 3× avec backoff 30s → 2min → 10min | | ||||
| 40 | −| `src/scheduler/daily_job.py` | Job quotidien à 02:00 (APScheduler), collecteurs en parallèle et indépendants | | ||||
| 41 | −| `src/scheduler/backfill.py` | Rattrapage automatique des dates manquées (7 derniers jours) | | ||||
| 42 | −| `src/api/` | FastAPI sur 127.0.0.1:8000, exposée uniquement via ngrok (www.api-ka.com) | | ||||
| 43 | −| `src/utils/backup.py` | Dump quotidien horodaté par service (`data/backups/YYYY-MM-DD/`, rétention 90 j) | | ||||
| 44 | −| `systemd/` | `apika-api`, `apika-scheduler`, `apika-ngrok` (Restart=always) | | ||||
| 45 | 108 | ||||
| 46 | −## Endpoints | 109 | +- **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** + backfill | ||||
| 115 | + - **`apika-ngrok`** — le tunnel **www.api-ka.com** | ||||
| 47 | 116 | ||||
| 48 | −- `GET /` — statut de la plateforme + version | 117 | +```bash | ||
| 49 | −- `GET /health` — node (m3u96b), état DB, dernière collecte par service | 118 | +pm2 ls | grep apika # état des 3 process | ||
| 50 | −- `GET /api/v1/{service}` — données paginées (`?page=&limit=`, limit max 500) | 119 | +pm2 restart apika-api # après un changement de code | ||
| 51 | −- `GET /api/v1/{service}/latest` — dernière collecte | 120 | +pm2 logs apika-scheduler # suivre les collectes | ||
| 52 | −- `GET /api/v1/{service}/date/{YYYY-MM-DD}` — données d'une date précise | 121 | +``` | ||
| 53 | −- `GET /api/v1/{service}/stats` — enregistrements par jour, dernière réussite | ||||
| 54 | −- `GET /api/v1/runs` — historique des collectes (filtrable par service/statut) | ||||
| 55 | 122 | ||||
| 56 | −`{service}` ∈ `louka`, `immoka`, `foodka`, `autoka`, `fabrika`, `restoka`, `sortika`, `creaka`. | 123 | +## Développement remote-first (IMPORTANT) | ||
| 57 | 124 | ||||
| 58 | −## Tests | 125 | +La **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**. | ||
| 59 | 126 | ||||
| 60 | −```bash | 127 | +- Remote **`origin`** = **spbgit** (git perso **git.spboucher.ai**, bare repos sur M3U96a) — **pas GitHub**. | ||
| 61 | −pip install -r requirements.txt | 128 | +- **Agent forwarding** actif : le `git push origin main` fonctionne pendant une session SSH depuis le laptop. | ||
| 62 | −pytest tests/ -v | ||||
| 63 | −``` | ||||
| 64 | 129 | ||||
| 65 | --- | 130 | --- | ||
| 66 | 131 | ||||
| 67 | −*Plateforme légendaire API-KA — Node m3u96b — créée par Simon-Pierre Boucher (contact@spboucher.ai)* | 132 | +Un service **Groupe Ka** — créé par **Simon-Pierre Boucher** (contact@spboucher.ai) | ||
added
docs/screenshot.png
+0 −0
Binary file not shown.