SPB Git

spb/crea-ka

Public

Créa·Ka — annuaire public cross-plateforme des créateurs de contenu québécois (crea-ka.com)

crea-ka: couverture 13 plateformes (Apify) + refresh auto 7j + max-parallélisme

- +patreon-apify +discord-apify (code invit sensible à la casse via URL)
- run_actor_sharded : N runs parallèles (défaut 32x2Go), retry+jitter, hook target_of
- rotation hebdo (APIFY_REVISIT_DAYS=7) : le watch PM2 quotidien couvre tout le bassin en <=7j
- +tavily-seed (1271 graines moissonnées) +snowball-ig (related_profiles) pour lexpansion
- frontend : stats/badges/contenu récent par plateforme

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Simon-Pierre Boucher committed (Aug 18, 2026) parent 7f300ef Browse files

44 changed files +2,211 −217

44 changed files
Unified Split
modified creaka/connectors/apify_social.py +150 −37
@@ -27,7 +27,9 @@ Uniquement des profils PUBLICS (§15) ; un profil privé/introuvable est ignoré
27 from __future__ import annotations 27 from __future__ import annotations
28 28
29 import os 29 import os
30+import random
30 import time 31 import time
32+from concurrent.futures import ThreadPoolExecutor, as_completed
31 from datetime import datetime, timedelta, timezone 33 from datetime import datetime, timedelta, timezone
32 34
33 import requests 35 import requests
@@ -42,34 +44,60 @@ APIFY_API = "https://api.apify.com/v2"
42 ACTOR_OWNER = "gorgeous_thistle" 44 ACTOR_OWNER = "gorgeous_thistle"
43 RESIDENTIAL = {"useApifyProxy": True, "apifyProxyGroups": ["RESIDENTIAL"]} 45 RESIDENTIAL = {"useApifyProxy": True, "apifyProxyGroups": ["RESIDENTIAL"]}
44 46
45− 47+# --- parallélisme : on dispose de 256 Go de RAM Apify → au lieu d'UN run à
46−def run_actor(name: str, run_input: dict, *, timeout_s: int = 2400, 48+# 1 Go, on éclate le lot en tranches lancées EN PARALLÈLE, chacune avec plus de
47− memory_mb: int = 1024) -> list[dict]: 49+# mémoire (donc plus de CPU/vCPU côté Apify) et une concurrence interne accrue.
48− """Lance un acteur KA sur Apify et retourne les items de son dataset. 50+# profil « max parallélisme » : ces acteurs sont I/O-bound (requêtes proxy),
49− 51+# donc BEAUCOUP de petits runs > peu de gros runs. 32 × 2 Go = 64 Go de pointe
50− Run asynchrone + polling (run-sync plafonne à 300 s, trop court pour les 52+# (large sous les 256 Go / 128 runs concurrents du plan).
51− gros lots). Le run est avorté si `timeout_s` est dépassé. 53+SHARD_SIZE = int(os.environ.get("APIFY_SHARD_SIZE", "60")) # handles / run
52− """ 54+MAX_SHARDS = int(os.environ.get("APIFY_MAX_SHARDS", "32")) # runs simultanés
55+RUN_MEMORY_MB = int(os.environ.get("APIFY_RUN_MEMORY_MB", "2048")) # /run
56+RUN_CONCURRENCY = int(os.environ.get("APIFY_RUN_CONCURRENCY", "10")) # interne (max 10)
57+# rafraîchissement : un compte est re-sondé s'il n'a pas été enrichi depuis
58+# REVISIT_DAYS jours. Le watch quotidien couvre ainsi TOUT le bassin en ≤ N j.
59+REVISIT_DAYS = int(os.environ.get("APIFY_REVISIT_DAYS", "7"))
60+
61+
62+def _token() -> str:
53 token = os.environ.get("APIFY_TOKEN") 63 token = os.environ.get("APIFY_TOKEN")
54 if not token: 64 if not token:
55 raise SkipSource("APIFY_TOKEN manquant (voir .env)") 65 raise SkipSource("APIFY_TOKEN manquant (voir .env)")
56− headers = {"Authorization": f"Bearer {token}"} 66+ return token
57− resp = requests.post( 67+
58− f"{APIFY_API}/acts/{ACTOR_OWNER}~{name}/runs", 68+
59− json=run_input, headers=headers, 69+def _launch(name: str, run_input: dict, memory_mb: int,
60− params={"memory": memory_mb}, timeout=60) 70+ retries: int = 6) -> str:
71+ """Démarre un run. Retry sur 400/429 (limite mémoire concurrente atteinte :
72+ elle se libère quand d'autres tranches terminent) avec backoff."""
73+ headers = {"Authorization": f"Bearer {_token()}"}
74+ for attempt in range(retries):
75+ resp = requests.post(
76+ f"{APIFY_API}/acts/{ACTOR_OWNER}~{name}/runs",
77+ json=run_input, headers=headers,
78+ params={"memory": memory_mb}, timeout=60)
79+ if resp.status_code in (400, 429, 402) or resp.status_code >= 500:
80+ if attempt < retries - 1:
81+ # backoff + jitter : désynchronise les tranches (évite le
82+ # lockstep où toutes redemandent la RAM au même instant)
83+ time.sleep(min(60, 8 * (attempt + 1)) + random.uniform(0, 6))
84+ continue
85+ resp.raise_for_status()
86+ return resp.json()["data"]["id"]
61 resp.raise_for_status() 87 resp.raise_for_status()
62− run_id = resp.json()["data"]["id"] 88+ return resp.json()["data"]["id"]
89+
90+
91+def _await_items(run_id: str, name: str, timeout_s: int) -> list[dict]:
92+ headers = {"Authorization": f"Bearer {_token()}"}
63 t0 = time.time() 93 t0 = time.time()
64− status: dict = {}
65 while True: 94 while True:
66 time.sleep(15) 95 time.sleep(15)
67 r = requests.get(f"{APIFY_API}/actor-runs/{run_id}", 96 r = requests.get(f"{APIFY_API}/actor-runs/{run_id}",
68 headers=headers, timeout=60) 97 headers=headers, timeout=60)
69 r.raise_for_status() 98 r.raise_for_status()
70 status = r.json()["data"] 99 status = r.json()["data"]
71− if status["status"] in ("SUCCEEDED", "FAILED", "ABORTED", 100+ if status["status"] in ("SUCCEEDED", "FAILED", "ABORTED", "TIMED-OUT"):
72− "TIMED-OUT"):
73 break 101 break
74 if time.time() - t0 > timeout_s: 102 if time.time() - t0 > timeout_s:
75 requests.post(f"{APIFY_API}/actor-runs/{run_id}/abort", 103 requests.post(f"{APIFY_API}/actor-runs/{run_id}/abort",
@@ -93,24 +121,68 @@ def run_actor(name: str, run_input: dict, *, timeout_s: int = 2400,
93 offset += 1000 121 offset += 1000
94 122
95 123
124+def run_actor(name: str, run_input: dict, *, timeout_s: int = 2400,
125+ memory_mb: int = RUN_MEMORY_MB) -> list[dict]:
126+ """Un seul run (recherche, petit lot)."""
127+ return _await_items(_launch(name, run_input, memory_mb), name, timeout_s)
128+
129+
130+def run_actor_sharded(name: str, base_input: dict, usernames: list[str], *,
131+ timeout_s: int = 2400,
132+ shard_size: int = SHARD_SIZE,
133+ max_shards: int = MAX_SHARDS,
134+ memory_mb: int = RUN_MEMORY_MB) -> list[dict]:
135+ """Éclate `usernames` en tranches lancées EN PARALLÈLE sur Apify.
136+
137+ Chaque tranche = un run indépendant (mémoire dédiée → plus de CPU). On
138+ plafonne à `max_shards` runs simultanés (256 Go de RAM = large marge :
139+ 12 × 4 Go = 48 Go). Les datasets sont fusionnés. Une tranche qui échoue
140+ n'annule pas les autres.
141+ """
142+ if not usernames:
143+ return []
144+ n = max(1, min(max_shards,
145+ (len(usernames) + shard_size - 1) // shard_size))
146+ shards = [usernames[i::n] for i in range(n)] # répartition équilibrée
147+ items: list[dict] = []
148+ with ThreadPoolExecutor(max_workers=n) as pool:
149+ futs = {pool.submit(run_actor, name,
150+ {**base_input, "usernames": shard},
151+ timeout_s=timeout_s, memory_mb=memory_mb): i
152+ for i, shard in enumerate(shards) if shard}
153+ for fut in as_completed(futs):
154+ try:
155+ items.extend(fut.result())
156+ except Exception as exc: # une tranche morte ne bloque pas le reste
157+ print(f"[crea-ka] {name} tranche {futs[fut]} échouée : {exc}")
158+ return items
159+
160+
96 class _ApifySocialEnrich(BaseConnector): 161 class _ApifySocialEnrich(BaseConnector):
97 """Base commune des enrichissements Apify (un acteur par plateforme).""" 162 """Base commune des enrichissements Apify (un acteur par plateforme)."""
98 163
99 kind = "enrichment" 164 kind = "enrichment"
100 platform = "" # plateforme canonique (§6.2) 165 platform = "" # plateforme canonique (§6.2)
101 actor = "" # nom court de l'acteur (ka-instagram…) 166 actor = "" # nom court de l'acteur (ka-instagram…)
102− cap = 300 # comptes max par run (maîtrise du coût) 167+ cap = 3000 # comptes max par passage (shardé en parallèle)
103− revisit_days = 5 # ne pas re-sonder un compte plus frais que ça 168+ revisit_days = REVISIT_DAYS # re-sonde hebdo par défaut (env APIFY_REVISIT_DAYS)
104 content_key = "" # clé du contenu récent dans l'item acteur 169 content_key = "" # clé du contenu récent dans l'item acteur
105 # clés d'item copiées telles quelles dans account.metrics si non nulles 170 # clés d'item copiées telles quelles dans account.metrics si non nulles
106 metric_map: dict[str, str] = {} 171 metric_map: dict[str, str] = {}
107 172
173+ @property
174+ def _stamp_key(self) -> str:
175+ # tampon PROPRE au connecteur : quand CE connecteur a enrichi ce compte.
176+ # On ne se base PAS sur acc.last_checked, re-tamponné par la découverte
177+ # (kick-decouverte etc.) même sans enrichissement → fausse fraîcheur.
178+ return f"{self.source_id}_at"
179+
108 def _stale(self, acc) -> bool: 180 def _stale(self, acc) -> bool:
109− if not acc.last_checked: 181+ stamp = (acc.metrics or {}).get(self._stamp_key)
182+ if not stamp:
110 return True 183 return True
111 try: 184 try:
112− seen = datetime.fromisoformat( 185+ seen = datetime.fromisoformat(str(stamp).replace("Z", "+00:00"))
113− acc.last_checked.replace("Z", "+00:00"))
114 except ValueError: 186 except ValueError:
115 return True 187 return True
116 return (datetime.now(timezone.utc) - seen 188 return (datetime.now(timezone.utc) - seen
@@ -119,6 +191,16 @@ class _ApifySocialEnrich(BaseConnector):
119 def extra_input(self) -> dict: 191 def extra_input(self) -> dict:
120 return {} 192 return {}
121 193
194+ def target_of(self, acc) -> str:
195+ """Valeur envoyée à l'acteur pour ce compte (défaut : le handle).
196+
197+ Certaines plateformes exigent autre chose que le handle minusculé —
198+ ex. Discord, dont le code d'invitation est SENSIBLE À LA CASSE et doit
199+ être repris depuis l'URL. Le rapprochement se fait ensuite en
200+ minuscules des deux côtés.
201+ """
202+ return acc.handle
203+
122 def enrich(self, creators: list[Creator]) -> list[Creator]: 204 def enrich(self, creators: list[Creator]) -> list[Creator]:
123 targets: dict[str, list] = {} 205 targets: dict[str, list] = {}
124 for cr in creators: 206 for cr in creators:
@@ -126,22 +208,23 @@ class _ApifySocialEnrich(BaseConnector):
126 if a.platform == self.platform and a.handle), None) 208 if a.platform == self.platform and a.handle), None)
127 if acc is None or not self._stale(acc): 209 if acc is None or not self._stale(acc):
128 continue 210 continue
129− targets.setdefault(acc.handle, []).append((cr, acc)) 211+ targets.setdefault(self.target_of(acc), []).append((cr, acc))
130 if len(targets) >= self.cap: 212 if len(targets) >= self.cap:
131 break 213 break
132 if not targets: 214 if not targets:
133 return [] 215 return []
134− items = run_actor(self.actor, { 216+ items = run_actor_sharded(
135− "usernames": sorted(targets), 217+ self.actor,
136− "proxyConfiguration": RESIDENTIAL, 218+ {"proxyConfiguration": RESIDENTIAL,
137− **self.extra_input(), 219+ "concurrency": RUN_CONCURRENCY,
138− }) 220+ **self.extra_input()},
221+ sorted(targets))
139 by_handle = {str(it.get("username") or "").lower(): it 222 by_handle = {str(it.get("username") or "").lower(): it
140 for it in items if it.get("kind") == "profile"} 223 for it in items if it.get("kind") == "profile"}
141 enriched: list[Creator] = [] 224 enriched: list[Creator] = []
142 self.errors = 0 225 self.errors = 0
143 for handle, pairs in targets.items(): 226 for handle, pairs in targets.items():
144− it = by_handle.get(handle) 227+ it = by_handle.get(handle.lower())
145 if it is None: 228 if it is None:
146 continue 229 continue
147 if not it.get("found"): 230 if not it.get("found"):
@@ -163,6 +246,7 @@ class _ApifySocialEnrich(BaseConnector):
163 if it.get(src) is not None} 246 if it.get(src) is not None}
164 if self.content_key and it.get(self.content_key): 247 if self.content_key and it.get(self.content_key):
165 metrics[self.content_key] = it[self.content_key][:12] 248 metrics[self.content_key] = it[self.content_key][:12]
249+ metrics[self._stamp_key] = now_iso() # tampon d'enrichissement propre
166 acc.metrics.update(metrics) 250 acc.metrics.update(metrics)
167 if not cr.avatar_url and it.get("avatar"): 251 if not cr.avatar_url and it.get("avatar"):
168 cr.avatar_url = it["avatar"] 252 cr.avatar_url = it["avatar"]
@@ -195,7 +279,7 @@ class ApifyInstagram(_ApifySocialEnrich):
195 source_id = "instagram-apify" 279 source_id = "instagram-apify"
196 platform = "instagram" 280 platform = "instagram"
197 actor = "ka-instagram" 281 actor = "ka-instagram"
198− cap = 400 282+ cap = 1800
199 content_key = "recent_posts" 283 content_key = "recent_posts"
200 metric_map = {"following": "following", "posts_count": "posts", 284 metric_map = {"following": "following", "posts_count": "posts",
201 "category": "category", "is_business": "is_business", 285 "category": "category", "is_business": "is_business",
@@ -224,7 +308,7 @@ class ApifyTikTok(_ApifySocialEnrich):
224 source_id = "tiktok-apify" 308 source_id = "tiktok-apify"
225 platform = "tiktok" 309 platform = "tiktok"
226 actor = "ka-tiktok" 310 actor = "ka-tiktok"
227− cap = 300 311+ cap = 1800
228 content_key = "recent_videos" 312 content_key = "recent_videos"
229 metric_map = {"following": "following", "total_likes": "likes", 313 metric_map = {"following": "following", "total_likes": "likes",
230 "videos_count": "videos", "region": "region", 314 "videos_count": "videos", "region": "region",
@@ -245,7 +329,7 @@ class ApifyX(_ApifySocialEnrich):
245 source_id = "x-apify" 329 source_id = "x-apify"
246 platform = "x" 330 platform = "x"
247 actor = "ka-x" 331 actor = "ka-x"
248− cap = 300 332+ cap = 1800
249 content_key = "recent_tweets" 333 content_key = "recent_tweets"
250 metric_map = {"following": "following", "tweets_count": "tweets", 334 metric_map = {"following": "following", "tweets_count": "tweets",
251 "location": "location", "created_at": "created_at", 335 "location": "location", "created_at": "created_at",
@@ -269,7 +353,7 @@ class ApifyFacebook(_ApifySocialEnrich):
269 source_id = "facebook-apify" 353 source_id = "facebook-apify"
270 platform = "facebook" 354 platform = "facebook"
271 actor = "ka-facebook" 355 actor = "ka-facebook"
272− cap = 100 356+ cap = 400
273 revisit_days = 7 357 revisit_days = 7
274 metric_map = {"category": "category"} 358 metric_map = {"category": "category"}
275 359
@@ -306,7 +390,7 @@ class ApifyYouTube(_ApifySocialEnrich):
306 source_id = "youtube-apify" 390 source_id = "youtube-apify"
307 platform = "youtube" 391 platform = "youtube"
308 actor = "ka-youtube" 392 actor = "ka-youtube"
309− cap = 300 393+ cap = 1800
310 content_key = "recent_videos" 394 content_key = "recent_videos"
311 metric_map = {"videos_count": "videos", "country": "country", 395 metric_map = {"videos_count": "videos", "country": "country",
312 "keywords": "keywords", "channel_id": "channel_id", 396 "keywords": "keywords", "channel_id": "channel_id",
@@ -318,7 +402,7 @@ class ApifyTwitch(_ApifySocialEnrich):
318 source_id = "twitch-apify" 402 source_id = "twitch-apify"
319 platform = "twitch" 403 platform = "twitch"
320 actor = "ka-twitch" 404 actor = "ka-twitch"
321− cap = 300 405+ cap = 1200
322 content_key = "recent_videos" 406 content_key = "recent_videos"
323 metric_map = {"is_partner": "is_partner", "is_affiliate": "is_affiliate", 407 metric_map = {"is_partner": "is_partner", "is_affiliate": "is_affiliate",
324 "team": "team", "created_at": "created_at", 408 "team": "team", "created_at": "created_at",
@@ -334,7 +418,7 @@ class ApifyKick(_ApifySocialEnrich):
334 source_id = "kick-apify" 418 source_id = "kick-apify"
335 platform = "kick" 419 platform = "kick"
336 actor = "ka-kick" 420 actor = "ka-kick"
337− cap = 120 421+ cap = 600
338 metric_map = {"is_live_now": "is_live_now", "live_viewers": "live_viewers", 422 metric_map = {"is_live_now": "is_live_now", "live_viewers": "live_viewers",
339 "subscription_enabled": "subscription_enabled", 423 "subscription_enabled": "subscription_enabled",
340 "recent_categories": "recent_categories"} 424 "recent_categories": "recent_categories"}
@@ -381,13 +465,42 @@ class ApifyFansly(_ApifySocialEnrich):
381 source_id = "fansly-apify" 465 source_id = "fansly-apify"
382 platform = "fansly" 466 platform = "fansly"
383 actor = "ka-fansly" 467 actor = "ka-fansly"
384− cap = 200 468+ cap = 600
385 revisit_days = 7 469 revisit_days = 7
386 metric_map = {"posts_count": "posts", "images_count": "images", 470 metric_map = {"posts_count": "posts", "images_count": "images",
387 "videos_count": "videos", "likes": "likes", 471 "videos_count": "videos", "likes": "likes",
388 "following": "following", "location": "location"} 472 "following": "following", "location": "location"}
389 473
390 474
475+class ApifyPatreon(_ApifySocialEnrich):
476+ source_id = "patreon-apify"
477+ platform = "patreon"
478+ actor = "ka-patreon"
479+ cap = 400
480+ revisit_days = 7
481+ metric_map = {"patrons": "patrons", "posts_count": "posts",
482+ "is_monthly": "is_monthly"}
483+
484+
485+class ApifyDiscord(_ApifySocialEnrich):
486+ source_id = "discord-apify"
487+ platform = "discord"
488+ actor = "ka-discord"
489+ cap = 400
490+ revisit_days = 7
491+ metric_map = {"members": "members", "online": "online", "boosts": "boosts",
492+ "partnered": "partnered", "guild_id": "guild_id"}
493+
494+ def target_of(self, acc) -> str:
495+ """Code d'invitation SENSIBLE À LA CASSE, repris de l'URL (pas du
496+ handle minusculé) : discord.gg/<CODE> ou discord.com/invite/<CODE>."""
497+ url = acc.url or ""
498+ for sep in ("discord.gg/", "discord.com/invite/", "/invite/"):
499+ if sep in url:
500+ return url.split(sep, 1)[1].split("/")[0].split("?")[0]
501+ return acc.handle
502+
503+
391 # --- découverte Instagram (topsearch, mots-clés QC) --------------------------- 504 # --- découverte Instagram (topsearch, mots-clés QC) ---------------------------
392 505
393 # thèmes × marqueurs QC — mêmes familles que youtube-recherche, adaptées à la 506 # thèmes × marqueurs QC — mêmes familles que youtube-recherche, adaptées à la
added creaka/connectors/snowball.py +75 −0
@@ -0,0 +1,75 @@
1+# ==============================================================================
2+# Author: Simon-Pierre Boucher <contact@spboucher.ai>
3+# File: creaka/connectors/snowball.py
4+# Desc: Connecteur DÉCOUVERTE par boule de neige — exploite les profils
5+# reliés (`related_profiles`) captés par l'enrichissement Instagram
6+# (instagram-apify) pour créer de nouvelles fiches. C'est le levier
7+# d'échelle : chaque profil IG suggère ~10-20 comptes similaires →
8+# parcours en largeur qui fait croître le bassin de dizaines de milliers
9+# au fil des vagues quotidiennes. Aucune requête réseau (lit la base).
10+# ==============================================================================
11+"""Découverte par boule de neige sur les profils reliés Instagram.
12+
13+Déclaré `enrichment` pour recevoir la liste des créateurs existants, mais il
14+RETOURNE de NOUVELLES fiches (le pipeline sync_source les ajoute par uid). On
15+lit `account.metrics["related_profiles"]` (posé par instagram-apify), on écarte
16+les handles déjà connus, et on crée une graine par nouveau compte suggéré.
17+Signal `mention` (0.60) : proximité algorithmique, à confirmer par
18+l'enrichissement — sous le seuil de publication tant que non vérifié (§12.1).
19+"""
20+from __future__ import annotations
21+
22+from ..identity import account
23+from ..normalize import canonical_url
24+from ..schema import Creator
25+from .base import BaseConnector
26+
27+
28+class SnowballConnector(BaseConnector):
29+ source_id = "snowball-ig"
30+ kind = "enrichment"
31+ max_new = 4000 # garde-fou par vague
32+
33+ def enrich(self, creators: list[Creator]) -> list[Creator]:
34+ known: set[str] = set()
35+ for cr in creators:
36+ for a in cr.platforms:
37+ if a.platform == "instagram":
38+ known.add(a.handle)
39+ new: list[Creator] = []
40+ emitted: set[str] = set()
41+ for cr in creators:
42+ ig = next((a for a in cr.platforms
43+ if a.platform == "instagram"), None)
44+ if ig is None:
45+ continue
46+ for rel in (ig.metrics or {}).get("related_profiles", []) or []:
47+ handle = (rel.get("username") if isinstance(rel, dict)
48+ else rel)
49+ handle = (handle or "").strip().lstrip("@").lower()
50+ if (not handle or rel and isinstance(rel, dict)
51+ and rel.get("is_private")):
52+ continue
53+ if handle in known or handle in emitted:
54+ continue
55+ emitted.add(handle)
56+ try:
57+ acc = account("instagram", handle, "mention",
58+ url=canonical_url("instagram", handle),
59+ verified=(rel.get("is_verified")
60+ if isinstance(rel, dict)
61+ else None)).finalize()
62+ except Exception:
63+ continue
64+ name = (rel.get("full_name") if isinstance(rel, dict)
65+ else None) or handle
66+ new.append(Creator(
67+ source=self.source_id,
68+ external_id=f"instagram:{handle}",
69+ display_name=name,
70+ platforms=[acc],
71+ notes="découvert par boule de neige (profils reliés IG)",
72+ ))
73+ if len(new) >= self.max_new:
74+ return new
75+ return new
added creaka/connectors/tavily_seed.py +71 −0
@@ -0,0 +1,71 @@
1+# ==============================================================================
2+# Author: Simon-Pierre Boucher <contact@spboucher.ai>
3+# File: creaka/connectors/tavily_seed.py
4+# Desc: Connecteur DÉCOUVERTE à grande échelle — graines de créateurs
5+# québécois moissonnées par le Tavily scout (outils/creator-harvest.py
6+# du dépôt groupe-ka-connecteurs) : handles sociaux extraits des pages
7+# d'annuaires/palmarès/agences QC. Dataset local (aucune requête ici) :
8+# data/seed/qc_creator_seeds.jsonl. L'enrichissement (Apify) vérifie
9+# ensuite l'existence et remplit nom/abonnés/contenu.
10+# ==============================================================================
11+"""Découverte massive par moisson web (Tavily).
12+
13+Chaque ligne du seed = `{"platform": "...", "handle": "..."}`. On crée une
14+fiche par handle avec un compte de plateforme (signal `listes_medias` 0.85 :
15+issu de listes publiques concordantes). Les handles qui n'existent pas seront
16+simplement non enrichis (found=false côté Apify) ; un balayage d'archivage
17+retire à terme les fiches jamais confirmées. But : élargir le bassin de
18+créateurs de plusieurs milliers par vague, sans requête réseau à ce stade.
19+"""
20+from __future__ import annotations
21+
22+import json
23+from pathlib import Path
24+
25+from ..identity import account
26+from ..normalize import canonical_url
27+from ..schema import Creator
28+from .base import BaseConnector
29+
30+SEED_PATH = (Path(__file__).resolve().parent.parent.parent
31+ / "data" / "seed" / "qc_creator_seeds.jsonl")
32+
33+
34+class TavilySeedConnector(BaseConnector):
35+ source_id = "tavily-seed"
36+ kind = "discovery"
37+
38+ def fetch(self) -> list[Creator]:
39+ if not SEED_PATH.exists():
40+ return [] # pas encore de moisson : passage vide, pas d'erreur
41+ creators: list[Creator] = []
42+ seen: set[str] = set()
43+ for line in SEED_PATH.read_text(encoding="utf-8").splitlines():
44+ line = line.strip()
45+ if not line:
46+ continue
47+ try:
48+ row = json.loads(line)
49+ except json.JSONDecodeError:
50+ continue
51+ platform = (row.get("platform") or "").strip().lower()
52+ handle = (row.get("handle") or "").strip().lstrip("@").lower()
53+ if not platform or not handle:
54+ continue
55+ key = f"{platform}:{handle}"
56+ if key in seen:
57+ continue
58+ seen.add(key)
59+ try:
60+ acc = account(platform, handle, "listes_medias",
61+ url=canonical_url(platform, handle)).finalize()
62+ except Exception:
63+ continue
64+ creators.append(Creator(
65+ source=self.source_id,
66+ external_id=key,
67+ display_name=handle, # nom réel rempli à l'enrichissement
68+ platforms=[acc],
69+ notes="découvert par moisson web Tavily (annuaires/palmarès QC)",
70+ ))
71+ return creators
modified creaka/ingest.py +2 −2
@@ -30,10 +30,10 @@ from .dedup import dedupe
30 # ordre d'exécution des connecteurs d'enrichissement — link-in-bio vers la 30 # ordre d'exécution des connecteurs d'enrichissement — link-in-bio vers la
31 # fin (il consomme les link_in_bio_url des étapes précédentes) ; bio-liens en 31 # fin (il consomme les link_in_bio_url des étapes précédentes) ; bio-liens en
32 # tout dernier (il relit les bios enrichies, sans aucune requête) 32 # tout dernier (il relit les bios enrichies, sans aucune requête)
33−ENRICH_ORDER = ["instagram-apify", "tiktok-apify", "x-apify", 33+ENRICH_ORDER = ["instagram-apify", "snowball-ig", "tiktok-apify", "x-apify",
34 "facebook-apify", "threads-apify", "snapchat-apify", 34 "facebook-apify", "threads-apify", "snapchat-apify",
35 "youtube-apify", "twitch-apify", "kick-apify", 35 "youtube-apify", "twitch-apify", "kick-apify",
36− "fansly-apify", 36+ "fansly-apify", "patreon-apify", "discord-apify",
37 "instagram-profil", "tiktok-profil", "youtube", "twitch", 37 "instagram-profil", "tiktok-profil", "youtube", "twitch",
38 "x-profil", "balados-rss", "podcastindex", 38 "x-profil", "balados-rss", "podcastindex",
39 "link-in-bio", "bio-liens", "region-bio"] 39 "link-in-bio", "bio-liens", "region-bio"]
added data/seed/qc_creator_seeds.jsonl +1271 −0
@@ -0,0 +1,1271 @@
1+{"platform": "instagram", "handle": "ppscanada"}
2+{"platform": "instagram", "handle": "engageunhumoriste"}
3+{"platform": "youtube", "handle": "engageunhumoriste"}
4+{"platform": "x", "handle": "etiennefg"}
5+{"platform": "instagram", "handle": "etiennefg"}
6+{"platform": "x", "handle": "icircpremiere"}
7+{"platform": "x", "handle": "lexpresstoronto"}
8+{"platform": "instagram", "handle": "journal_larotonde"}
9+{"platform": "x", "handle": "larotonde"}
10+{"platform": "x", "handle": "historicacanada"}
11+{"platform": "instagram", "handle": "levraijodion"}
12+{"platform": "instagram", "handle": "evelyne.r.m"}
13+{"platform": "x", "handle": "onfr_tfo"}
14+{"platform": "x", "handle": "icirctele"}
15+{"platform": "x", "handle": "radiocanadainfo"}
16+{"platform": "instagram", "handle": "_lebalbuzard"}
17+{"platform": "instagram", "handle": "lecourrierdelanouvelleecosse"}
18+{"platform": "tiktok", "handle": "le.courrier"}
19+{"platform": "youtube", "handle": "lecourrierdelanouvelle-ecosse"}
20+{"platform": "x", "handle": "courrierne1937"}
21+{"platform": "twitch", "handle": "montreal"}
22+{"platform": "twitch", "handle": "events"}
23+{"platform": "instagram", "handle": "seb.lerouxx"}
24+{"platform": "instagram", "handle": "amealbert_"}
25+{"platform": "instagram", "handle": "nu.skin____"}
26+{"platform": "instagram", "handle": "erzu.lie"}
27+{"platform": "instagram", "handle": "canada.council"}
28+{"platform": "tiktok", "handle": "cbcmontreal"}
29+{"platform": "instagram", "handle": "6000mhz"}
30+{"platform": "tiktok", "handle": "lp_lapresse"}
31+{"platform": "x", "handle": "lp_lapresse"}
32+{"platform": "twitch", "handle": "xqc"}
33+{"platform": "x", "handle": "cache"}
34+{"platform": "twitch", "handle": "dominic"}
35+{"platform": "twitch", "handle": "zhartan"}
36+{"platform": "twitch", "handle": "p4sc4l"}
37+{"platform": "twitch", "handle": "th0ny"}
38+{"platform": "twitch", "handle": "marhados"}
39+{"platform": "twitch", "handle": "thelfus"}
40+{"platform": "twitch", "handle": "corstrix"}
41+{"platform": "instagram", "handle": "mathieupellerin"}
42+{"platform": "instagram", "handle": "papimelv"}
43+{"platform": "twitch", "handle": "gfz_parfait"}
44+{"platform": "instagram", "handle": "lewislefou"}
45+{"platform": "instagram", "handle": "cocottee"}
46+{"platform": "instagram", "handle": "elijah"}
47+{"platform": "instagram", "handle": "shahinouest"}
48+{"platform": "instagram", "handle": "gfz.parfait"}
49+{"platform": "instagram", "handle": "alybrassard"}
50+{"platform": "instagram", "handle": "achillefps"}
51+{"platform": "instagram", "handle": "arnaud.od"}
52+{"platform": "instagram", "handle": "commuquebec"}
53+{"platform": "twitch", "handle": "directory"}
54+{"platform": "twitch", "handle": "commuquebec"}
55+{"platform": "x", "handle": "commuquebec"}
56+{"platform": "instagram", "handle": "lelobby.lotoquebec"}
57+{"platform": "youtube", "handle": "lelobby-lotoquebec"}
58+{"platform": "twitch", "handle": "lotoquebec"}
59+{"platform": "twitch", "handle": "acegamersam"}
60+{"platform": "twitch", "handle": "alsenic"}
61+{"platform": "twitch", "handle": "annamoonz"}
62+{"platform": "twitch", "handle": "araashi_"}
63+{"platform": "twitch", "handle": "ashtaal"}
64+{"platform": "twitch", "handle": "avecsimon"}
65+{"platform": "twitch", "handle": "bastienart"}
66+{"platform": "twitch", "handle": "lebergy"}
67+{"platform": "twitch", "handle": "bethlame"}
68+{"platform": "twitch", "handle": "bubblymarie"}
69+{"platform": "twitch", "handle": "cafeinelau"}
70+{"platform": "twitch", "handle": "camgrandebrune"}
71+{"platform": "twitch", "handle": "canellotv"}
72+{"platform": "twitch", "handle": "capt_n_bill"}
73+{"platform": "twitch", "handle": "charest"}
74+{"platform": "twitch", "handle": "charlene"}
75+{"platform": "x", "handle": "fr"}
76+{"platform": "instagram", "handle": "chanou__"}
77+{"platform": "instagram", "handle": "lychesrychee"}
78+{"platform": "instagram", "handle": "thesonofhan"}
79+{"platform": "instagram", "handle": "itzkevtvv"}
80+{"platform": "instagram", "handle": "collabstr"}
81+{"platform": "tiktok", "handle": "collabstr.com"}
82+{"platform": "instagram", "handle": "heyraion"}
83+{"platform": "instagram", "handle": "dwyane101"}
84+{"platform": "instagram", "handle": "kevinhana_"}
85+{"platform": "instagram", "handle": "itslemonsquares"}
86+{"platform": "instagram", "handle": "cadiegrace"}
87+{"platform": "instagram", "handle": "awkventurer"}
88+{"platform": "instagram", "handle": "babyybaconator"}
89+{"platform": "instagram", "handle": "rychee"}
90+{"platform": "instagram", "handle": "farhadxray"}
91+{"platform": "instagram", "handle": "katbyday"}
92+{"platform": "instagram", "handle": "ermillyy"}
93+{"platform": "instagram", "handle": "thechocolatecanvas"}
94+{"platform": "instagram", "handle": "queenglitterchaos"}
95+{"platform": "instagram", "handle": "yeaitsmt"}
96+{"platform": "instagram", "handle": "reaperky7"}
97+{"platform": "instagram", "handle": "villanarei"}
98+{"platform": "instagram", "handle": "ggria"}
99+{"platform": "instagram", "handle": "itsbenmalka"}
100+{"platform": "instagram", "handle": "chanou"}
101+{"platform": "instagram", "handle": "kevinhana"}
102+{"platform": "instagram", "handle": "ogrobinson10"}
103+{"platform": "instagram", "handle": "marcelo"}
104+{"platform": "instagram", "handle": "shinanova"}
105+{"platform": "instagram", "handle": "victoriacharlton"}
106+{"platform": "instagram", "handle": "oliprimeau"}
107+{"platform": "instagram", "handle": "lysandrenadeau"}
108+{"platform": "instagram", "handle": "enola.bedard"}
109+{"platform": "instagram", "handle": "sj.bleau"}
110+{"platform": "instagram", "handle": "laurent.dagenais"}
111+{"platform": "instagram", "handle": "aliciamoffet"}
112+{"platform": "instagram", "handle": "olivierprimeaubc"}
113+{"platform": "instagram", "handle": "elisabethrioux"}
114+{"platform": "instagram", "handle": "lefitcook"}
115+{"platform": "instagram", "handle": "claudiemercier_"}
116+{"platform": "instagram", "handle": "marc_fitt"}
117+{"platform": "instagram", "handle": "victoria.charlton"}
118+{"platform": "instagram", "handle": "maxgourgues"}
119+{"platform": "instagram", "handle": "lucierheaume"}
120+{"platform": "instagram", "handle": "rosalielessard_"}
121+{"platform": "tiktok", "handle": "enola.bedard"}
122+{"platform": "tiktok", "handle": "sjbleau"}
123+{"platform": "tiktok", "handle": "laurent.dagenais"}
124+{"platform": "tiktok", "handle": "shinanova"}
125+{"platform": "tiktok", "handle": "aliciamoffet"}
126+{"platform": "tiktok", "handle": "oliprimeau"}
127+{"platform": "tiktok", "handle": "lysandrenadeau"}
128+{"platform": "tiktok", "handle": "elisabeth.rioux"}
129+{"platform": "tiktok", "handle": "lefitcook"}
130+{"platform": "tiktok", "handle": "claudiemercier"}
131+{"platform": "tiktok", "handle": "victoriacharltonn"}
132+{"platform": "tiktok", "handle": "maxgourgues"}
133+{"platform": "tiktok", "handle": "lucie_rheaume"}
134+{"platform": "tiktok", "handle": "rosalielessard_"}
135+{"platform": "youtube", "handle": "enola.bedard"}
136+{"platform": "youtube", "handle": "sjbleau"}
137+{"platform": "youtube", "handle": "laurentdagenais"}
138+{"platform": "youtube", "handle": "shinanovayt"}
139+{"platform": "youtube", "handle": "aliciamoffetchannel"}
140+{"platform": "youtube", "handle": "olivierprimeau"}
141+{"platform": "youtube", "handle": "lysandrenadeau"}
142+{"platform": "youtube", "handle": "elisabethrioux7657"}
143+{"platform": "youtube", "handle": "lefitcook"}
144+{"platform": "youtube", "handle": "claudiemercier"}
145+{"platform": "youtube", "handle": "marcfitt"}
146+{"platform": "youtube", "handle": "victoriacharlton"}
147+{"platform": "youtube", "handle": "maxgourgues7062"}
148+{"platform": "youtube", "handle": "lucierheaume6512"}
149+{"platform": "youtube", "handle": "rosalielessardd"}
150+{"platform": "instagram", "handle": "sjbleau"}
151+{"platform": "instagram", "handle": "elisabeth.rioux"}
152+{"platform": "instagram", "handle": "claudiemercier"}
153+{"platform": "instagram", "handle": "marcfitt"}
154+{"platform": "instagram", "handle": "lucie"}
155+{"platform": "instagram", "handle": "rosalielessard"}
156+{"platform": "twitch", "handle": "quebec"}
157+{"platform": "twitch", "handle": "twitch"}
158+{"platform": "twitch", "handle": "assets"}
159+{"platform": "twitch", "handle": "videos"}
160+{"platform": "twitch", "handle": "inlacrimaelacrima"}
161+{"platform": "twitch", "handle": "acadianwoman"}
162+{"platform": "twitch", "handle": "alisonator"}
163+{"platform": "tiktok", "handle": "alisonation"}
164+{"platform": "twitch", "handle": "acadie"}
165+{"platform": "twitch", "handle": "acadiestream"}
166+{"platform": "x", "handle": "foxacadian"}
167+{"platform": "instagram", "handle": "foxacadian"}
168+{"platform": "instagram", "handle": "xboxuk"}
169+{"platform": "instagram", "handle": "noblechairs"}
170+{"platform": "instagram", "handle": "bethesda_uk"}
171+{"platform": "twitch", "handle": "acadianfox"}
172+{"platform": "x", "handle": "compose"}
173+{"platform": "x", "handle": "pixelatedvicka"}
174+{"platform": "x", "handle": "ff_xiv_en"}
175+{"platform": "x", "handle": "xboxuk"}
176+{"platform": "x", "handle": "xbox"}
177+{"platform": "x", "handle": "noblechairs"}
178+{"platform": "x", "handle": "bethesda_uk"}
179+{"platform": "x", "handle": "tos"}
180+{"platform": "x", "handle": "privacy"}
181+{"platform": "x", "handle": "articles"}
182+{"platform": "x", "handle": "resources"}
183+{"platform": "x", "handle": "en"}
184+{"platform": "instagram", "handle": "pixelatedvicka"}
185+{"platform": "instagram", "handle": "ff_xiv_en"}
186+{"platform": "instagram", "handle": "cbc"}
187+{"platform": "x", "handle": "cbc"}
188+{"platform": "tiktok", "handle": "alisonator"}
189+{"platform": "instagram", "handle": "minutemaquillage"}
190+{"platform": "instagram", "handle": "jeanfrancoiscd"}
191+{"platform": "instagram", "handle": "avedacanada"}
192+{"platform": "instagram", "handle": "virginievandelac"}
193+{"platform": "x", "handle": "vvandelac"}
194+{"platform": "instagram", "handle": "artistparmarilyn"}
195+{"platform": "tiktok", "handle": "artistparmarilyn"}
196+{"platform": "youtube", "handle": "artistparmarilyn"}
197+{"platform": "instagram", "handle": "lilirougecosmetics"}
198+{"platform": "tiktok", "handle": "lilirougecosmetics"}
199+{"platform": "instagram", "handle": "lapetitevengeance"}
200+{"platform": "instagram", "handle": "marcomarsolais"}
201+{"platform": "instagram", "handle": "aj.makeup"}
202+{"platform": "instagram", "handle": "sabiehairstylist"}
203+{"platform": "instagram", "handle": "luggageandlipstick"}
204+{"platform": "x", "handle": "luggage_lipstik"}
205+{"platform": "instagram", "handle": "bontraveler"}
206+{"platform": "instagram", "handle": "dominicpoirot"}
207+{"platform": "instagram", "handle": "lfayos"}
208+{"platform": "instagram", "handle": "loredana"}
209+{"platform": "instagram", "handle": "miss"}
210+{"platform": "instagram", "handle": "dermacureqc"}
211+{"platform": "instagram", "handle": "emmasroadmap"}
212+{"platform": "instagram", "handle": "antonioortegacouture"}
213+{"platform": "instagram", "handle": "mmodemtl"}
214+{"platform": "tiktok", "handle": "mmodemtl"}
215+{"platform": "youtube", "handle": "mmodelagrappemetropolitain4872"}
216+{"platform": "x", "handle": "linbleu"}
217+{"platform": "x", "handle": "gouvqc"}
218+{"platform": "instagram", "handle": "ellequebec"}
219+{"platform": "tiktok", "handle": "ellequebec"}
220+{"platform": "x", "handle": "ellequebec"}
221+{"platform": "instagram", "handle": "fringueefutee"}
222+{"platform": "instagram", "handle": "urbainedeschamps"}
223+{"platform": "instagram", "handle": "cestelle.ca"}
224+{"platform": "tiktok", "handle": "cestelle.ca"}
225+{"platform": "x", "handle": "cestellemode"}
226+{"platform": "instagram", "handle": "centrerockland"}
227+{"platform": "x", "handle": "centrerockland"}
228+{"platform": "instagram", "handle": "destinationnb"}
229+{"platform": "instagram", "handle": "village_acadien"}
230+{"platform": "youtube", "handle": "villagehistoriqueacadien_nb"}
231+{"platform": "instagram", "handle": "clubsportifmaa"}
232+{"platform": "instagram", "handle": "timeoutmontreal"}
233+{"platform": "instagram", "handle": "b52fit"}
234+{"platform": "instagram", "handle": "epix"}
235+{"platform": "instagram", "handle": "morphobleu.studio"}
236+{"platform": "instagram", "handle": "monstergymmtl"}
237+{"platform": "instagram", "handle": "cepsum"}
238+{"platform": "x", "handle": "cflri_icrcp"}
239+{"platform": "instagram", "handle": "econofitness"}
240+{"platform": "instagram", "handle": "jessica.b.25"}
241+{"platform": "instagram", "handle": "laulabo"}
242+{"platform": "instagram", "handle": "kaily"}
243+{"platform": "instagram", "handle": "fitnesssanteplus"}
244+{"platform": "tiktok", "handle": "fitnesssanteplus"}
245+{"platform": "instagram", "handle": "_chez_ashton_"}
246+{"platform": "instagram", "handle": "_qu"}
247+{"platform": "instagram", "handle": "_la_banquise_"}
248+{"platform": "instagram", "handle": "_le_plateau_"}
249+{"platform": "instagram", "handle": "_montr"}
250+{"platform": "instagram", "handle": "_poutineville_"}
251+{"platform": "instagram", "handle": "mywanderingvoyage"}
252+{"platform": "tiktok", "handle": "mywanderingvoyage"}
253+{"platform": "youtube", "handle": "mywanderingvoyage"}
254+{"platform": "instagram", "handle": "ontario"}
255+{"platform": "instagram", "handle": "scichefqc"}
256+{"platform": "x", "handle": "scichefqc"}
257+{"platform": "x", "handle": "francoislegault"}
258+{"platform": "instagram", "handle": "francoislegault"}
259+{"platform": "instagram", "handle": "frederiqueguay"}
260+{"platform": "x", "handle": "frederiqueguay"}
261+{"platform": "instagram", "handle": "urbanblisslife"}
262+{"platform": "tiktok", "handle": "urbanblisslife"}
263+{"platform": "x", "handle": "urbanblisslife"}
264+{"platform": "instagram", "handle": "noussommes.cafe"}
265+{"platform": "instagram", "handle": "berniebeigne"}
266+{"platform": "instagram", "handle": "lindork"}
267+{"platform": "instagram", "handle": "smithani"}
268+{"platform": "instagram", "handle": "suko287"}
269+{"platform": "instagram", "handle": "pamelinachang"}
270+{"platform": "instagram", "handle": "ginger"}
271+{"platform": "instagram", "handle": "erinbayly"}
272+{"platform": "instagram", "handle": "patisserie.coco"}
273+{"platform": "instagram", "handle": "kinkaizakayamtl"}
274+{"platform": "instagram", "handle": "raviolismaixiangyuan"}
275+{"platform": "instagram", "handle": "ottoyakitori"}
276+{"platform": "instagram", "handle": "fairmountbagel"}
277+{"platform": "instagram", "handle": "stviateurbagel"}
278+{"platform": "instagram", "handle": "bargeorgemtl"}
279+{"platform": "instagram", "handle": "lemalnecessaire"}
280+{"platform": "instagram", "handle": "lepetitdep"}
281+{"platform": "instagram", "handle": "kemcoba"}
282+{"platform": "instagram", "handle": "ladiperie"}
283+{"platform": "instagram", "handle": "zettiscremerie"}
284+{"platform": "instagram", "handle": "gibeauorangejulep"}
285+{"platform": "instagram", "handle": "restaurantaupieddecochon"}
286+{"platform": "instagram", "handle": "restaurant_cadet"}
287+{"platform": "instagram", "handle": "fiorellinosnackbar"}
288+{"platform": "instagram", "handle": "boustanrestaurant"}
289+{"platform": "instagram", "handle": "restolabanquise"}
290+{"platform": "instagram", "handle": "restobarmontrealpoutine"}
291+{"platform": "instagram", "handle": "schwartzsofficial"}
292+{"platform": "instagram", "handle": "ginger_mariah"}
293+{"platform": "instagram", "handle": "larisaopar"}
294+{"platform": "instagram", "handle": "biancaangotti"}
295+{"platform": "instagram", "handle": "jillds"}
296+{"platform": "instagram", "handle": "chels.robbins"}
297+{"platform": "instagram", "handle": "jengeegee"}
298+{"platform": "instagram", "handle": "shevonlam"}
299+{"platform": "instagram", "handle": "anisha_natalie"}
300+{"platform": "instagram", "handle": "gina._._marie"}
301+{"platform": "instagram", "handle": "dani.kuni"}
302+{"platform": "instagram", "handle": "maryannstep"}
303+{"platform": "instagram", "handle": "hopeful_li_soon"}
304+{"platform": "instagram", "handle": "fromnikiwithlove"}
305+{"platform": "instagram", "handle": "debs_wolf"}
306+{"platform": "instagram", "handle": "piggtailgirl"}
307+{"platform": "instagram", "handle": "rachelsrunway"}
308+{"platform": "instagram", "handle": "sketpicaljess"}
309+{"platform": "instagram", "handle": "justalillost"}
310+{"platform": "instagram", "handle": "elliotgaltgirl"}
311+{"platform": "instagram", "handle": "dr.neuroshannon"}
312+{"platform": "instagram", "handle": "sparrowandherbabies"}
313+{"platform": "instagram", "handle": "hiphu"}
314+{"platform": "instagram", "handle": "ansareece"}
315+{"platform": "instagram", "handle": "donopon"}
316+{"platform": "instagram", "handle": "hip_bean"}
317+{"platform": "instagram", "handle": "jaypeacee"}
318+{"platform": "instagram", "handle": "miktacular"}
319+{"platform": "instagram", "handle": "_paula.espinoza_"}
320+{"platform": "instagram", "handle": "dgordaneer"}
321+{"platform": "instagram", "handle": "pundogz"}
322+{"platform": "instagram", "handle": "anothernisha"}
323+{"platform": "instagram", "handle": "michelle835"}
324+{"platform": "instagram", "handle": "violet_pretty"}
325+{"platform": "instagram", "handle": "lillhabits"}
326+{"platform": "instagram", "handle": "habanerogal"}
327+{"platform": "instagram", "handle": "hojurific81"}
328+{"platform": "instagram", "handle": "devonhamplas"}
329+{"platform": "instagram", "handle": "dani_beee"}
330+{"platform": "instagram", "handle": "hunkaa.a"}
331+{"platform": "instagram", "handle": "adventuresofdustydoodle"}
332+{"platform": "instagram", "handle": "bestofshi"}
333+{"platform": "instagram", "handle": "asianting24"}
334+{"platform": "instagram", "handle": "shanss33"}
335+{"platform": "instagram", "handle": "miss_erin"}
336+{"platform": "instagram", "handle": "maepiq"}
337+{"platform": "instagram", "handle": "leslievarty"}
338+{"platform": "instagram", "handle": "mxmlvanity"}
339+{"platform": "instagram", "handle": "ofeliamtl2014"}
340+{"platform": "instagram", "handle": "kristenanto"}
341+{"platform": "instagram", "handle": "northernmint"}
342+{"platform": "instagram", "handle": "phoenixindacity"}
343+{"platform": "instagram", "handle": "kormachameleon"}
344+{"platform": "instagram", "handle": "liiveitout"}
345+{"platform": "instagram", "handle": "bom.yeg"}
346+{"platform": "instagram", "handle": "willing_an_abel"}
347+{"platform": "instagram", "handle": "natalie.mw"}
348+{"platform": "instagram", "handle": "jennie_fer"}
349+{"platform": "instagram", "handle": "alexandrabeley"}
350+{"platform": "instagram", "handle": "activechacha"}
351+{"platform": "instagram", "handle": "katierainboww"}
352+{"platform": "instagram", "handle": "thatjenk"}
353+{"platform": "instagram", "handle": "joannechau7"}
354+{"platform": "instagram", "handle": "globaljesus"}
355+{"platform": "instagram", "handle": "lieu.ski"}
356+{"platform": "instagram", "handle": "cup_of_josephine"}
357+{"platform": "instagram", "handle": "argenplath"}
358+{"platform": "instagram", "handle": "mig14"}
359+{"platform": "instagram", "handle": "genevieveshylo"}
360+{"platform": "tiktok", "handle": "lindorable"}
361+{"platform": "x", "handle": "lindork"}
362+{"platform": "x", "handle": "stviateurbagel"}
363+{"platform": "x", "handle": "pieddecochonmtl"}
364+{"platform": "x", "handle": "boustanmontreal"}
365+{"platform": "x", "handle": "montrealpoutine"}
366+{"platform": "instagram", "handle": "anisha"}
367+{"platform": "instagram", "handle": "gina"}
368+{"platform": "instagram", "handle": "hopeful"}
369+{"platform": "instagram", "handle": "debs"}
370+{"platform": "instagram", "handle": "rumbiman"}
371+{"platform": "instagram", "handle": "hip"}
372+{"platform": "instagram", "handle": "violet"}
373+{"platform": "instagram", "handle": "dani"}
374+{"platform": "instagram", "handle": "rwlovesfood"}
375+{"platform": "instagram", "handle": "arthursmtl"}
376+{"platform": "instagram", "handle": "willing"}
377+{"platform": "instagram", "handle": "jennie"}
378+{"platform": "instagram", "handle": "cup"}
379+{"platform": "instagram", "handle": "ohayocafemtl"}
380+{"platform": "instagram", "handle": "mapoulemouillee"}
381+{"platform": "instagram", "handle": "marcisurlaplaza"}
382+{"platform": "instagram", "handle": "tovogueorbust"}
383+{"platform": "x", "handle": "tovogueorbust"}
384+{"platform": "instagram", "handle": "glowtherapy"}
385+{"platform": "instagram", "handle": "mollylowerealtor"}
386+{"platform": "instagram", "handle": "mosaic_homes"}
387+{"platform": "instagram", "handle": "passion.escalade"}
388+{"platform": "instagram", "handle": "canyoningquebec"}
389+{"platform": "instagram", "handle": "au_canot_volant"}
390+{"platform": "instagram", "handle": "flora.bidaud"}
391+{"platform": "instagram", "handle": "ferme5etoiles"}
392+{"platform": "instagram", "handle": "meretmonde"}
393+{"platform": "instagram", "handle": "parckiamika"}
394+{"platform": "instagram", "handle": "parcpoissonblanc"}
395+{"platform": "instagram", "handle": "noryak_aventures"}
396+{"platform": "instagram", "handle": "noryak"}
397+{"platform": "instagram", "handle": "duvetnor"}
398+{"platform": "instagram", "handle": "echappee.bleue"}
399+{"platform": "instagram", "handle": "aventurequebec"}
400+{"platform": "instagram", "handle": "nature_aventure"}
401+{"platform": "instagram", "handle": "attitudenordique"}
402+{"platform": "instagram", "handle": "lesvagueshsp"}
403+{"platform": "instagram", "handle": "nature"}
404+{"platform": "instagram", "handle": "ottawatourism"}
405+{"platform": "tiktok", "handle": "ottawatourism"}
406+{"platform": "instagram", "handle": "liftoronto"}
407+{"platform": "youtube", "handle": "acpnation"}
408+{"platform": "x", "handle": "acpnation"}
409+{"platform": "x", "handle": "tele_mag_quebec"}
410+{"platform": "instagram", "handle": "tourismeontario"}
411+{"platform": "instagram", "handle": "_seripop_"}
412+{"platform": "instagram", "handle": "spotify"}
413+{"platform": "x", "handle": "spotify"}
414+{"platform": "instagram", "handle": "francomusique"}
415+{"platform": "x", "handle": "rocharchambault"}
416+{"platform": "instagram", "handle": "francaisavenir"}
417+{"platform": "x", "handle": "francaisavenir"}
418+{"platform": "instagram", "handle": "af_ottawa"}
419+{"platform": "x", "handle": "afottawa"}
420+{"platform": "instagram", "handle": "safwanmtl"}
421+{"platform": "instagram", "handle": "_celine_dion_concert.jpg"}
422+{"platform": "instagram", "handle": "hhqcofficiel"}
423+{"platform": "x", "handle": "hhqc"}
424+{"platform": "x", "handle": "hockeyrapper"}
425+{"platform": "instagram", "handle": "impac5canada"}
426+{"platform": "x", "handle": "impac5canada"}
427+{"platform": "instagram", "handle": "mtlelectronicmusic"}
428+{"platform": "instagram", "handle": "polyson"}
429+{"platform": "x", "handle": "edmmontreal"}
430+{"platform": "instagram", "handle": "edmtrain"}
431+{"platform": "instagram", "handle": "cassian"}
432+{"platform": "instagram", "handle": "bushbabybeats"}
433+{"platform": "instagram", "handle": "codymusic_"}
434+{"platform": "instagram", "handle": "whalesfm"}
435+{"platform": "instagram", "handle": "duskymusic"}
436+{"platform": "instagram", "handle": "romanceplanet"}
437+{"platform": "instagram", "handle": "avenueonemusic"}
438+{"platform": "instagram", "handle": "catalystgmail.com2"}
439+{"platform": "instagram", "handle": "sietch514"}
440+{"platform": "instagram", "handle": "rosasharin"}
441+{"platform": "instagram", "handle": "flytzmusic"}
442+{"platform": "instagram", "handle": "giorgia_angiuli"}
443+{"platform": "instagram", "handle": "felixpatry_"}
444+{"platform": "instagram", "handle": "kendal_ritmofatale"}
445+{"platform": "instagram", "handle": "mcmandiz"}
446+{"platform": "instagram", "handle": "noprospectscollective"}
447+{"platform": "instagram", "handle": "t78official"}
448+{"platform": "youtube", "handle": "emersonwoolf"}
449+{"platform": "instagram", "handle": "djprosper22"}
450+{"platform": "instagram", "handle": "1djjfro"}
451+{"platform": "instagram", "handle": "shiftermagazine"}
452+{"platform": "x", "handle": "shiftermagazine"}
453+{"platform": "instagram", "handle": "mrfloetic"}
454+{"platform": "instagram", "handle": "rxckz"}
455+{"platform": "instagram", "handle": "nightafternight"}
456+{"platform": "instagram", "handle": "eazyeldee"}
457+{"platform": "instagram", "handle": "djcsik"}
458+{"platform": "instagram", "handle": "sebcwestcoast"}
459+{"platform": "instagram", "handle": "djandre905"}
460+{"platform": "instagram", "handle": "rocswellradio"}
461+{"platform": "instagram", "handle": "dj.ftp"}
462+{"platform": "instagram", "handle": "topkatamazona"}
463+{"platform": "instagram", "handle": "godfather"}
464+{"platform": "instagram", "handle": "djfrankvinatra"}
465+{"platform": "instagram", "handle": "iamdjfusion"}
466+{"platform": "instagram", "handle": "icytouch"}
467+{"platform": "instagram", "handle": "djrychkydd"}
468+{"platform": "instagram", "handle": "lecolededansedequebec"}
469+{"platform": "instagram", "handle": "revuejeu"}
470+{"platform": "instagram", "handle": "enmoderythme"}
471+{"platform": "tiktok", "handle": "rythme105.7"}
472+{"platform": "youtube", "handle": "cogecomedia"}
473+{"platform": "x", "handle": "zaptele"}
474+{"platform": "instagram", "handle": "agence.m"}
475+{"platform": "instagram", "handle": "policy"}
476+{"platform": "instagram", "handle": "motelstudio"}
477+{"platform": "instagram", "handle": "moniteuracadien"}
478+{"platform": "tiktok", "handle": "jasonjouellette"}
479+{"platform": "youtube", "handle": "lemoniteuracadien"}
480+{"platform": "instagram", "handle": "onf_nfb"}
481+{"platform": "tiktok", "handle": "nfb_onf"}
482+{"platform": "x", "handle": "onf"}
483+{"platform": "instagram", "handle": "imdb"}
484+{"platform": "tiktok", "handle": "imdb"}
485+{"platform": "x", "handle": "imdb"}
486+{"platform": "instagram", "handle": "forteartists"}
487+{"platform": "instagram", "handle": "agence_ada"}
488+{"platform": "x", "handle": "adultes"}
489+{"platform": "x", "handle": "adolescents"}
490+{"platform": "x", "handle": "enfants"}
491+{"platform": "x", "handle": "voix"}
492+{"platform": "x", "handle": "variete"}
493+{"platform": "x", "handle": "agence"}
494+{"platform": "x", "handle": "ecole"}
495+{"platform": "x", "handle": "devenir"}
496+{"platform": "instagram", "handle": "agencechantalbrossard"}
497+{"platform": "instagram", "handle": "moffattariane"}
498+{"platform": "instagram", "handle": "anneelisabethbosse"}
499+{"platform": "instagram", "handle": "abeillegelinas"}
500+{"platform": "instagram", "handle": "emilybegin"}
501+{"platform": "instagram", "handle": "karinevanasse"}
502+{"platform": "instagram", "handle": "wonderwomanpicture"}
503+{"platform": "instagram", "handle": "magalielb"}
504+{"platform": "instagram", "handle": "julebreton"}
505+{"platform": "instagram", "handle": "mariloupwolfe"}
506+{"platform": "instagram", "handle": "mag_clindoeil"}
507+{"platform": "tiktok", "handle": "clindoeil.mag"}
508+{"platform": "instagram", "handle": "rebeccamakonnen"}
509+{"platform": "instagram", "handle": "sophiecads"}
510+{"platform": "instagram", "handle": "marieevelynelessard"}
511+{"platform": "instagram", "handle": "mariesoleildion"}
512+{"platform": "instagram", "handle": "kim_lizotte"}
513+{"platform": "instagram", "handle": "virginie_coossa"}
514+{"platform": "instagram", "handle": "waitresslacomediemusicale"}
515+{"platform": "instagram", "handle": "claudineprevost"}
516+{"platform": "instagram", "handle": "moniachokri"}
517+{"platform": "x", "handle": "cinemas"}
518+{"platform": "x", "handle": "activite"}
519+{"platform": "tiktok", "handle": "withnounna"}
520+{"platform": "instagram", "handle": "geneanet_officiel"}
521+{"platform": "tiktok", "handle": "geneanet"}
522+{"platform": "x", "handle": "geneanet"}
523+{"platform": "instagram", "handle": "bvachet"}
524+{"platform": "x", "handle": "bvachet"}
525+{"platform": "instagram", "handle": "maisondesparentsqc"}
526+{"platform": "instagram", "handle": "federationparentsacadiensne"}
527+{"platform": "youtube", "handle": "federationdesparentsacadie2075"}
528+{"platform": "instagram", "handle": "csap.officiel"}
529+{"platform": "x", "handle": "arsbfc"}
530+{"platform": "instagram", "handle": "ubereats"}
531+{"platform": "x", "handle": "ubereats"}
532+{"platform": "instagram", "handle": "santequebec.csmtl"}
533+{"platform": "youtube", "handle": "santequebec.csimtl"}
534+{"platform": "x", "handle": "montrealcc"}
535+{"platform": "x", "handle": "lacnpf"}
536+{"platform": "instagram", "handle": "fcfacanada"}
537+{"platform": "x", "handle": "fcfacanada"}
538+{"platform": "instagram", "handle": "samueltessierphotographe"}
539+{"platform": "youtube", "handle": "hellodarwin8652"}
540+{"platform": "instagram", "handle": "anniesimardphoto"}
541+{"platform": "instagram", "handle": "royaltonbavaroresort"}
542+{"platform": "instagram", "handle": "kaudet100"}
543+{"platform": "instagram", "handle": "fairmont"}
544+{"platform": "instagram", "handle": "fairmontfrontenac"}
545+{"platform": "instagram", "handle": "sparksmariages"}
546+{"platform": "instagram", "handle": "elodiefleuriste"}
547+{"platform": "instagram", "handle": "djkevinolsen"}
548+{"platform": "instagram", "handle": "lavieestunefete.ca"}
549+{"platform": "instagram", "handle": "groupeabp"}
550+{"platform": "instagram", "handle": "4elevation.ca"}
551+{"platform": "instagram", "handle": "manoirhovey"}
552+{"platform": "instagram", "handle": "alicemonnierphotographie"}
553+{"platform": "instagram", "handle": "anniegagnonphotographie"}
554+{"platform": "instagram", "handle": "highlightmarysebelanger"}
555+{"platform": "instagram", "handle": "madamealicefleuristestecath"}
556+{"platform": "instagram", "handle": "loccasion_dembellir"}
557+{"platform": "instagram", "handle": "highlight_maryse_belanger"}
558+{"platform": "instagram", "handle": "dreamityourselfmontreal"}
559+{"platform": "instagram", "handle": "montreal_bandindelloye"}
560+{"platform": "instagram", "handle": "mimosadesign.invitations"}
561+{"platform": "instagram", "handle": "lafleur_sucree"}
562+{"platform": "instagram", "handle": "justinequintaljewellery"}
563+{"platform": "instagram", "handle": "yasminerosedesigner"}
564+{"platform": "instagram", "handle": "meggie_lapointe"}
565+{"platform": "instagram", "handle": "maxalexleblanc"}
566+{"platform": "instagram", "handle": "missis101"}
567+{"platform": "instagram", "handle": "makeupbyalexandra.p"}
568+{"platform": "instagram", "handle": "marysewithlove"}
569+{"platform": "instagram", "handle": "aubergesaintantoine"}
570+{"platform": "instagram", "handle": "emiliesoprano"}
571+{"platform": "instagram", "handle": "cathylessardphoto"}
572+{"platform": "instagram", "handle": "so_lia"}
573+{"platform": "instagram", "handle": "helly819"}
574+{"platform": "instagram", "handle": "lamarieusesophiesamson"}
575+{"platform": "instagram", "handle": "sandosplayacar"}
576+{"platform": "instagram", "handle": "maebonnetphotographe"}
577+{"platform": "instagram", "handle": "alwaysplayingwithmakeup"}
578+{"platform": "instagram", "handle": "mart.menardimage"}
579+{"platform": "instagram", "handle": "karrelaubert"}
580+{"platform": "instagram", "handle": "erikaco.events"}
581+{"platform": "instagram", "handle": "robmalofilms"}
582+{"platform": "instagram", "handle": "club_atwater"}
583+{"platform": "instagram", "handle": "jacinthe.benoit"}
584+{"platform": "instagram", "handle": "ivoiremontreal"}
585+{"platform": "instagram", "handle": "montreal_blandindelloye"}
586+{"platform": "instagram", "handle": "anabelfrechettephotographe"}
587+{"platform": "instagram", "handle": "leplusbojour"}
588+{"platform": "instagram", "handle": "resort_entourage"}
589+{"platform": "instagram", "handle": "by_lemay"}
590+{"platform": "instagram", "handle": "fleurdeurope"}
591+{"platform": "instagram", "handle": "papeterieetconfetti"}
592+{"platform": "instagram", "handle": "cleobolduc"}
593+{"platform": "instagram", "handle": "chezmarcus"}
594+{"platform": "instagram", "handle": "xperience_applyrs"}
595+{"platform": "instagram", "handle": "mart.menard"}
596+{"platform": "instagram", "handle": "laurenceflortie"}
597+{"platform": "instagram", "handle": "paulinaco.events"}
598+{"platform": "instagram", "handle": "beyondthehearts"}
599+{"platform": "instagram", "handle": "annieli.mtl"}
600+{"platform": "instagram", "handle": "wang_dion"}
601+{"platform": "instagram", "handle": "kerstinhahnphotography"}
602+{"platform": "instagram", "handle": "myriammenardphoto"}
603+{"platform": "instagram", "handle": "chateausteagnes"}
604+{"platform": "instagram", "handle": "studio_ck_flowers"}
605+{"platform": "instagram", "handle": "blandindelloye.mariage"}
606+{"platform": "instagram", "handle": "nargessheed"}
607+{"platform": "instagram", "handle": "fulkoweddings"}
608+{"platform": "instagram", "handle": "loft.bijoux"}
609+{"platform": "instagram", "handle": "whitewillowpaperco"}
610+{"platform": "instagram", "handle": "letraiteurarcher"}
611+{"platform": "instagram", "handle": "buvette_mobile_lapero"}
612+{"platform": "instagram", "handle": "celebrationsgroup"}
613+{"platform": "instagram", "handle": "simplybeautifuldecor"}
614+{"platform": "instagram", "handle": "emilieviolon"}
615+{"platform": "instagram", "handle": "fairmontmanoir"}
616+{"platform": "instagram", "handle": "eclatprive.signature"}
617+{"platform": "instagram", "handle": "fetesgrenadine"}
618+{"platform": "instagram", "handle": "cvezinabride"}
619+{"platform": "instagram", "handle": "mepm"}
620+{"platform": "instagram", "handle": "joe_lbri"}
621+{"platform": "instagram", "handle": "christianlouboutin"}
622+{"platform": "instagram", "handle": "arvirestaurant"}
623+{"platform": "instagram", "handle": "cremesodaevenement"}
624+{"platform": "instagram", "handle": "cremesodaevenements"}
625+{"platform": "instagram", "handle": "maecaouette"}
626+{"platform": "instagram", "handle": "dior"}
627+{"platform": "instagram", "handle": "hiltonquebec"}
628+{"platform": "instagram", "handle": "agence.elegance"}
629+{"platform": "instagram", "handle": "mapatisserie.ca"}
630+{"platform": "instagram", "handle": "chateau.nadia"}
631+{"platform": "instagram", "handle": "catherinehardy_photographe"}
632+{"platform": "instagram", "handle": "dekoraalbum"}
633+{"platform": "instagram", "handle": "elisabethb_eb"}
634+{"platform": "instagram", "handle": "wed_vibes"}
635+{"platform": "instagram", "handle": "happy.moments.collector"}
636+{"platform": "instagram", "handle": "villapizzo"}
637+{"platform": "instagram", "handle": "sociallymichelleandco"}
638+{"platform": "instagram", "handle": "riccardociceri"}
639+{"platform": "instagram", "handle": "blunotteventi"}
640+{"platform": "instagram", "handle": "latinidesign"}
641+{"platform": "instagram", "handle": "tablesetrentals"}
642+{"platform": "instagram", "handle": "raraavis_group"}
643+{"platform": "instagram", "handle": "evgeniadragun"}
644+{"platform": "instagram", "handle": "jennymakeupland"}
645+{"platform": "instagram", "handle": "dadoallestimenti"}
646+{"platform": "instagram", "handle": "einpraegsam.co"}
647+{"platform": "instagram", "handle": "louska.v"}
648+{"platform": "instagram", "handle": "raphaelpalmeer"}
649+{"platform": "instagram", "handle": "coiffuredistinctiveqc"}
650+{"platform": "instagram", "handle": "wedding_chateaufrontenac"}
651+{"platform": "instagram", "handle": "magentastudiophoto"}
652+{"platform": "instagram", "handle": "photo_g.b"}
653+{"platform": "x", "handle": "blogue"}
654+{"platform": "x", "handle": "wp"}
655+{"platform": "instagram", "handle": "raavquebec"}
656+{"platform": "instagram", "handle": "francoisgaudet"}
657+{"platform": "instagram", "handle": "macbsp"}
658+{"platform": "instagram", "handle": "aaapnb"}
659+{"platform": "instagram", "handle": "leseloizes"}
660+{"platform": "instagram", "handle": "olyangertattoo"}
661+{"platform": "instagram", "handle": "tatouageroyal"}
662+{"platform": "instagram", "handle": "imagotattoo"}
663+{"platform": "instagram", "handle": "studioartease"}
664+{"platform": "instagram", "handle": "le.malandrin"}
665+{"platform": "instagram", "handle": "velours.studio"}
666+{"platform": "instagram", "handle": "velours.tattoo"}
667+{"platform": "instagram", "handle": "dominiquebodkintattoo"}
668+{"platform": "instagram", "handle": "arnostattoos"}
669+{"platform": "instagram", "handle": "e.a.tattoo"}
670+{"platform": "instagram", "handle": "christianlanouette"}
671+{"platform": "instagram", "handle": "tattoo.noirsurpeau"}
672+{"platform": "instagram", "handle": "phylotattoos"}
673+{"platform": "instagram", "handle": "lucitattoos"}
674+{"platform": "instagram", "handle": "lmariera"}
675+{"platform": "instagram", "handle": "softbrattattz"}
676+{"platform": "instagram", "handle": "mllealyx_tattoo"}
677+{"platform": "instagram", "handle": "piewchoquette"}
678+{"platform": "instagram", "handle": "murieldemai_tattoo"}
679+{"platform": "instagram", "handle": "laracailletattoo"}
680+{"platform": "instagram", "handle": "fredpokes"}
681+{"platform": "instagram", "handle": "b.hurricane"}
682+{"platform": "instagram", "handle": "lav4gurl"}
683+{"platform": "instagram", "handle": "steamboat_vinnie"}
684+{"platform": "instagram", "handle": "mllealyx"}
685+{"platform": "instagram", "handle": "murieldemai"}
686+{"platform": "instagram", "handle": "bb.hurricane"}
687+{"platform": "instagram", "handle": "steamboat"}
688+{"platform": "instagram", "handle": "lukalajoie"}
689+{"platform": "instagram", "handle": "christinastattoos"}
690+{"platform": "instagram", "handle": "ayako666"}
691+{"platform": "instagram", "handle": "maxxlemieux"}
692+{"platform": "instagram", "handle": "yannblacktattoo"}
693+{"platform": "instagram", "handle": "zema1"}
694+{"platform": "instagram", "handle": "ink.maude"}
695+{"platform": "instagram", "handle": "waynemcfarlane"}
696+{"platform": "instagram", "handle": "shaemotztattoos"}
697+{"platform": "instagram", "handle": "draworking"}
698+{"platform": "instagram", "handle": "getmooretattoos"}
699+{"platform": "instagram", "handle": "inkredible"}
700+{"platform": "instagram", "handle": "inkredible_shawn"}
701+{"platform": "instagram", "handle": "rebeccablairtattoos"}
702+{"platform": "instagram", "handle": "johnnynoirtattoo"}
703+{"platform": "instagram", "handle": "the_burning_jewel"}
704+{"platform": "instagram", "handle": "808byjack"}
705+{"platform": "instagram", "handle": "tattoomontreal"}
706+{"platform": "instagram", "handle": "montrealtattooguide"}
707+{"platform": "instagram", "handle": "monsieur.pitch"}
708+{"platform": "instagram", "handle": "lashopchaos"}
709+{"platform": "instagram", "handle": "velco.tattoo"}
710+{"platform": "instagram", "handle": "baroquebabetattoos"}
711+{"platform": "instagram", "handle": "chez.bebelala"}
712+{"platform": "instagram", "handle": "thedavidcote"}
713+{"platform": "instagram", "handle": "noirsurpeau"}
714+{"platform": "instagram", "handle": "studio.amormio"}
715+{"platform": "instagram", "handle": "brizz.amor"}
716+{"platform": "instagram", "handle": "dani.l.pokes"}
717+{"platform": "instagram", "handle": "passelebriquet"}
718+{"platform": "instagram", "handle": "isabelroseink"}
719+{"platform": "instagram", "handle": "industrial.inktattoo"}
720+{"platform": "instagram", "handle": "itslumibeauty"}
721+{"platform": "instagram", "handle": "permanence.pmu"}
722+{"platform": "instagram", "handle": "hayls.ink"}
723+{"platform": "instagram", "handle": "tattoobysoso"}
724+{"platform": "instagram", "handle": "saintpaul.tattoo"}
725+{"platform": "instagram", "handle": "subielachani.cs"}
726+{"platform": "instagram", "handle": "charlessimardcoiffeur"}
727+{"platform": "instagram", "handle": "hair_by_pk.t"}
728+{"platform": "instagram", "handle": "marcuuus"}
729+{"platform": "instagram", "handle": "cathesoe_hair"}
730+{"platform": "instagram", "handle": "kimmcgillis"}
731+{"platform": "instagram", "handle": "andree.anne.gagne"}
732+{"platform": "instagram", "handle": "hairbynathaliemichaud"}
733+{"platform": "instagram", "handle": "vikingmax.hair"}
734+{"platform": "instagram", "handle": "salonno1coiffure"}
735+{"platform": "instagram", "handle": "la_capillicultrice"}
736+{"platform": "instagram", "handle": "laurence_hairstylist"}
737+{"platform": "instagram", "handle": "sam.chab"}
738+{"platform": "instagram", "handle": "staellecolorful"}
739+{"platform": "instagram", "handle": "melagagn"}
740+{"platform": "instagram", "handle": "les_couloirs"}
741+{"platform": "instagram", "handle": "st_laurent_coiffure"}
742+{"platform": "instagram", "handle": "karianne_artistika"}
743+{"platform": "instagram", "handle": "eleganzaqc"}
744+{"platform": "instagram", "handle": "billie.qc"}
745+{"platform": "instagram", "handle": "luxetmusa"}
746+{"platform": "instagram", "handle": "zazzpareleganza"}
747+{"platform": "instagram", "handle": "salontestuvulallure"}
748+{"platform": "instagram", "handle": "alia_victoria_coiffure"}
749+{"platform": "instagram", "handle": "labelleetlatete"}
750+{"platform": "instagram", "handle": "parikart_"}
751+{"platform": "instagram", "handle": "litchicoiffure"}
752+{"platform": "instagram", "handle": "mcoupebeaute"}
753+{"platform": "instagram", "handle": "lakwaflevis"}
754+{"platform": "instagram", "handle": "hakima_matata"}
755+{"platform": "instagram", "handle": "matrix"}
756+{"platform": "instagram", "handle": "schwarzkopfpro"}
757+{"platform": "instagram", "handle": "babylissprousa"}
758+{"platform": "instagram", "handle": "neumabeauty"}
759+{"platform": "instagram", "handle": "joellienadeau"}
760+{"platform": "instagram", "handle": "goldwellca"}
761+{"platform": "instagram", "handle": "coiffure_le_saint"}
762+{"platform": "instagram", "handle": "hair_by_roxks"}
763+{"platform": "instagram", "handle": "carolabelleetlatete"}
764+{"platform": "instagram", "handle": "annieracine01"}
765+{"platform": "x", "handle": "jdequebec"}
766+{"platform": "instagram", "handle": "alexandrinepoirier"}
767+{"platform": "instagram", "handle": "maudegervais_"}
768+{"platform": "instagram", "handle": "lorealpro"}
769+{"platform": "instagram", "handle": "olaplex"}
770+{"platform": "instagram", "handle": "mutetienne"}
771+{"platform": "instagram", "handle": "gab.brulotte"}
772+{"platform": "instagram", "handle": "annepier"}
773+{"platform": "instagram", "handle": "klaudiaodeth"}
774+{"platform": "instagram", "handle": "biolage"}
775+{"platform": "instagram", "handle": "ruskhaircare"}
776+{"platform": "instagram", "handle": "ruskcanada"}
777+{"platform": "instagram", "handle": "aquagecanada"}
778+{"platform": "instagram", "handle": "aquagehaircare"}
779+{"platform": "instagram", "handle": "alexeloranger"}
780+{"platform": "instagram", "handle": "cath_marier"}
781+{"platform": "instagram", "handle": "fresha"}
782+{"platform": "instagram", "handle": "virginietrc"}
783+{"platform": "instagram", "handle": "clemencexchezmarcus"}
784+{"platform": "instagram", "handle": "kingperse"}
785+{"platform": "instagram", "handle": "annejuice10"}
786+{"platform": "instagram", "handle": "charlesxeda"}
787+{"platform": "instagram", "handle": "lau.gre"}
788+{"platform": "instagram", "handle": "cynth.haircolors"}
789+{"platform": "instagram", "handle": "kellyextensions"}
790+{"platform": "instagram", "handle": "sxmos_"}
791+{"platform": "instagram", "handle": "kateextensions"}
792+{"platform": "instagram", "handle": "est"}
793+{"platform": "instagram", "handle": "saloncoiffurelestudio"}
794+{"platform": "instagram", "handle": "conceptbeaute.esthetique"}
795+{"platform": "instagram", "handle": "institut.esthetique.qc"}
796+{"platform": "instagram", "handle": "skinandcoesthetique"}
797+{"platform": "tiktok", "handle": "skinco.esthtique"}
798+{"platform": "tiktok", "handle": "dermacureqc"}
799+{"platform": "instagram", "handle": "cfameriques"}
800+{"platform": "instagram", "handle": "icrml.cirlm"}
801+{"platform": "x", "handle": "icrml_cirlm"}
802+{"platform": "instagram", "handle": "nalyses"}
803+{"platform": "instagram", "handle": "gmc"}
804+{"platform": "instagram", "handle": "gmccanada"}
805+{"platform": "tiktok", "handle": "gmccanada"}
806+{"platform": "instagram", "handle": "triumphamerica"}
807+{"platform": "x", "handle": "triumphamerica"}
808+{"platform": "instagram", "handle": "motomontrealcycle"}
809+{"platform": "instagram", "handle": "motorcycleandpowersportshows"}
810+{"platform": "instagram", "handle": "bmwmotorradmontreal"}
811+{"platform": "instagram", "handle": "themotosocial"}
812+{"platform": "instagram", "handle": "idlegarageandcoffee"}
813+{"platform": "instagram", "handle": "cafelefalco"}
814+{"platform": "instagram", "handle": "hocheglace"}
815+{"platform": "instagram", "handle": "cantinova.cafe"}
816+{"platform": "instagram", "handle": "beausallnatural"}
817+{"platform": "instagram", "handle": "la_fille_au_casque_rouge_"}
818+{"platform": "instagram", "handle": "hawley_martin"}
819+{"platform": "instagram", "handle": "motor_cycle_bro"}
820+{"platform": "instagram", "handle": "nak_attaque"}
821+{"platform": "instagram", "handle": "vikpiccreative"}
822+{"platform": "instagram", "handle": "yamahamotorcanada"}
823+{"platform": "instagram", "handle": "mic"}
824+{"platform": "x", "handle": "enduro"}
825+{"platform": "instagram", "handle": "perrondesign"}
826+{"platform": "instagram", "handle": "adomicile_"}
827+{"platform": "instagram", "handle": "atelierzebulonperron"}
828+{"platform": "instagram", "handle": "atelierdansereau"}
829+{"platform": "instagram", "handle": "les"}
830+{"platform": "instagram", "handle": "bureautempo"}
831+{"platform": "instagram", "handle": "vivesstlaurent"}
832+{"platform": "instagram", "handle": "michaelgodmerstudio"}
833+{"platform": "instagram", "handle": "akbdesign"}
834+{"platform": "instagram", "handle": "bipede.design"}
835+{"platform": "instagram", "handle": "entrequatremurs"}
836+{"platform": "instagram", "handle": "entrepot_de_la_reno"}
837+{"platform": "instagram", "handle": "brookandpeony"}
838+{"platform": "instagram", "handle": "house_to_home.interiors"}
839+{"platform": "instagram", "handle": "rien_ne_se_perd"}
840+{"platform": "instagram", "handle": "alexandralarouche"}
841+{"platform": "instagram", "handle": "ashleyshaanan"}
842+{"platform": "x", "handle": "logisquebec"}
843+{"platform": "instagram", "handle": "davani_realtor"}
844+{"platform": "x", "handle": "behrooziani"}
845+{"platform": "instagram", "handle": "realtorpointca"}
846+{"platform": "x", "handle": "realtorpointca"}
847+{"platform": "instagram", "handle": "lespac"}
848+{"platform": "instagram", "handle": "royal_lepage"}
849+{"platform": "instagram", "handle": "remaxcanada"}
850+{"platform": "tiktok", "handle": "remax.canada"}
851+{"platform": "youtube", "handle": "remaxcanada_no1"}
852+{"platform": "x", "handle": "assets"}
853+{"platform": "x", "handle": "mex"}
854+{"platform": "instagram", "handle": "viacapitale"}
855+{"platform": "x", "handle": "viacapitale"}
856+{"platform": "instagram", "handle": "remaxquebec"}
857+{"platform": "tiktok", "handle": "remax.quebec"}
858+{"platform": "x", "handle": "notoriete"}
859+{"platform": "x", "handle": "formation"}
860+{"platform": "x", "handle": "contact"}
861+{"platform": "x", "handle": "remaxquebec"}
862+{"platform": "x", "handle": "default"}
863+{"platform": "youtube", "handle": "findevcanada"}
864+{"platform": "x", "handle": "findev_canada"}
865+{"platform": "instagram", "handle": "eycanada"}
866+{"platform": "instagram", "handle": "quebecintl"}
867+{"platform": "tiktok", "handle": "quebecintl"}
868+{"platform": "instagram", "handle": "yesmontreal"}
869+{"platform": "x", "handle": "yesmontreal"}
870+{"platform": "instagram", "handle": "fahdalhattab"}
871+{"platform": "youtube", "handle": "fahdalhattab"}
872+{"platform": "x", "handle": "fahdalhattab"}
873+{"platform": "instagram", "handle": "myriambariltessier_v4.jpg"}
874+{"platform": "instagram", "handle": "punctuatedesign"}
875+{"platform": "instagram", "handle": "startupfest"}
876+{"platform": "instagram", "handle": "inrsciences"}
877+{"platform": "x", "handle": "u_inrs"}
878+{"platform": "instagram", "handle": "fse_udem"}
879+{"platform": "instagram", "handle": "englishmtl"}
880+{"platform": "instagram", "handle": "hecmontreal"}
881+{"platform": "x", "handle": "hec_montreal"}
882+{"platform": "x", "handle": "recordingservic"}
883+{"platform": "instagram", "handle": "csf_cb"}
884+{"platform": "instagram", "handle": "bibliothequedequebec"}
885+{"platform": "youtube", "handle": "bibliotheque_quebec"}
886+{"platform": "instagram", "handle": "moongirlreads"}
887+{"platform": "instagram", "handle": "bookedj"}
888+{"platform": "instagram", "handle": "meemoreads"}
889+{"platform": "instagram", "handle": "thrillerbooklover"}
890+{"platform": "instagram", "handle": "literallyjohngreen"}
891+{"platform": "instagram", "handle": "thechloegong"}
892+{"platform": "instagram", "handle": "victoriaaveyard"}
893+{"platform": "instagram", "handle": "runwithskizzers"}
894+{"platform": "instagram", "handle": "michael.bjork"}
895+{"platform": "instagram", "handle": "penguin"}
896+{"platform": "tiktok", "handle": "girlyalex83"}
897+{"platform": "tiktok", "handle": "morgannbook"}
898+{"platform": "tiktok", "handle": "yabooktok"}
899+{"platform": "x", "handle": "ncbi"}
900+{"platform": "x", "handle": "nlm_nih"}
901+{"platform": "instagram", "handle": "daansbooks"}
902+{"platform": "instagram", "handle": "spinesvines"}
903+{"platform": "instagram", "handle": "spinesandvines"}
904+{"platform": "tiktok", "handle": "baker.reads"}
905+{"platform": "tiktok", "handle": "c15r5y4"}
906+{"platform": "tiktok", "handle": "ajunxx"}
907+{"platform": "tiktok", "handle": "iamstephanienoble"}
908+{"platform": "tiktok", "handle": "bigbooklady"}
909+{"platform": "tiktok", "handle": "thelibraryofdais"}
910+{"platform": "x", "handle": "culture"}
911+{"platform": "x", "handle": "exhaustdata"}
912+{"platform": "instagram", "handle": "booknet"}
913+{"platform": "instagram", "handle": "cbcbooks"}
914+{"platform": "instagram", "handle": "lat46publishing"}
915+{"platform": "instagram", "handle": "readflare"}
916+{"platform": "x", "handle": "pcitoyen"}
917+{"platform": "instagram", "handle": "msss_qc"}
918+{"platform": "x", "handle": "msss_qc"}
919+{"platform": "instagram", "handle": "acadianhealth"}
920+{"platform": "instagram", "handle": "creons_la_suite"}
921+{"platform": "x", "handle": "creonslasuite"}
922+{"platform": "x", "handle": "santefrancais"}
923+{"platform": "instagram", "handle": "lunayogamtl"}
924+{"platform": "instagram", "handle": "institutyogaessentiel"}
925+{"platform": "instagram", "handle": "yogashakmontreal"}
926+{"platform": "instagram", "handle": "naadayoga"}
927+{"platform": "x", "handle": "naadayoga"}
928+{"platform": "instagram", "handle": "sfvictoria.ca"}
929+{"platform": "x", "handle": "francophone_vic"}
930+{"platform": "x", "handle": "podkatt"}
931+{"platform": "instagram", "handle": "podkatt"}
932+{"platform": "instagram", "handle": "podthenorth"}
933+{"platform": "instagram", "handle": "labrigadepod.th"}
934+{"platform": "instagram", "handle": "jezebel.bardotsuivez"}
935+{"platform": "instagram", "handle": "celestelevisyoutube"}
936+{"platform": "instagram", "handle": "srnhasselaslinkedin"}
937+{"platform": "instagram", "handle": "makhena"}
938+{"platform": "instagram", "handle": "miquemichellesuivez"}
939+{"platform": "instagram", "handle": "leflofrancosite"}
940+{"platform": "instagram", "handle": "lexinemenard"}
941+{"platform": "instagram", "handle": "lexinephotographie"}
942+{"platform": "instagram", "handle": "lexiphotoboothsite"}
943+{"platform": "instagram", "handle": "lydiamariebpinstagram"}
944+{"platform": "instagram", "handle": "lydiamariebplinkedin"}
945+{"platform": "instagram", "handle": "monassemblee"}
946+{"platform": "instagram", "handle": "danieroy11"}
947+{"platform": "tiktok", "handle": "ledevoir"}
948+{"platform": "x", "handle": "ledevoir"}
949+{"platform": "instagram", "handle": "rubytdoll"}
950+{"platform": "instagram", "handle": "aleeranight"}
951+{"platform": "instagram", "handle": "verona_verushka"}
952+{"platform": "instagram", "handle": "madolamotte"}
953+{"platform": "instagram", "handle": "huffpost"}
954+{"platform": "instagram", "handle": "rainbow.drag"}
955+{"platform": "instagram", "handle": "ritabagaz"}
956+{"platform": "instagram", "handle": "gabryelledrag"}
957+{"platform": "instagram", "handle": "matante.alex"}
958+{"platform": "instagram", "handle": "gisele_lullaby"}
959+{"platform": "instagram", "handle": "kiara.qc.ca"}
960+{"platform": "instagram", "handle": "ladydeboomboom"}
961+{"platform": "instagram", "handle": "pythia.queen"}
962+{"platform": "instagram", "handle": "umagahd"}
963+{"platform": "instagram", "handle": "itsheavengenderfck"}
964+{"platform": "instagram", "handle": "selmagahd"}
965+{"platform": "x", "handle": "huffpost"}
966+{"platform": "x", "handle": "philippelepine"}
967+{"platform": "instagram", "handle": "sugarandspice"}
968+{"platform": "instagram", "handle": "callmespice"}
969+{"platform": "instagram", "handle": "sugar"}
970+{"platform": "instagram", "handle": "rc.ohdio"}
971+{"platform": "instagram", "handle": "she_laa9"}
972+{"platform": "tiktok", "handle": "samilandri"}
973+{"platform": "tiktok", "handle": "queenrosebeef"}
974+{"platform": "tiktok", "handle": "radpointca"}
975+{"platform": "tiktok", "handle": "she_laa9"}
976+{"platform": "tiktok", "handle": "danslebainaveccelin"}
977+{"platform": "tiktok", "handle": "rc.ohdio"}
978+{"platform": "tiktok", "handle": "sugarandspice"}
979+{"platform": "tiktok", "handle": "rainbow.drag"}
980+{"platform": "tiktok", "handle": "demone_lastrange"}
981+{"platform": "tiktok", "handle": "paspeufieres"}
982+{"platform": "tiktok", "handle": "rosiepetalsdrag"}
983+{"platform": "tiktok", "handle": "cityofquebec"}
984+{"platform": "tiktok", "handle": "scoobydoobydrew22"}
985+{"platform": "tiktok", "handle": "yap.mtl"}
986+{"platform": "tiktok", "handle": "ximena.do.santos"}
987+{"platform": "instagram", "handle": "samilandri"}
988+{"platform": "instagram", "handle": "queenrosebeef"}
989+{"platform": "instagram", "handle": "radpointca"}
990+{"platform": "instagram", "handle": "danslebainaveccelin"}
991+{"platform": "instagram", "handle": "agence.ludik"}
992+{"platform": "instagram", "handle": "barbada"}
993+{"platform": "instagram", "handle": "rita"}
994+{"platform": "instagram", "handle": "demone_lastrange"}
995+{"platform": "instagram", "handle": "paspeufieres"}
996+{"platform": "instagram", "handle": "chiquita"}
997+{"platform": "instagram", "handle": "rosiepetalsdrag"}
998+{"platform": "instagram", "handle": "cityofquebec"}
999+{"platform": "instagram", "handle": "scoobydoobydrew22"}
1000+{"platform": "instagram", "handle": "yap.mtl"}
1001+{"platform": "instagram", "handle": "ximena.do.santos"}
1002+{"platform": "instagram", "handle": "cult_mag_"}
1003+{"platform": "youtube", "handle": "cultmagazine"}
1004+{"platform": "youtube", "handle": "helpez-moi"}
1005+{"platform": "x", "handle": "cult_mag_"}
1006+{"platform": "instagram", "handle": "samilandri_"}
1007+{"platform": "instagram", "handle": "velma.johnny"}
1008+{"platform": "instagram", "handle": "chiquita.mere"}
1009+{"platform": "instagram", "handle": "queermtl"}
1010+{"platform": "instagram", "handle": "stefan"}
1011+{"platform": "instagram", "handle": "cclgbtqplus"}
1012+{"platform": "youtube", "handle": "bibliothequealivresouverts7986"}
1013+{"platform": "instagram", "handle": "barlestud"}
1014+{"platform": "instagram", "handle": "champs_montreal"}
1015+{"platform": "instagram", "handle": "motel_motel"}
1016+{"platform": "instagram", "handle": "bar_taboo_inc"}
1017+{"platform": "instagram", "handle": "ballroom4community"}
1018+{"platform": "instagram", "handle": "bareoke"}
1019+{"platform": "instagram", "handle": "violet_hour_lit"}
1020+{"platform": "instagram", "handle": "leclubdds"}
1021+{"platform": "instagram", "handle": "jontaemccrory"}
1022+{"platform": "instagram", "handle": "blackgxrlsesh"}
1023+{"platform": "instagram", "handle": "queerkaraokemtl"}
1024+{"platform": "instagram", "handle": "p10montreal"}
1025+{"platform": "instagram", "handle": "queerbodiesmontreal"}
1026+{"platform": "instagram", "handle": "bring_it_mtl"}
1027+{"platform": "instagram", "handle": "juke.collective"}
1028+{"platform": "instagram", "handle": "bmqs.mtl"}
1029+{"platform": "instagram", "handle": "dodgeball.ratons.chasseurs"}
1030+{"platform": "instagram", "handle": "out_runclub"}
1031+{"platform": "instagram", "handle": "queer_bloc"}
1032+{"platform": "instagram", "handle": "theunfitclub"}
1033+{"platform": "instagram", "handle": "justice.trans"}
1034+{"platform": "instagram", "handle": "audreyrivet"}
1035+{"platform": "instagram", "handle": "josianekonate"}
1036+{"platform": "instagram", "handle": "faulhaber.agency"}
1037+{"platform": "instagram", "handle": "trangreeny"}
1038+{"platform": "x", "handle": "faulhabercomm"}
1039+{"platform": "instagram", "handle": "legurky"}
1040+{"platform": "instagram", "handle": "adamparadisio"}
1041+{"platform": "instagram", "handle": "alexane"}
1042+{"platform": "instagram", "handle": "samanthaleclerc"}
1043+{"platform": "instagram", "handle": "emylalune"}
1044+{"platform": "instagram", "handle": "agenceoneway"}
1045+{"platform": "tiktok", "handle": "emylalune"}
1046+{"platform": "tiktok", "handle": "adamparadisio"}
1047+{"platform": "tiktok", "handle": "hydroquebec"}
1048+{"platform": "tiktok", "handle": "accouuu"}
1049+{"platform": "tiktok", "handle": "influencecreation"}
1050+{"platform": "instagram", "handle": "influencecreation"}
1051+{"platform": "instagram", "handle": "la.boite.dinfluence"}
1052+{"platform": "instagram", "handle": "nath.hebert"}
1053+{"platform": "instagram", "handle": "sarahmboily"}
1054+{"platform": "instagram", "handle": "samonthenews"}
1055+{"platform": "tiktok", "handle": "camilledufresne_"}
1056+{"platform": "instagram", "handle": "iamjahantea"}
1057+{"platform": "instagram", "handle": "aiequi"}
1058+{"platform": "tiktok", "handle": "sjbleauellington"}
1059+{"platform": "tiktok", "handle": "denyzee"}
1060+{"platform": "tiktok", "handle": "iamjahantea"}
1061+{"platform": "youtube", "handle": "denyzee"}
1062+{"platform": "youtube", "handle": "cocottee_"}
1063+{"platform": "instagram", "handle": "sjbleauellington"}
1064+{"platform": "instagram", "handle": "denyzee"}
1065+{"platform": "instagram", "handle": "felixdolci"}
1066+{"platform": "instagram", "handle": "nailzzbymyka"}
1067+{"platform": "instagram", "handle": "lasenza"}
1068+{"platform": "instagram", "handle": "quebecbroue"}
1069+{"platform": "instagram", "handle": "msfphotographie"}
1070+{"platform": "instagram", "handle": "calvinklein"}
1071+{"platform": "instagram", "handle": "tvanouvelles"}
1072+{"platform": "instagram", "handle": "salutbonjourofficiel"}
1073+{"platform": "instagram", "handle": "pascalerobitaille"}
1074+{"platform": "instagram", "handle": "upawasessions"}
1075+{"platform": "instagram", "handle": "soufiane"}
1076+{"platform": "instagram", "handle": "wherepaganoat"}
1077+{"platform": "instagram", "handle": "clatetu"}
1078+{"platform": "instagram", "handle": "killwilliamhennessey"}
1079+{"platform": "instagram", "handle": "d.rec.2"}
1080+{"platform": "instagram", "handle": "duber72_"}
1081+{"platform": "instagram", "handle": "bahoboxing"}
1082+{"platform": "instagram", "handle": "kayttykat"}
1083+{"platform": "instagram", "handle": "kaikupanda"}
1084+{"platform": "instagram", "handle": "yturcotte17"}
1085+{"platform": "instagram", "handle": "verolagachette"}
1086+{"platform": "instagram", "handle": "emiliebruncormier"}
1087+{"platform": "instagram", "handle": "laureantardif"}
1088+{"platform": "instagram", "handle": "ecoledecirquedequebec"}
1089+{"platform": "instagram", "handle": "speedbird3000"}
1090+{"platform": "instagram", "handle": "katiacuradeau"}
1091+{"platform": "instagram", "handle": "annagervaiss"}
1092+{"platform": "instagram", "handle": "kellyannturcot"}
1093+{"platform": "instagram", "handle": "juliette_painchaud"}
1094+{"platform": "tiktok", "handle": "emiliebruncormier"}
1095+{"platform": "tiktok", "handle": "juliettepainchaud"}
1096+{"platform": "instagram", "handle": "ledraguecabaretclub"}
1097+{"platform": "instagram", "handle": "unholyzipper"}
1098+{"platform": "instagram", "handle": "capitals"}
1099+{"platform": "instagram", "handle": "duber72"}
1100+{"platform": "instagram", "handle": "jecoursqc"}
1101+{"platform": "instagram", "handle": "lecoachingducoureur"}
1102+{"platform": "instagram", "handle": "yvesstlouis"}
1103+{"platform": "instagram", "handle": "lacliniqueducoureur"}
1104+{"platform": "instagram", "handle": "dioafitness"}
1105+{"platform": "instagram", "handle": "velocartel"}
1106+{"platform": "instagram", "handle": "kartelmusik"}
1107+{"platform": "instagram", "handle": "blackxlfc"}
1108+{"platform": "instagram", "handle": "goodjudy.ca"}
1109+{"platform": "instagram", "handle": "lunenoiretatouage"}
1110+{"platform": "instagram", "handle": "northerntattoosupply"}
1111+{"platform": "instagram", "handle": "bishoprotary"}
1112+{"platform": "instagram", "handle": "sportsexpertslaurier"}
1113+{"platform": "instagram", "handle": "julbocanada"}
1114+{"platform": "instagram", "handle": "krononutrition"}
1115+{"platform": "instagram", "handle": "heyheytiskenny"}
1116+{"platform": "instagram", "handle": "choco"}
1117+{"platform": "instagram", "handle": "photokurado"}
1118+{"platform": "instagram", "handle": "qbedshostel"}
1119+{"platform": "instagram", "handle": "elorouthe"}
1120+{"platform": "instagram", "handle": "skyvision.optometrie"}
1121+{"platform": "instagram", "handle": "lapetiteecoledeliledorleans"}
1122+{"platform": "instagram", "handle": "undz"}
1123+{"platform": "instagram", "handle": "audrey"}
1124+{"platform": "instagram", "handle": "spekoptics"}
1125+{"platform": "instagram", "handle": "popeyesquebec"}
1126+{"platform": "instagram", "handle": "lecoureurnordique"}
1127+{"platform": "instagram", "handle": "juliette"}
1128+{"platform": "instagram", "handle": "juliettepainchaud"}
1129+{"platform": "instagram", "handle": "eugeniemalenfant"}
1130+{"platform": "instagram", "handle": "pellandworkout"}
1131+{"platform": "instagram", "handle": "rachelledion"}
1132+{"platform": "instagram", "handle": "pcnphysio"}
1133+{"platform": "instagram", "handle": "kev"}
1134+{"platform": "instagram", "handle": "sim"}
1135+{"platform": "instagram", "handle": "elianne"}
1136+{"platform": "instagram", "handle": "jeannot.bou"}
1137+{"platform": "instagram", "handle": "srxproducts"}
1138+{"platform": "instagram", "handle": "supraathletique"}
1139+{"platform": "instagram", "handle": "vb.pod"}
1140+{"platform": "instagram", "handle": "tyrsport"}
1141+{"platform": "instagram", "handle": "ta.tristan"}
1142+{"platform": "instagram", "handle": "julieanneho"}
1143+{"platform": "instagram", "handle": "franceskafournier"}
1144+{"platform": "instagram", "handle": "marc"}
1145+{"platform": "instagram", "handle": "mikechabotfitness"}
1146+{"platform": "instagram", "handle": "claudiatihan"}
1147+{"platform": "instagram", "handle": "maudelavoie"}
1148+{"platform": "instagram", "handle": "emyjade.g"}
1149+{"platform": "instagram", "handle": "recklessxminds"}
1150+{"platform": "instagram", "handle": "rymnebbak"}
1151+{"platform": "instagram", "handle": "myriamlemaay"}
1152+{"platform": "instagram", "handle": "sousinfluencepc"}
1153+{"platform": "instagram", "handle": "essaimcollective"}
1154+{"platform": "instagram", "handle": "girlcrushgang"}
1155+{"platform": "instagram", "handle": "mariloublg_"}
1156+{"platform": "instagram", "handle": "milaydie"}
1157+{"platform": "instagram", "handle": "alanis.desilets"}
1158+{"platform": "instagram", "handle": "lacampagnedici"}
1159+{"platform": "instagram", "handle": "lajasette.co"}
1160+{"platform": "instagram", "handle": "fautquonsappelle"}
1161+{"platform": "instagram", "handle": "emmaverdeyt"}
1162+{"platform": "instagram", "handle": "lisahomsy"}
1163+{"platform": "instagram", "handle": "catherinepeachh"}
1164+{"platform": "instagram", "handle": "appy.secret"}
1165+{"platform": "instagram", "handle": "beatricebouchard"}
1166+{"platform": "instagram", "handle": "cath_belle"}
1167+{"platform": "instagram", "handle": "mahdiba"}
1168+{"platform": "instagram", "handle": "andreanec"}
1169+{"platform": "instagram", "handle": "audreyannej"}
1170+{"platform": "instagram", "handle": "alexcentomo"}
1171+{"platform": "instagram", "handle": "rise"}
1172+{"platform": "instagram", "handle": "hoaka_swimwear"}
1173+{"platform": "instagram", "handle": "hoaka_apparel"}
1174+{"platform": "instagram", "handle": "tastiofficial"}
1175+{"platform": "instagram", "handle": "mariloublg"}
1176+{"platform": "instagram", "handle": "cath"}
1177+{"platform": "instagram", "handle": "mariloubiz"}
1178+{"platform": "instagram", "handle": "boblechef"}
1179+{"platform": "instagram", "handle": "emilierossignolarts"}
1180+{"platform": "instagram", "handle": "antho.tran"}
1181+{"platform": "instagram", "handle": "carlarsenault"}
1182+{"platform": "instagram", "handle": "ricardocuisine"}
1183+{"platform": "instagram", "handle": "influenceursquebecois"}
1184+{"platform": "instagram", "handle": "justinebrouill"}
1185+{"platform": "instagram", "handle": "vivitowers"}
1186+{"platform": "instagram", "handle": "teachme"}
1187+{"platform": "instagram", "handle": "rcitystyle"}
1188+{"platform": "instagram", "handle": "winnspiration"}
1189+{"platform": "instagram", "handle": "pldetails"}
1190+{"platform": "instagram", "handle": "carli.vanheerden"}
1191+{"platform": "instagram", "handle": "toninabaratta"}
1192+{"platform": "instagram", "handle": "shayna"}
1193+{"platform": "instagram", "handle": "natalieast"}
1194+{"platform": "instagram", "handle": "struckblog"}
1195+{"platform": "instagram", "handle": "mylittlesecrets"}
1196+{"platform": "instagram", "handle": "leoniepelletier"}
1197+{"platform": "instagram", "handle": "mfpellerin"}
1198+{"platform": "instagram", "handle": "anacruz"}
1199+{"platform": "instagram", "handle": "working"}
1200+{"platform": "instagram", "handle": "mllegeri"}
1201+{"platform": "instagram", "handle": "thefitfatale"}
1202+{"platform": "tiktok", "handle": "thecordwlu"}
1203+{"platform": "x", "handle": "cordnews"}
1204+{"platform": "instagram", "handle": "festivalfranco"}
1205+{"platform": "instagram", "handle": "amys.clients"}
1206+{"platform": "instagram", "handle": "kyleandcodesign"}
1207+{"platform": "instagram", "handle": "sportsclubatelier"}
1208+{"platform": "instagram", "handle": "bartroveca"}
1209+{"platform": "instagram", "handle": "trovelivingca"}
1210+{"platform": "instagram", "handle": "crissycutz"}
1211+{"platform": "instagram", "handle": "iza.bee"}
1212+{"platform": "instagram", "handle": "narcityquebec"}
1213+{"platform": "instagram", "handle": "makeup"}
1214+{"platform": "instagram", "handle": "schulichmeddent"}
1215+{"platform": "instagram", "handle": "datcrusher"}
1216+{"platform": "instagram", "handle": "wearfigs"}
1217+{"platform": "instagram", "handle": "ashiamade"}
1218+{"platform": "instagram", "handle": "illkeepthese"}
1219+{"platform": "instagram", "handle": "trywhyte.ca"}
1220+{"platform": "instagram", "handle": "untilimdone"}
1221+{"platform": "instagram", "handle": "elite"}
1222+{"platform": "instagram", "handle": "style.withintention"}
1223+{"platform": "instagram", "handle": "boutiqueevolutionhomme"}
1224+{"platform": "instagram", "handle": "reneythemc"}
1225+{"platform": "instagram", "handle": "speke"}
1226+{"platform": "instagram", "handle": "sartoriameucci"}
1227+{"platform": "instagram", "handle": "giabymeucci"}
1228+{"platform": "instagram", "handle": "meuccifoundation"}
1229+{"platform": "instagram", "handle": "midnighthoopclub"}
1230+{"platform": "instagram", "handle": "carnetdyves"}
1231+{"platform": "instagram", "handle": "sj.mortgages"}
1232+{"platform": "instagram", "handle": "lapelinc"}
1233+{"platform": "instagram", "handle": "hellfiretattooco"}
1234+{"platform": "instagram", "handle": "heathenhandrecords"}
1235+{"platform": "instagram", "handle": "nikkarooo"}
1236+{"platform": "instagram", "handle": "forgatherfloralco"}
1237+{"platform": "instagram", "handle": "designingpolly"}
1238+{"platform": "instagram", "handle": "bluehavenwellness"}
1239+{"platform": "instagram", "handle": "livpilateswellness"}
1240+{"platform": "instagram", "handle": "pinklablondeclub"}
1241+{"platform": "instagram", "handle": "pinklablondeatelier"}
1242+{"platform": "instagram", "handle": "maurten"}
1243+{"platform": "instagram", "handle": "rouvyapp"}
1244+{"platform": "instagram", "handle": "bookishlifeofbrie"}
1245+{"platform": "instagram", "handle": "kindred.lindsay"}
1246+{"platform": "instagram", "handle": "kindred.bobcaygeon"}
1247+{"platform": "instagram", "handle": "dmilstein75"}
1248+{"platform": "instagram", "handle": "hrlexperience"}
1249+{"platform": "instagram", "handle": "arccommunity"}
1250+{"platform": "instagram", "handle": "okeanasretreats"}
1251+{"platform": "instagram", "handle": "thesoulslife"}
1252+{"platform": "instagram", "handle": "op.pfc"}
1253+{"platform": "instagram", "handle": "goldenheartcacao"}
1254+{"platform": "instagram", "handle": "sherisesfestival"}
1255+{"platform": "instagram", "handle": "cloudrealty"}
1256+{"platform": "instagram", "handle": "moresoona"}
1257+{"platform": "instagram", "handle": "thebarberszone.ca"}
1258+{"platform": "instagram", "handle": "dishwithjudy"}
1259+{"platform": "instagram", "handle": "lakeshoretattoocollective"}
1260+{"platform": "instagram", "handle": "clearcanvas.lasers"}
1261+{"platform": "instagram", "handle": "sandosmusic"}
1262+{"platform": "instagram", "handle": "amaaramaara"}
1263+{"platform": "instagram", "handle": "williamshirschtalent"}
1264+{"platform": "instagram", "handle": "chum1045"}
1265+{"platform": "instagram", "handle": "cynthiaandjosie"}
1266+{"platform": "instagram", "handle": "olivier.boyer"}
1267+{"platform": "instagram", "handle": "lovetunay"}
1268+{"platform": "instagram", "handle": "pineandpaisleyminiatures"}
1269+{"platform": "instagram", "handle": "drcindyhovington"}
1270+{"platform": "instagram", "handle": "thefeduppotter"}
1271+{"platform": "instagram", "handle": "cedricgrolet"}
modified data/sources.json +36 −0
@@ -283,6 +283,42 @@
283 "signal_identite": "—", 283 "signal_identite": "—",
284 "cadence": "hebdomadaire (rotation 7 j, lot <=200)", 284 "cadence": "hebdomadaire (rotation 7 j, lot <=200)",
285 "notes": "abonnés, bio, badge, compteurs de médias, avatar" 285 "notes": "abonnés, bio, badge, compteurs de médias, avatar"
286+ },
287+ {
288+ "id": "tavily-seed",
289+ "famille": "decouverte",
290+ "palier": 3,
291+ "acces": "dataset local moissonné par le Tavily scout (outils/creator-harvest.py) : handles extraits des annuaires/palmarès/agences QC",
292+ "signal_identite": "listes_medias (0.85)",
293+ "cadence": "par vague (re-moisson périodique)",
294+ "notes": "expansion massive du bassin ; existence vérifiée ensuite par lenrichissement Apify"
295+ },
296+ {
297+ "id": "snowball-ig",
298+ "famille": "decouverte",
299+ "palier": 1,
300+ "acces": "base interne : profils reliés Instagram (related_profiles) captés par instagram-apify",
301+ "signal_identite": "mention (0.60) — à confirmer par enrichissement",
302+ "cadence": "quotidienne (parcours en largeur, cap 4000/vague)",
303+ "notes": "levier déchelle : chaque profil IG suggère ~10-20 comptes similaires"
304+ },
305+ {
306+ "id": "patreon-apify",
307+ "famille": "enrichissement",
308+ "palier": 3,
309+ "acces": "acteur Apify maison ka-patreon (données embarquées de la page publique)",
310+ "signal_identite": "—",
311+ "cadence": "hebdomadaire (rotation 7 j)",
312+ "notes": "patrons, publications, nom, avatar"
313+ },
314+ {
315+ "id": "discord-apify",
316+ "famille": "enrichissement",
317+ "palier": 2,
318+ "acces": "acteur Apify maison ka-discord (API publique d'invitation, code sensible à la casse depuis l'URL)",
319+ "signal_identite": "—",
320+ "cadence": "hebdomadaire (rotation 7 j)",
321+ "notes": "membres approximatifs, en ligne, boosts, nom/description du serveur"
286 } 322 }
287 ] 323 ]
288 } 324 }
\ No newline at end of file
modified docs/connecteurs/INDEX.md +20 −16
@@ -1,21 +1,21 @@
1 # Créa-Ka — Index des connecteurs 1 # Créa-Ka — Index des connecteurs
2 2
3−_Généré automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Généré automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5−**31 sources au registre** · **9437 créateurs** et **10512 comptes** en BD. 5+**35 sources au registre** · **9437 créateurs** et **10533 comptes** en BD.
6 6
7 | Source | Famille | Palier | Type d'accès | Backend | Découverts | Comptes (plateforme) | État | Dernier passage | 7 | Source | Famille | Palier | Type d'accès | Backend | Découverts | Comptes (plateforme) | État | Dernier passage |
8 |---|---|---|---|---|---|---|---|---| 8 |---|---|---|---|---|---|---|---|---|
9 | [`listes-medias`](listes-medias.md) | decouverte | P3 | dataset local compilé (data/seed) | direct | 310 | — | actif | 2026-08-18T10:27… | 9 | [`listes-medias`](listes-medias.md) | decouverte | P3 | dataset local compilé (data/seed) | direct | 310 | — | actif | 2026-08-18T10:27… |
10 | [`wikidata-qc`](wikidata-qc.md) | decouverte | P3 | API SPARQL publique (Wikidata) | direct | 73 | — | actif | 2026-08-18T10:36… | 10 | [`wikidata-qc`](wikidata-qc.md) | decouverte | P3 | API SPARQL publique (Wikidata) | direct | 73 | — | actif | 2026-08-18T10:36… |
11−| [`onlyqueb`](onlyqueb.md) | decouverte | P3 | sitemap XML + JSON-LD des pages profil (S… | direct | 253 | 248 (onlyfans) | actif | 2026-08-18T10:32… | 11+| [`onlyqueb`](onlyqueb.md) | decouverte | P3 | sitemap XML + JSON-LD des pages profil (S… | direct | 253 | 250 (onlyfans) | actif | 2026-08-18T10:32… |
12−| [`youtube-recherche`](youtube-recherche.md) | decouverte | P3 | API JSON | direct | 7876 | 8084 (youtube) | actif | 2026-08-18T17:05… | 12+| [`youtube-recherche`](youtube-recherche.md) | decouverte | P3 | API JSON | direct | 7876 | 8086 (youtube) | actif | 2026-08-18T17:05… |
13 | [`wikipedia-qc`](wikipedia-qc.md) | decouverte | P3 | API SPARQL publique (Wikidata) | direct | 84 | — | actif | 2026-08-18T14:44… | 13 | [`wikipedia-qc`](wikipedia-qc.md) | decouverte | P3 | API SPARQL publique (Wikidata) | direct | 84 | — | actif | 2026-08-18T14:44… |
14 | [`palmares-apple`](palmares-apple.md) | decouverte | P2 | API iTunes Search/Lookup (publique) | direct | 0 | 462 (podcast) | actif | 2026-08-18T10:35… | 14 | [`palmares-apple`](palmares-apple.md) | decouverte | P2 | API iTunes Search/Lookup (publique) | direct | 0 | 462 (podcast) | actif | 2026-08-18T10:35… |
15−| [`balados-itunes`](balados-itunes.md) | decouverte | P2 | API iTunes Search/Lookup (publique) | direct | 460 | 462 (podcast) | actif | 2026-08-18T14:48… | 15+| [`balados-itunes`](balados-itunes.md) | decouverte | P2 | API iTunes Search/Lookup (publique) | direct | 460 | 462 (podcast) | actif | 2026-08-18T20:11… |
16 | [`instagram-profil`](instagram-profil.md) | enrichissement | P4 | pages HTML publiques | Scrapfly | 0 | 495 (instagram) | actif | 2026-08-18T12:04… | 16 | [`instagram-profil`](instagram-profil.md) | enrichissement | P4 | pages HTML publiques | Scrapfly | 0 | 495 (instagram) | actif | 2026-08-18T12:04… |
17 | [`tiktok-profil`](tiktok-profil.md) | enrichissement | P4 | pages HTML publiques | Scrapfly | 0 | 224 (tiktok) | actif | 2026-08-18T13:25… | 17 | [`tiktok-profil`](tiktok-profil.md) | enrichissement | P4 | pages HTML publiques | Scrapfly | 0 | 224 (tiktok) | actif | 2026-08-18T13:25… |
18−| [`youtube`](youtube.md) | enrichissement | P2 | API JSON | direct | 0 | 8084 (youtube) | actif | 2026-08-18T17:21… | 18+| [`youtube`](youtube.md) | enrichissement | P2 | API JSON | direct | 0 | 8086 (youtube) | actif | 2026-08-18T17:21… |
19 | [`twitch`](twitch.md) | enrichissement | P2 | API JSON | direct | 0 | 292 (twitch) | actif | 2026-08-18T17:05… | 19 | [`twitch`](twitch.md) | enrichissement | P2 | API JSON | direct | 0 | 292 (twitch) | actif | 2026-08-18T17:05… |
20 | [`link-in-bio`](link-in-bio.md) | enrichissement | P1 | pages HTML publiques | Firecrawl | 0 | — | actif | 2026-08-18T17:29… | 20 | [`link-in-bio`](link-in-bio.md) | enrichissement | P1 | pages HTML publiques | Firecrawl | 0 | — | actif | 2026-08-18T17:29… |
21 | [`balados-rss`](balados-rss.md) | enrichissement | P1 | flux RSS publics | direct | 0 | 462 (podcast) | actif | 2026-08-18T13:48… | 21 | [`balados-rss`](balados-rss.md) | enrichissement | P1 | flux RSS publics | direct | 0 | 462 (podcast) | actif | 2026-08-18T13:48… |
@@ -25,15 +25,19 @@ _Généré automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:
25 | [`twitch-decouverte`](twitch-decouverte.md) | decouverte | P3 | pages HTML publiques | direct | 262 | — | actif | 2026-08-18T14:33… | 25 | [`twitch-decouverte`](twitch-decouverte.md) | decouverte | P3 | pages HTML publiques | direct | 262 | — | actif | 2026-08-18T14:33… |
26 | [`kick-decouverte`](kick-decouverte.md) | decouverte | P4 | pages HTML publiques | Scrapfly | 119 | — | actif | 2026-08-18T14:42… | 26 | [`kick-decouverte`](kick-decouverte.md) | decouverte | P4 | pages HTML publiques | Scrapfly | 119 | — | actif | 2026-08-18T14:42… |
27 | [`region-bio`](region-bio.md) | enrichissement | P1 | pages HTML publiques | direct | 0 | — | actif | 2026-08-18T17:29… | 27 | [`region-bio`](region-bio.md) | enrichissement | P1 | pages HTML publiques | direct | 0 | — | actif | 2026-08-18T17:29… |
28−| [`instagram-apify`](instagram-apify.md) | enrichissement | P4 | — | — | 0 | — | actif | — | 28+| [`instagram-apify`](instagram-apify.md) | enrichissement | P4 | — | — | 0 | — | actif | 2026-08-18T19:58… |
29−| [`tiktok-apify`](tiktok-apify.md) | enrichissement | P4 | — | — | 0 | — | actif | — | 29+| [`tiktok-apify`](tiktok-apify.md) | enrichissement | P4 | — | — | 0 | — | actif | 2026-08-18T20:05… |
30−| [`x-apify`](x-apify.md) | enrichissement | P3 | — | — | 0 | — | actif | — | 30+| [`x-apify`](x-apify.md) | enrichissement | P3 | — | — | 0 | — | actif | 2026-08-18T19:51… |
31−| [`facebook-apify`](facebook-apify.md) | enrichissement | P4 | — | — | 0 | — | actif | — | 31+| [`facebook-apify`](facebook-apify.md) | enrichissement | P4 | — | — | 0 | — | actif | 2026-08-18T19:21… |
32−| [`threads-apify`](threads-apify.md) | enrichissement | P4 | — | — | 0 | — | actif | — | 32+| [`threads-apify`](threads-apify.md) | enrichissement | P4 | — | — | 0 | — | actif | 2026-08-18T19:21… |
33−| [`snapchat-apify`](snapchat-apify.md) | enrichissement | P3 | — | — | 0 | — | actif | — | 33+| [`snapchat-apify`](snapchat-apify.md) | enrichissement | P3 | — | — | 0 | — | actif | 2026-08-18T19:21… |
34 | [`instagram-decouverte`](instagram-decouverte.md) | decouverte | P4 | API JSON | direct | 0 | — | actif | — | 34 | [`instagram-decouverte`](instagram-decouverte.md) | decouverte | P4 | API JSON | direct | 0 | — | actif | — |
35−| [`youtube-apify`](youtube-apify.md) | enrichissement | P3 | — | — | 0 | — | actif | — | 35+| [`youtube-apify`](youtube-apify.md) | enrichissement | P3 | — | — | 0 | — | actif | 2026-08-18T19:55… |
36−| [`twitch-apify`](twitch-apify.md) | enrichissement | P3 | — | — | 0 | — | actif | — | 36+| [`twitch-apify`](twitch-apify.md) | enrichissement | P3 | — | — | 0 | — | actif | 2026-08-18T19:21… |
37−| [`kick-apify`](kick-apify.md) | enrichissement | P4 | — | — | 0 | — | actif | — | 37+| [`kick-apify`](kick-apify.md) | enrichissement | P4 | — | — | 0 | — | actif | 2026-08-18T19:21… |
38 | [`onlyfans-apify`](onlyfans-apify.md) | enrichissement | P4 | — | — | 0 | — | actif | — | 38 | [`onlyfans-apify`](onlyfans-apify.md) | enrichissement | P4 | — | — | 0 | — | actif | — |
39−| [`fansly-apify`](fansly-apify.md) | enrichissement | P3 | — | — | 0 | — | actif | — | 39+| [`fansly-apify`](fansly-apify.md) | enrichissement | P3 | — | — | 0 | — | actif | 2026-08-18T19:21… |
40+| [`tavily-seed`](tavily-seed.md) | decouverte | P3 | dataset local compilé (data/seed) | direct | 0 | — | actif | — |
41+| [`snowball-ig`](snowball-ig.md) | decouverte | P1 | pages HTML publiques | direct | 0 | — | actif | — |
42+| [`patreon-apify`](patreon-apify.md) | enrichissement | P3 | — | — | 0 | — | actif | — |
43+| [`discord-apify`](discord-apify.md) | enrichissement | P2 | — | — | 0 | — | actif | — |
modified docs/connecteurs/balados-itunes.md +7 −7
@@ -1,6 +1,6 @@
1 # `balados-itunes` — connecteur decouverte (palier 2) 1 # `balados-itunes` — connecteur decouverte (palier 2)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 460 · touchés : 460 5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 460 · touchés : 460
6 6
@@ -39,7 +39,7 @@ Source de **découverte** : produit des fiches `Creator` (tables `creators` + `a
39 | `primary_platform` | Plateforme principale | 100 % | instagram | 39 | `primary_platform` | Plateforme principale | 100 % | instagram |
40 | `platforms` | Comptes sociaux (liste) | 100 % | instagram:@quebec_nostalgie, youtube:@UC10F7nTroeQocT2vqf2LoIw, podcast:@1741442896 | 40 | `platforms` | Comptes sociaux (liste) | 100 % | instagram:@quebec_nostalgie, youtube:@UC10F7nTroeQocT2vqf2LoIw, podcast:@1741442896 |
41 | `avatar_url` | Avatar | 100 % | https://is1-ssl.mzstatic.com/image/thumb/Podcasts211/v4/3a/5f/12/3a5f1256-74a6-f716-ffb8-… | 41 | `avatar_url` | Avatar | 100 % | https://is1-ssl.mzstatic.com/image/thumb/Podcasts211/v4/3a/5f/12/3a5f1256-74a6-f716-ffb8-… |
42−| `total_reach` | Portée totale (abonnés cumulés) | 0 % | 109744 | 42+| `total_reach` | Portée totale (abonnés cumulés) | 1 % | 109741 |
43 | `link_in_bio_url` | Lien-en-bio | 0 % | https://linktr.ee/QuebecNostalgie | 43 | `link_in_bio_url` | Lien-en-bio | 0 % | https://linktr.ee/QuebecNostalgie |
44 44
45 Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les plateforme(s) `podcast` (462 comptes en BD, confiance moyenne 0.98). 45 Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les plateforme(s) `podcast` (462 comptes en BD, confiance moyenne 0.98).
@@ -58,16 +58,16 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
58 ## Fréquence & budget 58 ## Fréquence & budget
59 59
60 - **Cadence déclarée (registre)** : quotidienne (watch) 60 - **Cadence déclarée (registre)** : quotidienne (watch)
61−- **Cadence observée** (médiane sync_log) : ≈ 40 min 61+- **Cadence observée** (médiane sync_log) : ≈ 47 min
62−- **Dernier passage** : 2026-08-18T14:48:10Z — 460 créateurs, 460 comptes, +27 / ~433, 0 erreur(s), 241 s 62+- **Dernier passage** : 2026-08-18T20:11:39Z — 460 créateurs, 460 comptes, +0 / ~460, 0 erreur(s), 224 s
63 - **Throttling** : 1.5 s entre requêtes (`request_delay`) 63 - **Throttling** : 1.5 s entre requêtes (`request_delay`)
64 64
65 ## Volumétrie & complétude 65 ## Volumétrie & complétude
66 66
67 - **Créateurs découverts par la source** (`doc.source`) : 460 · **fiches touchées** (`source_ids`) : 460 67 - **Créateurs découverts par la source** (`doc.source`) : 460 · **fiches touchées** (`source_ids`) : 460
68−- **Complétude clé (découverts)** : niches 100 % · avatar 100 % · portée 0 % · région 8 % 68+- **Complétude clé (découverts)** : niches 100 % · avatar 100 % · portée 1 % · région 8 %
69−- **Comptes `podcast` en BD** : 462 — abonnés 0 % · métriques 100 % · dernière vérification 2026-08-18T17:28:28Z 69+- **Comptes `podcast` en BD** : 462 — abonnés 0 % · métriques 100 % · dernière vérification 2026-08-18T20:11:39Z
70−- **Runs journalisés (60 derniers)** : 9, dont 0 avec erreurs 70+- **Runs journalisés (60 derniers)** : 10, dont 0 avec erreurs
71 71
72 ## Erreurs connues & dépannage 72 ## Erreurs connues & dépannage
73 73
modified docs/connecteurs/balados-rss.md +2 −2
@@ -1,6 +1,6 @@
1 # `balados-rss` — connecteur enrichissement (palier 1) 1 # `balados-rss` — connecteur enrichissement (palier 1)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0
6 6
@@ -48,7 +48,7 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
48 ## Volumétrie & complétude 48 ## Volumétrie & complétude
49 49
50 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 50 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
51−- **Comptes `podcast` en BD** : 462 — abonnés 0 % · métriques 100 % · dernière vérification 2026-08-18T17:28:28Z 51+- **Comptes `podcast` en BD** : 462 — abonnés 0 % · métriques 100 % · dernière vérification 2026-08-18T20:11:39Z
52 - **Runs journalisés (60 derniers)** : 6, dont 5 avec erreurs 52 - **Runs journalisés (60 derniers)** : 6, dont 5 avec erreurs
53 53
54 ## Erreurs connues & dépannage 54 ## Erreurs connues & dépannage
modified docs/connecteurs/bio-liens.md +1 −1
@@ -1,6 +1,6 @@
1 # `bio-liens` — connecteur enrichissement (palier 1) 1 # `bio-liens` — connecteur enrichissement (palier 1)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0
6 6
added docs/connecteurs/discord-apify.md +45 −0
@@ -0,0 +1,45 @@
1+# `discord-apify` — connecteur enrichissement (palier 2)
2+
3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4+
5+**État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0
6+
7+## Description de la source
8+
9+- **Notes (registre)** : membres approximatifs, en ligne, boosts, nom/description du serveur
10+- **Signal d'identité** : — (colonne `accounts.signal` / `confidence`)
11+- **Module** : introuvable (vérifier le registre)
12+
13+## Accès
14+
15+- **Accès (registre)** : acteur Apify maison ka-discord (API publique d'invitation, code sensible à la casse depuis l'URL)
16+
17+## Champs récupérés → schéma cible
18+
19+Aucune donnée attribuable à cette source en BD pour l'instant (clés manquantes ou source en attente) — schéma cible : `creators` + `accounts`.
20+
21+## Fréquence & budget
22+
23+- **Cadence déclarée (registre)** : hebdomadaire (rotation 7 j)
24+- **Cadence observée** (médiane sync_log) : —
25+
26+## Volumétrie & complétude
27+
28+- **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
29+- **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs
30+
31+## Erreurs connues & dépannage
32+
33+Aucune erreur ni alerte dans les 60 derniers runs journalisés.
34+
35+Rejouer la source seule : `python3 run.py sync discord-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='discord-apify' ORDER BY ts DESC LIMIT 5;`).
36+
37+## Licence, attribution & conditions
38+
39+- **Cadre d'accès (registre)** : acteur Apify maison ka-discord (API publique d'invitation, code sensible à la casse depuis l'URL)
40+- **API publique** utilisée selon ses conditions (pas de clé détournée, throttling poli) ; données limitées aux profils publics.
41+- Retrait sur demande : contact@spboucher.ai (opt-out honoré à la prochaine ingestion).
42+
43+## Historique
44+
45+- 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`).
modified docs/connecteurs/facebook-apify.md +9 −4
@@ -1,6 +1,6 @@
1 # `facebook-apify` — connecteur enrichissement (palier 4) 1 # `facebook-apify` — connecteur enrichissement (palier 4)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0
6 6
@@ -21,16 +21,20 @@ Aucune donnée attribuable à cette source en BD pour l'instant (clés manquante
21 ## Fréquence & budget 21 ## Fréquence & budget
22 22
23 - **Cadence déclarée (registre)** : hebdomadaire (rotation 7 j, lot <=100) 23 - **Cadence déclarée (registre)** : hebdomadaire (rotation 7 j, lot <=100)
24−- **Cadence observée** (médiane sync_log) : — 24+- **Cadence observée** (médiane sync_log) : ≈ 9 min
25+- **Dernier passage** : 2026-08-18T19:21:41Z — 0 créateurs, 0 comptes, +0 / ~0, 0 erreur(s), 0 s
25 26
26 ## Volumétrie & complétude 27 ## Volumétrie & complétude
27 28
28 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 29 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
29−- **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs 30+- **Runs journalisés (60 derniers)** : 3, dont 0 avec erreurs
30 31
31 ## Erreurs connues & dépannage 32 ## Erreurs connues & dépannage
32 33
33−Aucune erreur ni alerte dans les 60 derniers runs journalisés. 34+| Passage | Erreurs | Alerte (sync_log) |
35+|---|---|---|
36+| 2026-08-18T19:21:41Z | 0 | 0 créateur retourné — source possiblement bloquée |
37+| 2026-08-18T19:03:59Z | 0 | 0 créateur retourné — source possiblement bloquée |
34 38
35 Rejouer la source seule : `python3 run.py sync facebook-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='facebook-apify' ORDER BY ts DESC LIMIT 5;`). 39 Rejouer la source seule : `python3 run.py sync facebook-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='facebook-apify' ORDER BY ts DESC LIMIT 5;`).
36 40
@@ -42,4 +46,5 @@ Rejouer la source seule : `python3 run.py sync facebook-apify` · vérifier `syn
42 46
43 ## Historique 47 ## Historique
44 48
49+- 2026-08-18 — plus ancien passage journalisé dans `sync_log` (fenêtre des 60 derniers).
45 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`). 50 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`).
modified docs/connecteurs/fansly-apify.md +9 −4
@@ -1,6 +1,6 @@
1 # `fansly-apify` — connecteur enrichissement (palier 3) 1 # `fansly-apify` — connecteur enrichissement (palier 3)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0
6 6
@@ -21,16 +21,20 @@ Aucune donnée attribuable à cette source en BD pour l'instant (clés manquante
21 ## Fréquence & budget 21 ## Fréquence & budget
22 22
23 - **Cadence déclarée (registre)** : hebdomadaire (rotation 7 j, lot <=200) 23 - **Cadence déclarée (registre)** : hebdomadaire (rotation 7 j, lot <=200)
24−- **Cadence observée** (médiane sync_log) : — 24+- **Cadence observée** (médiane sync_log) : ≈ 9 min
25+- **Dernier passage** : 2026-08-18T19:21:41Z — 0 créateurs, 0 comptes, +0 / ~0, 0 erreur(s), 0 s
25 26
26 ## Volumétrie & complétude 27 ## Volumétrie & complétude
27 28
28 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 29 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
29−- **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs 30+- **Runs journalisés (60 derniers)** : 3, dont 0 avec erreurs
30 31
31 ## Erreurs connues & dépannage 32 ## Erreurs connues & dépannage
32 33
33−Aucune erreur ni alerte dans les 60 derniers runs journalisés. 34+| Passage | Erreurs | Alerte (sync_log) |
35+|---|---|---|
36+| 2026-08-18T19:21:41Z | 0 | 0 créateur retourné — source possiblement bloquée |
37+| 2026-08-18T19:03:58Z | 0 | 0 créateur retourné — source possiblement bloquée |
34 38
35 Rejouer la source seule : `python3 run.py sync fansly-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='fansly-apify' ORDER BY ts DESC LIMIT 5;`). 39 Rejouer la source seule : `python3 run.py sync fansly-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='fansly-apify' ORDER BY ts DESC LIMIT 5;`).
36 40
@@ -42,4 +46,5 @@ Rejouer la source seule : `python3 run.py sync fansly-apify` · vérifier `sync_
42 46
43 ## Historique 47 ## Historique
44 48
49+- 2026-08-18 — plus ancien passage journalisé dans `sync_log` (fenêtre des 60 derniers).
45 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`). 50 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`).
modified docs/connecteurs/instagram-apify.md +10 −4
@@ -1,6 +1,6 @@
1 # `instagram-apify` — connecteur enrichissement (palier 4) 1 # `instagram-apify` — connecteur enrichissement (palier 4)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0
6 6
@@ -21,16 +21,21 @@ Aucune donnée attribuable à cette source en BD pour l'instant (clés manquante
21 ## Fréquence & budget 21 ## Fréquence & budget
22 22
23 - **Cadence déclarée (registre)** : quotidienne (rotation 5 j, lot <=400) 23 - **Cadence déclarée (registre)** : quotidienne (rotation 5 j, lot <=400)
24−- **Cadence observée** (médiane sync_log) : — 24+- **Cadence observée** (médiane sync_log) : ≈ 18 min
25+- **Dernier passage** : 2026-08-18T19:58:58Z — 276 créateurs, 767 comptes, +0 / ~276, 0 erreur(s), 182 s
25 26
26 ## Volumétrie & complétude 27 ## Volumétrie & complétude
27 28
28 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 29 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
29−- **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs 30+- **Runs journalisés (60 derniers)** : 4, dont 0 avec erreurs
30 31
31 ## Erreurs connues & dépannage 32 ## Erreurs connues & dépannage
32 33
33−Aucune erreur ni alerte dans les 60 derniers runs journalisés. 34+| Passage | Erreurs | Alerte (sync_log) |
35+|---|---|---|
36+| 2026-08-18T19:29:35Z | 0 | 0 créateur retourné — source possiblement bloquée |
37+| 2026-08-18T19:21:42Z | 0 | 0 créateur retourné — source possiblement bloquée |
38+| 2026-08-18T19:03:58Z | 0 | 0 créateur retourné — source possiblement bloquée |
34 39
35 Rejouer la source seule : `python3 run.py sync instagram-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='instagram-apify' ORDER BY ts DESC LIMIT 5;`). 40 Rejouer la source seule : `python3 run.py sync instagram-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='instagram-apify' ORDER BY ts DESC LIMIT 5;`).
36 41
@@ -42,4 +47,5 @@ Rejouer la source seule : `python3 run.py sync instagram-apify` · vérifier `sy
42 47
43 ## Historique 48 ## Historique
44 49
50+- 2026-08-18 — plus ancien passage journalisé dans `sync_log` (fenêtre des 60 derniers).
45 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`). 51 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`).
modified docs/connecteurs/instagram-decouverte.md +1 −1
@@ -1,6 +1,6 @@
1 # `instagram-decouverte` — connecteur decouverte (palier 4) 1 # `instagram-decouverte` — connecteur decouverte (palier 4)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 0 · touchés : 0
6 6
modified docs/connecteurs/instagram-profil.md +6 −6
@@ -1,6 +1,6 @@
1 # `instagram-profil` — connecteur enrichissement (palier 4) 1 # `instagram-profil` — connecteur enrichissement (palier 4)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichment) · Backend : Scrapfly · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichment) · Backend : Scrapfly · Créateurs découverts : 0 · touchés : 0
6 6
@@ -31,12 +31,12 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
31 |---|---|---|---| 31 |---|---|---|---|
32 | `handle` | Handle | 100 % | catherinepaiz | 32 | `handle` | Handle | 100 % | catherinepaiz |
33 | `url` | URL du profil | 100 % | https://www.instagram.com/catherinepaiz/ | 33 | `url` | URL du profil | 100 % | https://www.instagram.com/catherinepaiz/ |
34−| `followers` | Abonnés | 70 % | 7023251 | 34+| `followers` | Abonnés | 73 % | 7022873 |
35−| `verified` | Badge vérifié | 58 % | 1 | 35+| `verified` | Badge vérifié | 62 % | 1 |
36 | `confidence` | Confiance d'identité | 100 % | 0.85 | 36 | `confidence` | Confiance d'identité | 100 % | 0.85 |
37 | `signal` | Signal d'identité | 100 % | base_publique | 37 | `signal` | Signal d'identité | 100 % | base_publique |
38−| `metrics` | Métriques détaillées (JSON) | 58 % | {"following": 248, "posts": 667, "is_business": false} | 38+| `metrics` | Métriques détaillées (JSON) | 62 % | {"following": 248, "posts": 667, "is_business": false, "highlight_reels": 22, "avg_likes"… |
39−| `last_checked` | Dernière vérification | 100 % | 2026-08-18T11:35:29Z | 39+| `last_checked` | Dernière vérification | 100 % | 2026-08-18T19:58:58Z |
40 40
41 ## Fréquence & budget 41 ## Fréquence & budget
42 42
@@ -48,7 +48,7 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
48 ## Volumétrie & complétude 48 ## Volumétrie & complétude
49 49
50 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 50 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
51−- **Comptes `instagram` en BD** : 495 — abonnés 70 % · métriques 58 % · dernière vérification 2026-08-18T17:29:45Z 51+- **Comptes `instagram` en BD** : 495 — abonnés 73 % · métriques 62 % · dernière vérification 2026-08-18T20:05:02Z
52 - **Runs journalisés (60 derniers)** : 5, dont 0 avec erreurs 52 - **Runs journalisés (60 derniers)** : 5, dont 0 avec erreurs
53 53
54 ## Erreurs connues & dépannage 54 ## Erreurs connues & dépannage
modified docs/connecteurs/kick-apify.md +9 −4
@@ -1,6 +1,6 @@
1 # `kick-apify` — connecteur enrichissement (palier 4) 1 # `kick-apify` — connecteur enrichissement (palier 4)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0
6 6
@@ -21,16 +21,20 @@ Aucune donnée attribuable à cette source en BD pour l'instant (clés manquante
21 ## Fréquence & budget 21 ## Fréquence & budget
22 22
23 - **Cadence déclarée (registre)** : quotidienne (rotation 5 j, lot <=120) 23 - **Cadence déclarée (registre)** : quotidienne (rotation 5 j, lot <=120)
24−- **Cadence observée** (médiane sync_log) : — 24+- **Cadence observée** (médiane sync_log) : ≈ 9 min
25+- **Dernier passage** : 2026-08-18T19:21:40Z — 0 créateurs, 0 comptes, +0 / ~0, 0 erreur(s), 0 s
25 26
26 ## Volumétrie & complétude 27 ## Volumétrie & complétude
27 28
28 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 29 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
29−- **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs 30+- **Runs journalisés (60 derniers)** : 3, dont 0 avec erreurs
30 31
31 ## Erreurs connues & dépannage 32 ## Erreurs connues & dépannage
32 33
33−Aucune erreur ni alerte dans les 60 derniers runs journalisés. 34+| Passage | Erreurs | Alerte (sync_log) |
35+|---|---|---|
36+| 2026-08-18T19:21:40Z | 0 | 0 créateur retourné — source possiblement bloquée |
37+| 2026-08-18T19:03:58Z | 0 | 0 créateur retourné — source possiblement bloquée |
34 38
35 Rejouer la source seule : `python3 run.py sync kick-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='kick-apify' ORDER BY ts DESC LIMIT 5;`). 39 Rejouer la source seule : `python3 run.py sync kick-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='kick-apify' ORDER BY ts DESC LIMIT 5;`).
36 40
@@ -42,4 +46,5 @@ Rejouer la source seule : `python3 run.py sync kick-apify` · vérifier `sync_lo
42 46
43 ## Historique 47 ## Historique
44 48
49+- 2026-08-18 — plus ancien passage journalisé dans `sync_log` (fenêtre des 60 derniers).
45 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`). 50 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`).
modified docs/connecteurs/kick-decouverte.md +7 −7
@@ -1,6 +1,6 @@
1 # `kick-decouverte` — connecteur decouverte (palier 4) 1 # `kick-decouverte` — connecteur decouverte (palier 4)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : decouverte (discovery) · Backend : Scrapfly · Créateurs découverts : 119 · touchés : 119 5 **État : actif** · Famille : decouverte (discovery) · Backend : Scrapfly · Créateurs découverts : 119 · touchés : 119
6 6
@@ -29,17 +29,17 @@ Source de **découverte** : produit des fiches `Creator` (tables `creators` + `a
29 29
30 | Champ du doc créateur | Contenu | Renseigné | Exemple réel | 30 | Champ du doc créateur | Contenu | Renseigné | Exemple réel |
31 |---|---|---|---| 31 |---|---|---|---|
32−| `display_name` | Nom public | 100 % | valquebrada | 32+| `display_name` | Nom public | 100 % | juandemontreal |
33−| `bio` | Bio | 25 % | Meu nome é Valmir Lima, tenho 32 anos de idade, curto jogar GTA RP. Vou mostrar um pouco … | 33+| `bio` | Bio | 28 % | Gracias por seguirme hasta aqui tmb............ |
34 | `region` | Région | 0 % | — | 34 | `region` | Région | 0 % | — |
35 | `city` | Ville | 0 % | — | 35 | `city` | Ville | 0 % | — |
36 | `niches` | Niches (liste) | 100 % | gaming | 36 | `niches` | Niches (liste) | 100 % | gaming |
37 | `languages` | Langues (liste) | 100 % | fr | 37 | `languages` | Langues (liste) | 100 % | fr |
38 | `creator_type` | Type de créateur | 100 % | streamer | 38 | `creator_type` | Type de créateur | 100 % | streamer |
39−| `primary_platform` | Plateforme principale | 100 % | twitch | 39+| `primary_platform` | Plateforme principale | 100 % | tiktok |
40−| `platforms` | Comptes sociaux (liste) | 100 % | twitch:@valquebrada, kick:@valquebrada, instagram:@val_quebrada | 40+| `platforms` | Comptes sociaux (liste) | 100 % | tiktok:@juandemontrealoficial, instagram:@juandemontreal, kick:@juandemontreal |
41−| `avatar_url` | Avatar | 40 % | https://files.kick.com/images/user/15480678/profile_image/conversion/f1cf1446-e43a-478d-8… | 41+| `avatar_url` | Avatar | 40 % | https://files.kick.com/images/user/36432333/profile_image/conversion/2e63a30c-e041-4915-9… |
42−| `total_reach` | Portée totale (abonnés cumulés) | 56 % | 2772 | 42+| `total_reach` | Portée totale (abonnés cumulés) | 56 % | 23455724 |
43 | `link_in_bio_url` | Lien-en-bio | 0 % | — | 43 | `link_in_bio_url` | Lien-en-bio | 0 % | — |
44 44
45 ## Fréquence & budget 45 ## Fréquence & budget
modified docs/connecteurs/link-in-bio.md +1 −1
@@ -1,6 +1,6 @@
1 # `link-in-bio` — connecteur enrichissement (palier 1) 1 # `link-in-bio` — connecteur enrichissement (palier 1)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichment) · Backend : Firecrawl · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichment) · Backend : Firecrawl · Créateurs découverts : 0 · touchés : 0
6 6
modified docs/connecteurs/listes-medias.md +6 −6
@@ -1,6 +1,6 @@
1 # `listes-medias` — connecteur decouverte (palier 3) 1 # `listes-medias` — connecteur decouverte (palier 3)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 310 · touchés : 310 5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 310 · touchés : 310
6 6
@@ -29,7 +29,7 @@ Source de **découverte** : produit des fiches `Creator` (tables `creators` + `a
29 | Champ du doc créateur | Contenu | Renseigné | Exemple réel | 29 | Champ du doc créateur | Contenu | Renseigné | Exemple réel |
30 |---|---|---|---| 30 |---|---|---|---|
31 | `display_name` | Nom public | 100 % | Enola Bédard | 31 | `display_name` | Nom public | 100 % | Enola Bédard |
32−| `bio` | Bio | 73 % | Énola Bédard (born September 14, 2000) is a Canadian dancer, singer, and social media per… | 32+| `bio` | Bio | 76 % | Énola Bédard (born September 14, 2000) is a Canadian dancer, singer, and social media per… |
33 | `region` | Région | 51 % | Capitale-Nationale | 33 | `region` | Région | 51 % | Capitale-Nationale |
34 | `city` | Ville | 51 % | Québec | 34 | `city` | Ville | 51 % | Québec |
35 | `niches` | Niches (liste) | 100 % | danse, lifestyle | 35 | `niches` | Niches (liste) | 100 % | danse, lifestyle |
@@ -37,9 +37,9 @@ Source de **découverte** : produit des fiches `Creator` (tables `creators` + `a
37 | `creator_type` | Type de créateur | 100 % | createur-tiktok | 37 | `creator_type` | Type de créateur | 100 % | createur-tiktok |
38 | `primary_platform` | Plateforme principale | 100 % | tiktok | 38 | `primary_platform` | Plateforme principale | 100 % | tiktok |
39 | `platforms` | Comptes sociaux (liste) | 100 % | tiktok:@enola.bedard, youtube:@enola.bedard, instagram:@enola.bedard | 39 | `platforms` | Comptes sociaux (liste) | 100 % | tiktok:@enola.bedard, youtube:@enola.bedard, instagram:@enola.bedard |
40−| `avatar_url` | Avatar | 75 % | https://scontent-lga3-2.cdninstagram.com/v/t51.82787-19/515154150_18510310135012441_32506… | 40+| `avatar_url` | Avatar | 78 % | https://scontent-lga3-2.cdninstagram.com/v/t51.82787-19/515154150_18510310135012441_32506… |
41−| `total_reach` | Portée totale (abonnés cumulés) | 90 % | 24917522 | 41+| `total_reach` | Portée totale (abonnés cumulés) | 91 % | 24996097 |
42−| `link_in_bio_url` | Lien-en-bio | 24 % | — | 42+| `link_in_bio_url` | Lien-en-bio | 25 % | — |
43 43
44 ## Fréquence & budget 44 ## Fréquence & budget
45 45
@@ -51,7 +51,7 @@ Source de **découverte** : produit des fiches `Creator` (tables `creators` + `a
51 ## Volumétrie & complétude 51 ## Volumétrie & complétude
52 52
53 - **Créateurs découverts par la source** (`doc.source`) : 310 · **fiches touchées** (`source_ids`) : 310 53 - **Créateurs découverts par la source** (`doc.source`) : 310 · **fiches touchées** (`source_ids`) : 310
54−- **Complétude clé (découverts)** : niches 100 % · avatar 75 % · portée 90 % · région 51 % 54+- **Complétude clé (découverts)** : niches 100 % · avatar 78 % · portée 91 % · région 51 %
55 - **Runs journalisés (60 derniers)** : 12, dont 0 avec erreurs 55 - **Runs journalisés (60 derniers)** : 12, dont 0 avec erreurs
56 56
57 ## Erreurs connues & dépannage 57 ## Erreurs connues & dépannage
modified docs/connecteurs/onlyfans-apify.md +1 −1
@@ -1,6 +1,6 @@
1 # `onlyfans-apify` — connecteur enrichissement (palier 4) 1 # `onlyfans-apify` — connecteur enrichissement (palier 4)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0
6 6
modified docs/connecteurs/onlyqueb.md +7 −7
@@ -1,6 +1,6 @@
1 # `onlyqueb` — connecteur decouverte (palier 3) 1 # `onlyqueb` — connecteur decouverte (palier 3)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 253 · touchés : 253 5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 253 · touchés : 253
6 6
@@ -37,12 +37,12 @@ Source de **découverte** : produit des fiches `Creator` (tables `creators` + `a
37 | `languages` | Langues (liste) | 100 % | fr | 37 | `languages` | Langues (liste) | 100 % | fr |
38 | `creator_type` | Type de créateur | 100 % | influenceur | 38 | `creator_type` | Type de créateur | 100 % | influenceur |
39 | `primary_platform` | Plateforme principale | 100 % | instagram | 39 | `primary_platform` | Plateforme principale | 100 % | instagram |
40−| `platforms` | Comptes sociaux (liste) | 100 % | instagram:@jadelavoie, x:@missjadelavoie, onlyfans:@misslavoie | 40+| `platforms` | Comptes sociaux (liste) | 100 % | instagram:@jadelavoie, tiktok:@miss.jadelavoie, x:@missjadelavoie |
41 | `avatar_url` | Avatar | 100 % | https://storage.googleapis.com/onlyqueb/MQZBiXsbMQa31zxj9P_mabNxNITFBxa6 | 41 | `avatar_url` | Avatar | 100 % | https://storage.googleapis.com/onlyqueb/MQZBiXsbMQa31zxj9P_mabNxNITFBxa6 |
42−| `total_reach` | Portée totale (abonnés cumulés) | 20 % | 1571053 | 42+| `total_reach` | Portée totale (abonnés cumulés) | 35 % | 2615987 |
43−| `link_in_bio_url` | Lien-en-bio | 2 % | — | 43+| `link_in_bio_url` | Lien-en-bio | 5 % | — |
44 44
45−Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les plateforme(s) `onlyfans` (248 comptes en BD, confiance moyenne 0.90). 45+Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les plateforme(s) `onlyfans` (250 comptes en BD, confiance moyenne 0.90).
46 46
47 | Colonne `accounts` | Contenu | Renseignée | Exemple réel | 47 | Colonne `accounts` | Contenu | Renseignée | Exemple réel |
48 |---|---|---|---| 48 |---|---|---|---|
@@ -65,8 +65,8 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
65 ## Volumétrie & complétude 65 ## Volumétrie & complétude
66 66
67 - **Créateurs découverts par la source** (`doc.source`) : 253 · **fiches touchées** (`source_ids`) : 253 67 - **Créateurs découverts par la source** (`doc.source`) : 253 · **fiches touchées** (`source_ids`) : 253
68−- **Complétude clé (découverts)** : niches 100 % · avatar 100 % · portée 20 % · région 2 % 68+- **Complétude clé (découverts)** : niches 100 % · avatar 100 % · portée 35 % · région 2 %
69−- **Comptes `onlyfans` en BD** : 248 — abonnés 0 % · métriques 0 % · dernière vérification 2026-08-18T17:29:45Z 69+- **Comptes `onlyfans` en BD** : 250 — abonnés 0 % · métriques 0 % · dernière vérification 2026-08-18T19:58:58Z
70 - **Runs journalisés (60 derniers)** : 8, dont 0 avec erreurs 70 - **Runs journalisés (60 derniers)** : 8, dont 0 avec erreurs
71 71
72 ## Erreurs connues & dépannage 72 ## Erreurs connues & dépannage
modified docs/connecteurs/palmares-apple.md +2 −2
@@ -1,6 +1,6 @@
1 # `palmares-apple` — connecteur decouverte (palier 2) 1 # `palmares-apple` — connecteur decouverte (palier 2)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 0 · touchés : 0
6 6
@@ -48,7 +48,7 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
48 ## Volumétrie & complétude 48 ## Volumétrie & complétude
49 49
50 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 50 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
51−- **Comptes `podcast` en BD** : 462 — abonnés 0 % · métriques 100 % · dernière vérification 2026-08-18T17:28:28Z 51+- **Comptes `podcast` en BD** : 462 — abonnés 0 % · métriques 100 % · dernière vérification 2026-08-18T20:11:39Z
52 - **Runs journalisés (60 derniers)** : 3, dont 0 avec erreurs 52 - **Runs journalisés (60 derniers)** : 3, dont 0 avec erreurs
53 53
54 ## Erreurs connues & dépannage 54 ## Erreurs connues & dépannage
added docs/connecteurs/patreon-apify.md +45 −0
@@ -0,0 +1,45 @@
1+# `patreon-apify` — connecteur enrichissement (palier 3)
2+
3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4+
5+**État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0
6+
7+## Description de la source
8+
9+- **Notes (registre)** : patrons, publications, nom, avatar
10+- **Signal d'identité** : — (colonne `accounts.signal` / `confidence`)
11+- **Module** : introuvable (vérifier le registre)
12+
13+## Accès
14+
15+- **Accès (registre)** : acteur Apify maison ka-patreon (données embarquées de la page publique)
16+
17+## Champs récupérés → schéma cible
18+
19+Aucune donnée attribuable à cette source en BD pour l'instant (clés manquantes ou source en attente) — schéma cible : `creators` + `accounts`.
20+
21+## Fréquence & budget
22+
23+- **Cadence déclarée (registre)** : hebdomadaire (rotation 7 j)
24+- **Cadence observée** (médiane sync_log) : —
25+
26+## Volumétrie & complétude
27+
28+- **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
29+- **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs
30+
31+## Erreurs connues & dépannage
32+
33+Aucune erreur ni alerte dans les 60 derniers runs journalisés.
34+
35+Rejouer la source seule : `python3 run.py sync patreon-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='patreon-apify' ORDER BY ts DESC LIMIT 5;`).
36+
37+## Licence, attribution & conditions
38+
39+- **Cadre d'accès (registre)** : acteur Apify maison ka-patreon (données embarquées de la page publique)
40+- **API publique** utilisée selon ses conditions (pas de clé détournée, throttling poli) ; données limitées aux profils publics.
41+- Retrait sur demande : contact@spboucher.ai (opt-out honoré à la prochaine ingestion).
42+
43+## Historique
44+
45+- 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`).
modified docs/connecteurs/podcastindex.md +2 −2
@@ -1,6 +1,6 @@
1 # `podcastindex` — connecteur enrichissement (palier 2) 1 # `podcastindex` — connecteur enrichissement (palier 2)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : prêt — clés requises** · Famille : enrichissement (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0 5 **État : prêt — clés requises** · Famille : enrichissement (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0
6 6
@@ -47,7 +47,7 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
47 ## Volumétrie & complétude 47 ## Volumétrie & complétude
48 48
49 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 49 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
50−- **Comptes `podcast` en BD** : 462 — abonnés 0 % · métriques 100 % · dernière vérification 2026-08-18T17:28:28Z 50+- **Comptes `podcast` en BD** : 462 — abonnés 0 % · métriques 100 % · dernière vérification 2026-08-18T20:11:39Z
51 - **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs 51 - **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs
52 52
53 ## Erreurs connues & dépannage 53 ## Erreurs connues & dépannage
modified docs/connecteurs/region-bio.md +1 −1
@@ -1,6 +1,6 @@
1 # `region-bio` — connecteur enrichissement (palier 1) 1 # `region-bio` — connecteur enrichissement (palier 1)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0
6 6
modified docs/connecteurs/snapchat-apify.md +9 −4
@@ -1,6 +1,6 @@
1 # `snapchat-apify` — connecteur enrichissement (palier 3) 1 # `snapchat-apify` — connecteur enrichissement (palier 3)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0
6 6
@@ -21,16 +21,20 @@ Aucune donnée attribuable à cette source en BD pour l'instant (clés manquante
21 ## Fréquence & budget 21 ## Fréquence & budget
22 22
23 - **Cadence déclarée (registre)** : hebdomadaire (rotation 7 j, lot <=60) 23 - **Cadence déclarée (registre)** : hebdomadaire (rotation 7 j, lot <=60)
24−- **Cadence observée** (médiane sync_log) : — 24+- **Cadence observée** (médiane sync_log) : ≈ 9 min
25+- **Dernier passage** : 2026-08-18T19:21:40Z — 0 créateurs, 0 comptes, +0 / ~0, 0 erreur(s), 0 s
25 26
26 ## Volumétrie & complétude 27 ## Volumétrie & complétude
27 28
28 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 29 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
29−- **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs 30+- **Runs journalisés (60 derniers)** : 3, dont 0 avec erreurs
30 31
31 ## Erreurs connues & dépannage 32 ## Erreurs connues & dépannage
32 33
33−Aucune erreur ni alerte dans les 60 derniers runs journalisés. 34+| Passage | Erreurs | Alerte (sync_log) |
35+|---|---|---|
36+| 2026-08-18T19:21:40Z | 0 | 0 créateur retourné — source possiblement bloquée |
37+| 2026-08-18T19:03:59Z | 0 | 0 créateur retourné — source possiblement bloquée |
34 38
35 Rejouer la source seule : `python3 run.py sync snapchat-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='snapchat-apify' ORDER BY ts DESC LIMIT 5;`). 39 Rejouer la source seule : `python3 run.py sync snapchat-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='snapchat-apify' ORDER BY ts DESC LIMIT 5;`).
36 40
@@ -42,4 +46,5 @@ Rejouer la source seule : `python3 run.py sync snapchat-apify` · vérifier `syn
42 46
43 ## Historique 47 ## Historique
44 48
49+- 2026-08-18 — plus ancien passage journalisé dans `sync_log` (fenêtre des 60 derniers).
45 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`). 50 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`).
added docs/connecteurs/snowball-ig.md +54 −0
@@ -0,0 +1,54 @@
1+# `snowball-ig` — connecteur decouverte (palier 1)
2+
3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4+
5+**État : actif** · Famille : decouverte (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0
6+
7+## Description de la source
8+
9+Connecteur DÉCOUVERTE par boule de neige — exploite les profils reliés (`related_profiles`) captés par l'enrichissement Instagram (instagram-apify) pour créer de nouvelles fiches. C'est le levier d'échelle : chaque profil IG suggère ~10-20 comptes similaires → parcours en largeur qui fait croître le bassin de dizaines de milliers au fil des vagues quotidiennes. Aucune requête réseau (lit la base).
10+
11+- **Notes (registre)** : levier déchelle : chaque profil IG suggère ~10-20 comptes similaires
12+- **Signal d'identité** : mention (0.60) — à confirmer par enrichissement (colonne `accounts.signal` / `confidence`)
13+- **Module** : `creaka/connectors/snowball.py` — classe `SnowballConnector` (`kind = "enrichment"`)
14+
15+## Accès
16+
17+- **Accès (registre)** : base interne : profils reliés Instagram (related_profiles) captés par instagram-apify
18+- **Type d'accès (code)** : pages HTML publiques
19+- **Endpoint de base** : —
20+- **Pagination** : réponse unique (pas de pagination)
21+- **Backend anti-bot / rendu** : requests direct
22+- **Politesse** : 0.8 s entre requêtes, timeout 30 s, UA `CreaKaBot/1.0 (+https://www.crea-ka.com/bot)`
23+- **Authentification** : aucune — contenu public / API anonyme
24+
25+## Champs récupérés → schéma cible
26+
27+Aucune donnée attribuable à cette source en BD pour l'instant (clés manquantes ou source en attente) — schéma cible : `creators` + `accounts`.
28+
29+## Fréquence & budget
30+
31+- **Cadence déclarée (registre)** : quotidienne (parcours en largeur, cap 4000/vague)
32+- **Cadence observée** (médiane sync_log) : —
33+- **Throttling** : 0.8 s entre requêtes (`request_delay`)
34+
35+## Volumétrie & complétude
36+
37+- **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
38+- **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs
39+
40+## Erreurs connues & dépannage
41+
42+Aucune erreur ni alerte dans les 60 derniers runs journalisés.
43+
44+Rejouer la source seule : `python3 run.py sync snowball-ig` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='snowball-ig' ORDER BY ts DESC LIMIT 5;`).
45+
46+## Licence, attribution & conditions
47+
48+- **Cadre d'accès (registre)** : base interne : profils reliés Instagram (related_profiles) captés par instagram-apify
49+- **Profils publics uniquement** : UA identifiable `CreaKaBot/1.0 (+https://www.crea-ka.com/bot; contact@spboucher.ai)`, throttling poli, respect des opt-out (`data/optout.json`) et du volet éthique (`creaka/ethics.py` — mineurs exclus via `is_minor`).
50+- Retrait sur demande : contact@spboucher.ai (opt-out honoré à la prochaine ingestion).
51+
52+## Historique
53+
54+- 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`).
added docs/connecteurs/tavily-seed.md +54 −0
@@ -0,0 +1,54 @@
1+# `tavily-seed` — connecteur decouverte (palier 3)
2+
3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4+
5+**État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 0 · touchés : 0
6+
7+## Description de la source
8+
9+Connecteur DÉCOUVERTE à grande échelle — graines de créateurs québécois moissonnées par le Tavily scout (outils/creator-harvest.py du dépôt groupe-ka-connecteurs) : handles sociaux extraits des pages d'annuaires/palmarès/agences QC. Dataset local (aucune requête ici) : data/seed/qc_creator_seeds.jsonl. L'enrichissement (Apify) vérifie ensuite l'existence et remplit nom/abonnés/contenu.
10+
11+- **Notes (registre)** : expansion massive du bassin ; existence vérifiée ensuite par lenrichissement Apify
12+- **Signal d'identité** : listes_medias (0.85) (colonne `accounts.signal` / `confidence`)
13+- **Module** : `creaka/connectors/tavily_seed.py` — classe `TavilySeedConnector` (`kind = "discovery"`)
14+
15+## Accès
16+
17+- **Accès (registre)** : dataset local moissonné par le Tavily scout (outils/creator-harvest.py) : handles extraits des annuaires/palmarès/agences QC
18+- **Type d'accès (code)** : dataset local compilé (data/seed)
19+- **Endpoint de base** : —
20+- **Pagination** : réponse unique (pas de pagination)
21+- **Backend anti-bot / rendu** : requests direct
22+- **Politesse** : 0.8 s entre requêtes, timeout 30 s, UA `CreaKaBot/1.0 (+https://www.crea-ka.com/bot)`
23+- **Authentification** : aucune — contenu public / API anonyme
24+
25+## Champs récupérés → schéma cible
26+
27+Aucune donnée attribuable à cette source en BD pour l'instant (clés manquantes ou source en attente) — schéma cible : `creators` + `accounts`.
28+
29+## Fréquence & budget
30+
31+- **Cadence déclarée (registre)** : par vague (re-moisson périodique)
32+- **Cadence observée** (médiane sync_log) : —
33+- **Throttling** : 0.8 s entre requêtes (`request_delay`)
34+
35+## Volumétrie & complétude
36+
37+- **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
38+- **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs
39+
40+## Erreurs connues & dépannage
41+
42+Aucune erreur ni alerte dans les 60 derniers runs journalisés.
43+
44+Rejouer la source seule : `python3 run.py sync tavily-seed` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='tavily-seed' ORDER BY ts DESC LIMIT 5;`).
45+
46+## Licence, attribution & conditions
47+
48+- **Cadre d'accès (registre)** : dataset local moissonné par le Tavily scout (outils/creator-harvest.py) : handles extraits des annuaires/palmarès/agences QC
49+- **Données compilées** de listes et palmarès médias **publics** ; seuls des faits publics (nom, handle, audience approximative) sont conservés.
50+- Retrait sur demande : contact@spboucher.ai (opt-out honoré à la prochaine ingestion).
51+
52+## Historique
53+
54+- 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`).
modified docs/connecteurs/threads-apify.md +9 −4
@@ -1,6 +1,6 @@
1 # `threads-apify` — connecteur enrichissement (palier 4) 1 # `threads-apify` — connecteur enrichissement (palier 4)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0
6 6
@@ -21,16 +21,20 @@ Aucune donnée attribuable à cette source en BD pour l'instant (clés manquante
21 ## Fréquence & budget 21 ## Fréquence & budget
22 22
23 - **Cadence déclarée (registre)** : hebdomadaire (rotation 7 j, lot <=60) 23 - **Cadence déclarée (registre)** : hebdomadaire (rotation 7 j, lot <=60)
24−- **Cadence observée** (médiane sync_log) : — 24+- **Cadence observée** (médiane sync_log) : ≈ 9 min
25+- **Dernier passage** : 2026-08-18T19:21:41Z — 0 créateurs, 0 comptes, +0 / ~0, 0 erreur(s), 0 s
25 26
26 ## Volumétrie & complétude 27 ## Volumétrie & complétude
27 28
28 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 29 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
29−- **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs 30+- **Runs journalisés (60 derniers)** : 3, dont 0 avec erreurs
30 31
31 ## Erreurs connues & dépannage 32 ## Erreurs connues & dépannage
32 33
33−Aucune erreur ni alerte dans les 60 derniers runs journalisés. 34+| Passage | Erreurs | Alerte (sync_log) |
35+|---|---|---|
36+| 2026-08-18T19:21:41Z | 0 | 0 créateur retourné — source possiblement bloquée |
37+| 2026-08-18T19:03:59Z | 0 | 0 créateur retourné — source possiblement bloquée |
34 38
35 Rejouer la source seule : `python3 run.py sync threads-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='threads-apify' ORDER BY ts DESC LIMIT 5;`). 39 Rejouer la source seule : `python3 run.py sync threads-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='threads-apify' ORDER BY ts DESC LIMIT 5;`).
36 40
@@ -42,4 +46,5 @@ Rejouer la source seule : `python3 run.py sync threads-apify` · vérifier `sync
42 46
43 ## Historique 47 ## Historique
44 48
49+- 2026-08-18 — plus ancien passage journalisé dans `sync_log` (fenêtre des 60 derniers).
45 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`). 50 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`).
modified docs/connecteurs/tiktok-apify.md +10 −4
@@ -1,6 +1,6 @@
1 # `tiktok-apify` — connecteur enrichissement (palier 4) 1 # `tiktok-apify` — connecteur enrichissement (palier 4)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0
6 6
@@ -21,16 +21,21 @@ Aucune donnée attribuable à cette source en BD pour l'instant (clés manquante
21 ## Fréquence & budget 21 ## Fréquence & budget
22 22
23 - **Cadence déclarée (registre)** : quotidienne (rotation 5 j, lot <=300) 23 - **Cadence déclarée (registre)** : quotidienne (rotation 5 j, lot <=300)
24−- **Cadence observée** (médiane sync_log) : — 24+- **Cadence observée** (médiane sync_log) : ≈ 31 min
25+- **Dernier passage** : 2026-08-18T20:05:02Z — 176 créateurs, 642 comptes, +0 / ~176, 38 erreur(s), 364 s
25 26
26 ## Volumétrie & complétude 27 ## Volumétrie & complétude
27 28
28 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 29 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
29−- **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs 30+- **Runs journalisés (60 derniers)** : 3, dont 1 avec erreurs
30 31
31 ## Erreurs connues & dépannage 32 ## Erreurs connues & dépannage
32 33
33−Aucune erreur ni alerte dans les 60 derniers runs journalisés. 34+| Passage | Erreurs | Alerte (sync_log) |
35+|---|---|---|
36+| 2026-08-18T20:05:02Z | 38 | — |
37+| 2026-08-18T19:21:42Z | 0 | 0 créateur retourné — source possiblement bloquée |
38+| 2026-08-18T19:03:58Z | 0 | 0 créateur retourné — source possiblement bloquée |
34 39
35 Rejouer la source seule : `python3 run.py sync tiktok-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='tiktok-apify' ORDER BY ts DESC LIMIT 5;`). 40 Rejouer la source seule : `python3 run.py sync tiktok-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='tiktok-apify' ORDER BY ts DESC LIMIT 5;`).
36 41
@@ -42,4 +47,5 @@ Rejouer la source seule : `python3 run.py sync tiktok-apify` · vérifier `sync_
42 47
43 ## Historique 48 ## Historique
44 49
50+- 2026-08-18 — plus ancien passage journalisé dans `sync_log` (fenêtre des 60 derniers).
45 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`). 51 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`).
modified docs/connecteurs/tiktok-profil.md +10 −10
@@ -1,6 +1,6 @@
1 # `tiktok-profil` — connecteur enrichissement (palier 4) 1 # `tiktok-profil` — connecteur enrichissement (palier 4)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichment) · Backend : Scrapfly · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichment) · Backend : Scrapfly · Créateurs découverts : 0 · touchés : 0
6 6
@@ -29,14 +29,14 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
29 29
30 | Colonne `accounts` | Contenu | Renseignée | Exemple réel | 30 | Colonne `accounts` | Contenu | Renseignée | Exemple réel |
31 |---|---|---|---| 31 |---|---|---|---|
32−| `handle` | Handle | 100 % | enola.bedard | 32+| `handle` | Handle | 100 % | juandemontrealoficial |
33−| `url` | URL du profil | 100 % | https://www.tiktok.com/@enola.bedard | 33+| `url` | URL du profil | 100 % | https://www.tiktok.com/@juandemontrealoficial |
34−| `followers` | Abonnés | 63 % | 17000000 | 34+| `followers` | Abonnés | 84 % | 19810972 |
35−| `verified` | Badge vérifié | 59 % | 1 | 35+| `verified` | Badge vérifié | 83 % | 1 |
36−| `confidence` | Confiance d'identité | 100 % | 0.85 | 36+| `confidence` | Confiance d'identité | 100 % | 0.9 |
37−| `signal` | Signal d'identité | 100 % | base_publique | 37+| `signal` | Signal d'identité | 100 % | cross_link |
38−| `metrics` | Métriques détaillées (JSON) | 59 % | {"following": 813, "likes": 438100000, "videos": 2847} | 38+| `metrics` | Métriques détaillées (JSON) | 83 % | {"following": 3800, "likes": 686001479, "videos": 5366, "friends": 3637, "is_seller": fal… |
39−| `last_checked` | Dernière vérification | 100 % | 2026-08-18T14:44:09Z | 39+| `last_checked` | Dernière vérification | 100 % | 2026-08-18T20:05:02Z |
40 40
41 ## Fréquence & budget 41 ## Fréquence & budget
42 42
@@ -48,7 +48,7 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
48 ## Volumétrie & complétude 48 ## Volumétrie & complétude
49 49
50 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 50 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
51−- **Comptes `tiktok` en BD** : 224 — abonnés 63 % · métriques 59 % · dernière vérification 2026-08-18T17:29:45Z 51+- **Comptes `tiktok` en BD** : 224 — abonnés 84 % · métriques 83 % · dernière vérification 2026-08-18T20:05:02Z
52 - **Runs journalisés (60 derniers)** : 3, dont 0 avec erreurs 52 - **Runs journalisés (60 derniers)** : 3, dont 0 avec erreurs
53 53
54 ## Erreurs connues & dépannage 54 ## Erreurs connues & dépannage
modified docs/connecteurs/twitch-apify.md +9 −4
@@ -1,6 +1,6 @@
1 # `twitch-apify` — connecteur enrichissement (palier 3) 1 # `twitch-apify` — connecteur enrichissement (palier 3)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0
6 6
@@ -21,16 +21,20 @@ Aucune donnée attribuable à cette source en BD pour l'instant (clés manquante
21 ## Fréquence & budget 21 ## Fréquence & budget
22 22
23 - **Cadence déclarée (registre)** : quotidienne (rotation 5 j, lot <=300) 23 - **Cadence déclarée (registre)** : quotidienne (rotation 5 j, lot <=300)
24−- **Cadence observée** (médiane sync_log) : — 24+- **Cadence observée** (médiane sync_log) : ≈ 9 min
25+- **Dernier passage** : 2026-08-18T19:21:40Z — 0 créateurs, 0 comptes, +0 / ~0, 0 erreur(s), 0 s
25 26
26 ## Volumétrie & complétude 27 ## Volumétrie & complétude
27 28
28 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 29 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
29−- **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs 30+- **Runs journalisés (60 derniers)** : 3, dont 0 avec erreurs
30 31
31 ## Erreurs connues & dépannage 32 ## Erreurs connues & dépannage
32 33
33−Aucune erreur ni alerte dans les 60 derniers runs journalisés. 34+| Passage | Erreurs | Alerte (sync_log) |
35+|---|---|---|
36+| 2026-08-18T19:21:40Z | 0 | 0 créateur retourné — source possiblement bloquée |
37+| 2026-08-18T19:03:58Z | 0 | 0 créateur retourné — source possiblement bloquée |
34 38
35 Rejouer la source seule : `python3 run.py sync twitch-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='twitch-apify' ORDER BY ts DESC LIMIT 5;`). 39 Rejouer la source seule : `python3 run.py sync twitch-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='twitch-apify' ORDER BY ts DESC LIMIT 5;`).
36 40
@@ -42,4 +46,5 @@ Rejouer la source seule : `python3 run.py sync twitch-apify` · vérifier `sync_
42 46
43 ## Historique 47 ## Historique
44 48
49+- 2026-08-18 — plus ancien passage journalisé dans `sync_log` (fenêtre des 60 derniers).
45 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`). 50 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`).
modified docs/connecteurs/twitch-decouverte.md +2 −2
@@ -1,6 +1,6 @@
1 # `twitch-decouverte` — connecteur decouverte (palier 3) 1 # `twitch-decouverte` — connecteur decouverte (palier 3)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 262 · touchés : 262 5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 262 · touchés : 262
6 6
@@ -38,7 +38,7 @@ Source de **découverte** : produit des fiches `Creator` (tables `creators` + `a
38 | `primary_platform` | Plateforme principale | 100 % | twitch | 38 | `primary_platform` | Plateforme principale | 100 % | twitch |
39 | `platforms` | Comptes sociaux (liste) | 100 % | twitch:@plaqueboymax | 39 | `platforms` | Comptes sociaux (liste) | 100 % | twitch:@plaqueboymax |
40 | `avatar_url` | Avatar | 100 % | https://static-cdn.jtvnw.net/jtv_user_pictures/14f0fcfd-00d4-4004-9379-93e0c6336f5e-profi… | 40 | `avatar_url` | Avatar | 100 % | https://static-cdn.jtvnw.net/jtv_user_pictures/14f0fcfd-00d4-4004-9379-93e0c6336f5e-profi… |
41−| `total_reach` | Portée totale (abonnés cumulés) | 74 % | 2841225 | 41+| `total_reach` | Portée totale (abonnés cumulés) | 74 % | 2841236 |
42 | `link_in_bio_url` | Lien-en-bio | 0 % | — | 42 | `link_in_bio_url` | Lien-en-bio | 0 % | — |
43 43
44 ## Fréquence & budget 44 ## Fréquence & budget
modified docs/connecteurs/twitch.md +6 −6
@@ -1,6 +1,6 @@
1 # `twitch` — connecteur enrichissement (palier 2) 1 # `twitch` — connecteur enrichissement (palier 2)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0
6 6
@@ -31,12 +31,12 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
31 |---|---|---|---| 31 |---|---|---|---|
32 | `handle` | Handle | 100 % | xqc | 32 | `handle` | Handle | 100 % | xqc |
33 | `url` | URL du profil | 100 % | https://www.twitch.tv/xqc | 33 | `url` | URL du profil | 100 % | https://www.twitch.tv/xqc |
34−| `followers` | Abonnés | 98 % | 12535878 | 34+| `followers` | Abonnés | 98 % | 12535875 |
35−| `verified` | Badge vérifié | 6 % | 1 | 35+| `verified` | Badge vérifié | 96 % | 1 |
36 | `confidence` | Confiance d'identité | 100 % | 0.85 | 36 | `confidence` | Confiance d'identité | 100 % | 0.85 |
37 | `signal` | Signal d'identité | 100 % | base_publique | 37 | `signal` | Signal d'identité | 100 % | base_publique |
38−| `metrics` | Métriques détaillées (JSON) | 79 % | {"last_stream": "2026-08-18T08:03:23.924661Z", "game": "Just Chatting"} | 38+| `metrics` | Métriques détaillées (JSON) | 97 % | {"last_stream": "2026-08-18T08:03:23.924661Z", "game": "Just Chatting", "is_partner": tru… |
39−| `last_checked` | Dernière vérification | 100 % | 2026-08-18T17:05:24Z | 39+| `last_checked` | Dernière vérification | 100 % | 2026-08-18T19:10:08Z |
40 40
41 ## Fréquence & budget 41 ## Fréquence & budget
42 42
@@ -48,7 +48,7 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
48 ## Volumétrie & complétude 48 ## Volumétrie & complétude
49 49
50 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 50 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
51−- **Comptes `twitch` en BD** : 292 — abonnés 98 % · métriques 79 % · dernière vérification 2026-08-18T17:28:20Z 51+- **Comptes `twitch` en BD** : 292 — abonnés 98 % · métriques 97 % · dernière vérification 2026-08-18T20:05:02Z
52 - **Runs journalisés (60 derniers)** : 4, dont 0 avec erreurs 52 - **Runs journalisés (60 derniers)** : 4, dont 0 avec erreurs
53 53
54 ## Erreurs connues & dépannage 54 ## Erreurs connues & dépannage
modified docs/connecteurs/wikidata-qc.md +12 −12
@@ -1,6 +1,6 @@
1 # `wikidata-qc` — connecteur decouverte (palier 3) 1 # `wikidata-qc` — connecteur decouverte (palier 3)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 73 · touchés : 73 5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 73 · touchés : 73
6 6
@@ -29,17 +29,17 @@ Source de **découverte** : produit des fiches `Creator` (tables `creators` + `a
29 29
30 | Champ du doc créateur | Contenu | Renseigné | Exemple réel | 30 | Champ du doc créateur | Contenu | Renseigné | Exemple réel |
31 |---|---|---|---| 31 |---|---|---|---|
32−| `display_name` | Nom public | 100 % | xQc | 32+| `display_name` | Nom public | 100 % | Nigel Braun |
33−| `bio` | Bio | 77 % | Félix Lengyel, mieux connu sous le pseudonyme « xQc » (Félix Québec), né le 12 novembre 1… | 33+| `bio` | Bio | 78 % | Capturing the natural beauty of chemistry Find me on YouTube: @NileRed/@NileBlue |
34−| `region` | Région | 18 % | Laval | 34+| `region` | Région | 18 % | — |
35−| `city` | Ville | 18 % | Laval | 35+| `city` | Ville | 18 % | — |
36−| `niches` | Niches (liste) | 100 % | gaming, lifestyle | 36+| `niches` | Niches (liste) | 100 % | lifestyle |
37−| `languages` | Langues (liste) | 100 % | en, fr | 37+| `languages` | Langues (liste) | 100 % | fr |
38 | `creator_type` | Type de créateur | 100 % | influenceur | 38 | `creator_type` | Type de créateur | 100 % | influenceur |
39−| `primary_platform` | Plateforme principale | 100 % | twitch | 39+| `primary_platform` | Plateforme principale | 100 % | youtube |
40−| `platforms` | Comptes sociaux (liste) | 99 % | twitch:@xqc, youtube:@UCmDTrq0LNgPodDOFZiSbsww, x:@xqc | 40+| `platforms` | Comptes sociaux (liste) | 99 % | youtube:@nilered, tiktok:@nilered, instagram:@nile.red |
41−| `avatar_url` | Avatar | 73 % | https://scontent-yyz1-1.cdninstagram.com/v/t51.2885-19/387770319_137990486044045_21612287… | 41+| `avatar_url` | Avatar | 75 % | https://scontent-yyz1-1.cdninstagram.com/v/t51.2885-19/441008830_1124225362150102_4410959… |
42−| `total_reach` | Portée totale (abonnés cumulés) | 64 % | 17219949 | 42+| `total_reach` | Portée totale (abonnés cumulés) | 67 % | 22759897 |
43 | `link_in_bio_url` | Lien-en-bio | 19 % | — | 43 | `link_in_bio_url` | Lien-en-bio | 19 % | — |
44 44
45 ## Fréquence & budget 45 ## Fréquence & budget
@@ -52,7 +52,7 @@ Source de **découverte** : produit des fiches `Creator` (tables `creators` + `a
52 ## Volumétrie & complétude 52 ## Volumétrie & complétude
53 53
54 - **Créateurs découverts par la source** (`doc.source`) : 73 · **fiches touchées** (`source_ids`) : 73 54 - **Créateurs découverts par la source** (`doc.source`) : 73 · **fiches touchées** (`source_ids`) : 73
55−- **Complétude clé (découverts)** : niches 100 % · avatar 73 % · portée 64 % · région 18 % 55+- **Complétude clé (découverts)** : niches 100 % · avatar 75 % · portée 67 % · région 18 %
56 - **Runs journalisés (60 derniers)** : 10, dont 1 avec erreurs 56 - **Runs journalisés (60 derniers)** : 10, dont 1 avec erreurs
57 57
58 ## Erreurs connues & dépannage 58 ## Erreurs connues & dépannage
modified docs/connecteurs/wikipedia-qc.md +4 −4
@@ -1,6 +1,6 @@
1 # `wikipedia-qc` — connecteur decouverte (palier 3) 1 # `wikipedia-qc` — connecteur decouverte (palier 3)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 84 · touchés : 84 5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 84 · touchés : 84
6 6
@@ -38,8 +38,8 @@ Source de **découverte** : produit des fiches `Creator` (tables `creators` + `a
38 | `creator_type` | Type de créateur | 100 % | youtubeur | 38 | `creator_type` | Type de créateur | 100 % | youtubeur |
39 | `primary_platform` | Plateforme principale | 100 % | x | 39 | `primary_platform` | Plateforme principale | 100 % | x |
40 | `platforms` | Comptes sociaux (liste) | 100 % | x:@eviluno, instagram:@evil.uno, twitch:@eviluno | 40 | `platforms` | Comptes sociaux (liste) | 100 % | x:@eviluno, instagram:@evil.uno, twitch:@eviluno |
41−| `avatar_url` | Avatar | 80 % | https://upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Unoenjoy.jpg/500px-Unoenjoy.jpg… | 41+| `avatar_url` | Avatar | 83 % | https://upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Unoenjoy.jpg/500px-Unoenjoy.jpg… |
42−| `total_reach` | Portée totale (abonnés cumulés) | 12 % | 268165 | 42+| `total_reach` | Portée totale (abonnés cumulés) | 17 % | 268180 |
43 | `link_in_bio_url` | Lien-en-bio | 5 % | http://linktr.ee/eviluno | 43 | `link_in_bio_url` | Lien-en-bio | 5 % | http://linktr.ee/eviluno |
44 44
45 ## Fréquence & budget 45 ## Fréquence & budget
@@ -52,7 +52,7 @@ Source de **découverte** : produit des fiches `Creator` (tables `creators` + `a
52 ## Volumétrie & complétude 52 ## Volumétrie & complétude
53 53
54 - **Créateurs découverts par la source** (`doc.source`) : 84 · **fiches touchées** (`source_ids`) : 84 54 - **Créateurs découverts par la source** (`doc.source`) : 84 · **fiches touchées** (`source_ids`) : 84
55−- **Complétude clé (découverts)** : niches 100 % · avatar 80 % · portée 12 % · région 49 % 55+- **Complétude clé (découverts)** : niches 100 % · avatar 83 % · portée 17 % · région 49 %
56 - **Runs journalisés (60 derniers)** : 4, dont 0 avec erreurs 56 - **Runs journalisés (60 derniers)** : 4, dont 0 avec erreurs
57 57
58 ## Erreurs connues & dépannage 58 ## Erreurs connues & dépannage
modified docs/connecteurs/x-apify.md +12 −4
@@ -1,6 +1,6 @@
1 # `x-apify` — connecteur enrichissement (palier 3) 1 # `x-apify` — connecteur enrichissement (palier 3)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0
6 6
@@ -21,16 +21,23 @@ Aucune donnée attribuable à cette source en BD pour l'instant (clés manquante
21 ## Fréquence & budget 21 ## Fréquence & budget
22 22
23 - **Cadence déclarée (registre)** : quotidienne (rotation 5 j, lot <=300) 23 - **Cadence déclarée (registre)** : quotidienne (rotation 5 j, lot <=300)
24−- **Cadence observée** (médiane sync_log) : — 24+- **Cadence observée** (médiane sync_log) : ≈ 8 min
25+- **Dernier passage** : 2026-08-18T19:51:07Z — 30 créateurs, 121 comptes, +0 / ~30, 2 erreur(s), 515 s
25 26
26 ## Volumétrie & complétude 27 ## Volumétrie & complétude
27 28
28 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 29 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
29−- **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs 30+- **Runs journalisés (60 derniers)** : 6, dont 1 avec erreurs
30 31
31 ## Erreurs connues & dépannage 32 ## Erreurs connues & dépannage
32 33
33−Aucune erreur ni alerte dans les 60 derniers runs journalisés. 34+| Passage | Erreurs | Alerte (sync_log) |
35+|---|---|---|
36+| 2026-08-18T19:51:07Z | 2 | — |
37+| 2026-08-18T19:39:57Z | 0 | 0 créateur retourné — source possiblement bloquée |
38+| 2026-08-18T19:33:34Z | 0 | 0 créateur retourné — source possiblement bloquée |
39+| 2026-08-18T19:25:32Z | 0 | 0 créateur retourné — source possiblement bloquée |
40+| 2026-08-18T19:21:41Z | 0 | 0 créateur retourné — source possiblement bloquée |
34 41
35 Rejouer la source seule : `python3 run.py sync x-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='x-apify' ORDER BY ts DESC LIMIT 5;`). 42 Rejouer la source seule : `python3 run.py sync x-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='x-apify' ORDER BY ts DESC LIMIT 5;`).
36 43
@@ -42,4 +49,5 @@ Rejouer la source seule : `python3 run.py sync x-apify` · vérifier `sync_log`
42 49
43 ## Historique 50 ## Historique
44 51
52+- 2026-08-18 — plus ancien passage journalisé dans `sync_log` (fenêtre des 60 derniers).
45 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`). 53 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`).
modified docs/connecteurs/x-profil.md +6 −6
@@ -1,6 +1,6 @@
1 # `x-profil` — connecteur enrichissement (palier 3) 1 # `x-profil` — connecteur enrichissement (palier 3)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0
6 6
@@ -31,12 +31,12 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
31 |---|---|---|---| 31 |---|---|---|---|
32 | `handle` | Handle | 100 % | xqc | 32 | `handle` | Handle | 100 % | xqc |
33 | `url` | URL du profil | 100 % | https://x.com/xqc | 33 | `url` | URL du profil | 100 % | https://x.com/xqc |
34−| `followers` | Abonnés | 18 % | 1598794 | 34+| `followers` | Abonnés | 26 % | 1599135 |
35−| `verified` | Badge vérifié | 0 % | — | 35+| `verified` | Badge vérifié | 13 % | 1 |
36 | `confidence` | Confiance d'identité | 100 % | 0.9 | 36 | `confidence` | Confiance d'identité | 100 % | 0.9 |
37 | `signal` | Signal d'identité | 100 % | cross_link | 37 | `signal` | Signal d'identité | 100 % | cross_link |
38−| `metrics` | Métriques détaillées (JSON) | 32 % | {"following": 526, "x_checked": "2026-08-18T06:14:55Z"} | 38+| `metrics` | Métriques détaillées (JSON) | 39 % | {"following": 526, "x_checked": "2026-08-18T06:14:55Z", "tweets": 4328, "location": "", "… |
39−| `last_checked` | Dernière vérification | 100 % | 2026-08-18T14:44:09Z | 39+| `last_checked` | Dernière vérification | 100 % | 2026-08-18T19:58:58Z |
40 40
41 ## Fréquence & budget 41 ## Fréquence & budget
42 42
@@ -48,7 +48,7 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
48 ## Volumétrie & complétude 48 ## Volumétrie & complétude
49 49
50 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 50 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
51−- **Comptes `x` en BD** : 228 — abonnés 18 % · métriques 32 % · dernière vérification 2026-08-18T17:29:45Z 51+- **Comptes `x` en BD** : 228 — abonnés 26 % · métriques 39 % · dernière vérification 2026-08-18T19:58:58Z
52 - **Runs journalisés (60 derniers)** : 6, dont 6 avec erreurs 52 - **Runs journalisés (60 derniers)** : 6, dont 6 avec erreurs
53 53
54 ## Erreurs connues & dépannage 54 ## Erreurs connues & dépannage
modified docs/connecteurs/youtube-apify.md +12 −4
@@ -1,6 +1,6 @@
1 # `youtube-apify` — connecteur enrichissement (palier 3) 1 # `youtube-apify` — connecteur enrichissement (palier 3)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichissement) · Backend : — · Créateurs découverts : 0 · touchés : 0
6 6
@@ -21,16 +21,23 @@ Aucune donnée attribuable à cette source en BD pour l'instant (clés manquante
21 ## Fréquence & budget 21 ## Fréquence & budget
22 22
23 - **Cadence déclarée (registre)** : quotidienne (rotation 5 j, lot <=300) 23 - **Cadence déclarée (registre)** : quotidienne (rotation 5 j, lot <=300)
24−- **Cadence observée** (médiane sync_log) : — 24+- **Cadence observée** (médiane sync_log) : ≈ 8 min
25+- **Dernier passage** : 2026-08-18T19:55:55Z — 1220 créateurs, 1352 comptes, +0 / ~1220, 0 erreur(s), 288 s
25 26
26 ## Volumétrie & complétude 27 ## Volumétrie & complétude
27 28
28 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 29 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
29−- **Runs journalisés (60 derniers)** : 0, dont 0 avec erreurs 30+- **Runs journalisés (60 derniers)** : 6, dont 0 avec erreurs
30 31
31 ## Erreurs connues & dépannage 32 ## Erreurs connues & dépannage
32 33
33−Aucune erreur ni alerte dans les 60 derniers runs journalisés. 34+| Passage | Erreurs | Alerte (sync_log) |
35+|---|---|---|
36+| 2026-08-18T19:42:16Z | 0 | 0 créateur retourné — source possiblement bloquée |
37+| 2026-08-18T19:35:56Z | 0 | 0 créateur retourné — source possiblement bloquée |
38+| 2026-08-18T19:27:33Z | 0 | 0 créateur retourné — source possiblement bloquée |
39+| 2026-08-18T19:21:42Z | 0 | 0 créateur retourné — source possiblement bloquée |
40+| 2026-08-18T19:03:58Z | 0 | 0 créateur retourné — source possiblement bloquée |
34 41
35 Rejouer la source seule : `python3 run.py sync youtube-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='youtube-apify' ORDER BY ts DESC LIMIT 5;`). 42 Rejouer la source seule : `python3 run.py sync youtube-apify` · vérifier `sync_log` (`SELECT * FROM sync_log WHERE source='youtube-apify' ORDER BY ts DESC LIMIT 5;`).
36 43
@@ -42,4 +49,5 @@ Rejouer la source seule : `python3 run.py sync youtube-apify` · vérifier `sync
42 49
43 ## Historique 50 ## Historique
44 51
52+- 2026-08-18 — plus ancien passage journalisé dans `sync_log` (fenêtre des 60 derniers).
45 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`). 53 - 2026-08-18 — vague d'enrichissement : standardisation de la documentation des connecteurs (fiche générée par `scripts/gen_connector_docs.py`).
modified docs/connecteurs/youtube-recherche.md +5 −5
@@ -1,6 +1,6 @@
1 # `youtube-recherche` — connecteur decouverte (palier 3) 1 # `youtube-recherche` — connecteur decouverte (palier 3)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 7876 · touchés : 7876 5 **État : actif** · Famille : decouverte (discovery) · Backend : direct · Créateurs découverts : 7876 · touchés : 7876
6 6
@@ -42,7 +42,7 @@ Source de **découverte** : produit des fiches `Creator` (tables `creators` + `a
42 | `total_reach` | Portée totale (abonnés cumulés) | 95 % | 1860000 | 42 | `total_reach` | Portée totale (abonnés cumulés) | 95 % | 1860000 |
43 | `link_in_bio_url` | Lien-en-bio | 0 % | — | 43 | `link_in_bio_url` | Lien-en-bio | 0 % | — |
44 44
45−Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les plateforme(s) `youtube` (8084 comptes en BD, confiance moyenne 0.98). 45+Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les plateforme(s) `youtube` (8086 comptes en BD, confiance moyenne 0.98).
46 46
47 | Colonne `accounts` | Contenu | Renseignée | Exemple réel | 47 | Colonne `accounts` | Contenu | Renseignée | Exemple réel |
48 |---|---|---|---| 48 |---|---|---|---|
@@ -52,8 +52,8 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
52 | `verified` | Badge vérifié | 0 % | — | 52 | `verified` | Badge vérifié | 0 % | — |
53 | `confidence` | Confiance d'identité | 100 % | 0.9 | 53 | `confidence` | Confiance d'identité | 100 % | 0.9 |
54 | `signal` | Signal d'identité | 100 % | cross_link | 54 | `signal` | Signal d'identité | 100 % | cross_link |
55−| `metrics` | Métriques détaillées (JSON) | 10 % | {"yt_checked": "2026-08-18T10:08:15Z", "videos": 400, "views": 4647638686, "last_video": … | 55+| `metrics` | Métriques détaillées (JSON) | 18 % | {"yt_checked": "2026-08-18T10:08:15Z", "videos": 400, "views": 4647638686, "last_video": … |
56−| `last_checked` | Dernière vérification | 100 % | 2026-08-18T11:35:25Z | 56+| `last_checked` | Dernière vérification | 100 % | 2026-08-18T19:58:58Z |
57 57
58 ## Fréquence & budget 58 ## Fréquence & budget
59 59
@@ -66,7 +66,7 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
66 66
67 - **Créateurs découverts par la source** (`doc.source`) : 7876 · **fiches touchées** (`source_ids`) : 7876 67 - **Créateurs découverts par la source** (`doc.source`) : 7876 · **fiches touchées** (`source_ids`) : 7876
68 - **Complétude clé (découverts)** : niches 100 % · avatar 98 % · portée 95 % · région 16 % 68 - **Complétude clé (découverts)** : niches 100 % · avatar 98 % · portée 95 % · région 16 %
69−- **Comptes `youtube` en BD** : 8084 — abonnés 94 % · métriques 10 % · dernière vérification 2026-08-18T17:29:45Z 69+- **Comptes `youtube` en BD** : 8086 — abonnés 94 % · métriques 18 % · dernière vérification 2026-08-18T20:05:02Z
70 - **Runs journalisés (60 derniers)** : 5, dont 0 avec erreurs 70 - **Runs journalisés (60 derniers)** : 5, dont 0 avec erreurs
71 71
72 ## Erreurs connues & dépannage 72 ## Erreurs connues & dépannage
modified docs/connecteurs/youtube.md +5 −5
@@ -1,6 +1,6 @@
1 # `youtube` — connecteur enrichissement (palier 2) 1 # `youtube` — connecteur enrichissement (palier 2)
2 2
3−_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 14:47 — ne pas éditer à la main, régénérer._ 3+_Fiche générée automatiquement par `scripts/gen_connector_docs.py` le 2026-08-18 16:14 — ne pas éditer à la main, régénérer._
4 4
5 **État : actif** · Famille : enrichissement (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0 5 **État : actif** · Famille : enrichissement (enrichment) · Backend : direct · Créateurs découverts : 0 · touchés : 0
6 6
@@ -25,7 +25,7 @@ Connecteur ENRICHISSEMENT YouTube — stats de chaîne par créateur. Mode d'acc
25 25
26 ## Champs récupérés → schéma cible 26 ## Champs récupérés → schéma cible
27 27
28−Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les plateforme(s) `youtube` (8084 comptes en BD, confiance moyenne 0.98). 28+Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les plateforme(s) `youtube` (8086 comptes en BD, confiance moyenne 0.98).
29 29
30 | Colonne `accounts` | Contenu | Renseignée | Exemple réel | 30 | Colonne `accounts` | Contenu | Renseignée | Exemple réel |
31 |---|---|---|---| 31 |---|---|---|---|
@@ -35,8 +35,8 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
35 | `verified` | Badge vérifié | 0 % | — | 35 | `verified` | Badge vérifié | 0 % | — |
36 | `confidence` | Confiance d'identité | 100 % | 0.9 | 36 | `confidence` | Confiance d'identité | 100 % | 0.9 |
37 | `signal` | Signal d'identité | 100 % | cross_link | 37 | `signal` | Signal d'identité | 100 % | cross_link |
38−| `metrics` | Métriques détaillées (JSON) | 10 % | {"yt_checked": "2026-08-18T10:08:15Z", "videos": 400, "views": 4647638686, "last_video": … | 38+| `metrics` | Métriques détaillées (JSON) | 18 % | {"yt_checked": "2026-08-18T10:08:15Z", "videos": 400, "views": 4647638686, "last_video": … |
39−| `last_checked` | Dernière vérification | 100 % | 2026-08-18T11:35:25Z | 39+| `last_checked` | Dernière vérification | 100 % | 2026-08-18T19:58:58Z |
40 40
41 ## Fréquence & budget 41 ## Fréquence & budget
42 42
@@ -48,7 +48,7 @@ Cible d'**enrichissement** : colonnes de la table `accounts` pour la/les platefo
48 ## Volumétrie & complétude 48 ## Volumétrie & complétude
49 49
50 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0 50 - **Créateurs découverts par la source** (`doc.source`) : 0 · **fiches touchées** (`source_ids`) : 0
51−- **Comptes `youtube` en BD** : 8084 — abonnés 94 % · métriques 10 % · dernière vérification 2026-08-18T17:29:45Z 51+- **Comptes `youtube` en BD** : 8086 — abonnés 94 % · métriques 18 % · dernière vérification 2026-08-18T20:05:02Z
52 - **Runs journalisés (60 derniers)** : 5, dont 3 avec erreurs 52 - **Runs journalisés (60 derniers)** : 5, dont 3 avec erreurs
53 53
54 ## Erreurs connues & dépannage 54 ## Erreurs connues & dépannage
modified frontend/dist/index.html +98 −14
@@ -722,12 +722,47 @@ select.f.active{background-color:var(--accent-soft);color:var(--ink);border-colo
722 background:var(--surface);border:1.5px solid var(--ink);border-radius:var(--r-card); 722 background:var(--surface);border:1.5px solid var(--ink);border-radius:var(--r-card);
723 padding:13px 17px;box-shadow:var(--shadow-off-soft)} 723 padding:13px 17px;box-shadow:var(--shadow-off-soft)}
724 .sect-title{font-size:19px;margin:36px 0 15px;display:flex;align-items:center;gap:10px;text-transform:uppercase} 724 .sect-title{font-size:19px;margin:36px 0 15px;display:flex;align-items:center;gap:10px;text-transform:uppercase}
725−.acc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:14px} 725+.acc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:14px}
726 @media(max-width:640px){.acc-grid{grid-template-columns:1fr}} 726 @media(max-width:640px){.acc-grid{grid-template-columns:1fr}}
727−.acc{display:flex;align-items:center;gap:13px;background:var(--surface); 727+.acc-card{display:flex;flex-direction:column;background:var(--surface);
728− border:1.5px solid var(--ink);border-radius:var(--r-card);padding:14px 16px; 728+ border:1.5px solid var(--ink);border-radius:var(--r-card);
729− box-shadow:var(--shadow-off-soft);transition:transform .16s ease,box-shadow .16s ease;min-width:0} 729+ box-shadow:var(--shadow-off-soft);transition:transform .16s ease,box-shadow .16s ease;
730−.acc:hover{transform:translate(-2px,-2px);box-shadow:var(--shadow-off)} 730+ min-width:0;overflow:hidden}
731+.acc-card:hover{transform:translate(-2px,-2px);box-shadow:var(--shadow-off)}
732+.acc{display:flex;align-items:center;gap:13px;padding:14px 16px;min-width:0}
733+/* rangée de stats riches */
734+.astat-row{display:flex;flex-wrap:wrap;gap:6px;padding:0 16px 10px}
735+.astat{display:flex;flex-direction:column;background:var(--surface-2);
736+ border:1px solid var(--line);border-radius:var(--r-ctl);padding:4px 9px;line-height:1.1}
737+.astat b{font-family:var(--font-display);font-size:13px;color:var(--ink);font-weight:700}
738+.astat span{font-family:var(--font-mono);font-size:8.5px;color:var(--ink-3);
739+ text-transform:uppercase;letter-spacing:.05em;font-weight:700;margin-top:1px}
740+.abadge-row{display:flex;flex-wrap:wrap;gap:5px;padding:0 16px 12px}
741+.abadge{display:inline-flex;background:var(--lime-soft);color:var(--green-deep);
742+ border:1px solid var(--line);border-radius:var(--r-ctl);padding:2px 8px;
743+ font-family:var(--font-mono);font-size:9.5px;font-weight:700;letter-spacing:.02em}
744+.abadge.live{background:#ffe3e0;color:#b0201a;border-color:#b0201a}
745+/* bande de contenu récent */
746+.cstrip{border-top:1px dashed var(--line);padding:11px 0 13px}
747+.cstrip-h{font-family:var(--font-mono);font-size:9.5px;font-weight:700;color:var(--ink-3);
748+ text-transform:uppercase;letter-spacing:.07em;padding:0 16px 8px}
749+.cstrip-scroll{display:flex;gap:9px;overflow-x:auto;padding:0 16px 3px;scroll-snap-type:x proximity}
750+.cstrip-scroll::-webkit-scrollbar{height:5px}
751+.cstrip-scroll::-webkit-scrollbar-thumb{background:var(--line);border-radius:3px}
752+.cstrip-item{flex:none;width:120px;scroll-snap-align:start;text-decoration:none;color:inherit;
753+ display:flex;flex-direction:column;gap:4px}
754+.cstrip-thumb{position:relative;display:block;width:120px;height:120px;border-radius:9px;
755+ background-size:cover;background-position:center;background-color:var(--surface-2);
756+ border:1px solid var(--line);overflow:hidden}
757+.cstrip-thumb.noimg{display:flex;align-items:center;justify-content:center}
758+.cstrip-thumb.noimg svg{width:34px;height:34px;opacity:.35}
759+.cstrip-play{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
760+ color:#fff;font-size:20px;text-shadow:0 1px 4px rgba(0,0,0,.6)}
761+.cstrip-dur{position:absolute;right:5px;bottom:5px;background:rgba(0,0,0,.78);color:#fff;
762+ font-family:var(--font-mono);font-size:9px;padding:1px 5px;border-radius:5px}
763+.cstrip-cap{font-size:11px;line-height:1.25;color:var(--ink-2);display:-webkit-box;
764+ -webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
765+.cstrip-meta{font-family:var(--font-mono);font-size:9px;color:var(--ink-3);line-height:1.2}
731 .acc .plat{width:44px;height:44px;border-radius:9px;flex:none} 766 .acc .plat{width:44px;height:44px;border-radius:9px;flex:none}
732 .acc .plat svg{width:20px;height:20px} 767 .acc .plat svg{width:20px;height:20px}
733 .acc-mid{min-width:0;flex:1;display:flex;flex-direction:column;gap:2px;overflow:hidden} 768 .acc-mid{min-width:0;flex:1;display:flex;flex-direction:column;gap:2px;overflow:hidden}
@@ -1170,6 +1205,30 @@ async function reload(more){
1170 } 1205 }
1171 1206
1172 /* ---------- page créateur ---------- */ 1207 /* ---------- page créateur ---------- */
1208+/* --- bande de contenu récent par compte (enrichissement Apify) --- */
1209+const _relTime=ts=>{if(!ts)return"";if(typeof ts==="string"&&!/^\d+$/.test(ts))return esc(ts.slice(0,10));
1210+ const d=Math.floor((Date.now()/1000-Number(ts))/86400);
1211+ return d<=0?"aujourd'hui":d===1?"hier":d<30?d+" j":d<365?Math.floor(d/30)+" mois":Math.floor(d/365)+" ans";};
1212+function contentStrip(a){
1213+ const m=a.metrics||{};
1214+ const items=m.recent_posts||m.recent_videos||m.recent_tweets||[];
1215+ if(!items.length)return"";
1216+ const cards=items.slice(0,8).map(it=>{
1217+ const img=it.display_url||it.thumbnail_url||"";
1218+ const title=esc((it.caption||it.title||it.text||"").slice(0,90));
1219+ const stats=[
1220+ it.views!=null?fmt.format(it.views)+" vues":null,
1221+ it.likes!=null?fmt.format(it.likes)+" ❤":null,
1222+ it.comments!=null?fmt.format(it.comments)+" 💬":null,
1223+ it.retweets!=null?fmt.format(it.retweets)+" ↻":null,
1224+ ].filter(Boolean).join(" · ");
1225+ const when=_relTime(it.timestamp||it.published_at||it.published||it.created_at);
1226+ return `<a class="cstrip-item" href="${esc(it.url||a.url)}" target="_blank" rel="noopener" onclick="event.stopPropagation()">
1227+ ${img?`<span class="cstrip-thumb" style="background-image:url('${esc(img)}')">${it.type==="video"||it.type==="reel"||it.duration?'<span class="cstrip-play">▶</span>':""}${it.duration?`<span class="cstrip-dur">${esc(it.duration)}</span>`:""}</span>`:`<span class="cstrip-thumb noimg">${icon(a.platform)}</span>`}
1228+ ${title?`<span class="cstrip-cap">${title}</span>`:""}
1229+ <span class="cstrip-meta">${stats}${when?` · ${when}`:""}</span></a>`}).join("");
1230+ return `<div class="cstrip"><div class="cstrip-h">Contenu récent</div><div class="cstrip-scroll">${cards}</div></div>`;
1231+}
1173 async function renderCreator(id){ 1232 async function renderCreator(id){
1174 app.innerHTML=header()+`<div class="container"><div class="spin"></div></div>`+footer()+tabbar("");bindNav(); 1233 app.innerHTML=header()+`<div class="container"><div class="spin"></div></div>`+footer()+tabbar("");bindNav();
1175 let c;try{c=await api("/api/creators/"+encodeURIComponent(id))} 1234 let c;try{c=await api("/api/creators/"+encodeURIComponent(id))}
@@ -1179,18 +1238,43 @@ async function renderCreator(id){
1179 const verified=(c.platforms||[]).some(a=>a.verified); 1238 const verified=(c.platforms||[]).some(a=>a.verified);
1180 const niches=(c.niches||[]).map(n=>`<span class="mchip">${NICHE_LBL[n]||n}</span>`).join(""); 1239 const niches=(c.niches||[]).map(n=>`<span class="mchip">${NICHE_LBL[n]||n}</span>`).join("");
1181 const M_LBL={following:"abonnements",posts:"publications",likes:"j'aime", 1240 const M_LBL={following:"abonnements",posts:"publications",likes:"j'aime",
1182− views:"vues",videos:"vidéos",episodes:"épisodes"}; 1241+ views:"vues",videos:"vidéos",episodes:"épisodes",images:"photos",
1242+ friends:"amis",listed:"listes"};
1183 const accs=(c.platforms||[]).map(a=>{const p=PLAT[a.platform]||PLAT.autre; 1243 const accs=(c.platforms||[]).map(a=>{const p=PLAT[a.platform]||PLAT.autre;
1184 const conf=(a.confidence||0)>=0.75?["hi","confiance élevée"]:["mid","à confirmer"]; 1244 const conf=(a.confidence||0)>=0.75?["hi","confiance élevée"]:["mid","à confirmer"];
1185− const mx=Object.entries(a.metrics||{}).filter(([k,v])=>M_LBL[k]&&v!=null) 1245+ const m=a.metrics||{};
1246+ const mx=Object.entries(m).filter(([k,v])=>M_LBL[k]&&v!=null)
1186 .map(([k,v])=>`${fmt.format(v)} ${M_LBL[k]}`).join(" · "); 1247 .map(([k,v])=>`${fmt.format(v)} ${M_LBL[k]}`).join(" · ");
1187− return `<a class="acc" href="${esc(a.url)}" target="_blank" rel="noopener"> 1248+ // rangée de statistiques riches (enrichissement Apify multi-plateforme)
1188− <span class="plat" style="background:${p.color}">${icon(a.platform)}</span> 1249+ const stat=(v,l)=>v==null?"":`<span class="astat"><b>${typeof v==="number"?fmt.format(v):esc(v)}</b><span>${l}</span></span>`;
1189− <span class="acc-mid"><span class="acc-name">${p.label}${a.verified?checkSvg:""}</span> 1250+ const stats=[
1190− <span class="acc-handle">@${esc(a.handle)}</span> 1251+ stat(m.engagement_rate_pct!=null?m.engagement_rate_pct+" %":null,"engagement"),
1191− <span class="acc-handle" style="overflow:visible"><span class="conf ${conf[0]}" title="Score de rattachement ${Math.round((a.confidence||0)*100)} %">${conf[1]}</span>${mx?` <span style="font-size:11px">${mx}</span>`:""}</span></span> 1252+ stat(m.avg_likes,"j'aime/moy"),
1192− <span class="acc-right">${a.followers?`<b>${fmt.format(a.followers)}</b><span>abonnés</span>`:`<span style="font-size:11px">voir le profil ↗</span>`}</span></a>`}).join(""); 1253+ stat(m.avg_views!=null?m.avg_views:m.avg_video_views,"vues/moy"),
1193− const checked=(c.platforms||[]).map(a=>a.last_checked).filter(Boolean).sort().pop(); 1254+ stat(m.avg_retweets,"RT/moy"),
1255+ stat(m.posts_per_week!=null?m.posts_per_week:m.tweets_per_week,"/semaine"),
1256+ ].filter(Boolean).join("");
1257+ const badges=[
1258+ m.is_partner?'<span class="abadge">Partenaire</span>':"",
1259+ m.is_affiliate&&!m.is_partner?'<span class="abadge">Affilié</span>':"",
1260+ m.is_live_now?'<span class="abadge live">● En direct</span>':"",
1261+ m.is_seller?'<span class="abadge">Boutique</span>':"",
1262+ m.is_free===true?'<span class="abadge">Gratuit</span>':"",
1263+ m.has_story?'<span class="abadge">Story active</span>':"",
1264+ (m.recent_games||[]).length?`<span class="abadge">${esc((m.recent_games||[])[0])}</span>`:"",
1265+ (m.top_hashtags||[]).slice(0,2).map(h=>`<span class="abadge">#${esc(h)}</span>`).join(""),
1266+ ].filter(Boolean).join("");
1267+ return `<div class="acc-card">
1268+ <a class="acc" href="${esc(a.url)}" target="_blank" rel="noopener">
1269+ <span class="plat" style="background:${p.color}">${icon(a.platform)}</span>
1270+ <span class="acc-mid"><span class="acc-name">${p.label}${a.verified?checkSvg:""}</span>
1271+ <span class="acc-handle">@${esc(a.handle)}</span>
1272+ <span class="acc-handle" style="overflow:visible"><span class="conf ${conf[0]}" title="Score de rattachement ${Math.round((a.confidence||0)*100)} %">${conf[1]}</span>${mx?` <span style="font-size:11px">${mx}</span>`:""}</span></span>
1273+ <span class="acc-right">${a.followers?`<b>${fmt.format(a.followers)}</b><span>abonnés</span>`:`<span style="font-size:11px">voir le profil ↗</span>`}</span></a>
1274+ ${stats?`<div class="astat-row">${stats}</div>`:""}
1275+ ${badges?`<div class="abadge-row">${badges}</div>`:""}
1276+ ${contentStrip(a)}</div>`}).join("");
1277+ const checked=(c.platforms||[]).map(a=>(a.metrics||{}).instagram_apify_at||a.last_checked).filter(Boolean).sort().pop()||(c.platforms||[]).map(a=>a.last_checked).filter(Boolean).sort().pop();
1194 app.innerHTML=header()+` 1278 app.innerHTML=header()+`
1195 <div class="container cpage"> 1279 <div class="container cpage">
1196 <a class="backlink" href="/" data-nav>← Tous les créateurs</a> 1280 <a class="backlink" href="/" data-nav>← Tous les créateurs</a>
modified frontend/src/index.template.html +98 −14
@@ -264,12 +264,47 @@ select.f.active{background-color:var(--accent-soft);color:var(--ink);border-colo
264 background:var(--surface);border:1.5px solid var(--ink);border-radius:var(--r-card); 264 background:var(--surface);border:1.5px solid var(--ink);border-radius:var(--r-card);
265 padding:13px 17px;box-shadow:var(--shadow-off-soft)} 265 padding:13px 17px;box-shadow:var(--shadow-off-soft)}
266 .sect-title{font-size:19px;margin:36px 0 15px;display:flex;align-items:center;gap:10px;text-transform:uppercase} 266 .sect-title{font-size:19px;margin:36px 0 15px;display:flex;align-items:center;gap:10px;text-transform:uppercase}
267−.acc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:14px} 267+.acc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:14px}
268 @media(max-width:640px){.acc-grid{grid-template-columns:1fr}} 268 @media(max-width:640px){.acc-grid{grid-template-columns:1fr}}
269−.acc{display:flex;align-items:center;gap:13px;background:var(--surface); 269+.acc-card{display:flex;flex-direction:column;background:var(--surface);
270− border:1.5px solid var(--ink);border-radius:var(--r-card);padding:14px 16px; 270+ border:1.5px solid var(--ink);border-radius:var(--r-card);
271− box-shadow:var(--shadow-off-soft);transition:transform .16s ease,box-shadow .16s ease;min-width:0} 271+ box-shadow:var(--shadow-off-soft);transition:transform .16s ease,box-shadow .16s ease;
272−.acc:hover{transform:translate(-2px,-2px);box-shadow:var(--shadow-off)} 272+ min-width:0;overflow:hidden}
273+.acc-card:hover{transform:translate(-2px,-2px);box-shadow:var(--shadow-off)}
274+.acc{display:flex;align-items:center;gap:13px;padding:14px 16px;min-width:0}
275+/* rangée de stats riches */
276+.astat-row{display:flex;flex-wrap:wrap;gap:6px;padding:0 16px 10px}
277+.astat{display:flex;flex-direction:column;background:var(--surface-2);
278+ border:1px solid var(--line);border-radius:var(--r-ctl);padding:4px 9px;line-height:1.1}
279+.astat b{font-family:var(--font-display);font-size:13px;color:var(--ink);font-weight:700}
280+.astat span{font-family:var(--font-mono);font-size:8.5px;color:var(--ink-3);
281+ text-transform:uppercase;letter-spacing:.05em;font-weight:700;margin-top:1px}
282+.abadge-row{display:flex;flex-wrap:wrap;gap:5px;padding:0 16px 12px}
283+.abadge{display:inline-flex;background:var(--lime-soft);color:var(--green-deep);
284+ border:1px solid var(--line);border-radius:var(--r-ctl);padding:2px 8px;
285+ font-family:var(--font-mono);font-size:9.5px;font-weight:700;letter-spacing:.02em}
286+.abadge.live{background:#ffe3e0;color:#b0201a;border-color:#b0201a}
287+/* bande de contenu récent */
288+.cstrip{border-top:1px dashed var(--line);padding:11px 0 13px}
289+.cstrip-h{font-family:var(--font-mono);font-size:9.5px;font-weight:700;color:var(--ink-3);
290+ text-transform:uppercase;letter-spacing:.07em;padding:0 16px 8px}
291+.cstrip-scroll{display:flex;gap:9px;overflow-x:auto;padding:0 16px 3px;scroll-snap-type:x proximity}
292+.cstrip-scroll::-webkit-scrollbar{height:5px}
293+.cstrip-scroll::-webkit-scrollbar-thumb{background:var(--line);border-radius:3px}
294+.cstrip-item{flex:none;width:120px;scroll-snap-align:start;text-decoration:none;color:inherit;
295+ display:flex;flex-direction:column;gap:4px}
296+.cstrip-thumb{position:relative;display:block;width:120px;height:120px;border-radius:9px;
297+ background-size:cover;background-position:center;background-color:var(--surface-2);
298+ border:1px solid var(--line);overflow:hidden}
299+.cstrip-thumb.noimg{display:flex;align-items:center;justify-content:center}
300+.cstrip-thumb.noimg svg{width:34px;height:34px;opacity:.35}
301+.cstrip-play{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
302+ color:#fff;font-size:20px;text-shadow:0 1px 4px rgba(0,0,0,.6)}
303+.cstrip-dur{position:absolute;right:5px;bottom:5px;background:rgba(0,0,0,.78);color:#fff;
304+ font-family:var(--font-mono);font-size:9px;padding:1px 5px;border-radius:5px}
305+.cstrip-cap{font-size:11px;line-height:1.25;color:var(--ink-2);display:-webkit-box;
306+ -webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
307+.cstrip-meta{font-family:var(--font-mono);font-size:9px;color:var(--ink-3);line-height:1.2}
273 .acc .plat{width:44px;height:44px;border-radius:9px;flex:none} 308 .acc .plat{width:44px;height:44px;border-radius:9px;flex:none}
274 .acc .plat svg{width:20px;height:20px} 309 .acc .plat svg{width:20px;height:20px}
275 .acc-mid{min-width:0;flex:1;display:flex;flex-direction:column;gap:2px;overflow:hidden} 310 .acc-mid{min-width:0;flex:1;display:flex;flex-direction:column;gap:2px;overflow:hidden}
@@ -712,6 +747,30 @@ async function reload(more){
712 } 747 }
713 748
714 /* ---------- page créateur ---------- */ 749 /* ---------- page créateur ---------- */
750+/* --- bande de contenu récent par compte (enrichissement Apify) --- */
751+const _relTime=ts=>{if(!ts)return"";if(typeof ts==="string"&&!/^\d+$/.test(ts))return esc(ts.slice(0,10));
752+ const d=Math.floor((Date.now()/1000-Number(ts))/86400);
753+ return d<=0?"aujourd'hui":d===1?"hier":d<30?d+" j":d<365?Math.floor(d/30)+" mois":Math.floor(d/365)+" ans";};
754+function contentStrip(a){
755+ const m=a.metrics||{};
756+ const items=m.recent_posts||m.recent_videos||m.recent_tweets||[];
757+ if(!items.length)return"";
758+ const cards=items.slice(0,8).map(it=>{
759+ const img=it.display_url||it.thumbnail_url||"";
760+ const title=esc((it.caption||it.title||it.text||"").slice(0,90));
761+ const stats=[
762+ it.views!=null?fmt.format(it.views)+" vues":null,
763+ it.likes!=null?fmt.format(it.likes)+" ❤":null,
764+ it.comments!=null?fmt.format(it.comments)+" 💬":null,
765+ it.retweets!=null?fmt.format(it.retweets)+" ↻":null,
766+ ].filter(Boolean).join(" · ");
767+ const when=_relTime(it.timestamp||it.published_at||it.published||it.created_at);
768+ return `<a class="cstrip-item" href="${esc(it.url||a.url)}" target="_blank" rel="noopener" onclick="event.stopPropagation()">
769+ ${img?`<span class="cstrip-thumb" style="background-image:url('${esc(img)}')">${it.type==="video"||it.type==="reel"||it.duration?'<span class="cstrip-play">▶</span>':""}${it.duration?`<span class="cstrip-dur">${esc(it.duration)}</span>`:""}</span>`:`<span class="cstrip-thumb noimg">${icon(a.platform)}</span>`}
770+ ${title?`<span class="cstrip-cap">${title}</span>`:""}
771+ <span class="cstrip-meta">${stats}${when?` · ${when}`:""}</span></a>`}).join("");
772+ return `<div class="cstrip"><div class="cstrip-h">Contenu récent</div><div class="cstrip-scroll">${cards}</div></div>`;
773+}
715 async function renderCreator(id){ 774 async function renderCreator(id){
716 app.innerHTML=header()+`<div class="container"><div class="spin"></div></div>`+footer()+tabbar("");bindNav(); 775 app.innerHTML=header()+`<div class="container"><div class="spin"></div></div>`+footer()+tabbar("");bindNav();
717 let c;try{c=await api("/api/creators/"+encodeURIComponent(id))} 776 let c;try{c=await api("/api/creators/"+encodeURIComponent(id))}
@@ -721,18 +780,43 @@ async function renderCreator(id){
721 const verified=(c.platforms||[]).some(a=>a.verified); 780 const verified=(c.platforms||[]).some(a=>a.verified);
722 const niches=(c.niches||[]).map(n=>`<span class="mchip">${NICHE_LBL[n]||n}</span>`).join(""); 781 const niches=(c.niches||[]).map(n=>`<span class="mchip">${NICHE_LBL[n]||n}</span>`).join("");
723 const M_LBL={following:"abonnements",posts:"publications",likes:"j'aime", 782 const M_LBL={following:"abonnements",posts:"publications",likes:"j'aime",
724− views:"vues",videos:"vidéos",episodes:"épisodes"}; 783+ views:"vues",videos:"vidéos",episodes:"épisodes",images:"photos",
784+ friends:"amis",listed:"listes"};
725 const accs=(c.platforms||[]).map(a=>{const p=PLAT[a.platform]||PLAT.autre; 785 const accs=(c.platforms||[]).map(a=>{const p=PLAT[a.platform]||PLAT.autre;
726 const conf=(a.confidence||0)>=0.75?["hi","confiance élevée"]:["mid","à confirmer"]; 786 const conf=(a.confidence||0)>=0.75?["hi","confiance élevée"]:["mid","à confirmer"];
727− const mx=Object.entries(a.metrics||{}).filter(([k,v])=>M_LBL[k]&&v!=null) 787+ const m=a.metrics||{};
788+ const mx=Object.entries(m).filter(([k,v])=>M_LBL[k]&&v!=null)
728 .map(([k,v])=>`${fmt.format(v)} ${M_LBL[k]}`).join(" · "); 789 .map(([k,v])=>`${fmt.format(v)} ${M_LBL[k]}`).join(" · ");
729− return `<a class="acc" href="${esc(a.url)}" target="_blank" rel="noopener"> 790+ // rangée de statistiques riches (enrichissement Apify multi-plateforme)
730− <span class="plat" style="background:${p.color}">${icon(a.platform)}</span> 791+ const stat=(v,l)=>v==null?"":`<span class="astat"><b>${typeof v==="number"?fmt.format(v):esc(v)}</b><span>${l}</span></span>`;
731− <span class="acc-mid"><span class="acc-name">${p.label}${a.verified?checkSvg:""}</span> 792+ const stats=[
732− <span class="acc-handle">@${esc(a.handle)}</span> 793+ stat(m.engagement_rate_pct!=null?m.engagement_rate_pct+" %":null,"engagement"),
733− <span class="acc-handle" style="overflow:visible"><span class="conf ${conf[0]}" title="Score de rattachement ${Math.round((a.confidence||0)*100)} %">${conf[1]}</span>${mx?` <span style="font-size:11px">${mx}</span>`:""}</span></span> 794+ stat(m.avg_likes,"j'aime/moy"),
734− <span class="acc-right">${a.followers?`<b>${fmt.format(a.followers)}</b><span>abonnés</span>`:`<span style="font-size:11px">voir le profil ↗</span>`}</span></a>`}).join(""); 795+ stat(m.avg_views!=null?m.avg_views:m.avg_video_views,"vues/moy"),
735− const checked=(c.platforms||[]).map(a=>a.last_checked).filter(Boolean).sort().pop(); 796+ stat(m.avg_retweets,"RT/moy"),
797+ stat(m.posts_per_week!=null?m.posts_per_week:m.tweets_per_week,"/semaine"),
798+ ].filter(Boolean).join("");
799+ const badges=[
800+ m.is_partner?'<span class="abadge">Partenaire</span>':"",
801+ m.is_affiliate&&!m.is_partner?'<span class="abadge">Affilié</span>':"",
802+ m.is_live_now?'<span class="abadge live">● En direct</span>':"",
803+ m.is_seller?'<span class="abadge">Boutique</span>':"",
804+ m.is_free===true?'<span class="abadge">Gratuit</span>':"",
805+ m.has_story?'<span class="abadge">Story active</span>':"",
806+ (m.recent_games||[]).length?`<span class="abadge">${esc((m.recent_games||[])[0])}</span>`:"",
807+ (m.top_hashtags||[]).slice(0,2).map(h=>`<span class="abadge">#${esc(h)}</span>`).join(""),
808+ ].filter(Boolean).join("");
809+ return `<div class="acc-card">
810+ <a class="acc" href="${esc(a.url)}" target="_blank" rel="noopener">
811+ <span class="plat" style="background:${p.color}">${icon(a.platform)}</span>
812+ <span class="acc-mid"><span class="acc-name">${p.label}${a.verified?checkSvg:""}</span>
813+ <span class="acc-handle">@${esc(a.handle)}</span>
814+ <span class="acc-handle" style="overflow:visible"><span class="conf ${conf[0]}" title="Score de rattachement ${Math.round((a.confidence||0)*100)} %">${conf[1]}</span>${mx?` <span style="font-size:11px">${mx}</span>`:""}</span></span>
815+ <span class="acc-right">${a.followers?`<b>${fmt.format(a.followers)}</b><span>abonnés</span>`:`<span style="font-size:11px">voir le profil ↗</span>`}</span></a>
816+ ${stats?`<div class="astat-row">${stats}</div>`:""}
817+ ${badges?`<div class="abadge-row">${badges}</div>`:""}
818+ ${contentStrip(a)}</div>`}).join("");
819+ const checked=(c.platforms||[]).map(a=>(a.metrics||{}).instagram_apify_at||a.last_checked).filter(Boolean).sort().pop()||(c.platforms||[]).map(a=>a.last_checked).filter(Boolean).sort().pop();
736 app.innerHTML=header()+` 820 app.innerHTML=header()+`
737 <div class="container cpage"> 821 <div class="container cpage">
738 <a class="backlink" href="/" data-nav>← Tous les créateurs</a> 822 <a class="backlink" href="/" data-nav>← Tous les créateurs</a>
739 823
Menu

Theme