Un site pour partager le PDF, ainsi que les autres versions du programme
  • TypeScript 47.1%
  • CSS 27%
  • HTML 16.1%
  • Python 8.5%
  • Makefile 0.6%
  • Other 0.7%
Find a file
2026-07-26 15:45:18 +00:00
apps Merge pull request 'Restore a theme control: OS by default, with an explicit override' (#36) from new-design-ux-pass into main 2026-07-26 15:28:36 +00:00
assets Track the licensed font files in assets/fonts/ 2026-07-26 17:40:15 +02:00
docs Restore a theme control: OS by default, with an explicit override 2026-07-26 17:24:10 +02:00
scripts Add a placeholder-narration generator plus tiny committed fixtures 2026-07-26 15:24:54 +02:00
tests Rework the app's UX: layout bugs, palette, search, content, a11y widget 2026-07-26 17:10:46 +02:00
.dockerignore Adapt PR #29: separate audio origin, Node 24, declared narration availability 2026-07-26 13:28:41 +02:00
.env.example Add .env.example so the audio slugs stop getting lost 2026-07-26 15:54:13 +02:00
.gitignore Merge pull request 'Track the licensed font files in assets/fonts/' (#37) from new-design-ux-pass into main 2026-07-26 15:45:18 +00:00
CLAUDE.md Merge pull request 'Restore a theme control: OS by default, with an explicit override' (#36) from new-design-ux-pass into main 2026-07-26 15:28:36 +00:00
design-system.html Evolve the design system for the 2026-07 reading-UX handoff (support colors, dark pairs) 2026-07-26 12:17:04 +02:00
design.md Restore a theme control: OS by default, with an explicit override 2026-07-26 17:24:10 +02:00
docker-compose.yml Let the accueil's « Écouter le programme » CTA be enabled 2026-07-26 14:11:34 +02:00
Dockerfile Adapt PR #29: separate audio origin, Node 24, declared narration availability 2026-07-26 13:28:41 +02:00
index.html Add RGAA/SEO/AI-agent readability baseline (robots.txt, sitemap.xml, llms.txt) 2026-07-25 17:54:01 +02:00
llms.txt Add RGAA/SEO/AI-agent readability baseline (robots.txt, sitemap.xml, llms.txt) 2026-07-25 17:54:01 +02:00
Makefile Integrate the real open-dataec API, switch programme pages to dynamic rendering 2026-07-26 11:43:40 +02:00
mise.toml Adapt PR #29: separate audio origin, Node 24, declared narration availability 2026-07-26 13:28:41 +02:00
package-lock.json Dockerize the Next.js app as a Turborepo monorepo package 2026-07-25 16:35:34 +02:00
package.json Adapt PR #29: separate audio origin, Node 24, declared narration availability 2026-07-26 13:28:41 +02:00
README.md Adapt PR #29: separate audio origin, Node 24, declared narration availability 2026-07-26 13:28:41 +02:00
robots.txt Add RGAA/SEO/AI-agent readability baseline (robots.txt, sitemap.xml, llms.txt) 2026-07-25 17:54:01 +02:00
sitemap.xml Add RGAA/SEO/AI-agent readability baseline (robots.txt, sitemap.xml, llms.txt) 2026-07-25 17:54:01 +02:00
TODONEXT.md Adapt PR #29: separate audio origin, Node 24, declared narration availability 2026-07-26 13:28:41 +02:00
turbo.json Let the accueil's « Écouter le programme » CTA be enabled 2026-07-26 14:11:34 +02:00
vitest.config.ts Dockerize the Next.js app as a Turborepo monorepo package 2026-07-25 16:35:34 +02:00

aec2027

Campaign landing page for "L'Avenir en Commun" (Jean-Luc Mélenchon, presidential election 2027 / La France Insoumise). Canonical domain: aec2027.fr.

Repo layout

The repo is an npm-workspaces + Turborepo monorepo (apps/*):

  • apps/web/ — the Next.js app (App Router, TypeScript, Vitest). This is the site.
  • apps/backend/ — an empty placeholder for a possible future in-repo backend.

See CLAUDE.md for the full design-system conventions and docs/plans/ for in-progress planning artifacts.

Running locally without Docker

npm install          # installs all workspaces
npm run dev           # turbo run dev -> apps/web's `next dev`, http://localhost:3000

A Makefile wraps the common tasks — run make to list the targets.

Running with Docker

docker compose up app                         # http://localhost:3000 (+ the audio origin)
docker compose --profile test run --rm test   # apps/web's typecheck + test suite

Without compose:

docker build .                     # production image (runner target)
docker build --target test .       # test image

There are no build args: every page is force-dynamic, so nothing about the audio origin or the open-dataec API is baked into the image. Configure both through environment: at run time (see below) — changing the audio host doesn't need a rebuild.

docker compose up app also starts audio, a dev-only nginx:alpine origin on http://localhost:8081 that serves apps/web/public/audio/ over HTTP. It exists so the app can be exercised against real, multi-megabyte narration without committing it to git or rebuilding to change it — the directory is bind-mounted read-only, its contents are gitignored, and .dockerignore keeps them out of the image. Production points AUDIO_CDN_BASE_URL at object storage instead. See apps/web/public/audio/README.md.

Testing

npm run typecheck    # via Turborepo
npm run test         # via Turborepo — same commands the Docker `test` target runs

Environment variables

All three are runtime values (docker-compose.yml's environment:), never build args. apps/web/.env.example documents them for non-Docker runs.

  • OPEN_DATAEC_API_URL (optional) — base URL of the open-dataec API. Fetched server-side only, so a Docker-internal hostname like http://open-dataec:3000 is fine. Falls back to http://localhost:3000. See apps/web/lib/dataec.ts.
  • AUDIO_CDN_BASE_URL (optional) — base URL of the narration audio origin. Unlike the above, this one is emitted into the HTML as an <audio> src and fetched by the browser, so it must be reachable from the visitor's browser — never http://audio:80. Unset means Next.js serves apps/web/public/audio/<slug>.mp3 itself. Compose defaults it to the dev audio service, http://localhost:8081/audio. See apps/web/lib/audio.ts.
  • AUDIO_AVAILABLE_SLUGS (optional) — comma-separated chapter slugs that actually have a recording. Empty by default: no narration exists yet (2026-07-26), so no listen button renders anywhere rather than offering one that 404s. Malformed entries are ignored. See apps/web/lib/audioAvailability.ts.

Whatever origin serves the audio must honour HTTP Range requests — the player's slider and ±15 s buttons seek mid-file. Next.js's public/ handler, nginx, and object storage all do.