尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗Le carnet de santé numérique du matériel agricole. Site vitrine, blog et base de fiches techniques (caractéristiques, entretien, pannes connues et tests), et un SaaS pour suivre son parc : relevés de compteur, carnet d’entretien automatique avec rappels, dépenses, coût de revient à l’heure et rapport d’historique pour la revente. Un espace administrateur sécurisé gère membres, abonnements, blog et fiches techniques (rédigées par Claude puis validées par un humain).
| Rôle | Outil |
|---|---|
| Site et application | Next.js 16 (App Router), React 19, TypeScript, Tailwind CSS 4 |
| Base de données, comptes, fichiers | Supabase (Postgres + Auth + Storage) |
| Paiements | Stripe (Checkout, portail client, webhooks) |
| IA | API Claude d’Anthropic (fiches techniques, aide au diagnostic) |
supabase/
migrations/…_init.sql Schéma complet + règles de sécurité (RLS) + stockage
seed.sql Données de démonstration (facultatif)
scripts/test-db.mjs Tests automatiques des règles de sécurité de la base
src/
proxy.ts Rafraîchit la session et filtre les accès (ex-middleware)
lib/
auth.ts Vérification des droits (membre, admin + double authentification)
ai.ts Appels à Claude (fiches, corrections, diagnostic)
sheets/schema.ts Format d’une fiche technique (partagé IA / base / affichage)
supabase/ Clients Supabase (navigateur, serveur, clé secrète)
fleet.ts Parc matériel de l’exploitant (machines, relevés, entretiens, dépenses)
maintenance.ts Échéances d’entretien (heures ou mois, au premier terme atteint)
costs.ts Coût de revient à l’heure (charges fixes + variables)
stripe.ts, audit.ts, rate-limit.ts, markdown.ts…
app/
(site)/ Pages publiques : accueil, blog, fiches, tarifs, pages légales
(auth)/ Connexion, inscription, mot de passe oublié
securite/2fa/ Double authentification (obligatoire pour l’admin)
app/ Espace exploitant : tableau de bord, parc matériel (fiche machine,
rapport pour la revente), diagnostic, abonnement, compte
admin/ Espace administrateur : vue d’ensemble, membres, paiements,
blog, fiches techniques (IA), journal d’activité
api/ Webhook Stripe, exports de données, génération des fiches
components/ Éléments d’interface partagés
Prérequis : Node.js 22.
git clone https://github.com/theo31470/sillon.git
cd sillon
npm install
cp .env.example .env.local # puis remplissez les valeurs (voir ci-dessous)
npm run dev # http://localhost:3000
Sans clés, les pages publiques s’affichent mais la connexion et l’application ne fonctionnent pas.
supabase/migrations/…_init.sql, puis (facultatif) supabase/seed.sql.
Avec la CLI Supabase : supabase link puis supabase db push..env.local.http://localhost:3000/**
et https://votre-domaine.fr/** aux Redirect URLs.update public.profiles set role = 'admin' where email = '[email protected]';
À la première visite de /admin, le site vous demandera d’activer la double authentification.price_… dans
STRIPE_PRICE_COMPLET (mensuel) et STRIPE_PRICE_COMPLET_ANNUEL (annuel). Les prix affichés sont dans
src/lib/plans.ts (COMPLET_PRICES) : gardez-les alignés avec Stripe.https://votre-domaine.fr/api/stripe/webhook avec les événements
customer.subscription.created, customer.subscription.updated, customer.subscription.deleted,
customer.subscription.trial_will_end, invoice.paid, invoice.payment_failed et charge.refunded
(avoirs automatiques). Copiez le secret whsec_… dans STRIPE_WEBHOOK_SECRET.
En local : stripe listen --forward-to localhost:3000/api/stripe/webhook.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY (pk_live_…, Developers → API keys). Elle n’est pas
secrète : elle sert au formulaire de carte intégré à la page « Abonnement ».
Settings → Payment method domains : ajoutez tracteursandco.fr (Apple Pay et Google Pay).
Settings → Customer emails : désactivez les reçus et e-mails de remboursement de Stripe : c’est le site qui
envoie les factures et avoirs Tracteurs & Co.Paiement et facturation (tout sur le site, sans page Stripe) :
/app/abonnement avec le Payment Element de Stripe (champs de carte hébergés par Stripe :
aucune donnée de carte ne passe par nos serveurs). Premier abonnement : essai de 30 jours, la carte est
enregistrée (SetupIntent) puis l’abonnement créé côté serveur ; sinon, premier paiement immédiat (3-D Secure géré) ;src/lib/invoices/) : émis par le site à chaque invoice.paid et à chaque
remboursement, numérotés sans trou (FA-2026-00001, AV-2026-00001, fonction SQL issue_invoice), figés en base
(ni modification ni suppression, 10 ans), PDF généré à la demande (/api/factures/[id]) et joint aux e-mails.
Les paiements antérieurs à ce système gardent leur facture Stripe.Tous les e-mails partent du site, aux couleurs de Tracteurs & Co, par Resend
(gratuit jusqu’à 3 000 e-mails/mois, 100/jour). Code : src/lib/email/.
tracteurs-and-co.com), sans quoi Resend n’écrit qu’au propriétaire du compte.RESEND_API_KEY (Vercel, option Sensitive).EMAIL_FROM = Tracteurs & Co <[email protected]> ; EMAIL_REPLY_TO (facultatif) = une boîte que vous lisez.https://votre-domaine.fr/api/auth/email-hook, bouton Generate secret → copiez le secret (v1,whsec_…)
dans SEND_EMAIL_HOOK_SECRET (Vercel, Sensitive), redéployez, puis activez le hook.
Sans hook, Supabase continue d’envoyer ses propres e-mails (en anglais, limités à quelques par heure).supabase/cron.sql (tous les matins, 7 h).E-mails gérés :
/api/e-mails/rappels) : une tournée par jour (verrou reminder_runs) ; un membre est
prévenu quand une échéance passe « bientôt » puis « en retard », une seule fois par niveau (maintenance_reminders),
dans un seul e-mail récapitulatif./admin/emails) : rédaction en Markdown, aperçu, test sur sa propre adresse, envoi par paquets de 100./preferences-e-mail, sans connexion grâce à un
jeton propre à chaque membre) et l’en-tête de désinscription en un clic (Gmail, Apple Mail). Préférences aussi
dans « Mon compte ».email_log, visible dans l’admin. Aperçu de tous les modèles : /admin/emails/modeles.Créez une clé sur console.anthropic.com et mettez-la dans ANTHROPIC_API_KEY.
L’usage est facturé au nombre de tokens : la consommation de chaque appel est enregistrée dans la table ai_usage.
Fixez une limite de dépense dans la console Anthropic.
hour_readings) : le compteur ne recule jamais ; chaque relevé sert au calcul des heures annuelles.machine_tasks, qui remplace l’opération de même nom). Échéance au premier terme atteint (heures ou mois),
statuts « en retard », « bientôt » (25 h / 10 % de l’intervalle ou 30 jours), « à jour ».machine_costs, € HT) : carburant (avec litres → L/h), entretien, réparations, pneumatiques,
assurance, autres. Un entretien noté avec un coût crée la dépense correspondante.src/lib/costs.ts, formule Complet) : charges fixes annuelles (amortissement
(prix − revente) / durée, frais financiers sur le capital moyen, assurance) ÷ heures annuelles, plus charges
variables des 12 derniers mois ÷ heures travaillées sur la période. Heures annuelles : relevés sur au moins
2 mois, sinon estimation saisie. Marge affichée si un tarif facturé à l’heure est renseigné (CUMA, ETA)./app/materiel/[id]/rapport, formule Complet) : identité, entretiens, relevés,
dépenses par année en option ; imprimable en PDF.Plusieurs couches indépendantes protègent les données :
admin et une session validée par double authentification (aal2).
Même un administrateur ne lit pas le parc matériel ni les dépenses des exploitants.src/lib/auth.ts).
Le proxy ne fait qu’un premier filtrage.next.config.ts).src/lib/pwned.ts). Si le service ne répond pas,
l’inscription n’est pas bloquée.src/lib/sheets/schema.ts) et est validée à la réception.Admin → Fiches techniques → Importer les tracteurs d’une marque (/admin/fiches/catalogue) :
La file tourne sur le serveur, même page fermée : chaque minute, la base (extensions pg_cron + pg_net)
appelle /api/catalogue/tick, qui traite une étape. Au plus 3 étapes en parallèle. Mise en place : exécuter
supabase/cron.sql une fois dans le SQL Editor (en remplaçant l’adresse du site).
Maîtrise des coûts (leçon du premier essai : ~1,30 $ par fiche avec Sonnet et des brochures lues en entier) :
ANTHROPIC_IMPORT_MODEL), 20 fois moins cher que Sonnet tant qu’une requête
reste sous 100 000 tokens ;ai_usage.cost_usd ; l’écran d’import affiche la dépense du jour et
une estimation avant de lancer ;CATALOG_DAILY_BUDGET_USD (1 $ par défaut) est atteint, ou quand les
crédits Anthropic sont épuisés.
Fixez aussi une limite de dépense mensuelle dans la console Anthropic.Entretien, pannes et tests : en parallèle du dossier technique, une seconde recherche par série cible le plan d’entretien (manuels, carnets), les pannes connues (rappels, presse agricole, problèmes rapportés par plusieurs propriétaires sur les forums) et les tests à faire. Chaque opération et chaque panne affiche son origine : Constructeur, Presse agricole, Retours d’utilisateurs ou Repère indicatif (pratique habituelle pour ce type de tracteur, ajoutée quand les sources sont muettes, sans capacité ni référence inventée). Les retours d’utilisateurs et les repères indicatifs sont toujours « à vérifier » : la fiche ne peut pas être publiée sans relecture. L’origine est modifiable dans la relecture.
Photos : après la rédaction, Tracteurs & Co cherche une photo du modèle sur Wikimedia Commons (licences libres
uniquement : CC BY, CC BY-SA, CC0, domaine public). Claude regarde les candidates et ne retient qu’une photo qui montre
clairement ce modèle ; sinon la fiche garde son illustration. La photo est copiée dans le stockage media et la fiche
affiche auteur, licence et lien vers la source, comme l’exigent ces licences. Dans la relecture, l’admin peut
relancer la recherche, retirer la photo ou déposer une photo (photo presse, photo personnelle) : auteur et
autorisation sont alors obligatoires. Les photos des constructeurs, de la presse ou des annonces sont protégées
par le droit d’auteur : citer la source ne suffit pas, il faut l’accord du détenteur des droits.
Sources exclues (BLOCKED_DOMAINS dans src/lib/ai-web.ts) : bases de caractéristiques d’autres éditeurs et
petites annonces. En droit européen, reprendre systématiquement le contenu d’une base de données tierce est interdit,
même valeur par valeur (droit sui generis des bases de données). Les sites des constructeurs restent la source principale.
Tarifs de référence (à vérifier sur la page tarifs d’Anthropic) : recherche web 10 $ les 1 000 ; Haiku 5.5 0,10 $ /
0,50 $ par million de tokens (entrée / sortie, sous 100 000 tokens par requête) ; Sonnet 5.5 2 $ / 10 $. Les prix
utilisés pour l’estimation sont dans src/lib/ai.ts (PRICES).
sitemap.xml et robots.txt générés, pages par marque (/fiches/marque/fendt), données structurées (TechArticle, fil d’Ariane), liens entre modèles d’une même série./p/CODE (cookie 60 jours). Le filleul a 6,99 € de remise sur son premier paiement (coupon Stripe parrainage-1-mois, créé automatiquement), le parrain reçoit 6,99 € de crédit (solde client Stripe) au premier vrai paiement du filleul. Suivi dans Admin → Promos et parrainage./app/equipe) : le titulaire d’une formule Complet invite 2 personnes par e-mail (lien /invitation/<jeton>, usage unique). Rôles : collaborateur (note relevés et entretiens) ou lecture seule. Les dépenses, le coût de revient, les informations de la machine et l’abonnement restent au titulaire. La base applique ces règles (private.fleet_role, migration 20261101000300_parc_partage.sql) ; l’accès est suspendu si le titulaire repasse en Gratuit. Une barre « Parc affiché » permet de passer d’un parc à l’autre (cookie tc_parc).src/lib/invoice-reader.ts), puis le membre relit et coche ce qui entre dans le carnet (entretiens, relevé de compteur, dépense). Le document n’est pas conservé.Admin → Mode maintenance : ferme le site au public le temps d’une mise à jour. Le proxy (src/proxy.ts) lit l’état dans site_settings (cache de 15 s par instance) et sert /maintenance avec un code 503 à tous, sauf aux administrateurs. Les routes API (webhook Stripe, tâches planifiées) ne sont pas concernées. La page affiche une scène 3D (three.js, chargée uniquement sur cette page, src/app/maintenance/scene.ts) et se recharge seule à la réouverture (/api/statut). Aperçu à tout moment : /maintenance?apercu=1 (admin).
npm run lint # qualité du code
npm run typecheck # typage TypeScript
npm run build # build de production
npm run test:db # lance un vrai Postgres local et vérifie les règles de sécurité (une cinquantaine de tests)
test:db vérifie notamment qu’un exploitant ne voit pas les données d’un autre, ne peut pas se donner
les droits admin, que la formule gratuite est limitée à 3 machines, qu’un admin sans double authentification
n’a aucun droit étendu, et qu’un compte suspendu ne peut plus écrire. (À lancer hors compte root.)
Le plus simple : Vercel.
.env.example (avec l’adresse définitive dans NEXT_PUBLIC_SITE_URL).src/app/(site)/[legal]/page.tsx) avec un professionnel (mentions, RGPD, CGU).Stripe en mode réel (26/10/2026) : compte activé. Créés par l'API en réel : produit prod_VVw1RdCLMVnBVH,
prix mensuel price_1UUu9mBMy0t4Mfm1GAZtSGVZ (6,99 €) et annuel price_1UUu9nBMy0t4Mfm1ttWEITOh (69 €),
portail bpc_1UUuA6BMy0t4Mfm1lN5vyJJO, webhook we_1UUuAIBMy0t4Mfm12EdKgIP7 (7 événements). Clé API : clé
secrète standard sk_live_… (accès complet). Les données de test (client, abonnement, paiement) ont été effacées de la base.
Reste dans le tableau de bord : informations publiques (nom, contact@) et e-mails clients.
Aide au diagnostic (26/10/2026) : modèle Haiku 5.5 (ANTHROPIC_DIAGNOSTIC_MODEL, ~0,2 centime par diagnostic),
quota compté en base : 30 par mois et 10 par 24 h (src/lib/plans.ts). À comparer avec Sonnet sur quelques pannes
réelles une fois le crédit rechargé ; pour revenir à Sonnet, mettre ANTHROPIC_DIAGNOSTIC_MODEL=claude-sonnet-5-5.
Gestion des membres (26/10/2026) : fiche /admin/membres/[id] (formule offerte hors Stripe, jours offerts,
résiliation, remboursement, quota de diagnostics, infos, notes et étiquettes internes, activité, e-mail personnel)
et liste filtrée/triée avec actions groupées (fonction admin_member_list, appelée côté serveur).
Si la clé Stripe devient un jour une clé restreinte (rk_), y inclure Refunds (écriture) et Invoice Payments (lecture). Les formules
offertes expirent chaque matin (tournée des rappels) ou à la visite suivante du membre.
Boutique de goodies et vêtements (idée, 26/10/2026) : à l'ouverture, mettre à jour la description d'activité dans Stripe, déclarer l'activité commerciale (vente de marchandises) au guichet unique, rédiger des CGV grand public (rétractation 14 jours, livraison, retours). Piste : impression à la demande (pas de stock).
Mentions légales : ajouter le téléphone de l'éditeur (src/lib/site.ts, champ phone).
DNS (Vercel) : tracteursandco.fr (site, Resend, messagerie Amen MX + SPF include:spf1/spf2.webapps.net),
tracteursandco.com (redirection, v=spf1 -all, DMARC reject). Ne pas modifier le MX Amen
(Amen supprime les boîtes si le MX ne pointe plus chez eux).
Import des tracteurs — budget (24/10/2026) : premier essai à ~1,30 $ par fiche (Sonnet, brochures lues en entier) ; version corrigée (Haiku, une recherche par série) estimée à ~3,5 centimes par fiche, soit ~250 fiches pour 10 € ; avec la recherche entretien/pannes ajoutée le 25/10 : ~5 centimes par fiche, soit ~180 fiches pour 10 €. : lancer une seule série (Fendt 700 Vario, 5 modèles, estimation ≈ 0,17 $), comparer avec la dépense affichée dans l’écran d’import, puis recalculer. Les 57 Fendt sont déjà listés (« À générer »). Penser à fixer une limite de dépense mensuelle dans la console Anthropic.
proxy.ts remplace middleware.ts (nouvelle convention de Next.js 16).src/lib/markdown.ts), volontairement limité et sûr.git checkout -b fonction/xxx), puis une Pull Request vers main.npm run lint && npm run typecheck && npm run build.supabase/migrations/ (ne jamais modifier
une migration déjà appliquée), avec un test ajouté dans scripts/test-db.mjs si elle touche à la sécurité..env.local ni aucune clé.Import : documentation officielle d'abord (26/10/2026, soir) : le dossier technique d'une série est d'abord
recopié depuis le site du constructeur (2 recherches et 2 pages lues au plus, limitées aux domaines officiels de
BRAND_SITES / EXTRA_BRAND_DOMAINS), sous forme de tableaux modèle par modèle. Recherche élargie (presse) seulement
si rien d'exploitable n'est trouvé. Bases de données tierces bloquées (droit des bases de données) : agridonnees,
tractorbook ajoutés. Réflexion désactivée pendant la recherche (sinon dossier vide). Constat du 26/10 avant ce
changement : ~0,16 $ par recherche (palier > 100 000 tokens de Haiku), fiches 900 Vario sans puissance par modèle.
Import : sources officielles par marque (27–28/10/2026). Le site télécharge lui-même le tableau officiel
(src/lib/official-pages.ts), suit les liens « brochure » des pages de série (PDF : seules les pages riches en
données sont gardées, via unpdf), essaie la même page dans un autre pays (hreflang) si la brochure n'y est pas liée,
et lit les données JSON des sites en JavaScript. Indications par marque : TECHDATA_HINTS (src/lib/ai-web.ts).
Résultats : Fendt (api.fendt.com/techdata) et Claas (brochure PDF) 28 à 40 caractéristiques ; Case IH et New Holland
(brochure sur cnhi-p-001-delivery.sitecorecontenthub.cloud) 25 à 37 ; Kubota (page de série partielle) 15 à 19 ;
John Deere : caractéristiques chargées en JavaScript depuis un service interne, inaccessibles → recherche web en
secours. Outil de mise au point temporaire : /api/dev/probe (jeton PROBE_TOKEN), à supprimer à la fin.
Si la qualité des fiches rédigées par Haiku déçoit : repasser Sonnet pour la seule étape de rédaction (peu coûteuse).