docs: README à jour avec screenshot
2 changed files +84 −52
modified
README.md
+84 −52
@@ -1,7 +1,7 @@ | |||||
| 1 | <!-- | 1 | <!-- | ||
| 2 | Author: Simon-Pierre Boucher <contact@spboucher.ai> | 2 | Author: Simon-Pierre Boucher <contact@spboucher.ai> | ||
| 3 | File: README.md | 3 | File: README.md | ||
| 4 | − Desc: Créa-Ka — agrégateur des créateurs de contenu québécois | 4 | + Desc: Créa·Ka — agrégateur des créateurs de contenu québécois | ||
| 5 | --> | 5 | --> | ||
| 6 | <div align="center"> | 6 | <div align="center"> | ||
| 7 | 7 | ||||
@@ -9,6 +9,8 @@ | |||||
| 9 | 9 | ||||
| 10 | **Tous les créateurs québécois. Tous leurs liens.** | 10 | **Tous les créateurs québécois. Tous leurs liens.** | ||
| 11 | 11 | ||||
| 12 | + | ||||
| 13 | + | ||||
| 12 | [](https://www.crea-ka.com) | 14 | [](https://www.crea-ka.com) | ||
| 13 | [](https://www.crea-ka.com/stats) | 15 | [](https://www.crea-ka.com/stats) | ||
| 14 | [](https://www.crea-ka.com) | 16 | [](https://www.crea-ka.com) | ||
@@ -20,35 +22,27 @@ | |||||
| 20 | [](creaka/connectors/) | 22 | [](creaka/connectors/) | ||
| 21 | [](https://www.crea-ka.com) | 23 | [](https://www.crea-ka.com) | ||
| 22 | 24 | ||||
| 23 | −Annuaire public, québécois, exhaustif et **cross-plateforme** des créateurs de | ||||
| 24 | −contenu — un croisement entre un annuaire cherchable et un « Linktree | ||||
| 25 | −collectif », membre de la famille **Groupe KA**. | ||||
| 26 | − | ||||
| 27 | **https://www.crea-ka.com** | 25 | **https://www.crea-ka.com** | ||
| 28 | 26 | ||||
| 29 | </div> | 27 | </div> | ||
| 30 | 28 | ||||
| 31 | --- | 29 | --- | ||
| 32 | 30 | ||||
| 33 | −## Captures | 31 | +## Description | ||
| 34 | 32 | ||||
| 35 | −| Accueil (annuaire) | Page créateur | | 33 | +**Créa·Ka** est l'**annuaire public, québécois et cross-plateforme des créateurs de contenu** — un croisement entre un **annuaire cherchable** et un **« Linktree collectif »**, membre de la famille **Groupe Ka**. | ||
| 36 | −|---|---| | ||||
| 37 | −|  |  | | ||||
| 38 | 34 | ||||
| 39 | −| Statistiques | Mobile (tab bar Lou·Ka) | | 35 | +Chaque créateur québécois a **une fiche canonique** qui regroupe **tous ses comptes publics** — **Instagram, TikTok, YouTube, Twitch, X, Facebook, Snapchat, Kick, Substack, Patreon, OnlyFans, balado**… — chacun avec son **URL canonique**, ses **métriques** (abonnés, publications, j'aime, vues, épisodes) et son **score de confiance de rattachement**. | ||
| 40 | −|---|---| | ||||
| 41 | −|  |  | | ||||
| 42 | 36 | ||||
| 43 | −## Ce que fait Créa·Ka | 37 | +## Fonctionnalités | ||
| 44 | 38 | ||||
| 45 | −Chaque créateur québécois a **une fiche canonique** qui regroupe **tous ses | 39 | +- **Annuaire filtrable** par **niche** (20), **région** (17 régions administratives), **langue**, **plateforme** et **taille d'audience** (**nano/micro/macro/méga**). | ||
| 46 | −comptes publics** — Instagram, TikTok, YouTube, Twitch, X, Facebook, Snapchat, | 40 | +- **Page dédiée par créateur** : `/createur/{id}` avec tous ses liens et métriques. | ||
| 47 | −Kick, Substack, Patreon, OnlyFans, balado… — chacun avec son **URL canonique**, | 41 | +- **Tableau de bord analytique** `/stats` + **rapport PDF** aux couleurs Groupe-KA. | ||
| 48 | −ses **métriques** (abonnés, publications, j'aime, vues, épisodes) et son **score | 42 | +- **Connexion « Se connecter avec KA ID »** via le hub **groupe-ka.com** (SSO de l'écosystème). | ||
| 49 | −de confiance de rattachement**. L'annuaire se filtre par **niche** (20), **région** | 43 | +- **Widget KA Agent** (bulle de chat IA Groupe KA) câblé sur le site. | ||
| 50 | −(17 régions administratives), **langue**, **plateforme** et **taille d'audience** | 44 | +- **Couverture cumulative** : un **watch quotidien** relance découverte + enrichissement — nouveaux créateurs, métriques rafraîchies, comptes croisés révélés via les **liens de bio** et les pages **link-in-bio**. | ||
| 51 | −(nano/micro/macro/méga). Chaque créateur a sa page dédiée `/createur/{id}`. | 45 | +- **Opt-out immédiat et persistant** (`/retrait`) et **éthique stricte** (voir plus bas). | ||
| 52 | 46 | ||||
| 53 | ## Architecture (calquée sur Lou·Ka) | 47 | ## Architecture (calquée sur Lou·Ka) | ||
| 54 | 48 | ||||
@@ -58,31 +52,37 @@ DÉCOUVERTE → EXTRACTION → RÉSOLUTION D'IDENTITÉ → NORMALISATION → DÉ | |||||
| 58 | 52 | ||||
| 59 | | Module | Rôle | | 53 | | Module | Rôle | | ||
| 60 | |---|---| | 54 | |---|---| | ||
| 61 | −| `creaka/schema.py` | fiche `Creator` + `PlatformAccount`, validation stricte (compte sans url/confidence = rejeté) | | 55 | +| `creaka/schema.py` | fiche **`Creator`** + **`PlatformAccount`**, **validation stricte** (compte sans url/confidence = rejeté) | | ||
| 62 | −| `creaka/identity.py` | signaux de rattachement §12.1 : `profil_source` 0.98 · `link_in_bio` 0.95 · `cross_link` 0.90 · `listes_medias`/`base_publique` 0.85 · `handle_match` 0.75 | | 56 | +| `creaka/identity.py` | **signaux de rattachement** §12.1 : `profil_source` 0.98 · `link_in_bio` 0.95 · `cross_link` 0.90 · `listes_medias`/`base_publique` 0.85 · `handle_match` 0.75 | | ||
| 63 | −| `creaka/dedup.py` | fusion **uniquement** sur compte fort partagé — jamais sur le nom (homonymes) | | 57 | +| `creaka/dedup.py` | fusion **uniquement** sur compte fort partagé — **jamais sur le nom** (homonymes) | | ||
| 64 | −| `creaka/ethics.py` | purge des données privées, opt-out persistant, régime restreint des mineurs | | 58 | +| `creaka/ethics.py` | **purge des données privées**, opt-out persistant, **régime restreint des mineurs** | | ||
| 65 | −| `creaka/db.py` | SQLite WAL : fiches canoniques + index des comptes + journal des syncs | | 59 | +| `creaka/db.py` | **SQLite WAL** : fiches canoniques + index des comptes + journal des syncs | | ||
| 66 | −| `creaka/web.py` | API FastAPI + frontend statique | | 60 | +| `creaka/auth.py` | connexion **KA ID** (hub groupe-ka.com) | | ||
| 61 | +| `creaka/stats.py` + `creaka/kapdf.py` | statistiques `/stats` + **rapport PDF** | | ||||
| 62 | +| `creaka/web.py` | **API FastAPI** + frontend statique | | ||||
| 67 | 63 | ||||
| 68 | −### Connecteurs (registre auto-découvrant) | 64 | +### Connecteurs (registre auto-découvrant — `creaka/connectors/`) | ||
| 69 | 65 | ||||
| 70 | | Connecteur | Famille | Accès | Signal | | 66 | | Connecteur | Famille | Accès | Signal | | ||
| 71 | |---|---|---|---| | 67 | |---|---|---|---| | ||
| 72 | −| `listes-medias` | découverte | dataset local (palmarès médias publics croisés, 376 profils) | 0.85 | | 68 | +| `listes-medias` | découverte | dataset local (palmarès médias publics croisés, **376 profils**) | 0.85 | | ||
| 73 | −| `wikidata-qc` | découverte | SPARQL Wikidata (nés/résidant au QC, handles curés) | 0.85 | | 69 | +| `wikidata-qc` | découverte | **SPARQL Wikidata** (nés/résidant au QC, handles curés) | 0.85 | | ||
| 74 | | `onlyqueb` | découverte | sitemap + JSON-LD (annuaire public, liens auto-déclarés) | 0.90 | | 70 | | `onlyqueb` | découverte | sitemap + JSON-LD (annuaire public, liens auto-déclarés) | 0.90 | | ||
| 75 | −| `youtube-recherche` | découverte | recherche publique YouTube, ~120 requêtes × marqueur QC obligatoire | 0.98 | | 71 | +| `youtube-recherche` | découverte | recherche publique YouTube, ~120 requêtes × **marqueur QC obligatoire**, pagination par continuations | 0.98 | | ||
| 76 | | `balados-itunes` | découverte | **API officielle** iTunes/Apple Podcasts | 0.98 | | 72 | | `balados-itunes` | découverte | **API officielle** iTunes/Apple Podcasts | 0.98 | | ||
| 77 | | `instagram-profil` | enrichissement | Scrapfly (profil public : abonnés, bio, **liens de bio** → cross-link) | — | | 73 | | `instagram-profil` | enrichissement | Scrapfly (profil public : abonnés, bio, **liens de bio** → cross-link) | — | | ||
| 78 | | `tiktok-profil` | enrichissement | Scrapfly (JSON d'hydratation public) | — | | 74 | | `tiktok-profil` | enrichissement | Scrapfly (JSON d'hydratation public) | — | | ||
| 79 | −| `youtube` | enrichissement | API officielle v3 si clé, sinon page publique | — | | 75 | +| `youtube` | enrichissement | **API officielle v3** si clé, sinon page publique | — | | ||
| 80 | −| `twitch` | enrichissement | API officielle Helix (sauté sans clés) | — | | 76 | +| `twitch` | enrichissement | **API officielle Helix** (sauté sans clés) | — | | ||
| 81 | | `link-in-bio` | enrichissement | Linktree/Beacons/Bio.link… — **le levier nº 1** : une page → tous les comptes | 0.95 | | 77 | | `link-in-bio` | enrichissement | Linktree/Beacons/Bio.link… — **le levier nº 1** : une page → tous les comptes | 0.95 | | ||
| 82 | 78 | ||||
| 83 | −La couverture **s'accumule à chaque passage** (watch quotidien) : la découverte | 79 | +## Stack | ||
| 84 | −trouve de nouveaux créateurs, l'enrichissement rafraîchit les métriques et | 80 | + | ||
| 85 | −révèle les comptes croisés via les liens de bio et les pages link-in-bio. | 81 | +- **Python 3.14** · **FastAPI** · **SQLite (mode WAL)** | ||
| 82 | +- **Frontend SPA zéro build** (template HTML + `scripts/build_frontend.py`, icônes SVG injectées) | ||||
| 83 | +- Design **ka-ui « éditorial sharp »** Groupe KA — accent violet, footer commun (`ecosystem.json`, 13 sites), page `/contact` | ||||
| 84 | +- **25 tests** pytest (identité, homonymes, éthique…) | ||||
| 85 | +- Hébergé sous **PM2** + tunnel **ngrok** | ||||
| 86 | 86 | ||||
| 87 | ## API publique | 87 | ## API publique | ||
| 88 | 88 | ||||
@@ -92,41 +92,73 @@ GET /api/creators/{id} GET /api/stats GET /api/taxonomies | |||||
| 92 | GET /api/sources POST /api/optout GET /healthz | 92 | GET /api/sources POST /api/optout GET /healthz | ||
| 93 | ``` | 93 | ``` | ||
| 94 | 94 | ||||
| 95 | −## Éthique — prime sur tout (CLAUDE.md §15) | 95 | +## Structure du projet | ||
| 96 | 96 | ||||
| 97 | −- **Profils publics et professionnels seulement** ; `ethics.scrub()` purge | 97 | +``` | ||
| 98 | − téléphones, adresses civiques et courriels personnels avant tout stockage. | 98 | +crea-ka/ | ||
| 99 | −- **Opt-out immédiat et persistant** (`/retrait`) : fiche masquée sur-le-champ, | 99 | +├── creaka/ # cœur Python : schema, identity, dedup, ethics, db, web, auth, stats | ||
| 100 | − liste de suppression `data/optout.json`, **jamais ré-agrégée**. | 100 | +│ └── connectors/ # 10 connecteurs (découverte + enrichissement) | ||
| 101 | −- **Mineurs** : régime restreint automatique (année de naissance Wikidata) et | 101 | +├── frontend/ # src/ (template) → dist/ (généré) | ||
| 102 | − **exclusion de l'annuaire public**. | 102 | +├── scripts/ # build_frontend.py · deploy-m3u96b.sh · screenshots.sh | ||
| 103 | −- **Score de confiance** sur chaque rattachement ; sous 0.50 → « à vérifier », | 103 | +├── tests/ # 25 tests pytest | ||
| 104 | − jamais publié. Mieux vaut un lien de moins qu'un lien erroné. | 104 | +├── data/ # SQLite, optout.json, datasets locaux | ||
| 105 | −- Loi 25 : finalités documentées, accès/rectification/retrait via `/retrait`. | 105 | +├── docs/ # screenshot.png + captures | ||
| 106 | +└── run.py # CLI : sync · serve · optout | ||||
| 107 | +``` | ||||
| 106 | 108 | ||||
| 107 | −## Développement | 109 | +## Démarrage local | ||
| 108 | 110 | ||||
| 109 | ```bash | 111 | ```bash | ||
| 110 | python3 -m venv .venv && .venv/bin/pip install -r requirements.txt | 112 | python3 -m venv .venv && .venv/bin/pip install -r requirements.txt | ||
| 111 | cp .env.example .env # SCRAPFLY_KEY, YOUTUBE_API_KEY… | 113 | cp .env.example .env # SCRAPFLY_KEY, YOUTUBE_API_KEY… | ||
| 112 | −python3 -m pytest tests/ -q # 25 tests (identité, homonymes, éthique…) | 114 | +python3 -m pytest tests/ -q # 25 tests (identité, homonymes, éthique…) | ||
| 113 | python3 run.py sync # découverte + enrichissement | 115 | python3 run.py sync # découverte + enrichissement | ||
| 114 | −python3 run.py serve 8160 # API + frontend | 116 | +python3 run.py serve 8160 # API + frontend → http://localhost:8160 | ||
| 115 | python3 scripts/build_frontend.py # regénère frontend/dist (icônes SVG injectées) | 117 | python3 scripts/build_frontend.py # regénère frontend/dist (icônes SVG injectées) | ||
| 116 | python3 run.py optout "instagram:handle" # retrait manuel | 118 | python3 run.py optout "instagram:handle" # retrait manuel | ||
| 117 | ``` | 119 | ``` | ||
| 118 | 120 | ||||
| 119 | ## Déploiement | 121 | ## Déploiement | ||
| 120 | 122 | ||||
| 121 | −Node **M3U96b** (`~/apps/crea-ka`) : PM2 `crea-ka-web` (:8160) + | 123 | +- **Nœud** : **M3U96b** (`~/apps/crea-ka`) | ||
| 122 | −`crea-ka-sync` (watch 24 h) + `crea-ka-ngrok` (**www.crea-ka.com**). | 124 | +- **Port** : **8160** | ||
| 123 | −Redéploiement : `scripts/deploy-m3u96b.sh` · captures : `scripts/screenshots.sh`. | 125 | +- **Domaine** : **www.crea-ka.com** (tunnel **ngrok**) | ||
| 126 | +- **PM2** (3 process) : | ||||
| 127 | + - **`crea-ka-web`** — API FastAPI + frontend sur **:8160** | ||||
| 128 | + - **`crea-ka-sync`** — watch de synchronisation (**24 h**) : découverte + enrichissement | ||||
| 129 | + - **`crea-ka-ngrok`** — tunnel vers **www.crea-ka.com** | ||||
| 130 | +- Redéploiement : `scripts/deploy-m3u96b.sh` · captures : `scripts/screenshots.sh` | ||||
| 131 | + | ||||
| 132 | +## Développement remote-first (IMPORTANT) | ||||
| 133 | + | ||||
| 134 | +La **source de vérité est le repo git sur le nœud M3U96b** (`~/apps/crea-ka`), **pas** une copie laptop. Toute modification se fait **sur le nœud via SSH** (édition, tests, `pm2 restart`), puis commit/push **depuis le nœud**. | ||||
| 135 | + | ||||
| 136 | +- **`origin` = spbgit** (git perso **git.spboucher.ai** — bare repo `~/srv/git/crea-ka.git` sur M3U96a, alias SSH `gitsrv`). **Pas GitHub.** | ||||
| 137 | +- L'**agent forwarding** SSH est actif : le `git push origin main` fonctionne pendant une session SSH depuis le laptop. | ||||
| 138 | + | ||||
| 139 | +## Éthique — prime sur tout | ||||
| 140 | + | ||||
| 141 | +- **Profils publics et professionnels seulement** ; `ethics.scrub()` **purge téléphones, adresses civiques et courriels personnels** avant tout stockage. | ||||
| 142 | +- **Opt-out immédiat et persistant** (`/retrait`) : fiche masquée sur-le-champ, liste de suppression `data/optout.json`, **jamais ré-agrégée**. | ||||
| 143 | +- **Mineurs** : régime restreint automatique (année de naissance Wikidata) et **exclusion de l'annuaire public**. | ||||
| 144 | +- **Score de confiance** sur chaque rattachement ; **sous 0.50 → « à vérifier », jamais publié**. Mieux vaut un lien de moins qu'un lien erroné. | ||||
| 145 | +- **Loi 25** : finalités documentées, accès/rectification/retrait via `/retrait`. | ||||
| 146 | + | ||||
| 147 | +## Captures supplémentaires | ||||
| 148 | + | ||||
| 149 | +| Accueil (annuaire) | Page créateur | | ||||
| 150 | +|---|---| | ||||
| 151 | +|  |  | | ||||
| 152 | + | ||||
| 153 | +| Statistiques | Mobile (tab bar Lou·Ka) | | ||||
| 154 | +|---|---| | ||||
| 155 | +|  |  | | ||||
| 124 | 156 | ||||
| 125 | --- | 157 | --- | ||
| 126 | 158 | ||||
| 127 | <div align="center"> | 159 | <div align="center"> | ||
| 128 | 160 | ||||
| 129 | −**Groupe KA** · [KA ID](https://www.groupe-ka.com) · [Lou-Ka](https://www.lou-ka.com) · | 161 | +Un service **Groupe Ka** · [KA ID](https://www.groupe-ka.com) · [Lou-Ka](https://www.lou-ka.com) · | ||
| 130 | [Immo-Ka](https://www.immo-ka.com) · [Auto-Ka](https://www.auto-ka.com) · | 162 | [Immo-Ka](https://www.immo-ka.com) · [Auto-Ka](https://www.auto-ka.com) · | ||
| 131 | [Food-Ka](https://www.food-ka.com) · [Fabri-Ka](https://www.fabri-ka.com) | 163 | [Food-Ka](https://www.food-ka.com) · [Fabri-Ka](https://www.fabri-ka.com) | ||
| 132 | 164 | ||||
added
docs/screenshot.png
+0 −0
Binary file not shown.