Plateforme & Guide
Stack Technique & Dépendances
Versions : plage déclarée dans les package.json, et entre parenthèses la version résolue dans pnpm-lock.yaml lorsqu'elle diffère utilement.
🧱 Commun
- Runtime : Node.js 24 (
.nvmrc; au moins 24.11 selon lesenginesdupackage.jsonracine). La CI lit.nvmrc, les images Docker partent denode:24-alpine, et le site comme la documentation déclarent24.xà Vercel. - Langage : TypeScript 5 (5.9.3).
- Gestionnaire de paquets : pnpm 8 (
packageManager: pnpm@8.15.0) ; la CI utilise pnpm 9. - Monorepo : pnpm workspaces + Turborepo 2.
- Tests : Vitest 1 (API et ingestion ; côté frontend, seul le proxy
/api/v1est testé). - Logs : pino 8.
⚡ API (apps/api)
- Framework : Fastify 4 (4.29.1), avec
@fastify/compress,@fastify/cors,@fastify/helmet,@fastify/rate-limit,@fastify/swaggeret@fastify/swagger-ui. - ORM : Prisma 5 (5.22.0).
- Validation : Zod 3.
- Cache et limitation de débit : Redis, via ioredis.
- Recherche : requêtes PostgreSQL par Prisma (
contains, insensible à la casse), puis classement applicatif par similarité Jaro-Winkler (apps/api/src/utils/fuzzy-search.ts). Aucun moteur de recherche dédié.
💻 Frontend (apps/web)
- Framework : Next.js 14.0.4 (App Router), React 18.
- Styles : Tailwind CSS 3,
class-variance-authority,tailwind-merge,tailwindcss-animate, thème clair et sombre avecnext-themes. - Données : TanStack Query 5 ; les appels du navigateur passent par un proxy Next (
app/api/v1/[...path]/route.ts) qui relaie vers l'API. - Graphiques : Recharts 2.
- Icônes et animations : lucide-react, framer-motion.
- Mesure d'audience : Plausible (sans cookie).
📥 Ingestion (services/ingestion)
- CLI : commander 11.
- Téléchargement et lecture : axios, cheerio (HTML), xml2js (XML), csv-parse (CSV), tar-stream (archives de la base LEGI), lecteur XLSX maison (
src/utils/xlsx.ts),pdftotextde poppler-utils pour les comptes rendus de commission publiés en PDF. - Concurrence : p-limit, limiter.
- Références juridiques : @tricoteuses/tisseuse (AGPL-3.0, comme CLAIR) repère les textes et articles de loi cités dans le dispositif des amendements ; la résolution vers Légifrance passe par notre index de la base LEGI.
- Build : tsup (CJS + ESM) ; exécution en développement avec tsx.
- IA : API Mistral (
mistral-small-latestpour la génération,mistral-embedpour le classement des liens de contexte), Tavily (recherche ciblée sur vie-publique.fr).
📚 Documentation (docs)
- Portail : Zudoku 0.86 ; recherche plein texte par Pagefind.
- Référence de l'API : la spécification OpenAPI générée par l'API de production (
https://api.clair.vote/docs/json), téléchargée à chaque build dansdocs/public/openapi.json(fichier ignoré par git).
🌐 Infrastructure
| Élément | Développement local | Production |
|---|---|---|
| PostgreSQL | 16 (postgres:16-alpine, docker-compose.yml) | 17 (image Railway postgres-ssl:17) |
| Redis | 7 (redis:7-alpine) | 8.2.1 |
| Frontend | next dev sur le port 3000 | Vercel, région cdg1 (Paris) |
| API | tsx watch sur le port 3001 | Railway, image construite depuis le Dockerfile racine |
| Documentation | zudoku dev sur le port 3002 | Vercel (docs.clair.vote) |
| Ingestion | CLI lancée à la main | Railway, deux services planifiés (voir Déploiement) |
| CI | GitHub Actions : lint, tests, build (le type-check est désactivé en CI) |