Reprend worker/enrich.js (fusion, pas réécriture) pour le nouveau format de
soumission libre et l'infra en prod (décisions MOE du 27/09) :
- LLM Mistral direct → Bifrost (${BIFROST_URL}/v1/chat/completions,
x-bf-vk), modèle WORKER_MODEL (défaut groq/llama-3.1-8b-instant).
- Scrape crawl4ai/Python → fetch natif Node 22 : timeout 8s, corps
plafonné 500 Ko, titre + meta description + og:* + texte tronqué 4000c.
- Email Resend → notification ntfy, jamais l'email ni le texte du
contributeur (id NocoDB, nom suggéré, type, confiance uniquement).
- Sortie LLM {nom, description, type_suggere, ville, tags, confiance} ;
le worker ne réécrit `nom`/`submission_type` que si le formulaire assoupli
a laissé un placeholder ("[à qualifier]" / "Type : non précisé").
- Seuil « 5 fiches pending » retiré (décision volume faible, notée si le
volume remonte).
- --dry-run : fixture locale, mock Bifrost/scrape par défaut, aucune
écriture NocoDB, DRY_RUN_LIVE=1 pour forcer de vrais appels réseau.
- worker/daily-digest.js supprimé (non référencé, cron purgé le 15/07).
deploy/aep-worker/ : service + timer (15 min) + README avec les étapes
exactes de déploiement pour la session qui déploiera (backup NocoDB,
copie, systemctl, test bout-en-bout M3) — rien exécuté ni copié ici.
PIPE-IA-DOC.md §11 : documente tous les écarts vs la version NAV V2 d'origine.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Déploiement aep-worker (B5-M2)
Ce dossier n'a rien été exécuté ni copié sur le VPS par la session B5 — code seulement, comme demandé. Étapes exactes pour la session qui déploiera.
0. Pré-requis avant de commencer
- Backup NocoDB < 24 h avant le premier passage du worker (il écrit en base).
- Vérifier que
/opt/aep/.envcontient déjà :NOCODB_URL,NOCODB_TOKEN,NOCODB_BASE,NOCODB_TABLE_ORGAS,NOCODB_TABLE_STATS,BIFROST_URL,BIFROST_VK,NTFY_TOPIC(et optionnellementWORKER_MODEL,WORKER_LIMIT,BUDGET_MAX_EUR). Ne PAS créer de nouveau fichier .env — celui-ci existe déjà en prod (mission dit de le lire, pas de le chercher dans ce repo). - Confirmer que
/opt/nav-carte(l'ancien worker) est bien absent — il l'était au 27/09 selon B0. Sinon, l'arrêter/purger avant d'activer celui-ci pour éviter un double traitement des mêmes fiches pending.
1. Copier le code
ssh vps
mkdir -p /opt/aep-worker
exit
# depuis le poste de dev, après avoir buildé/vérifié la branche :
scp -r worker/enrich.js worker/package.json worker/fixtures vps:/opt/aep-worker/
ssh vps "cd /opt/aep-worker && npm install --omit=dev"
(npm install : le worker n'a plus de dépendance à dotenv côté prod puisque
EnvironmentFile= du service systemd charge déjà /opt/aep/.env — le
package.json du worker peut être simplifié à cette occasion, ou laissé tel
quel si dotenv sert encore pour un lancement manuel en local.)
2. Poser les unités systemd
scp deploy/aep-worker/aep-worker.service deploy/aep-worker/aep-worker.timer \
vps:/tmp/
ssh vps
sudo mv /tmp/aep-worker.service /tmp/aep-worker.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now aep-worker.timer
3. Vérifier
systemctl status aep-worker.timer
systemctl list-timers | grep aep-worker
# Lancer un passage manuel (sans attendre les 15 min) :
sudo systemctl start aep-worker.service
journalctl -u aep-worker.service -n 100 --no-pager
Logs attendus : === Worker AEP enrichissement démarré ===, un compte de
fiches pending, puis soit Rien à traiter. soit le détail par fiche
(scrape/Bifrost/ntfy).
4. Test bout-en-bout (M3, session suivante)
- Soumettre une vraie ressource de test via
/proposer(formulaire assoupli). - Vérifier le 201 + le record
pending/ai_processed=falsedans NocoDB. - Vérifier la notif ntfy de soumission (topic
NTFY_TOPIC). - Lancer le worker (
systemctl start aep-worker.serviceou attendre le timer) → vérifiermoderation_status=ai_processed,description_enrichie,tags_fonction,ai_raw_outputremplis, et la notif ntfy « Fiche enrichie ». - Modérer dans NocoDB UI (
ai_processed→approved) → vérifier l'affichage sur le front. - Supprimer les records de test dans NocoDB (orgas + stats_usage) une fois la preuve faite.
- Mettre à jour
PIPE-IA-DOC.md,Onglets/Proposer.md,PILOTE - AEP.mddans le vault avec le résultat réel (pas seulement ce README).
Anti-chevauchement
Lock fichier PID : /tmp/aep-worker.lock (configurable via WORKER_LOCK_FILE
dans .env si besoin). Nettoyé en fin de run normal, et automatiquement si le
PID contenu dans le lock n'est plus vivant (voir acquireLock() dans
enrich.js) — pas d'intervention manuelle attendue, sauf lock resté après un
crash dur du process (kill -9 externe) : dans ce cas rm /tmp/aep-worker.lock
suffit.
Écarts par rapport à la version NAV V2 (PIPE-IA-DOC.md)
Voir l'en-tête de commentaire de worker/enrich.js et PIPE-IA-DOC.md §11 —
LLM Bifrost au lieu de Mistral direct, scrape fetch natif au lieu de crawl4ai,
notification ntfy au lieu de Resend, écriture nom/submission_type par le
worker seulement quand le formulaire assoupli a laissé un placeholder.