feat(aep): M2 — worker adapté (Bifrost + scrape léger + ntfy)
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>
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
# 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/.env` contient déjà : `NOCODB_URL`, `NOCODB_TOKEN`,
|
||||
`NOCODB_BASE`, `NOCODB_TABLE_ORGAS`, `NOCODB_TABLE_STATS`, `BIFROST_URL`,
|
||||
`BIFROST_VK`, `NTFY_TOPIC` (et optionnellement `WORKER_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
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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)
|
||||
|
||||
1. Soumettre une vraie ressource de test via `/proposer` (formulaire assoupli).
|
||||
2. Vérifier le 201 + le record `pending`/`ai_processed=false` dans NocoDB.
|
||||
3. Vérifier la notif ntfy de soumission (topic `NTFY_TOPIC`).
|
||||
4. Lancer le worker (`systemctl start aep-worker.service` ou attendre le
|
||||
timer) → vérifier `moderation_status=ai_processed`, `description_enrichie`,
|
||||
`tags_fonction`, `ai_raw_output` remplis, et la notif ntfy « Fiche enrichie ».
|
||||
5. Modérer dans NocoDB UI (`ai_processed` → `approved`) → vérifier l'affichage
|
||||
sur le front.
|
||||
6. **Supprimer les records de test** dans NocoDB (orgas + stats_usage) une
|
||||
fois la preuve faite.
|
||||
7. Mettre à jour `PIPE-IA-DOC.md`, `Onglets/Proposer.md`, `PILOTE - AEP.md`
|
||||
dans 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.
|
||||
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=AEP — Worker enrichissement IA (scrape léger + Bifrost)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
WorkingDirectory=/opt/aep-worker
|
||||
EnvironmentFile=/opt/aep/.env
|
||||
ExecStart=/usr/bin/node enrich.js
|
||||
TimeoutStartSec=300
|
||||
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Timer 15 min — worker enrichissement IA AEP
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*:0/15
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
Reference in New Issue
Block a user