Runtime
- Electron 32
- electron-vite
- Node 20
Application desktop Electron + FastAPI pour scoring d’éditions rares de bande dessinée. Deux moteurs : RADAR scrape les marketplaces et alerte sous-cote BDM, CANON identifie les éditions par photo via Claude Haiku Vision et génère description et suggestion prix.
Restaurateur BD Tintin basé en France, 134 éditions client BDM 2023-2024 dans son inventaire (valeur estimée ~71 950 €), zero compétence terminal. Le brief : un outil unique qui détecte les sous-cotes BDM sur Leboncoin, eBay, Facebook, Catawiki et Delcampe, et qui sait reconnaître une édition à partir d’une photo abîmée.
Deux contraintes dures. Un : aucun POST automatisé sur les marketplaces (TOS-safe, drafts + ouverture navigateur). Deux : un cap absolu sur la facture Claude — 3 € par campagne CANON, pas un centime de plus. Le reste — architecture, scoring, packaging — devait tenir dans une app desktop qui se lance par double-clic.
Le pipeline RADAR + CANON tient sur trois layers, chacun avec son trade-off coût/précision.
tintin.py, asterix_dargaud.py, quick_flupke.py, jo_zette.py — un module dédié par série. Regex strictes par éditeur, lecture des mentions Casterman/Dargaud/Hachette en clair sur la description. Coût ≈ 0 €, faux positifs ≈ 0 sur les éditions standards.
Quand le scraper layer 1 ne tranche pas (annonce floue, photo seulement, vendeur qui ment), bascule vers Claude Haiku avec prompt caching. Coût ramené à ~1/10 vs cold call. Cap dur 0,05 € par deal — au-delà, le deal est marqué incertain.
Chaque deal sort avec un score 0-1. ≥0.6 → carte verte, achat suggéré. 0.3-0.6 → carte orange, scoring multiplié par 0,5 (prudence). <0.3 → cap 50 € + badge « ? » rouge dashed, aucune valeur affichée. L’utilisateur final voit la couleur, pas le chiffre.
Aucun POST automatisé sur les marketplaces. Le scraper lit, génère un draft, ouvre le navigateur sur la page produit. L’humain valide et publie. Zero risque de ban Leboncoin/eBay/Facebook.
Le prompt système (whitelist 64 éditions, format de sortie, garde-fous) est cached côté Anthropic. Coût ramené à ~1/10 d’un cold call. Cap dur 0,05 € par deal vérifié côté serveur, jamais côté UI.
BaseScraper._process_listing est l’unique point qui sanitize une annonce avant scoring. Modif sécurité = 1 patch, jamais 5. Audit avril 2026 a validé l’approche : zero injection prompt en EN+FR.
CSP injecté via session.webRequest.onHeadersReceived. Jamais en <meta>. Jamais double. Mode dev et mode prod partagent le même header — un seul fichier à patcher quand une nouvelle origine doit passer.
src/backend/services/edition_override.py — coût ramené à ~1/10 d’un cold call.
from anthropic import Anthropic
from .cap import deal_cap # 0.05 € par deal
client = Anthropic()
SYSTEM_PROMPT = load_whitelist_prompt() # 64 éditions strictes
def override_edition(listing: Listing) -> Verdict:
if deal_cap.exceeded(listing.id):
return Verdict.unknown(reason="cap_reached")
response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=256,
system=[{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"},
}],
messages=[{"role": "user", "content": listing.to_prompt()}],
)
deal_cap.charge(listing.id, response.usage)
return parse_verdict(response.content[0].text)