Commit initial de l'existant avant toute modification (rĂšgle transverse du playbook OKI). data/input/ est en lecture seule pour toute la suite du projet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
170 lines
18 KiB
Markdown
170 lines
18 KiB
Markdown
# PROMPT POUR KIMI CLI â Plateforme « Veille LĂ©gislative Guadeloupe »
|
||
|
||
> Copie-colle l'intégralité de ce fichier comme instruction initiale à Kimi CLI, lancé à la racine d'un dossier projet vide dans lequel tu auras préalablement copié les fichiers d'entrée listés en §2.
|
||
|
||
---
|
||
|
||
## 1. RĂŽle et mission
|
||
|
||
Tu es un développeur full-stack senior spécialisé SvelteKit, Python et systÚmes de veille documentaire. Ta mission : construire une **plateforme web de veille législative française** (lois, projets de loi, propositions de loi, décisions du Conseil constitutionnel) focalisée sur les **impacts sur les libertés des individus, des associations et des entreprises, avec un zoom Guadeloupe/outre-mer**.
|
||
|
||
La plateforme a deux composantes inséparables :
|
||
1. **Un pipeline d'automatisation Python** qui ingÚre les fichiers de recherche existants (seed), puis met à jour la base en continu depuis les sources officielles (Légifrance, Assemblée nationale, Sénat, Conseil constitutionnel).
|
||
2. **Une application web SvelteKit** présentant ces données avec recherche plein texte, filtres à facettes, vues calendaires et pages de détail.
|
||
|
||
Travaille en itérations vérifiables : chaque phase se termine par des commandes de test exécutables et un rapport de ce qui fonctionne. N'invente jamais de données : si une source est indisponible, code une dégradation gracieuse et documente-la.
|
||
|
||
## 2. Fichiers d'entrĂ©e (dĂ©jĂ gĂ©nĂ©rĂ©s â Ă ingĂ©rer)
|
||
|
||
J'ai copiĂ© dans `./data/input/` l'ensemble des livrables d'une recherche approfondie (date d'arrĂȘtĂ© : 25 juillet 2026, pĂ©rimĂštre : 1er mai â 30 septembre 2026). **Inventaire et rĂŽle de chaque fichier :**
|
||
|
||
| Fichier | RĂŽle dans le pipeline |
|
||
|---|---|
|
||
| `./data/input/lois-france-2026-guadeloupe.agent.final.md` | Rapport consolidĂ© complet (~37 000 mots, 10 chapitres + bibliographie) â **source de vĂ©ritĂ© mĂ©tier** pour le seed |
|
||
| `./data/input/lois-france-2026-guadeloupe.agent.outline.md` | Plan du rapport â utile pour la taxonomie des chapitres |
|
||
| `./data/input/lois-france-2026-guadeloupe_ref.md` | Bibliographie consolidĂ©e (481 rĂ©fĂ©rences) â **source des URLs de citation** Ă rattacher aux entrĂ©es |
|
||
| `./data/input/lois-france-2026-guadeloupe_sec00.md` ⊠`sec10.md` | Les 11 chapitres sĂ©parĂ©s (sec00 = synthĂšse exĂ©cutive, sec10 = **annexe avec 2 tableaux structurĂ©s : 27 lois promulguĂ©es + ~22 textes en attente** â parsing prioritaire pour le seed) |
|
||
| `./data/input/research/lois-2026_dim01.md` ⊠`dim12.md` | 12 rapports de dimension avec blocs structurĂ©s `Claim / Source / URL / Date / Excerpt / Confidence` â **matiĂšre brute sourcĂ©e** (dim07 et dim12 = outre-mer/Guadeloupe, dim04 = loi Riposte, dim08 = entreprises, dim09 = associations, dim11 = calendrier) |
|
||
| `./data/input/research/lois-2026_cross_verification.md` | Tiers de confiance (high/medium/low) + conflits tranchĂ©s â **Ă stocker comme mĂ©tadonnĂ©e de confiance** sur chaque entrĂ©e |
|
||
| `./data/input/research/lois-2026_insight.md` | 7 insights transversaux â Ă exposer comme « analyses » dans l'UI |
|
||
| `./data/input/research/lois-2026_phase5_validation.md` | 5 verdicts factuels tranchĂ©s (sources primaires) â rĂšgle de rĂ©solution de conflits pour le pipeline |
|
||
| `./data/input/plan.md` | Plan de travail initial (contexte) |
|
||
|
||
**Consignes d'ingestion :**
|
||
- Ăcris un parseur Python (`pipeline/seed_from_research.py`) qui extrait des fichiers ci-dessus un maximum d'entrĂ©es structurĂ©es. Les tableaux markdown de `sec10.md` sont le chemin le plus fiable pour les statuts et numĂ©ros ; les blocs `Claim/Source/URL/Date` des dim files fournissent citations et extraits.
|
||
- Chaque fait importé conserve sa **citation d'origine** (URL + date + extrait verbatim) et son **niveau de confiance**.
|
||
- Le format des marqueurs `[^dimXX-N^]` dans les chapitres permet de relier un fait du rapport à sa source dans les dim files : implémente cette résolution.
|
||
- Ne perds aucune entrée : objectif ℠49 textes législatifs au seed (27 promulgués + ~22 en attente/en navette).
|
||
|
||
## 3. Stack technique imposĂ©e (mes choix â ne pas dĂ©vier sans me demander)
|
||
|
||
- **Frontend** : SvelteKit 2 + Svelte 5 (runes) + TypeScript + Tailwind CSS. **SSR hybride avec `@sveltejs/adapter-node`** (je self-hĂ©berge sur VPS) â architecture de rendu dĂ©taillĂ©e et non nĂ©gociable au §3bis. htmx admis pour les interactions ponctuelles si plus simple.
|
||
- **Recherche** : SQLite FTS5 cĂŽtĂ© serveur via `better-sqlite3` dans les `load` functions (recherche plein texte + filtres SQL) â pas d'Elastic, pas d'Algolia, pas de SaaS. PrĂ©voir une abstraction pour passer Ă Meilisearch plus tard si le volume explose.
|
||
- **Base de données** : SQLite (fichier unique, backup = copie), accÚs via `better-sqlite3` ou Drizzle ORM. Migrations versionnées.
|
||
- **Pipeline** : Python 3.12, `httpx` + `selectolax`/`BeautifulSoup` pour le scraping, `pydantic` pour la validation, `structlog` pour les logs. Dépendances épinglées (`uv` ou `pip-tools`).
|
||
- **Automatisation** : `systemd timers` (pas de cron démon dépendant d'un framework ; fournir les unités `.service`/`.timer`). Fallback documenté : cron classique.
|
||
- **Licences** : stack 100 % open source, zĂ©ro tracker, zĂ©ro CDN externe (polices et assets auto-hĂ©bergĂ©s). Budget cible : tourne sur un VPS à †10 âŹ/mois.
|
||
- **PWA** : manifest + service worker minimal (consultation hors-ligne des derniÚres données), mobile-first.
|
||
|
||
## 3bis. Architecture de rendu SvelteKit (dĂ©cidĂ©e â ne pas dĂ©vier)
|
||
|
||
Choix d'architecture validĂ© par analyse de la doc officielle (https://svelte.dev/docs/kit/project-types, /adapters, /page-options, /adapter-node, /adapter-static) : **« transitional app » SSR sur `@sveltejs/adapter-node`, avec prerender ciblĂ© des pages figĂ©es**. Interdits : mode SPA (`ssr = false` global, `fallback` de adapter-static â dĂ©conseillĂ©s par la doc pour SEO/perf) ; SSG intĂ©gral (rebuild Ă chaque veille + `url.searchParams` interdit au prerender, incompatible avec les facettes partageables).
|
||
|
||
### Matrice de rendu par route
|
||
|
||
| Route | Option | Justification |
|
||
|---|---|---|
|
||
| `/` (tableau de bord) | SSR (défaut) | Données fraßches du dernier run pipeline, sans rebuild |
|
||
| `/recherche` | SSR (dĂ©faut) | Facettes lues cĂŽtĂ© serveur dans `url.searchParams` â URLs de filtres partageables ; FTS5 dans la `load` |
|
||
| `/textes/[slug]` | SSR (défaut) | Fiches fraßches dÚs que le pipeline écrit SQLite ; SEO optimal pour les contenus publics |
|
||
| `/calendrier` | SSR (dĂ©faut) | ĂchĂ©ances vivantes |
|
||
| `/a-propos`, `/methode` | `export const prerender = true` | Pages figées : exclues du manifest SSR, servies en statique |
|
||
| `/api/*` | `+server.js` | API JSON consommée par les `load` et réutilisable par d'autres projets |
|
||
|
||
Configuration attendue dans `svelte.config.js` :
|
||
|
||
```js
|
||
import adapter from '@sveltejs/adapter-node';
|
||
|
||
/** @type {import('@sveltejs/kit').Config} */
|
||
const config = {
|
||
kit: {
|
||
adapter: adapter({ precompress: true })
|
||
}
|
||
};
|
||
export default config;
|
||
```
|
||
|
||
Et dans `src/routes/a-propos/+layout.js` (ou équivalent) : `export const prerender = true;`. Ne JAMAIS poser `ssr = false` au layout racine, ni `export const csr = false` global (les pages de détail `/textes/[slug]` peuvent poser `csr = dev` pour profiter du HMR tout en restant HTML+CSS en production si elles n'ont pas d'interactivité).
|
||
|
||
### Exécution en production (systemd, documentée par la doc adapter-node)
|
||
|
||
- Service systemd de l'app web configurĂ© en **activation par socket** (`LISTEN_PID`/`LISTEN_FDS`, socket unit sur le port interne) + `Environment=IDLE_TIMEOUT=300` : l'app se met en sommeil sans trafic et systemd la rĂ©veille Ă la premiĂšre requĂȘte â empreinte quasi nulle sur le VPS, cohĂ©rent avec les timers du pipeline (§5).
|
||
- Reverse proxy nginx/Caddy devant, avec `ORIGIN=https://<domaine>` (ou `PROTOCOL_HEADER=x-forwarded-proto` + `HOST_HEADER=x-forwarded-host`) pour éviter l'erreur « Cross-site POST form submissions are forbidden ».
|
||
- Variables en production : `node --env-file=.env build` (Node â„ 20.6) â les `.env` ne sont PAS chargĂ©s automatiquement en prod.
|
||
- Fournir les unités `systemd/veille-web.service` + `veille-web.socket` documentées dans le README, en plus des timers du pipeline.
|
||
- `precompress: true` + compression gérée au niveau du reverse proxy.
|
||
|
||
## 4. ModÚle de données (SQLite)
|
||
|
||
Table principale `textes` (adapter les noms mais conserver la sémantique) :
|
||
|
||
- `id` (slug : ex. `loi-2026-491`, `pjl-pacte-migration`, `dc-2026-915`)
|
||
- `numero_officiel` (ex. « 2026-491 », nullable), `type` (`loi` | `loi_organique` | `pjl` | `ppl` | `ordonnance` | `decision_cc` | `decret` | `accord_international`)
|
||
- `titre_court`, `titre_officiel`
|
||
- `statut` â enum STRICT : `promulguee` | `adoptee_non_promulguee` | `saisie_cc` | `validee_cc` | `censuree_partiellement` | `navette` | `deposee_non_examinee` | `annoncee` | `rejetee` â avec `statut_date` (date du dernier changement)
|
||
- `date_depot`, `date_adoption`, `date_promulgation`, `date_entree_vigueur`, `prochaine_echeance`, `prochaine_echeance_label`
|
||
- `themes` (JSON array : `justice`, `securite`, `numerique`, `social`, `fiscal`, `environnement`, `agriculture`, `sante`, `memoire_patrimoine`, `outre_mer`, `economie`, `migration`, `institutions`)
|
||
- `impacts` (JSON : sous-ensembles de `individus`, `associations`, `entreprises`, chacun en `positif` | `negatif` | `mixte` | `neutre`, avec note courte)
|
||
- `guadeloupe_pertinence` (`forte` | `moyenne` | `faible`) + `guadeloupe_note` (texte court)
|
||
- `resume` (français, 3-5 phrases), `points_cles` (JSON array)
|
||
- `confiance` (`high` | `medium` | `low`), `source_seed` (fichier d'origine)
|
||
- `derniere_verif` (timestamp pipeline)
|
||
|
||
Tables liées : `sources` (url, titre, editeur, date, tier `T1|T2`, extrait_verbatim, FK texte), `evenements` (timeline par texte : date, type d'étape, description, source), `decisions_cc` (numéro d'affaire, date saisine, date décision, résultat, FK texte), `veille_log` (chaque run du pipeline : timestamp, ajouts, modifications, alertes).
|
||
|
||
## 5. Phase 2 â Pipeline d'automatisation (`pipeline/`)
|
||
|
||
Ăcris `pipeline/update.py` exĂ©cutant, dans l'ordre :
|
||
|
||
1. **Collecte** (chaque collecteur isolĂ©, tolĂ©rant Ă l'Ă©chec, avec cache HTTP et user-agent honnĂȘte) :
|
||
- Journal officiel : flux des lois/dĂ©crets rĂ©cents (LĂ©gifrance â API PISTE si la clĂ© `LEGIFRANCE_CLIENT_ID/SECRET` est prĂ©sente dans `.env`, sinon scraping lĂ©ger des pages de promulgations de l'AssemblĂ©e nationale : `https://www.assemblee-nationale.fr/dyn/actualites-accueil/promulgations-de-lois` et du SĂ©nat `https://www.senat.fr/lois/index.html`).
|
||
- Assemblée nationale : dossiers législatifs récents + ordre du jour (open data AN si exploitable, sinon scraping).
|
||
- Sénat : dossiers législatifs en discussion.
|
||
- Conseil constitutionnel : dĂ©cisions DC rĂ©centes (`https://www.conseil-constitutionnel.fr/decisions`) â matcher les numĂ©ros d'affaires en attente dans la base (ex. 2026-910 Ă 2026-915 DC au seed).
|
||
- vie-publique.fr : fil d'actualité législative (enrichissement contextuel).
|
||
2. **Matching et mise Ă jour** : rĂ©conciliation par `numero_officiel` puis par similaritĂ© de titre (fuzzy, seuil documentĂ©). Changement de `statut` dĂ©tectĂ© â nouvel `evenement` en timeline + mise Ă jour `statut_date`. RĂšgle de rĂ©solution de conflit : source primaire (JO/LĂ©gifrance > AN/SĂ©nat > CC > presse), conformĂ©ment au fichier `phase5_validation.md`.
|
||
3. **Classification** : heuristiques de thÚmes et d'impacts (mots-clés configurables dans `pipeline/config.yaml`) pour les NOUVEAUX textes ; les entrées seedées gardent leurs valeurs manuelles. Toute classification automatique est marquée `confiance='low'` et flaggée « à vérifier » dans l'UI.
|
||
4. **Enrichissement Guadeloupe/outre-mer** : rĂšgles de dĂ©tection (mots-clĂ©s : Guadeloupe, outre-mer, DROM, collectivitĂ©s d'OM, chlordĂ©cone, octroi de mer, RUPâŠ) qui posent `guadeloupe_pertinence` provisoire + flag de revue.
|
||
5. **Rapport de run** : écrit dans `veille_log` + optionnellement email/Matrix/webhook (config `.env`, désactivé par défaut).
|
||
6. **Sortie statique** : régénÚre `data/textes.json` (dump complet) pour le mode dégradé et le build statique.
|
||
|
||
Fournis : `systemd/veille-legislative.service` + `veille-legislative.timer` (run 2Ă/jour, 6h et 18h, + run intensif le dimanche pour le JO), un `Makefile` ou des scripts `just`/`npm run` pour `seed`, `update`, `dev`, `build`, et un `README-pipeline.md` (installation, clĂ©s API, dĂ©pannage). Mode `--dry-run` obligatoire. Tests : `pytest` sur les parseurs avec fixtures HTML figĂ©es.
|
||
|
||
## 6. Phase 3 â Application web (`web/` ou racine SvelteKit)
|
||
|
||
Interface **en français**, sobre et institutionnelle (pas de gadget). Pages :
|
||
|
||
- **`/` (accueil/tableau de bord)** : barre de recherche plein texte (SQLite FTS5, surlignage des correspondances), compteurs par statut, « prochaines échéances » (30 jours), derniers changements détectés par le pipeline (depuis `veille_log`), encart « point de veille » affichant les insights du fichier `lois-2026_insight.md`.
|
||
- **Filtres à facettes** (panneau latéral, combinables, reflétés dans l'URL pour partage) : statut, thÚme, type de texte, impact sur libertés (individus/associations/entreprises à positif/négatif/mixte), pertinence Guadeloupe, période (mois de promulgation/adoption), confiance. Chips actifs retirables.
|
||
- **Liste de résultats** : cartes compactes (titre, badges statut/thÚmes/Guadeloupe, date clé, résumé 2 lignes), tri par date ou pertinence, pagination ou scroll infini. Badge visuel distinct par statut (code couleur sobre + label texte, accessibilité daltonienne).
|
||
- **`/textes/[slug]` (dĂ©tail)** : rĂ©sumĂ© complet, points clĂ©s, timeline des Ă©vĂ©nements, impacts par catĂ©gorie, note Guadeloupe, bloc dĂ©cision CC Ă©ventuelle, **liste des sources avec URLs et extraits verbatim**, niveau de confiance affichĂ© honnĂȘtement, bouton copier-citation.
|
||
- **`/calendrier`** : vue chronologique aoĂ»tâoctobre 2026 (dĂ©cisions CC attendues ~20-24 aoĂ»t, entrĂ©es en vigueur du 1er septembre, sĂ©natoriales 27 septembre, PLF 2027) alimentĂ©e par `prochaine_echeance` + `evenements`.
|
||
- **`/a-propos/methode`** : explique la distinction promulguĂ©/adoptĂ©/navette, la date d'arrĂȘtĂ© des donnĂ©es seed, le fonctionnement du pipeline et ses limites (aucune donnĂ©e inventĂ©e ; entrĂ©es « Ă vĂ©rifier »).
|
||
- **API JSON** : `GET /api/textes` (query params : `q`, `statut`, `theme`, `impact`, `guadeloupe`, `from`, `to`), `GET /api/textes/[slug]`, `GET /api/echeances` â consommĂ©e par le front SvelteKit en SSR/load functions.
|
||
|
||
Accessibilité : WCAG AA (contraste, navigation clavier, aria-labels). Performance : page d'accueil < 100 Ko de JS. Aucune dépendance front superflue (pas de framework UI lourd ; composants maison + Tailwind).
|
||
|
||
## 7. Données seed attendues (garde-fous de vérification)
|
||
|
||
Ă l'issue du seed, ces entrĂ©es DOIVENT exister avec ces valeurs (extraits du corpus â tests d'acceptation) :
|
||
|
||
- `loi-2026-491` : chlordécone, `promulguee`, 12 juin 2026, `guadeloupe_pertinence=forte`, thÚmes `sante/outre_mer/memoire_patrimoine`.
|
||
- `loi-2026-534` : fraudes sociales et fiscales, `promulguee`, 25 juin 2026, décision CC 2026-904 DC rattachée.
|
||
- `loi-riposte` : `adoptee_non_promulguee` + Ă©vĂ©nement « saisie CC n° 2026-915 DC du 24 juillet 2026 », AFD 500 ⏠dans les points clĂ©s (montant tranchĂ© par `phase5_validation.md` â pas 1 500 âŹ).
|
||
- `ppl-aide-a-mourir` : adoption 15 juillet 2026 (291/241), 4 saisines dont n° 2026-910 DC.
|
||
- `pjl-pacte-migration` : `navette`, adoption Sénat 20 mai 2026, examen AN renvoyé à l'automne.
|
||
- `loi-2026-403` : simplification vie économique, 25 articles censurés (déc. 2026-903 DC), clause marchés publics ultramarins.
|
||
- SĂ©natoriales 27 septembre 2026 : la Guadeloupe n'est PAS concernĂ©e (sĂ©rie 2, dĂ©cret 2026-301) â si l'entrĂ©e calendrier existe, elle doit ĂȘtre correcte.
|
||
|
||
## 8. Livrables et critĂšres d'acceptation
|
||
|
||
1. Repo structuré : `pipeline/`, `web/` (ou racine SvelteKit), `data/`, `systemd/`, `tests/`, `README.md` (installation complÚte sur Debian/Ubuntu vierge), `.env.example`.
|
||
2. `make seed` (ou équivalent) : base SQLite remplie, ℠49 textes, 100 % des entrées avec ℠1 source URL, compte-rendu d'import (succÚs/échecs par fichier).
|
||
3. `make update --dry-run` : collecte réelle sans écriture, rapport des diffs détectés.
|
||
4. `npm run build` : build SvelteKit sans erreur ; `npm run check` : 0 erreur TypeScript.
|
||
5. `pytest` : parseurs couverts (â„ 70 % sur `pipeline/`).
|
||
6. Conformité rendu (§3bis) : grep prouvant qu'aucun layout/page ne pose `ssr = false` ; `prerender = true` présent sur `/a-propos` et `/methode` ; `adapter-node` en place ; `node build` démarre et répond sur `HOST=127.0.0.1` ; unités `veille-web.service`/`veille-web.socket` fournies.
|
||
7. DĂ©mo : recherche « chlordĂ©cone » â 1 rĂ©sultat pertinent avec sources ; filtre `statut=saisie_cc` â â„ 7 textes ; filtre `guadeloupe=forte` â liste non vide ; URL de recherche avec facettes (ex. `/recherche?statut=saisie_cc&guadeloupe=forte`) servie en SSR avec rĂ©sultats identiques au rechargement direct ; page dĂ©tail d'un texte avec timeline et sources.
|
||
7. Documentation des dégradations : ce qui fonctionne sans clé PISTE, ce qui la requiert.
|
||
|
||
## 9. Méthode de travail imposée
|
||
|
||
- Phase 0 : lis TOUS les fichiers de `./data/input/` (au minimum sec10, cross_verification, insight, phase5 + les dim files par survol structuré) avant d'écrire la moindre ligne ; produis un plan d'implémentation et attends ma validation.
|
||
- Une phase à la fois ; aprÚs chaque phase, exécute les tests/commandes de vérification et montre-moi la sortie réelle.
|
||
- Aucune donnée législative inventée : tout contenu vient des fichiers d'entrée ou des sources collectées, avec URL. En cas de doute, marque « à vérifier » plutÎt que deviner.
|
||
- Commentaires de code en français, nommage en français pour le domaine métier.
|
||
- Ne modifie jamais les fichiers de `./data/input/` (lecture seule).
|
||
|
||
Commence par la Phase 0.
|