# Veille législative Gwadloup Plateforme de veille sur la production législative française — lois, projets et propositions de loi, ordonnances, décisions du Conseil constitutionnel — lue sous l'angle des **libertés des individus, des associations et des entreprises**, avec un zoom Guadeloupe et outre-mer. > **Aucune donnée législative n'est inventée.** Chaque fait porte sa source > (adresse, date, extrait verbatim), son niveau de confiance et son fichier > d'origine. Ce qui n'est pas établi est marqué « à vérifier », avec son motif > affiché sur la fiche. --- ## Ce que contient la base | | | |---|---| | Textes législatifs | **59** — 52 issus du corpus de recherche, 7 ajoutés par le pipeline depuis les sources officielles | | Sources vérifiables | **367**, toutes avec adresse — aucun texte sans lien | | Événements de parcours | 90 | | Affaires du Conseil constitutionnel | 13 | | Analyses transversales | 7 | | Échéances de calendrier | 9 | | Marqueurs de citation résolus | **100 %** (332/332), dont 93 % avec un lien | Les valeurs déduites sont signalées comme telles, avec leur motif : 16 cotations Guadeloupe, 17 ventilations d'impact, et les 7 textes ajoutés par le pipeline — qui entrent tous avec la confiance la plus basse et le drapeau de revue. Les 52 textes du corpus couvrent la fenêtre du 1ᵉʳ mai au 30 septembre 2026. Les 7 ajouts sont antérieurs (janvier à avril 2026) : le pipeline les a relevés sur la liste du Sénat, qui couvre toute la session. Parmi eux, la loi de finances pour 2026 (n° 2026-103), qui modifie l'octroi de mer et étend le versement mobilité aux départements d'outre-mer. --- ## Architecture ``` veille_legislative_971/ ├── data/input/ corpus de recherche — LECTURE SEULE, jamais modifié ├── pipeline/ Python 3.12 : parseurs, collecteurs, run de veille ├── web/ SvelteKit 2 + Svelte 5, rendu serveur sur adapter-node ├── systemd/ 4 unités : timer du pipeline, socket + service de l'app ├── tests/ pytest, fixtures HTML figées — aucun test ne va au réseau └── scripts/ contrôles de conformité ``` Une seule base SQLite, `data/veille.db`. La recherche plein texte est assurée par SQLite lui-même (FTS5). Aucun service externe n'est nécessaire au fonctionnement : ni moteur de recherche, ni réseau de diffusion, ni traceur. --- ## Installation sur Debian ou Ubuntu vierge Testé sur Debian 13 et Ubuntu 24.04. ### 1. Dépendances système ```bash sudo apt update sudo apt install -y git curl build-essential sqlite3 ca-certificates ``` ### 2. Node.js ≥ 20.6 La version 20.6 est le minimum : l'application utilise `node --env-file`, qui n'existe pas avant. ```bash curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - sudo apt install -y nodejs node --version # doit afficher v20.6 ou plus ``` ### 3. Python 3.12 et uv ```bash curl -LsSf https://astral.sh/uv/install.sh | sh export PATH="$HOME/.local/bin:$PATH" uv python install 3.12 ``` ### 4. Le projet ```bash sudo mkdir -p /opt/veille-legislative sudo chown "$USER:$USER" /opt/veille-legislative git clone /opt/veille-legislative cd /opt/veille-legislative make install # environnement Python + dépendances npm cp .env.example .env $EDITOR .env # renseigner les identifiants PISTE — voir README-pipeline.md ``` ### 5. Remplir la base et construire l'application ```bash make seed # → 52 textes, 360 sources cd web && npm run polices && cd .. # copie les polices depuis npm make build make verifier # contrôles de conformité ``` ### 6. Vérifier localement ```bash cd web HOST=127.0.0.1 PORT=3971 VEILLE_DB=/opt/veille-legislative/data/veille.db node build ``` Puis, dans un autre terminal : ```bash curl -sI http://127.0.0.1:3971/ | head -1 # HTTP/1.1 200 OK curl -s http://127.0.0.1:3971/api/textes | head -c 200 ``` --- ## Mise en service ### Compte dédié ```bash sudo useradd --system --home /opt/veille-legislative --shell /usr/sbin/nologin veille sudo chown -R veille:veille /opt/veille-legislative sudo chmod 600 /opt/veille-legislative/.env ``` ### Unités systemd ```bash sudo cp systemd/*.service systemd/*.timer systemd/*.socket /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable --now veille-web.socket # l'app se réveille à la demande sudo systemctl enable --now veille-legislative.timer # collecte 6 h, 18 h, dimanche 9 h ``` L'application est **activée par socket** : systemd tient le port ouvert et ne démarre Node qu'à la première requête ; sans trafic pendant `IDLE_TIMEOUT` (300 s), elle s'arrête. Sur un site de veille peu fréquenté, l'empreinte mémoire tombe à zéro entre deux visites — ce qui compte sur un serveur à 5 € par mois. **Aucun fichier n'est à éditer avant de démarrer.** L'unité déduit son origine des en-têtes posés par le reverse proxy (`PROTOCOL_HEADER` / `HOST_HEADER`), donc elle fonctionne quel que soit votre domaine. Sans cette origine, adapter-node refuserait les soumissions de formulaire (« Cross-site POST form submissions are forbidden »). Ces en-têtes ne sont dignes de confiance que parce que l'application n'écoute que sur `127.0.0.1` : seul le proxy local peut les poser. **N'exposez jamais le port 3971 directement** — l'origine deviendrait falsifiable par le client. Pour figer l'origine plutôt que la déduire, renseignez `ORIGIN=` dans `.env` : adapter-node la retient d'office, sa résolution s'écrivant `origin || get_origin(headers)`. ### Reverse proxy Remplacez `veille.example.org` par votre domaine dans les deux exemples. **Caddy** (le plus court, HTTPS automatique — il pose les en-têtes attendus sans configuration supplémentaire) : ```caddy veille.example.org { encode gzip zstd reverse_proxy 127.0.0.1:3971 } ``` **nginx** : ```nginx server { listen 443 ssl http2; server_name veille.example.org; gzip on; gzip_types text/css application/javascript application/json image/svg+xml; location / { proxy_pass http://127.0.0.1:3971; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; } } ``` Les trois en-têtes `X-Forwarded-*` de cet exemple ne sont pas décoratifs : ce sont eux dont l'application déduit son origine. Les omettre casserait les soumissions de formulaire. ### Vérifier ```bash systemctl status veille-web.socket systemctl list-timers veille-legislative.timer journalctl -u veille-legislative -n 40 ``` --- ## Commandes ``` make install installe pipeline Python et application web make seed remplit la base depuis data/input/ make reseed repart d'une base vierge make update-dry collecte réelle, aucune écriture, rapport des écarts make update collecte et applique make test pytest avec couverture make lint ruff make dev serveur de développement (port 5971) make build build de production make check vérification TypeScript make verifier contrôles de conformité au cahier des charges ``` --- ## Dégradations documentées | Situation | Conséquence | |---|---| | Sans identifiants PISTE | Le collecteur Légifrance se désactive et l'annonce dans le rapport. Le Sénat et le Conseil constitutionnel prennent le relais : les promulgations et les décisions restent suivies. Voir `README-pipeline.md` §3. | | Une source indisponible | Le collecteur concerné échoue seul ; les autres poursuivent. L'erreur figure au rapport de run. | | Réseau coupé | `make update --hors-ligne` travaille sur le cache HTTP. Côté navigateur, le service worker sert les pages déjà consultées, en signalant qu'elles peuvent être périmées. | | Base absente | L'application refuse de démarrer avec un message indiquant les emplacements essayés. | **Deux adresses du cahier des charges sont mortes** et ont été remplacées : `senat.fr/lois/index.html` et `assemblee-nationale.fr/dyn/actualites-accueil/promulgations-de-lois` renvoient toutes deux 404. La liste `senat.fr/dossiers-legislatifs/lois-promulguees.html` couvre l'ensemble des promulgations et tient lieu de source unique. --- ## Sauvegarde La base est un fichier unique : ```bash sqlite3 data/veille.db ".backup /sauvegardes/veille-$(date +%F).db" ``` Ne copiez jamais le fichier pendant un passage du pipeline : le mode WAL laisse des fichiers annexes. `.backup` s'en charge correctement. --- ## Interface de programmation Ouverte, sans clé : | Route | Objet | |---|---| | `GET /api/textes` | liste filtrable — `q`, `statut`, `theme`, `type`, `impact`, `guadeloupe`, `confiance`, `from`, `to`, `tri`, `page` | | `GET /api/textes/[identifiant]` | fiche complète, sources et parcours compris | | `GET /api/echeances` | calendrier, avec `?jours=N` en option | ```bash curl -s 'https://veille.example.org/api/textes?statut=saisie_cc&guadeloupe=forte' | jq '.total' ``` --- ## Licence AGPL-3.0-or-later. Le corpus de `data/input/` reste la propriété de ses auteurs. Si vous réutilisez ces données, citez la source primaire — Journal officiel, assemblées, Conseil constitutionnel — plutôt que cette plateforme : elle n'est qu'un intermédiaire.