docs: README ultra détaillé + visite guidée en 10 captures
7 changed files +340 −38
modified
README.md
+340 −38
@@ -2,24 +2,125 @@ | |||||
| 2 | 2 | ||||
| 3 | **www.ka-stats.com** · Un service **Groupe KA** | 3 | **www.ka-stats.com** · Un service **Groupe KA** | ||
| 4 | 4 | ||||
| 5 | −Observatoire de données de l'écosystème : agrège en direct les dashboards | 5 | +Ka·Stats est l'**observatoire de données** de l'écosystème Groupe KA : un | ||
| 6 | −`GET /api/stats/dashboard` (contrat **ka-stats v2**) des 13 plateformes | 6 | +serveur Node **zéro dépendance** qui agrège **en direct** les tableaux de bord | ||
| 7 | −publiques (Lou·Ka, Immo·Ka, Vrai-Prix, Auto·Ka, Job·Ka, Food·Ka, Resto·Ka, | 7 | +`GET /api/stats/dashboard` (contrat **ka-stats v2**) des **14 plateformes | ||
| 8 | −Fabri·Ka, Sorti·Ka, Créa·Ka, Trouve·Ka, API·Ka) et les rend explorables : | 8 | +publiques** du groupe — Lou·Ka, Immo·Ka, House·Ka, Vrai-Prix, Auto·Ka, Job·Ka, | ||
| 9 | − | 9 | +Food·Ka, Resto·Ka, Fabri·Ka, Sorti·Ka, Créa·Ka, Trouve·Ka, Rent·Ka, API·Ka — | ||
| 10 | −- **Vue d'ensemble** — pouls de l'écosystème, grille des plateformes, prix du | 10 | +et les rend explorables dans une seule interface : graphiques interactifs, | ||
| 11 | − Québec en direct, records. | 11 | +indicateurs du Québec par thème, comparateur base 100, studio d'indicateurs | ||
| 12 | −- **/site/:id** — rendu générique et complet du contrat v2 : KPI + sparklines, | 12 | +sur mesure et palmarès des records. | ||
| 13 | − jauges, séries (crosshair + infobulles), multi-courbes (motifs de trait), | 13 | + | ||
| 14 | − empilées, anneaux, histogrammes, géo, heatmaps calendrier & horaire, | 14 | +Au moment d'écrire ces lignes, l'observatoire suit **plus de 5,8 millions | ||
| 15 | − tableaux triables/filtrables/paginés, records + liens vers les 5 rapports | 15 | +d'éléments** (annonces, propriétés, produits, offres d'emploi, événements, | ||
| 16 | − PDF de la plateforme. | 16 | +créateurs, pages indexées…), **434 graphiques** rendus depuis les dashboards | ||
| 17 | −- **/indicateurs** — les chiffres du Québec par thème (habitation, mobilité, | 17 | +satellites et un catalogue de **248 métriques** combinables dans le Studio — | ||
| 18 | − emploi, consommation, culture, infrastructure). | 18 | +le tout mis à jour en continu, sans base de données propre. | ||
| 19 | −- **/comparer** — jusqu'à 4 plateformes sur un seul axe, indice base 100. | 19 | + | ||
| 20 | −- **/palmares** — records agrégés + classement de croissance. | 20 | +**Identité visuelle** : accent **#095797** (le bleu officiel du Québec), | ||
| 21 | − | 21 | +wordmark « Ka·Stats » dont le segment **« Stats » est posé en boîte inversée** | ||
| 22 | −## Aperçu | 22 | +sur l'accent (le motif signature ka-ui), typographies Space Grotesk (titres) et | ||
| 23 | +JetBrains Mono (chiffres), design system `tokens.css` de ka-ui vendorisé. | ||||
| 24 | + | ||||
| 25 | +--- | ||||
| 26 | + | ||||
| 27 | +## Sommaire | ||||
| 28 | + | ||||
| 29 | +- [Visite guidée](#visite-guidée) | ||||
| 30 | +- [Aperçu mobile & desktop](#aperçu-mobile--desktop) | ||||
| 31 | +- [Les 14 plateformes agrégées](#les-14-plateformes-agrégées) | ||||
| 32 | +- [Pages & fonctionnalités](#pages--fonctionnalités) | ||||
| 33 | +- [Le contrat ka-stats v2 et son rendu générique](#le-contrat-ka-stats-v2-et-son-rendu-générique) | ||||
| 34 | +- [QCharts — graphiques SVG maison](#qcharts--graphiques-svg-maison) | ||||
| 35 | +- [API](#api) | ||||
| 36 | +- [Architecture](#architecture) | ||||
| 37 | +- [Structure du dépôt](#structure-du-dépôt) | ||||
| 38 | +- [Exploitation & déploiement](#exploitation--déploiement) | ||||
| 39 | +- [Développement remote-first](#développement-remote-first) | ||||
| 40 | +- [Écosystème & contact](#écosystème--contact) | ||||
| 41 | + | ||||
| 42 | +--- | ||||
| 43 | + | ||||
| 44 | +## Visite guidée | ||||
| 45 | + | ||||
| 46 | +*Captures desktop 1440×900 du 2026-08-28, prises sur le site en production | ||||
| 47 | +(www.ka-stats.com).* | ||||
| 48 | + | ||||
| 49 | +### 1 · Vue d'ensemble — le pouls de l'écosystème | ||||
| 50 | + | ||||
| 51 | + | ||||
| 52 | + | ||||
| 53 | +La page d'accueil (`/`) donne le pouls du Québec en un coup d'œil : total | ||||
| 54 | +d'éléments suivis, plateformes en direct, courbe de la somme quotidienne des | ||||
| 55 | +indicateurs principaux des 14 plateformes, grille des plateformes (chacune | ||||
| 56 | +avec son accent officiel, ses KPI et sa sparkline), prix du Québec en direct | ||||
| 57 | +et premiers records. Le sélecteur de période global (aujourd'hui → tout, | ||||
| 58 | +plus plage libre) est relayé à toutes les plateformes satellites. Le bouton | ||||
| 59 | +« ✦ Construire un indicateur sur mesure » mène directement au Studio. | ||||
| 60 | + | ||||
| 61 | +### 2 · Indicateurs — les chiffres du Québec par thème | ||||
| 62 | + | ||||
| 63 | + | ||||
| 64 | + | ||||
| 65 | +`/indicateurs` regroupe les chiffres du Québec par grand thème — habitation, | ||||
| 66 | +mobilité, emploi, consommation, culture, infrastructure : loyer moyen, prix | ||||
| 67 | +des propriétés, valeur foncière, prix des voitures usagées, salaires affichés, | ||||
| 68 | +prix d'épicerie… Chaque carte affiche la valeur en direct, son unité et son | ||||
| 69 | +delta (▲/▼ %) sur la période choisie, avec les graphiques associés en | ||||
| 70 | +deux colonnes sous chaque thème. | ||||
| 71 | + | ||||
| 72 | +### 3 · Comparer — la croissance sur un seul axe | ||||
| 73 | + | ||||
| 74 | + | ||||
| 75 | + | ||||
| 76 | +`/comparer` met jusqu'à **4 plateformes sur un seul axe** en **indice | ||||
| 77 | +base 100** (100 = début de période) : des univers aux unités hétérogènes | ||||
| 78 | +(annonces, produits, pages indexées…) deviennent directement comparables, | ||||
| 79 | +sans jamais recourir à une double échelle. Un mode « valeurs brutes » existe | ||||
| 80 | +mais affiche un avertissement — l'indice est la lecture recommandée. | ||||
| 81 | + | ||||
| 82 | +### 4 · Studio — construisez votre indicateur sur mesure | ||||
| 83 | + | ||||
| 84 | + | ||||
| 85 | + | ||||
| 86 | +`/studio` est le **constructeur d'indicateurs** : recherche floue parmi les | ||||
| 87 | +**248 métriques** du catalogue (14 plateformes), sélection de **jusqu'à | ||||
| 88 | +4 métriques**, **transformations** (valeurs brutes, indice 100, variation % | ||||
| 89 | +jour, moyenne mobile 7 j, cumul), **combinaisons** de 2 métriques (ratio | ||||
| 90 | +A ÷ B, écart A − B, somme A + B), choix du type de graphique (ligne, aire, | ||||
| 91 | +barres), titre personnalisé, **enregistrement local** de ses indicateurs et | ||||
| 92 | +**lien partageable** (`/studio?c=…`, la configuration complète encodée dans | ||||
| 93 | +l'URL). Chaque graphique du site propose d'ailleurs un bouton « Ouvrir dans | ||||
| 94 | +le Studio » pour repartir de n'importe quelle courbe. | ||||
| 95 | + | ||||
| 96 | +### 5 · Palmarès — records et faits marquants | ||||
| 97 | + | ||||
| 98 | + | ||||
| 99 | + | ||||
| 100 | +`/palmares` agrège les faits saillants détectés dans les données : jours | ||||
| 101 | +records de chaque plateforme, classement des **plus fortes croissances** | ||||
| 102 | +(variation de l'indicateur principal entre le début et la fin de la période) | ||||
| 103 | +et la grille de tous les records de l'écosystème. | ||||
| 104 | + | ||||
| 105 | +### 6 · Fiche plateforme — le dashboard complet de Lou·Ka | ||||
| 106 | + | ||||
| 107 | + | ||||
| 108 | + | ||||
| 109 | +`/site/:id` (ici `/site/lou-ka`) rend **génériquement et intégralement** le | ||||
| 110 | +contrat ka-stats v2 de la plateforme, aux couleurs de son accent officiel : | ||||
| 111 | +KPI + sparklines, jauges, séries temporelles (crosshair + infobulles + | ||||
| 112 | +comparaison à la période précédente), multi-courbes, aires empilées, anneaux, | ||||
| 113 | +histogrammes, répartitions géographiques, heatmaps calendrier et horaire, | ||||
| 114 | +tableaux triables/filtrables/paginés, records — et les liens vers les | ||||
| 115 | +**5 rapports PDF** générés par la plateforme elle-même. | ||||
| 116 | + | ||||
| 117 | +> Remarque : les URL `/stats`, `/doc`, `/contact` et `/recherche` n'existent | ||||
| 118 | +> pas sur Ka·Stats (le routeur SPA replie toute route inconnue sur la vue | ||||
| 119 | +> d'ensemble) — Ka·Stats **est** la page stats de l'écosystème. | ||||
| 120 | + | ||||
| 121 | +--- | ||||
| 122 | + | ||||
| 123 | +## Aperçu mobile & desktop | ||||
| 23 | 124 | ||||
| 24 | *Captures du 2026-08-25 (mobile 390×844 · desktop 1440×900).* | 125 | *Captures du 2026-08-25 (mobile 390×844 · desktop 1440×900).* | ||
| 25 | 126 | ||||
@@ -45,32 +146,233 @@ Fabri·Ka, Sorti·Ka, Créa·Ka, Trouve·Ka, API·Ka) et les rend explorables : | |||||
| 45 | <td align="center"><img src="docs/screenshots/desktop/palmares.webp" width="420" alt="Palmarès"><br><sub><b>Palmarès — records et faits marquants détectés</b></sub></td> | 146 | <td align="center"><img src="docs/screenshots/desktop/palmares.webp" width="420" alt="Palmarès"><br><sub><b>Palmarès — records et faits marquants détectés</b></sub></td> | ||
| 46 | </tr> | 147 | </tr> | ||
| 47 | <tr> | 148 | <tr> | ||
| 48 | − <td align="center" colspan="2"><img src="docs/screenshots/desktop/studio.webp" width="640" alt="Studio"><br><sub><b>Studio — construisez votre indicateur : 227 métriques, 13 plateformes, transformations (indice 100, variation, moyenne mobile, cumul), partage par lien</b></sub></td> | 149 | + <td align="center" colspan="2"><img src="docs/screenshots/desktop/studio.webp" width="640" alt="Studio"><br><sub><b>Studio — construisez votre indicateur : 248 métriques, 14 plateformes, transformations (indice 100, variation, moyenne mobile, cumul), partage par lien</b></sub></td> | ||
| 49 | </tr> | 150 | </tr> | ||
| 50 | </table> | 151 | </table> | ||
| 51 | 152 | ||||
| 153 | +--- | ||||
| 154 | + | ||||
| 155 | +## Les 14 plateformes agrégées | ||||
| 156 | + | ||||
| 157 | +Chaque plateforme expose `GET /api/stats/dashboard` (contrat ka-stats v2) ; | ||||
| 158 | +Ka·Stats les interroge en parallèle avec la période demandée. Les accents | ||||
| 159 | +proviennent de l'`ecosystem.json` de ka-ui. | ||||
| 160 | + | ||||
| 161 | +| Plateforme | Domaine | Thème | Mission | | ||||
| 162 | +|---|---|---|---| | ||||
| 163 | +| Lou·Ka | www.lou-ka.com | habitation | Tous les logements à louer | | ||||
| 164 | +| Immo·Ka | www.immo-ka.com | habitation | Toutes les propriétés à vendre | | ||||
| 165 | +| House·Ka | www.house-ka.com | habitation | Maisons à vendre — Canada hors Québec (EN) | | ||||
| 166 | +| Vrai-Prix | www.vrai-prix.com | habitation | La valeur réelle de chaque propriété | | ||||
| 167 | +| Rent·Ka | www.rent-ka.com | habitation | Locations résidentielles — Canada hors Québec | | ||||
| 168 | +| Auto·Ka | www.auto-ka.com | mobilité | Les voitures usagées du Québec | | ||||
| 169 | +| Job·Ka | www.job-ka.com | emploi | Tous les emplois des employeurs québécois | | ||||
| 170 | +| Food·Ka | www.food-ka.com | consommation | Les prix d'épicerie, suivis à la source | | ||||
| 171 | +| Resto·Ka | www.resto-ka.com | consommation | Chaque resto, chaque plat, chaque prix | | ||||
| 172 | +| Fabri·Ka | www.fabri-ka.com | consommation | Les produits fabriqués au Québec | | ||||
| 173 | +| Sorti·Ka | www.sorti-ka.com | culture | Toutes les sorties, dans les 17 régions | | ||||
| 174 | +| Créa·Ka | www.crea-ka.com | culture | Les créateurs d'ici, tous leurs liens | | ||||
| 175 | +| Trouve·Ka | www.trouve-ka.com | culture | Le moteur de recherche du web québécois | | ||||
| 176 | +| API·Ka | www.api-ka.com | infrastructure | La donnée de l'écosystème, par API | | ||||
| 177 | + | ||||
| 178 | +--- | ||||
| 179 | + | ||||
| 180 | +## Pages & fonctionnalités | ||||
| 181 | + | ||||
| 182 | +| Route | Page | Contenu | | ||||
| 183 | +|---|---|---| | ||||
| 184 | +| `/` | Vue d'ensemble | Pouls de l'écosystème (somme quotidienne des indicateurs principaux), grille des 14 plateformes (accents officiels, KPI, sparklines), prix du Québec en direct, records, CTA vers le Studio | | ||||
| 185 | +| `/site/:id` | Fiche plateforme | Rendu générique complet du dashboard v2 de la plateforme + liens vers ses 5 rapports PDF (`/api/stats/report?mode=…` sur le domaine satellite) | | ||||
| 186 | +| `/indicateurs` | Indicateurs | Les chiffres du Québec par thème (habitation, mobilité, emploi, consommation, culture, infrastructure) avec deltas ▲/▼ % | | ||||
| 187 | +| `/comparer` | Comparateur | Jusqu'à 4 plateformes sur un seul axe, indice base 100 (mode brut disponible mais déconseillé — avertissement affiché) | | ||||
| 188 | +| `/studio` | Studio | Constructeur d'indicateurs : 248 métriques, transformations, combinaisons, types de graphique, sauvegarde locale, liens partageables | | ||||
| 189 | +| `/palmares` | Palmarès | Jours records, classement de croissance, grille des faits marquants | | ||||
| 190 | + | ||||
| 191 | +Fonctions transversales : | ||||
| 192 | + | ||||
| 193 | +- **Sélecteur de période global** — `auj / 7j / 30j / 3m / 6m / 12m / annee / | ||||
| 194 | + tout` + plage libre `from/to` (AAAA-MM-JJ), relayé tel quel aux satellites, | ||||
| 195 | + persistant à travers les pages. | ||||
| 196 | +- **Routeur History API** — SPA vanilla sans framework ; navigation interne | ||||
| 197 | + interceptée (`a[data-link]`), scroll remis à zéro à chaque page. | ||||
| 198 | +- **Exports** — chaque graphique offre **CSV** (données exactes) et **PNG** | ||||
| 199 | + (rendu du SVG), plus « Ouvrir dans le Studio » pour les séries temporelles. | ||||
| 200 | +- **Footer d'écosystème** — avis d'agrégateur (« nous ne vendons rien, ne | ||||
| 201 | + louons rien »), liens vers toutes les plateformes et Groupe-KA.com. | ||||
| 202 | +- **Analytics maison** — beacon `ka-a.js` d'administration-ka.com | ||||
| 203 | + (`__kaSite = "ka-stats"`), trafic humain seulement. | ||||
| 204 | + | ||||
| 205 | +--- | ||||
| 206 | + | ||||
| 207 | +## Le contrat ka-stats v2 et son rendu générique | ||||
| 208 | + | ||||
| 209 | +La fiche `/site/:id` ne connaît **aucune plateforme en particulier** : elle | ||||
| 210 | +rend ce que le dashboard v2 déclare, bloc par bloc. Types de blocs pris en | ||||
| 211 | +charge : | ||||
| 212 | + | ||||
| 213 | +| Bloc v2 | Rendu Ka·Stats | | ||||
| 214 | +|---|---| | ||||
| 215 | +| `kpis[]` | Cartes KPI (valeur, unité, delta %) + **sparkline** si fournie | | ||||
| 216 | +| `gauges[]` | **Jauges** (arc SVG) | | ||||
| 217 | +| `series[]` | Séries temporelles — ligne/aire/barres commutables, courbe fantôme « période précédente » en tireté si `compare` est fourni | | ||||
| 218 | +| `multiseries[]` | **Multi-courbes** (≤ 4 sous-séries, motifs de trait distincts pour l'accessibilité) | | ||||
| 219 | +| `stacked[]` | Aires/barres **empilées** | | ||||
| 220 | +| `breakdowns[]` | Répartitions — **barres horizontales ↔ anneau** commutables | | ||||
| 221 | +| `histograms[]` | **Histogrammes** de distribution | | ||||
| 222 | +| `geo[]` | Répartitions **géographiques** (barres par région) | | ||||
| 223 | +| `heatmap_calendar` / `heatmap_hours` | **Heatmaps** calendrier (jour × semaine) et horaire (heure × jour) | | ||||
| 224 | +| `tables[]` | Tableaux **triables, filtrables, paginés** | | ||||
| 225 | +| `records[]` | Cartes de records / faits marquants | | ||||
| 226 | + | ||||
| 227 | +L'enveloppe `{success, data}` propre à API·Ka est **dépliée automatiquement** | ||||
| 228 | +côté serveur — le front ne voit qu'un seul format. | ||||
| 229 | + | ||||
| 230 | +--- | ||||
| 231 | + | ||||
| 232 | +## QCharts — graphiques SVG maison | ||||
| 233 | + | ||||
| 234 | +`public/charts.js` (~1 000 lignes) : bibliothèque de graphiques **SVG | ||||
| 235 | +vanilla**, zéro dépendance, conforme au design system ka-ui et aux règles | ||||
| 236 | +dataviz du groupe : | ||||
| 237 | + | ||||
| 238 | +- marques fines (traits 2 px), grilles *hairline*, texte toujours en encre, | ||||
| 239 | + palette catégorielle validée en ordre fixe (`Q.CAT`), rampes mono-teinte, | ||||
| 240 | + motifs de trait (`Q.DASHES`) pour distinguer les séries sans dépendre de la | ||||
| 241 | + couleur seule ; | ||||
| 242 | +- **crosshair + infobulle toutes-séries** sur les lignes, infobulle par-marque | ||||
| 243 | + sur barres et cellules ; | ||||
| 244 | +- **zoom par sélection horizontale** (glisser sur le graphique), bandeau de | ||||
| 245 | + zoom avec bouton « Réinitialiser », **double-clic = réinitialiser** ; | ||||
| 246 | +- **légende cliquable** dès 2 séries pour masquer/afficher chaque série ; | ||||
| 247 | +- **vue tableau jumelle sur chaque graphique** (l'infobulle ne « garde » | ||||
| 248 | + jamais une valeur : les données exactes sont toujours à un clic) ; | ||||
| 249 | +- exports **CSV** et **PNG** intégrés à la coquille de carte (`switchableChart`), | ||||
| 250 | + types commutables (ligne ↔ aire ↔ barres, barres ↔ anneau) ; | ||||
| 251 | +- primitives : `sparkline`, `lineChart`, `vBarChart`, `hBarChart`, `donut`, | ||||
| 252 | + `stackedBar`, `gauge`, `calendarHeatmap`, `hourHeatmap`. | ||||
| 253 | + | ||||
| 254 | +--- | ||||
| 255 | + | ||||
| 256 | +## API | ||||
| 257 | + | ||||
| 258 | +Toutes les routes acceptent `?period=` (`auj|7j|30j|3m|6m|12m|annee|tout`, | ||||
| 259 | +défaut `30j`) et, pour une plage libre, `?from=AAAA-MM-JJ&to=AAAA-MM-JJ`. | ||||
| 260 | + | ||||
| 261 | +| Route | Rôle | | ||||
| 262 | +|---|---| | ||||
| 263 | +| `GET /healthz` (alias `/api/health`) | Healthcheck : `{ok, app, sites, uptime}` | | ||||
| 264 | +| `GET /api/sites` | Les 14 plateformes (id, wordmark, domaine, accents, tagline, thème) | | ||||
| 265 | +| `GET /api/overview` | Agrégat global : totaux (éléments, plateformes en vie, graphiques), pouls quotidien, KPI et records par plateforme | | ||||
| 266 | +| `GET /api/dashboard/:id` | Dashboard v2 complet d'une plateforme (proxy avec cache ; `stale: true` si copie de secours) | | ||||
| 267 | +| `GET /api/catalog` | Catalogue des métriques combinables du Studio (248 refs : `site\|kpi\|id`, `site\|series\|id`, `site\|multi\|id\|i`, `site\|stacked\|id\|i`) | | ||||
| 268 | +| `GET /api/metric?refs=a,b,…` | Points normalisés de 1 à 4 métriques (label, unité, série `{t,v}`) — le moteur du Studio | | ||||
| 269 | + | ||||
| 270 | +Exemple : | ||||
| 271 | + | ||||
| 272 | +```bash | ||||
| 273 | +curl -s "https://www.ka-stats.com/api/overview?period=30j" | jq .totals | ||||
| 274 | +curl -s "https://www.ka-stats.com/api/metric?refs=lou-ka|kpi|active,food-ka|series|avg_price&period=12m" | ||||
| 275 | +``` | ||||
| 276 | + | ||||
| 277 | +--- | ||||
| 278 | + | ||||
| 52 | ## Architecture | 279 | ## Architecture | ||
| 53 | 280 | ||||
| 54 | −- `server.mjs` — Node **zéro dépendance** : statique + `/api/sites`, | 281 | +``` | ||
| 55 | − `/api/overview`, `/api/dashboard/:id` (proxy agrégateur, cache mémoire + | 282 | +navigateur ── SPA vanilla (app.js + charts.js + tokens.css) | ||
| 56 | − disque 10 min, *stale-while-error* : satellite down ⇒ dernière bonne copie). | 283 | + │ | ||
| 57 | − Enveloppe `{success,data}` d'API·Ka dépliée automatiquement. | 284 | +server.mjs (Node ≥ 18, zéro dépendance, ~400 lignes) | ||
| 58 | −- `public/charts.js` — **QCharts**, graphiques SVG vanilla conformes au | 285 | + │ statique + SSR des metas SEO + API agrégatrice | ||
| 59 | − design system ka-ui + règles dataviz (marques fines, gaps de surface, | 286 | + ├── cache mémoire par (site, période) — TTL 10 min | ||
| 60 | − grilles hairline, légende dès 2 séries, vue tableau jumelle sur chaque | 287 | + ├── cache disque data/cache.json (périodes standard seulement) | ||
| 61 | − graphique, palette catégorielle validée en ordre fixe, rampes mono-teinte). | 288 | + └── fan-out HTTPS parallèle vers les 14 satellites | ||
| 62 | −- `public/app.js` — SPA vanilla, routeur History API, sélecteur de période | 289 | + https://<plateforme>/api/stats/dashboard?period=… | ||
| 63 | − global (auj/7j/30j/3m/6m/12m/année/tout + plage libre) relayé aux | 290 | +``` | ||
| 64 | − satellites. | 291 | + | ||
| 65 | −- Design system : `tokens.css` de ka-ui vendorisé + accent Ka·Stats | 292 | +- **Zéro dépendance** : `node:http`, `node:fs`, `node:path` — pas de | ||
| 66 | − **#095797** (bleu Québec). | 293 | + `node_modules`, pas de build, pas de base de données. | ||
| 67 | − | 294 | +- **Cache 10 min + *stale-while-error*** : chaque couple (site, période) est | ||
| 68 | −## Exploitation | 295 | + mis en cache 10 minutes (mémoire + disque). Si un satellite est injoignable, | ||
| 296 | + Ka·Stats sert **la dernière bonne copie** (marquée `stale: true`) au lieu | ||||
| 297 | + d'échouer ; les requêtes concurrentes vers un même satellite sont | ||||
| 298 | + dédupliquées (map *inflight*). Les plages libres (`from/to`) ne sont jamais | ||||
| 299 | + persistées sur disque (cardinalité illimitée). | ||||
| 300 | +- **SEO** : SSR léger des metas — title/description/canonical/OpenGraph + | ||||
| 301 | + **JSON-LD** (schema.org) injectés par route dans `index.html` (la SPA rend | ||||
| 302 | + le contenu, le serveur rend les metas — même approche que les autres sites | ||||
| 303 | + Ka). `sitemap.xml` et `robots.txt` servis statiquement. Routes `/site/:id` | ||||
| 304 | + titrées dynamiquement d'après la plateforme. | ||||
| 305 | +- **Sécurité/robustesse** : id de plateforme assaini (`[^a-z0-9-]` retiré), | ||||
| 306 | + périodes validées par liste blanche, dates par regex stricte ; en-têtes | ||||
| 307 | + `Cache-Control` différenciés (HTML `no-cache`, assets 1 h). | ||||
| 308 | + | ||||
| 309 | +--- | ||||
| 310 | + | ||||
| 311 | +## Structure du dépôt | ||||
| 312 | + | ||||
| 313 | +``` | ||||
| 314 | +ka-stats/ | ||||
| 315 | +├── server.mjs # serveur Node zéro-dép : statique + API + SEO SSR | ||||
| 316 | +├── package.json # aucune dépendance — script start seulement | ||||
| 317 | +├── public/ | ||||
| 318 | +│ ├── index.html # coquille SPA (metas remplacées par le serveur) | ||||
| 319 | +│ ├── app.js # SPA vanilla : routeur, 6 pages, Studio, header/footer | ||||
| 320 | +│ ├── charts.js # QCharts — graphiques SVG maison (voir plus haut) | ||||
| 321 | +│ ├── styles.css # styles Ka·Stats (sur les tokens ka-ui) | ||||
| 322 | +│ ├── tokens.css # design system ka-ui vendorisé + accent #095797 | ||||
| 323 | +│ ├── fonts/ # Space Grotesk + JetBrains Mono (auto-hébergées) | ||||
| 324 | +│ ├── favicon.svg · og.png · apple-touch-icon.png | ||||
| 325 | +│ └── sitemap.xml · robots.txt | ||||
| 326 | +├── data/ | ||||
| 327 | +│ └── cache.json # cache disque (généré — ignoré par git) | ||||
| 328 | +└── docs/ | ||||
| 329 | + └── screenshots/ # visite guidée (JPG) + mobile/ + desktop/ (webp) | ||||
| 330 | +``` | ||||
| 331 | + | ||||
| 332 | +--- | ||||
| 333 | + | ||||
| 334 | +## Exploitation & déploiement | ||||
| 69 | 335 | ||||
| 70 | ```bash | 336 | ```bash | ||
| 71 | −node server.mjs 8140 # healthcheck : /healthz | 337 | +node server.mjs 8140 # défaut 8140 — healthcheck : /healthz | ||
| 72 | ``` | 338 | ``` | ||
| 73 | 339 | ||||
| 74 | −Déployé sur **M1M32** (`~/apps/ka-stats`) sous PM2 (`ka-stats` + | 340 | +- **Production** : nœud **M1M32** du cluster MacLustr, `~/apps/ka-stats`, | ||
| 75 | −`ka-stats-ngrok` → https://www.ka-stats.com). Registre : | 341 | + port **8140**, sous **PM2** (`ka-stats` pour le serveur, `ka-stats-ngrok` | ||
| 76 | −`~/Desktop/cluster-skill/cluster-deployments.json`. | 342 | + pour le tunnel) → **https://www.ka-stats.com**. | ||
| 343 | +- PM2 est configuré en service de démarrage (launchd) : l'app survit aux | ||||
| 344 | + redémarrages du nœud. | ||||
| 345 | +- Registre des déploiements du cluster : | ||||
| 346 | + `~/Desktop/cluster-skill/cluster-deployments.json`. | ||||
| 347 | +- Aucune clé, aucun secret : Ka·Stats ne consomme que les endpoints publics | ||||
| 348 | + des plateformes. | ||||
| 349 | + | ||||
| 350 | +--- | ||||
| 351 | + | ||||
| 352 | +## Développement remote-first | ||||
| 353 | + | ||||
| 354 | +La **source de vérité est le repo git sur le nœud de déploiement** | ||||
| 355 | +(M1M32 `~/apps/ka-stats`), pas une copie locale. Le remote `origin` est | ||||
| 356 | +**spbgit**, le serveur git personnel du groupe (bare repo | ||||
| 357 | +`srv/git/ka-stats.git` sur M3U96a, alias SSH `gitsrv`) — pas GitHub. | ||||
| 358 | + | ||||
| 359 | +Cycle type : éditer sur le nœud via SSH → tester (`curl localhost:8140/healthz`) | ||||
| 360 | +→ `pm2 restart ka-stats` → `git add/commit/push origin main` **sur le nœud** | ||||
| 361 | +(agent forwarding actif). Référence complète du flux remote-first : | ||||
| 362 | +`~/Desktop/cluster-skill/KA-REMOTE-DEV.md`. | ||||
| 363 | + | ||||
| 364 | +--- | ||||
| 365 | + | ||||
| 366 | +## Écosystème & contact | ||||
| 367 | + | ||||
| 368 | +Ka·Stats est l'observatoire transversal du **Groupe KA**, l'écosystème de | ||||
| 369 | +plateformes de données du Québec (et, pour House·Ka et Rent·Ka, du Canada | ||||
| 370 | +hors Québec). **Avis** : Groupe KA est un agrégateur de contenu — nous ne | ||||
| 371 | +vendons rien, ne louons rien et ne sommes partie à aucune transaction ; les | ||||
| 372 | +statistiques reflètent les données collectées par nos plateformes. | ||||
| 373 | + | ||||
| 374 | +- Hub : **https://www.groupe-ka.com** | ||||
| 375 | +- Données par API : **https://www.api-ka.com** | ||||
| 376 | +- Auteur : Simon-Pierre Boucher · contact@spboucher.ai | ||||
| 377 | + | ||||
| 378 | +© Groupe KA. Tous droits réservés. | ||||
added
docs/screenshots/01-accueil.jpg
+0 −0
Binary file not shown.
added
docs/screenshots/02-indicateurs.jpg
+0 −0
Binary file not shown.
added
docs/screenshots/03-comparer.jpg
+0 −0
Binary file not shown.
added
docs/screenshots/04-studio.jpg
+0 −0
Binary file not shown.
added
docs/screenshots/05-palmares.jpg
+0 −0
Binary file not shown.
added
docs/screenshots/06-site-lou-ka.jpg
+0 −0
Binary file not shown.