SPB Git forge

spb/groupe-ka

Public

Groupe KA — site du holding + KA ID (compte unique & SSO des 7 plateformes). Next.js 16, SQLite, Google & Apple login.

81commits 1branches 0releases
89.2 MBsize
maindefault branch
22 days agolast push
TypeScript 70.4% HTML 18.4% JavaScript 4% Python 3.8% CSS 3.4%

Job-Ka rejoint l écosystème : client SSO, métriques live, ticker, carte plateforme 11, socle, figures (accents officiels), footer, comptes dynamiques status/stats, ecosystem.json 13 sites

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed 1 mo ago (Aug 18, 2026) parent 6f20265

8 changed files +240 −38

modified src/app/figures.tsx +6 −5
@@ -12,16 +12,17 @@ export const FIG_PLATFORMS: {
12 12 accent: string;
13 13 domain: string;
14 14 }[] = [
15 − { name: "Lou·Ka", accent: "#d9f26b", domain: "lou-ka.com" },
15 + { name: "Lou·Ka", accent: "#ff6a00", domain: "lou-ka.com" },
16 16 { name: "Immo·Ka", accent: "#e23744", domain: "immo-ka.com" },
17 17 { name: "Vrai-Prix", accent: "#ff5148", domain: "vrai-prix.com" },
18 18 { name: "ValoPlex", accent: "#ff9f45", domain: "valoplex.com" },
19 19 { name: "Auto·Ka", accent: "#ff5a2a", domain: "auto-ka.com" },
20 20 { name: "Fabri·Ka", accent: "#C4532E", domain: "fabri-ka.com" },
21 − { name: "Food·Ka", accent: "#d9f26b", domain: "food-ka.com" },
22 − { name: "Resto·Ka", accent: "#ffc53d", domain: "resto-ka.com" },
23 − { name: "Sorti·Ka", accent: "#ff6a00", domain: "sorti-ka.com" },
24 − { name: "Créa·Ka", accent: "#7da2ff", domain: "crea-ka.com" },
21 + { name: "Food·Ka", accent: "#1f9d55", domain: "food-ka.com" },
22 + { name: "Resto·Ka", accent: "#f08c00", domain: "resto-ka.com" },
23 + { name: "Sorti·Ka", accent: "#d6336c", domain: "sorti-ka.com" },
24 + { name: "Créa·Ka", accent: "#7048e8", domain: "crea-ka.com" },
25 + { name: "Job·Ka", accent: "#0c8599", domain: "job-ka.com" },
25 26 ];
26 27
27 28 const ACCENT: Record<string, string> = Object.fromEntries(
modified src/app/layout.tsx +4 −2
@@ -19,11 +19,11 @@ export const metadata: Metadata = {
19 19 metadataBase: new URL("https://www.groupe-ka.com"),
20 20 title: "Groupe KA — holding d’agrégateurs automatisés, sans boîte noire",
21 21 description:
22 − "Groupe KA est un holding québécois d’agrégateurs de produits et services entièrement automatisés : Trouve·Ka (moteur de recherche du web québécois), Lou·Ka (location), Immo·Ka (propriétés à vendre), Vrai-Prix (valeur résidentielle), ValoPlex (plex), Auto·Ka (voitures usagées), Fabri·Ka (produits québécois), Food·Ka (épicerie), Resto·Ka (restaurants, menus et prix), Sorti·Ka (sorties et événements) et Créa·Ka (créateurs d’ici). Zéro saisie manuelle.",
22 + "Groupe KA est un holding québécois d’agrégateurs de produits et services entièrement automatisés : Trouve·Ka (moteur de recherche du web québécois), Lou·Ka (location), Immo·Ka (propriétés à vendre), Vrai-Prix (valeur résidentielle), ValoPlex (plex), Auto·Ka (voitures usagées), Fabri·Ka (produits québécois), Food·Ka (épicerie), Resto·Ka (restaurants, menus et prix), Sorti·Ka (sorties et événements) Créa·Ka (créateurs d’ici) et Job·Ka (emplois). Zéro saisie manuelle.",
23 23 openGraph: {
24 24 title: "Groupe KA — holding d’agrégateurs automatisés, sans boîte noire",
25 25 description:
26 − "Ka, c’est l’agrégation : des centaines de connecteurs, dix plateformes — Lou·Ka, Immo·Ka, Vrai-Prix, ValoPlex, Auto·Ka, Fabri·Ka, Food·Ka, Resto·Ka, Sorti·Ka et Créa·Ka.",
26 + "Ka, c’est l’agrégation : des centaines de connecteurs, dix plateformes — Lou·Ka, Immo·Ka, Vrai-Prix, ValoPlex, Auto·Ka, Fabri·Ka, Food·Ka, Resto·Ka, Sorti·Ka, Créa·Ka et Job·Ka.",
27 27 url: "https://www.groupe-ka.com",
28 28 siteName: "Groupe KA",
29 29 locale: "fr_CA",
@@ -68,6 +68,7 @@ const tickerItems = (m: LiveMetrics): string[] => [
68 68 `${fmtPlus(m.restoka.items)} plats et prix réels chez ${fmtPlus(m.restoka.restaurants)} restos — resto-ka.com`,
69 69 `${fmtPlus(m.sortika.active)} sorties et événements dans les 17 régions — sorti-ka.com`,
70 70 `${fmtPlus(m.creaka.creators)} créateurs québécois, tous leurs liens regroupés — crea-ka.com`,
71 + `${fmtPlus(m.jobka.total)} offres d'emploi chez ${m.jobka.employers} employeurs — job-ka.com`,
71 72 `${fmtInt(m.vraiprix.units)} propriétés évaluées au Québec`,
72 73 "393 867 plex · 1 733 744 portes",
73 74 "Ka2 & Ka4 cartographient le web québécois — ka2.bot · ka4.bot",
@@ -248,6 +249,7 @@ export default async function RootLayout({
248 249 ["Sorti·Ka", "https://www.sorti-ka.com"],
249 250 ["Créa·Ka", "https://www.crea-ka.com"],
250 251 ["API·Ka", "https://www.api-ka.com"],
252 + ["Job·Ka", "https://www.job-ka.com"],
251 253 ["Ka2", "https://www.ka2.bot"],
252 254 ["Ka4", "https://www.ka4.bot"],
253 255 ["Ka6", "https://www.ka6.bot"],
modified src/app/page.tsx +34 −0
@@ -233,6 +233,27 @@ const PRODUCTS: Product[] = [
233 233 ],
234 234 isNew: true,
235 235 },
236 + {
237 + num: "11",
238 + markLeft: "Job",
239 + markBoxed: "Ka",
240 + accent: "#6fd0e0",
241 + inkbox: "#0d1b1e",
242 + field: "Emploi",
243 + domain: "www.job-ka.com",
244 + url: "https://www.job-ka.com",
245 + tagline: "Tous les emplois des employeurs québécois. Un seul endroit.",
246 + description:
247 + "Les offres d'emploi collectées directement sur les pages carrières des employeurs du Québec — pas sur les job boards. Salaires normalisés en $/h et $/an, offres traçables à leur source, candidature chez l'employeur. Une offre retirée disparaît d'elle-même.",
248 + chips: ["4 400+ offres", "135 employeurs", "9 plateformes ATS"],
249 + features: [
250 + "Recherche par métier, ville, salaire et télétravail",
251 + "Salaires normalisés $/h et $/an quand l'employeur les publie",
252 + "Candidature directement chez l'employeur — zéro intermédiaire",
253 + "Expiration automatique des offres retirées ou échues",
254 + ],
255 + isNew: true,
256 + },
236 257 ];
237 258
238 259 type Bot = {
@@ -363,6 +384,12 @@ const socleRows = (m: LiveMetrics): [string, string, string, string][] => [
363 384 "Billetteries + données ouvertes — MàJ horaire",
364 385 "www.sorti-ka.com",
365 386 ],
387 + [
388 + "Job·Ka",
389 + "Emploi — pages carrières des employeurs",
390 + `${m.jobka.employers} employeurs suivis sur 9 plateformes ATS`,
391 + "www.job-ka.com",
392 + ],
366 393 [
367 394 "Créa·Ka",
368 395 "Créateurs de contenu",
@@ -576,6 +603,11 @@ function liveChips(m: LiveMetrics): Record<string, string[]> {
576 603 `${fmtPlus(m.creaka.accounts)} comptes reliés`,
577 604 `${m.creaka.platforms} plateformes`,
578 605 ],
606 + "www.job-ka.com": [
607 + `${fmtPlus(m.jobka.total)} offres`,
608 + `${m.jobka.employers} employeurs`,
609 + `${fmtPlus(m.jobka.withSalary)} salaires publiés`,
610 + ],
579 611 "www.vrai-prix.com": [
580 612 `${fmtInt(m.vraiprix.units)} propriétés estimées`,
581 613 `${fmtPlus(m.vraiprix.transactions)} transactions réelles`,
@@ -820,6 +852,7 @@ export default async function Home() {
820 852 { name: "Sorti·Ka", value: m.sortika.active, unit: "événements & sorties" },
821 853 { name: "Lou·Ka", value: m.louka.total, unit: "logements à louer" },
822 854 { name: "Créa·Ka", value: m.creaka.creators, unit: "créateurs d'ici" },
855 + { name: "Job·Ka", value: m.jobka.total, unit: "offres d'emploi" },
823 856 ]}
824 857 />
825 858 <ConnectorMatrix
@@ -829,6 +862,7 @@ export default async function Home() {
829 862 { name: "Food·Ka", count: m.foodka.sources, kind: "bannières" },
830 863 { name: "Immo·Ka", count: m.immoka.sources, kind: "agences" },
831 864 { name: "Resto·Ka", count: m.restoka.chains, kind: "chaînes de restos" },
865 + { name: "Job·Ka", count: m.jobka.employers, kind: "employeurs (pages carrières)" },
832 866 { name: "Sorti·Ka", count: 4, kind: "billetteries & données ouvertes" },
833 867 ]}
834 868 total={m.totals.connectors}
modified src/app/stats/page.tsx +2 −2
@@ -22,7 +22,7 @@ import {
22 22 export const metadata: Metadata = {
23 23 title: "Statistiques de l'écosystème — Groupe KA",
24 24 description:
25 − "Tableau de bord maître du Groupe KA : indicateurs consolidés en direct des 12 plateformes de l'écosystème ·Ka, classement par volume, résumé par plateforme et rapport écosystème PDF.",
25 + "Tableau de bord maître du Groupe KA : indicateurs consolidés en direct des plateformes de l'écosystème ·Ka, classement par volume, résumé par plateforme et rapport écosystème PDF.",
26 26 };
27 27
28 28 /** Format compact honnête pour les très grands nombres (G / M). */
@@ -208,7 +208,7 @@ export default async function StatsPage({
208 208 return (
209 209 <main className="mx-auto max-w-6xl px-4 py-12 sm:px-6">
210 210 {/* 1 — en-tête : titre, rapports PDF, fraîcheur, période */}
211 − <p className="kicker">Tableau de bord maître · les 12 plateformes</p>
211 + <p className="kicker">Tableau de bord maître · tout l’écosystème</p>
212 212 <h1 className="gk-display mt-3 text-[clamp(28px,4.5vw,44px)] leading-[1.02] font-bold tracking-[-0.035em] uppercase">
213 213 Statistiques de <span className="hl">l&apos;écosystème</span>
214 214 </h1>
modified src/app/status/page.tsx +3 −3
@@ -18,7 +18,7 @@ export const dynamic = "force-dynamic";
18 18 export const metadata: Metadata = {
19 19 title: "Statut des services — Groupe KA",
20 20 description:
21 − "État en direct et historique de disponibilité des 12 plateformes de l'écosystème Groupe KA : vérifications aux 5 minutes, barres 24 h et 90 jours, latences.",
21 + "État en direct et historique de disponibilité des plateformes de l'écosystème Groupe KA : vérifications aux 5 minutes, barres 24 h et 90 jours, latences.",
22 22 };
23 23
24 24 const BAR_COLORS: Record<string, string> = {
@@ -81,8 +81,8 @@ export default async function StatusPage() {
81 81 <main className="mx-auto max-w-6xl px-4 py-12 sm:px-6">
82 82 <p className="kicker">État des services · direct + historique</p>
83 83 <h1 className="gk-display mt-3 text-[clamp(28px,4.5vw,44px)] leading-[1.02] font-bold tracking-[-0.035em] uppercase">
84 − Les 12 plateformes,{" "}
85 − <span className="hl">{allUp ? "toutes en ligne" : `${upCount}/12 en ligne`}</span>
84 + Les {eco.sites.length} plateformes,{" "}
85 + <span className="hl">{allUp ? "toutes en ligne" : `${upCount}/${eco.sites.length} en ligne`}</span>
86 86 </h1>
87 87 <p className="mt-4 max-w-xl text-[14.5px] text-ink-2">
88 88 Chaque plateforme est vérifiée automatiquement aux 5 minutes, plus une
modified src/ka/ecosystem.json +175 −24
@@ -12,34 +12,185 @@
12 12 "signupNote": "La création de compte KA ID se fait sur le hub groupe-ka.com ; chaque site délègue sa connexion via /api/auth/ka/login."
13 13 },
14 14 "contacts": [
15 − { "email": "contact@groupe-ka.com", "role": "Projets, partenariats & données" },
16 − { "email": "info@groupe-ka.com", "role": "Médias & questions générales" },
17 − { "email": "admin@groupe-ka.com", "role": "Légal, vie privée & Loi 25" }
15 + {
16 + "email": "contact@groupe-ka.com",
17 + "role": "Projets, partenariats & données"
18 + },
19 + {
20 + "email": "info@groupe-ka.com",
21 + "role": "Médias & questions générales"
22 + },
23 + {
24 + "email": "admin@groupe-ka.com",
25 + "role": "Légal, vie privée & Loi 25"
26 + }
18 27 ],
19 28 "legal": [
20 − { "label": "Conditions d'utilisation", "href": "https://www.groupe-ka.com/conditions" },
21 − { "label": "Politique de confidentialité", "href": "https://www.groupe-ka.com/confidentialite" },
22 − { "label": "Protection des renseignements personnels (Loi 25)", "href": "https://www.groupe-ka.com/loi-25" },
23 − { "label": "Transparence des robots d'indexation", "href": "https://www.groupe-ka.com/bots" }
29 + {
30 + "label": "Conditions d'utilisation",
31 + "href": "https://www.groupe-ka.com/conditions"
32 + },
33 + {
34 + "label": "Politique de confidentialité",
35 + "href": "https://www.groupe-ka.com/confidentialite"
36 + },
37 + {
38 + "label": "Protection des renseignements personnels (Loi 25)",
39 + "href": "https://www.groupe-ka.com/loi-25"
40 + },
41 + {
42 + "label": "Transparence des robots d'indexation",
43 + "href": "https://www.groupe-ka.com/bots"
44 + }
24 45 ],
25 46 "sites": [
26 − { "id": "groupe-ka", "wordmark": "Groupe KA", "domain": "www.groupe-ka.com", "accent": "#d9f26b", "accentSoft": "#f0f9d2", "accentDeep": "#123f2e", "onAccent": "#141814", "tagline": "Le portail de l'écosystème ·Ka" },
27 − { "id": "trouve-ka", "wordmark": "Trouve·Ka", "domain": "www.trouve-ka.com", "accent": "#1c7ed6", "accentSoft": "#e7f2fd", "accentDeep": "#14508f", "onAccent": "#ffffff", "tagline": "Le moteur de recherche du web québécois" },
28 − { "id": "lou-ka", "wordmark": "Lou·Ka", "domain": "www.lou-ka.com", "accent": "#ff6a00", "accentSoft": "#fff1e6", "accentDeep": "#cc5500", "onAccent": "#ffffff", "tagline": "Tous les logements à louer" },
29 − { "id": "immo-ka", "wordmark": "Immo·Ka", "domain": "www.immo-ka.com", "accent": "#e23744", "accentSoft": "#fbe0e2", "accentDeep": "#a8232e", "onAccent": "#ffffff", "tagline": "Toutes les propriétés à vendre" },
30 − { "id": "vrai-prix", "wordmark": "Vrai-Prix", "domain": "www.vrai-prix.com", "accent": "#ff5148", "accentSoft": "#ffe3e0", "accentDeep": "#9e2a25", "onAccent": "#ffffff", "tagline": "La valeur réelle de chaque propriété" },
31 − { "id": "auto-ka", "wordmark": "Auto·Ka", "domain": "www.auto-ka.com", "accent": "#ff5a2a", "accentSoft": "#ffe8de", "accentDeep": "#cc3f16", "onAccent": "#ffffff", "tagline": "Les voitures usagées du Québec" },
32 − { "id": "fabri-ka", "wordmark": "Fabri·Ka", "domain": "www.fabri-ka.com", "accent": "#c4532e", "accentSoft": "#f7e3da", "accentDeep": "#a94525", "onAccent": "#ffffff", "tagline": "Les produits fabriqués au Québec" },
33 − { "id": "food-ka", "wordmark": "Food·Ka", "domain": "www.food-ka.com", "accent": "#1f9d55", "accentSoft": "#e2f5ea", "accentDeep": "#157a40", "onAccent": "#ffffff", "tagline": "Les prix d'épicerie, suivis à la source" },
34 − { "id": "resto-ka", "wordmark": "Resto·Ka", "domain": "www.resto-ka.com", "accent": "#f08c00", "accentSoft": "#fdeed7", "accentDeep": "#b96a00", "onAccent": "#141814", "tagline": "Chaque resto, chaque plat, chaque prix" },
35 − { "id": "sorti-ka", "wordmark": "Sorti·Ka", "domain": "www.sorti-ka.com", "accent": "#d6336c", "accentSoft": "#fbe0eb", "accentDeep": "#a12551", "onAccent": "#ffffff", "tagline": "Toutes les sorties, dans les 17 régions" },
36 − { "id": "crea-ka", "wordmark": "Créa·Ka", "domain": "www.crea-ka.com", "accent": "#7048e8", "accentSoft": "#ece5fc", "accentDeep": "#5433b8", "onAccent": "#ffffff", "tagline": "Les créateurs d'ici, tous leurs liens" },
37 − { "id": "api-ka", "wordmark": "API·Ka", "domain": "www.api-ka.com", "accent": "#3b5bdb", "accentSoft": "#e4eafb", "accentDeep": "#2b44a8", "onAccent": "#ffffff", "tagline": "La donnée de l'écosystème, par API" }
47 + {
48 + "id": "groupe-ka",
49 + "wordmark": "Groupe KA",
50 + "domain": "www.groupe-ka.com",
51 + "accent": "#d9f26b",
52 + "accentSoft": "#f0f9d2",
53 + "accentDeep": "#123f2e",
54 + "onAccent": "#141814",
55 + "tagline": "Le portail de l'écosystème ·Ka"
56 + },
57 + {
58 + "id": "trouve-ka",
59 + "wordmark": "Trouve·Ka",
60 + "domain": "www.trouve-ka.com",
61 + "accent": "#1c7ed6",
62 + "accentSoft": "#e7f2fd",
63 + "accentDeep": "#14508f",
64 + "onAccent": "#ffffff",
65 + "tagline": "Le moteur de recherche du web québécois"
66 + },
67 + {
68 + "id": "lou-ka",
69 + "wordmark": "Lou·Ka",
70 + "domain": "www.lou-ka.com",
71 + "accent": "#ff6a00",
72 + "accentSoft": "#fff1e6",
73 + "accentDeep": "#cc5500",
74 + "onAccent": "#ffffff",
75 + "tagline": "Tous les logements à louer"
76 + },
77 + {
78 + "id": "immo-ka",
79 + "wordmark": "Immo·Ka",
80 + "domain": "www.immo-ka.com",
81 + "accent": "#e23744",
82 + "accentSoft": "#fbe0e2",
83 + "accentDeep": "#a8232e",
84 + "onAccent": "#ffffff",
85 + "tagline": "Toutes les propriétés à vendre"
86 + },
87 + {
88 + "id": "vrai-prix",
89 + "wordmark": "Vrai-Prix",
90 + "domain": "www.vrai-prix.com",
91 + "accent": "#ff5148",
92 + "accentSoft": "#ffe3e0",
93 + "accentDeep": "#9e2a25",
94 + "onAccent": "#ffffff",
95 + "tagline": "La valeur réelle de chaque propriété"
96 + },
97 + {
98 + "id": "auto-ka",
99 + "wordmark": "Auto·Ka",
100 + "domain": "www.auto-ka.com",
101 + "accent": "#ff5a2a",
102 + "accentSoft": "#ffe8de",
103 + "accentDeep": "#cc3f16",
104 + "onAccent": "#ffffff",
105 + "tagline": "Les voitures usagées du Québec"
106 + },
107 + {
108 + "id": "fabri-ka",
109 + "wordmark": "Fabri·Ka",
110 + "domain": "www.fabri-ka.com",
111 + "accent": "#c4532e",
112 + "accentSoft": "#f7e3da",
113 + "accentDeep": "#a94525",
114 + "onAccent": "#ffffff",
115 + "tagline": "Les produits fabriqués au Québec"
116 + },
117 + {
118 + "id": "food-ka",
119 + "wordmark": "Food·Ka",
120 + "domain": "www.food-ka.com",
121 + "accent": "#1f9d55",
122 + "accentSoft": "#e2f5ea",
123 + "accentDeep": "#157a40",
124 + "onAccent": "#ffffff",
125 + "tagline": "Les prix d'épicerie, suivis à la source"
126 + },
127 + {
128 + "id": "resto-ka",
129 + "wordmark": "Resto·Ka",
130 + "domain": "www.resto-ka.com",
131 + "accent": "#f08c00",
132 + "accentSoft": "#fdeed7",
133 + "accentDeep": "#b96a00",
134 + "onAccent": "#141814",
135 + "tagline": "Chaque resto, chaque plat, chaque prix"
136 + },
137 + {
138 + "id": "sorti-ka",
139 + "wordmark": "Sorti·Ka",
140 + "domain": "www.sorti-ka.com",
141 + "accent": "#d6336c",
142 + "accentSoft": "#fbe0eb",
143 + "accentDeep": "#a12551",
144 + "onAccent": "#ffffff",
145 + "tagline": "Toutes les sorties, dans les 17 régions"
146 + },
147 + {
148 + "id": "crea-ka",
149 + "wordmark": "Créa·Ka",
150 + "domain": "www.crea-ka.com",
151 + "accent": "#7048e8",
152 + "accentSoft": "#ece5fc",
153 + "accentDeep": "#5433b8",
154 + "onAccent": "#ffffff",
155 + "tagline": "Les créateurs d'ici, tous leurs liens"
156 + },
157 + {
158 + "id": "api-ka",
159 + "wordmark": "API·Ka",
160 + "domain": "www.api-ka.com",
161 + "accent": "#3b5bdb",
162 + "accentSoft": "#e4eafb",
163 + "accentDeep": "#2b44a8",
164 + "onAccent": "#ffffff",
165 + "tagline": "La donnée de l'écosystème, par API"
166 + },
167 + {
168 + "id": "job-ka",
169 + "wordmark": "Job·Ka",
170 + "domain": "www.job-ka.com",
171 + "accent": "#0c8599",
172 + "accentSoft": "#def0f4",
173 + "accentDeep": "#095c6b",
174 + "onAccent": "#ffffff",
175 + "tagline": "Tous les emplois des employeurs québécois"
176 + }
38 177 ],
39 178 "extraFooterLinks": [
40 − { "label": "ValoPlex", "href": "https://www.valoplex.com" },
41 − { "label": "Ka2", "href": "https://www.ka2.bot" },
42 − { "label": "Ka4", "href": "https://www.ka4.bot" },
43 − { "label": "Ka6", "href": "https://www.ka6.bot" }
179 + {
180 + "label": "ValoPlex",
181 + "href": "https://www.valoplex.com"
182 + },
183 + {
184 + "label": "Ka2",
185 + "href": "https://www.ka2.bot"
186 + },
187 + {
188 + "label": "Ka4",
189 + "href": "https://www.ka4.bot"
190 + },
191 + {
192 + "label": "Ka6",
193 + "href": "https://www.ka6.bot"
194 + }
44 195 ]
45 −}
196 +}
\ No newline at end of file
modified src/lib/live.ts +11 −2
@@ -40,11 +40,12 @@ export type LiveMetrics = {
40 40 creaka: { creators: number; accounts: number; platforms: number };
41 41 trouveka: { pages: number; domains: number; running: boolean };
42 42 vraiprix: { units: number; transactions: number; valueTotal: number };
43 + jobka: { total: number; employers: number; withSalary: number };
43 44 totals: { connectors: number; items: number };
44 45 };
45 46
46 47 export async function getLiveMetrics(): Promise<LiveMetrics> {
47 − const [lou, immo, auto, fab, food, resto, sorti, crea, trouve, vp] =
48 + const [lou, immo, auto, fab, food, resto, sorti, crea, trouve, vp, job] =
48 49 await Promise.all([
49 50 fetchJson("https://www.lou-ka.com/api/stats"),
50 51 fetchJson("https://www.immo-ka.com/api/stats"),
@@ -56,6 +57,7 @@ export async function getLiveMetrics(): Promise<LiveMetrics> {
56 57 fetchJson("https://www.crea-ka.com/api/stats"),
57 58 fetchJson("https://www.trouve-ka.com/api/status"),
58 59 fetchJson("https://www.vrai-prix.com/api/stats"),
60 + fetchJson("https://www.job-ka.com/api/stats"),
59 61 ]);
60 62
61 63 const m: LiveMetrics = {
@@ -108,6 +110,11 @@ export async function getLiveMetrics(): Promise<LiveMetrics> {
108 110 transactions: num(vp, "transactions", 745119),
109 111 valueTotal: num(vp, "value_total_2026", 2009452277400),
110 112 },
113 + jobka: {
114 + total: num(job, "total", 4449),
115 + employers: num(job, "employers", 135),
116 + withSalary: num(job, "with_salary", 1069),
117 + },
111 118 totals: { connectors: 0, items: 0 },
112 119 };
113 120
@@ -117,6 +124,7 @@ export async function getLiveMetrics(): Promise<LiveMetrics> {
117 124 m.autoka.sources +
118 125 m.foodka.sources +
119 126 m.restoka.chains +
127 + m.jobka.employers +
120 128 4; // Sorti·Ka : billetteries & données ouvertes (pas d'API de comptage)
121 129 m.totals.items =
122 130 m.louka.total +
@@ -126,7 +134,8 @@ export async function getLiveMetrics(): Promise<LiveMetrics> {
126 134 m.foodka.total +
127 135 m.restoka.items +
128 136 m.sortika.active +
129 − m.creaka.creators;
137 + m.creaka.creators +
138 + m.jobka.total;
130 139
131 140 return m;
132 141 }
modified src/lib/sso.ts +5 −0
@@ -67,6 +67,11 @@ export const SSO_CLIENTS: Record<
67 67 redirectPrefixes: ["https://www.resto-ka.com/", "http://localhost:8115/"],
68 68 secretEnv: "KA_SSO_SECRET_RESTO_KA",
69 69 },
70 + "job-ka": {
71 + label: "Job·Ka",
72 + redirectPrefixes: ["https://www.job-ka.com/", "http://localhost:8096/"],
73 + secretEnv: "KA_SSO_SECRET_JOB_KA",
74 + },
70 75 "api-ka": {
71 76 label: "API·Ka",
72 77 redirectPrefixes: ["https://www.api-ka.com/", "http://localhost:8000/"],
73 78