# 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.