- Add accessToken (32 hex chars) to BilletBuyer, generated at creation
- URLs now: /ma-commande/{orderNumber}/{token} and /ma-commande/{orderNumber}/{token}/billet/{ref}
- Both orderNumber AND token must match to access order page
- Token is random, unpredictable, unique per order
- Migration generates tokens for existing rows
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- securityKey: HMAC-SHA256(reference, APP_SECRET) truncated to 16 hex chars
- Generated automatically at ticket creation via BilletOrderService
- Deterministic: same reference + secret = same key, verifiable server-side
- Cannot be forged without knowing APP_SECRET
- PDF: "Presentez ce QR code pour valider votre ticket" under QR code
- PDF: "Cle de securite" displayed with letter-spacing
- Tests: generateSecurityKey determinism, uniqueness, format
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- QR code (top): contains ticket reference in base64 for scanning
- New block before footer: 2 columns - left: orga info (name, SIRET, address,
email, phone, website), right: event description + QR code linking to event page
- Remove orga info from event info section (moved to dedicated block)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add isInvitation (nullable bool) to BilletOrder: null=no badge, true=invitation
- PDF footer: add SIRET, email, phone of organizer
- PDF: show invitation badge based on ticket.isInvitation instead of design
- Rename "Sortie libre" to "Sortie - Entree illimitee"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rewrite pdf/billet.html.twig with table-based layout compatible with dompdf
- Add order number (orderNumber) and order reference on PDF ticket
- Show order number on all order pages: guest, payment, public, summary partial
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Check redirect_status query param on confirmation page
- On succeeded: generate BilletOrders + send email with PDF tickets
- On failed: show error with retry button
- Success page links to /ma-commande/{reference} for ticket download
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- PaymentIntent instead of Checkout Session on connected account
- Stripe Elements Payment Element with neo-brutalist theme
- stripe-payment.js module with waitForStripe() for deferred loading
- No inline scripts (CSP compliant), data attributes on container
- Add order_number (YYYY-MM-DD-increment) to BilletBuyer
- Payment page redesign: full-width vertical layout with event info,
buyer info, billet listing with images/descriptions, payment form
- CSP: add js.stripe.com to script-src, api.stripe.com to connect-src
- Add stripe_pk parameter in services.yaml
- Add head block to base.html.twig for page-specific scripts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- BilletOrder entity: individual tickets with unique ETICKET-XXXX reference,
billetBuyer link, billet link, isScanned, scannedAt for entry control
- BilletOrderService: generates tickets after payment, creates A4 PDF with
BilletDesign colors if present (default otherwise), real QR code via
endroid/qr-code, event poster + org logo as base64, sends confirmation
email with all ticket PDFs attached
- PDF template (pdf/billet.html.twig): A4 layout matching preview design,
real QR code linking to /ticket/verify/{reference}
- Email template: order recap table, ticket references list, link to
/ma-commande/{reference}
- Public order page /ma-commande/{reference}: no auth required, shows
order details, ticket list with individual PDF download links
- Ticket verification page /ticket/verify/{reference}: shows valid/scanned
status with ticket and event details
- Download route /ma-commande/{ref}/billet/{ticketRef}: generates PDF on-the-fly
- Migration for billet_order table with unique reference index
- BilletOrderTest: 8 tests, 24 assertions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Create BilletBuyer entity: event, user (nullable for guests), firstName,
lastName, email, reference (ETICKET-XXXX-XXXX-XXXX), totalHT, status,
stripeSessionId, paidAt, items (OneToMany)
- Create BilletBuyerItem entity: billet, billetName (snapshot), quantity,
unitPriceHT, line total helpers
- OrderController with full checkout flow:
- POST /evenement/{id}/commander: create order from cart JSON
- GET/POST /commande/{id}/informations: guest form (name, email)
- GET /commande/{id}/paiement: payment page with recap
- POST /commande/{id}/stripe: Stripe Checkout on connected account
with application_fee, productId, and quantities
- GET /commande/{id}/confirmation: success page
- Cart JS: POST cart data on Commander click, redirect to guest/payment
- Templates: guest form, payment page, order summary partial, success page
- Stripe payment uses organizer connected account, application_fee based
on commissionRate, existing productId when available
- Tests: BilletBuyerTest (12), BilletBuyerItemTest (6), cart.test.js (13)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Each billet has +/- quantity buttons with max quantity enforcement
- Line total per billet updated in real-time
- Cart total and article count at the bottom
- Commander button disabled when cart is empty
- Full billet description displayed
- JS module cart.js with 10 tests covering all cases
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add isHidden field to Category entity with migration (DEFAULT false for existing rows)
- Add isHidden checkbox to edit category template and "Masquee" badge on category list
- Save isHidden in editCategory controller method
- Fix Category.isActive() indentation
- Create CategoryTest with full coverage (14 tests): defaults, setters, setEvent logic, isActive, isHidden
- Add category CRUD tests to AccountControllerTest: add/edit/delete/reorder categories with access control
- Add cookie-consent tests for dev env early return and Cloudflare tunnel script
- Exclude PayoutPdfService from phpunit coverage and SonarQube analysis
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add /mon-compte/evenement/{id}/categorie/{categoryId}/modifier route (GET/POST)
- Create edit_category.html.twig with name and date fields
- Add edit button (pencil icon) on category list items
- Add sortable.js module: native HTML5 drag & drop with fetch reorder API
- Auto-correct endAt < startAt on category edit
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Skip loading /stats/script.js and /assets/perf.js when data-env=dev
- Add data-env="{{ app.environment }}" to body tag
- Redirect to edit event page instead of events list after saving
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add setTimeout, globalThis, navigator, fetch, caches etc to ESLint globals
- Use Number.parseFloat in event-map.js
- Add for attribute to admin events search label
- Add tests: events search, toggle/delete access denied for other user
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Homepage: all text sizes responsive (320px→tablet→desktop)
- Background text text-[10rem] md:text-[30rem]
- Hero title text-4xl sm:text-5xl md:text-7xl lg:text-9xl
- Buttons smaller on mobile (px-6 py-4 md:px-10 md:py-6)
- Cards padding p-6 md:p-8, text sm on mobile
- Marquee text-base md:text-2xl
- CTA section responsive text and button sizes
- Fix AccountController: sort imports, use Event short class name
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Create pwa.yaml with manifest: name, icons (favicon.png), theme color
- Add {{ pwa() }} before stylesheets in base.html.twig head
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>
- Add event-map.js module: loads Leaflet dynamically, geocodes address, renders map with marker at zoom 16
- Remove iframe, address text and OSM link below map
- Add CSP entries for unpkg (Leaflet), tile.openstreetmap.org (tiles), nominatim (geocoding)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Change date display from d/m/Y + H:i to "Du d/m/Y H:i au d/m/Y H:i"
- Add map card with OSM iframe (300px), address text, and link to OpenStreetMap
- Add openstreetmap.org to CSP frame-src
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Left: organizer card with logo, name, city, social icons, email
- Right: contact form (name, firstname, email, message) sent to organizer
- Add /evenement/{id}/contact POST route with email to organizer (replyTo sender)
- Create event_contact.html.twig email template
- Add flash messages for success/error
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>