Prevents stale Doctrine L2 cache and app cache from causing issues
after schema changes. Clears both filesystem cache and Redis pool.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New SECRET_ANALYTICS variable replaces kernel.secret for analytics
- Ansible generates a random 32-char secret at each deploy
- Endpoint token and encryption key change with every deployment
- Existing sessions will get new visitor_id after deploy (expected)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The /admin/infra page was slow because Docker stats API blocks per container.
Now a cron (every 5min) generates var/infra.json via app:infra:snapshot,
and the page reads the static JSON file instantly.
Mount Docker socket in cron container for snapshot access.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The PHP container user needs the docker group to read the socket.
Uses DOCKER_GID env var in dev (defaults to 989) and dynamic GID
detection via Ansible stat in prod.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Complete rewrite of /admin/infra into 4 columns:
- Col 1 (Serveur): CPU, RAM, Disk, System, Services (Caddy, Docker, SSL cert)
- Col 2 (Containers): All Docker containers with CPU%, RAM, state via Docker API
- Col 3 (Redis): Global stats + per-DB (Messenger, Sessions, Cache)
- Col 4 (PostgreSQL): Instance stats + PgBouncer pools/stats
Extract all infra logic into InfraService. Mount Docker socket (read-only)
in PHP container for container stats. Check SSL cert expiry and Caddy status.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Without admin_users/stats_users, connecting to the pgbouncer virtual
database fails with "database pgbouncer does not exist".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Configure Redis DB 2 as Symfony cache adapter
- Cache Meilisearch search results for 5 minutes (invalidated on writes)
- Cache admin dashboard stats for 10 minutes
- Add invalidateSearchCache() called after each Meilisearch write
- Update tests to support cache mock injection
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The getmeili/meilisearch image (Debian slim) has neither curl nor wget,
so healthcheck commands always fail. Use condition: service_started
and rely on Messenger retry mechanism for brief startup delays.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The getmeili/meilisearch image does not include curl, causing the
healthcheck to fail and blocking messenger startup.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add toggle online/offline and delete routes in AdminController
- Add action buttons (En ligne, Modifier, Supprimer) in admin events template
- Bypass requireEventOwnership and requireStripeReady for ROLE_ROOT so admin can edit any event
- Add Meilisearch healthcheck and depends_on in messenger service (prod + dev)
- Add tests for all new admin routes and ROLE_ROOT bypass
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove Start/Wait/Translate LibreTranslate tasks from deploy.yml
- Add SESSION_HANDLER_DSN with Redis in env.local.j2 for prod sessions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix SESSION_HANDLER_DSN: use Redis db index (/1) instead of /sessions
which caused "dbindex must be a number" error
- Remove LibreTranslate service and volume from docker-compose prod
- Remove gitignore rules for translation files (en, es, de, it)
so all languages are tracked in git
- Apply PHP CS Fixer style fixes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ApiSandboxController: reduce scan() returns from 4 to 3 via ternary
- ApiDocController: add MIME_JSON constant, extract buildInsomniaRequest()
and buildInsomniaBody() to reduce cognitive complexity
- Store sessions in Redis to fix SSO disconnect with 2 PHP replicas
(round-robin load balancing caused session loss on filesystem storage)
- Configure session cookie: 24h lifetime, secure auto, samesite lax
- Replace Caddy analytics proxies (/stats/*, /assets/perf.js, /sperf)
with direct URLs to tools-security.esy-web.dev and cloudflareinsights.com
- Update JS tests for new direct analytics URLs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Ansible: healthcheck via PHP container (curl from php, not libretranslate)
- Ansible: exit 0 if LibreTranslate not ready (don't block deploy)
- Ansible: ignore_errors on translation step (non-blocking)
- AccountControllerTest: add testEventQrCode (PNG response) and testEventQrCodeDeniedForOtherUser (403)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- TranslateCommand: increase waitForApi retries from 30 to 90 (3 minutes total)
- Ansible deploy: add explicit healthcheck wait step (60×5s = 5min max) before translation
- First launch downloads ~2-4GB of language models, needs more time
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Separate webhook routes with different secrets
- Add verifyConnectWebhookSignature() to StripeService
- Add STRIPE_WEBHOOK_SECRET_CONNECT env var
- Update vault with prod secrets for both endpoints
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Create unavailable.html static page with neo-brutalist design and retry button
- Add handle_errors in Caddy for 502/503: serve unavailable.html
- Add dial/read/write timeouts to php_fastcgi (5s/30s/30s)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- sw.js regenerated by Workbox with full cache strategies
- Add screen.png, site.webmanifest, workbox/*, idb/*, pwa/* to Caddy static paths
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add favicon.png link and apple-touch-icon in base.html.twig
- Add theme-color meta tag (#fabf04)
- Add pwa_dev and pwa_prod Makefile commands
- Add PWA asset generation step in Ansible playbook after cache clear
- Update Caddy static paths for favicon.png, marker.png, manifest.json, sw.js
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Store smime_private_key in encrypted vault
- Add playbook tasks: create cert directory + deploy private key with 0600 permissions
- Certificate public already in git at config/cert/certificate.pem
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>