627 Commits

Author SHA1 Message Date
Serreau Jovann
bc93a1c9d5 Fix Caddy: serve static assets during maintenance, update reverse proxy ports to 4578-4579
- Add static file handler for logo.png, favicon.ico, build/*, uploads/* before maintenance check
- Update reverse_proxy ports from 9000-9001 to 4578-4579

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:33:46 +01:00
Serreau Jovann
9420bbf357 Remove Supervisor config from Ansible playbook, messenger runs via Docker
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:30:41 +01:00
Serreau Jovann
764f596771 Fix pgbouncer config permissions: 0644 so container can read mounted files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:22:25 +01:00
Serreau Jovann
f8de531973 Fix DB wait: use shell loop instead of inline PHP to avoid Ansible escaping issues
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:21:15 +01:00
Serreau Jovann
f45a348b2b Add healthcheck to pgbouncer and wait for healthy before starting php/messenger
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:20:42 +01:00
Serreau Jovann
e154df7ae1 Run composer/bun commands on host instead of Docker exec
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:18:29 +01:00
Serreau Jovann
3e9875a8a6 Run composer/bun commands via Docker exec instead of host in Ansible playbook
- composer install, bun install, bun run build now run inside php container
- Reorder: start containers first, then install dependencies via docker exec
- All php bin/console and dependency commands go through Docker

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:17:06 +01:00
Serreau Jovann
b61889d01d Add explicit e-ticket bridge network to all services in docker-compose-prod
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:16:10 +01:00
Serreau Jovann
14214b4df5 Remove pgbouncer.ini and userlist.txt from git, now generated by Ansible templates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:13:11 +01:00
Serreau Jovann
8dfaf0c9c8 Fix DB connectivity: remove host network, add wait for database before migration
- Remove unused host network from docker-compose-prod template
- Add 30s wait loop for pgbouncer connectivity before running migrations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:12:04 +01:00
Serreau Jovann
de945add75 Fix PgBouncer auth: template pgbouncer.ini and userlist.txt with vault db_password
- Create pgbouncer.ini.j2 with auth_type plain (no MD5 hash needed)
- Create userlist.txt.j2 with vault db_password
- Add Ansible tasks to deploy both files before docker-compose
- Mount pgbouncer files as read-only in compose template

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:07:16 +01:00
Serreau Jovann
d061748da6 Use vault variables for DATABASE_URL and MESSENGER_TRANSPORT_DSN passwords in env.local
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:04:44 +01:00
Serreau Jovann
a34fed7efd Fix slave PGDATA permissions: set 700 and postgres ownership before basebackup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:03:58 +01:00
Serreau Jovann
492e080059 Fix slave init: run pg_basebackup and postgres as postgres user via su-exec
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:03:32 +01:00
Serreau Jovann
932535e6aa Fix slave replication auth: add .pgpass for passwordless pg_basebackup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:02:50 +01:00
Serreau Jovann
552c1da07a Add public/.update to .gitignore
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:46:58 +01:00
Serreau Jovann
08704c9824 Fix PostgreSQL replication: add pg_hba.conf entries for replicator user
- Create init-master.sh that runs SQL and appends replication rules to pg_hba.conf
- Switch docker-compose-prod template from init-master.sql to init-master.sh
- Fixes "no pg_hba.conf entry for replication connection" error

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:45:58 +01:00
Serreau Jovann
10a19e20b1 Regenerate all vault passwords with strong random values and add webhook secret
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:37:34 +01:00
Serreau Jovann
6b61df7597 Move docker-compose-prod.yml template generation before build step
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:31:07 +01:00
Serreau Jovann
96de9bac8f fix error navbar 2026-03-20 13:29:38 +01:00
Serreau Jovann
d11c0cbea4 Convert docker-compose-prod.yml to Ansible template with vault secrets
- Create docker-compose-prod.yml.j2 with vault variables (db_password, redis_password, meilisearch_master_key)
- Add template deployment step in playbook after stop containers
- Remove docker-compose-prod.yml from git tracking (now generated by Ansible)
- Add docker-compose-prod.yml to .gitignore

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:26:38 +01:00
Serreau Jovann
2dc4326b66 Add build_prod step to Ansible playbook before pulling images
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:23:55 +01:00
Serreau Jovann
259a17c788 Simplify deploy workflow: SSH into server and run Ansible locally
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:23:19 +01:00
Serreau Jovann
8c2c3b5490 Switch Ansible inventory to local deployment (127.0.0.1)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:22:27 +01:00
Serreau Jovann
4a3c7cade6 Add /admin and /mon-compte to robots.txt controller, remove static file
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:18:07 +01:00
Serreau Jovann
b258c15f2c Add robots.txt to disallow /admin and /mon-compte from indexing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:17:27 +01:00
Serreau Jovann
0cdc0c151b Add /public/build/ to .gitignore
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:07:09 +01:00
Serreau Jovann
a831d37854 Add host network to docker-compose-prod.yml
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:05:27 +01:00
Serreau Jovann
12eadc95a9 Simplify Ansible playbook: remove Cloudflare tasks, add git pull and direct dependency install
- Remove entire Cloudflare configuration play (DNS, SSL, HSTS, bot management)
- Replace make install_prod with direct git pull, composer install, bun install, bun run build
- Add Docker image pull step before container restart
- Keep server deployment: env, containers, migrations, cache, uploads, Caddy, Supervisor

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:05:07 +01:00
Serreau Jovann
7a383d4e55 aa 2026-03-20 13:02:58 +01:00
Serreau Jovann
148d506881 Add deploy_prod Makefile command for Ansible deployment with vault password prompt
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:01:32 +01:00
Serreau Jovann
a328f2337c fix error navbar 2026-03-20 12:59:58 +01:00
Serreau Jovann
19bbf88d45 Fix pull_dev/pull_prod to only pull Docker images
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 12:52:26 +01:00
Serreau Jovann
5060eb849e Add pull_dev/pull_prod commands and change prod PHP ports to 4578-4579
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 12:52:01 +01:00
Serreau Jovann
8b3b1dab13 Add Event entity, create event page, and custom WYSIWYG editor component
- Create Event entity with fields: account, title, description (text), startAt, endAt, address, zipcode, city, eventMainPicture (VichUploader), isOnline, createdAt, updatedAt
- Create EventRepository
- Add migration for event table with all columns
- Add "Creer un evenement" button on account events tab
- Add create event page (/mon-compte/evenement/creer) with full form
- Build custom web component <e-ticket-editor> WYSIWYG editor:
  - Toolbar: bold, italic, underline, paragraph, bullet list, remove formatting
  - contentEditable div with HTML sync to hidden textarea
  - HTML sanitizer (strips disallowed tags, XSS safe)
  - Neo-brutalist CSS styling
  - CSP compliant (no inline styles)
- Register editor in app.js via customElements.define
- Add editor CSS in app.scss
- Add 16 Event entity tests (all fields + isOnline + picture upload + updatedAt)
- Add 16 editor JS tests (sanitizer + custom element lifecycle)
- Add 3 AccountController tests (create event page, submit, access control)
- Update placeholders to generic examples (no association-specific data)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 12:49:24 +01:00
Serreau Jovann
ffa6e04a2e Use BREADCRUMB_REGISTER constant for duplicate /inscription literal
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 11:41:50 +01:00
Serreau Jovann
563393c1df Fix PHP CS Fixer: add blank line after class constants
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 11:02:16 +01:00
Serreau Jovann
c2169eb5e8 Add coverage tests, extract breadcrumb constants, add thead to detail table, ignore css:S4662
- Add test for sitemap orgas with logo image coverage
- Add test for organizer settings with logo file upload
- Extract BREADCRUMB_HOME/BREADCRUMB_ACCOUNT constants in AccountController
- Extract BREADCRUMB_HOME/BREADCRUMB_ORGANIZERS constants in HomeController
- Extract BREADCRUMB_HOME/BREADCRUMB_REGISTER constants in RegistrationController
- Add thead with th headers to organizer detail info table
- Ignore SonarQube css:S4662 rule for assets (Tailwind @source directive)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 11:00:08 +01:00
Serreau Jovann
c273fd1df4 Fix remaining PHP CS Fixer concatenation spacing in SitemapController
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 10:49:10 +01:00
Serreau Jovann
2ce71025f1 Fix PHP CS Fixer: remove spaces around string concatenation operator
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 10:47:56 +01:00
Serreau Jovann
76fc64ebaf Fix Stylelint errors: add @source to ignored at-rules, reorder @import before @source
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 10:45:54 +01:00
Serreau Jovann
198d684fb8 Add organizer pages, SEO breadcrumbs, Open Graph, homepage redesign, and infrastructure updates
- Add public organizers list page (/organisateurs) with neo-brutalist card grid, social icons, and logo display
- Add organizer detail page (/organisateur/{id}-{slug}) with company info, SIRET, email, address, social links, and events placeholder
- Add slug-based URLs with 301 redirect on wrong slug, getSlug() method on User entity
- Add "Voir les evenements" button on organizer cards linking to detail page
- Add JSON-LD BreadcrumbList to all 17 pages that were missing breadcrumbs (login, forgot_password, register_success, email_verified, legal/*, attestation/*, account/*)
- Add Open Graph meta tags (og:title, og:description, og:image, og:type, og:locale, og:site_name) in base.html.twig with automatic inheritance from title/description blocks
- Add og:image with organizer logo on detail page
- Update sitemap: add /organisateurs to sitemap-main, generate organizer detail URLs in sitemap-orgas with logo images
- Update navbar to highlight "Organisateurs" on detail pages
- Redesign homepage with hero section, marquee, stats counters, how-it-works, and CTA sections
- Add Tailwind v4 @source "../templates" directive to app.scss and admin.scss
- Migrate Flysystem from S3 to local storage (uploads/events, uploads/logos)
- Update Liip Imagine config with FormatExtensionResolver for webp conversion
- Add User entity social fields (website, facebook, instagram, twitter, tiktok), logo upload (Vich), __serialize/__unserialize for session safety
- Add account page settings tab with profile, logo upload, and social media for organizers
- Add Stripe Connect status display and sub-account management in account page
- Delete WebpExtensionSubscriber (replaced by FormatExtensionResolver)
- Add migration for social fields and logo columns
- Add deploy.yml chmod tasks for uploads directories
- Add HomeController tests (detail success, wrong slug redirect, 404 cases)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 10:44:31 +01:00
Serreau Jovann
da0ddf639b Remove always-true condition in handlePayout
User is guaranteed non-null after early return refactoring

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:20:15 +01:00
Serreau Jovann
8257615c32 Add flash messages to login page, French security translations, fix CS
- Add success flash messages display on login page (reset password, email verified)
- Create translations/security.fr.yaml with French security messages
- Set default_locale to fr in translation.yaml
- Remove unused StripeObject import (CS Fixer)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 08:55:43 +01:00
Serreau Jovann
afbde944e1 Add comprehensive StripeWebhookController tests and fix payout creation
Tests (16 total):
- Valid/invalid signature
- v2.core.account.created/updated/closed status updates
- Account status with unknown user and missing related_object
- Merchant capability card_payments active
- Recipient capability payouts active
- Both capabilities active sets status to 'active'
- Capability update with unknown user
- Payout created with email notification
- Payout paid with PDF attachment
- Payout updated on existing payout
- Payout with missing payout ID
- Payout with unknown user (no organizer found)

Fix: skip payout creation when organizer not found instead of persisting
with null organizer_id (NOT NULL constraint)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 08:45:48 +01:00
Serreau Jovann
1bffb33c3b Replace role=presentation with thead headers on layout tables in PDF template
Dompdf requires table-based layouts (no CSS flexbox support)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 00:18:27 +01:00
Serreau Jovann
3723762f47 Add security tests for sub-account access control
- Test create sub-account denied for non-organizer (redirect)
- Test edit/submit/delete sub-account denied for wrong organizer (403)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 00:15:45 +01:00
Serreau Jovann
641c37699b Add coverage annotations, sub-account tests, and PDF improvements
- Add @codeCoverageIgnore to Stripe API methods in AccountController
- Add @codeCoverageIgnore to PayoutPdfService generate/generateToFile
- Add title tag and role=presentation to PDF attestation tables
- Fix DejaVu Sans font in PDF template
- Add 4 sub-account tests: create with email, edit page, edit submit, delete
- Fix duplicate PHPDoc in AccountControllerTest

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 00:05:17 +01:00
Serreau Jovann
ab52a8d02f Add payouts, PDF attestations, sub-accounts, and webhook improvements
Payout system:
- Create Payout entity (stripePayoutId, status, amount, currency, destination, arrivalDate)
- Webhook handles payout.created/updated/paid/failed/canceled with email notification
- Payout list in /mon-compte virements tab with status badges
- PDF attestation on paid payouts with email attachment

PDF attestation:
- dompdf with DejaVu Sans font, yellow-orange gradient background
- Orange centered title bar, E-Cosplay logo, emitter/beneficiary info blocks
- QR code linking to /attestation/check/{payoutId} for authenticity verification
- Public verification page: shows payout details if valid, error if altered
- Legal disclaimer and CGV reference
- Button visible only when status is paid, opens in new tab

Sub-accounts:
- Add parentOrganizer (self-referencing ManyToOne) and subAccountPermissions (JSON) to User
- Permissions: scanner (validate tickets), events (CRUD), tickets (free invitations)
- Create sub-account with random password, send email with credentials
- Edit page with name/email/permissions checkboxes
- Delete with confirmation
- hasPermission() helper method

Account improvements:
- Block entire page for unapproved organizers with validation pending message
- Display stripeStatus in Stripe Connect banners
- Remove test payout button

Webhook v2 Connect events:
- v2.core.account.created/updated/closed → update stripeStatus
- capability_status_updated → sync charges/payouts enabled from capabilities
- PayoutPdfService for reusable PDF generation

Migrations: stripeStatus, Payout table, sub-account fields, drop pdfPath

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 23:49:48 +01:00
Serreau Jovann
93e5ae67c0 Refactor Stripe integration: single Connect webhook, account pages, cleanup
Stripe webhook:
- Single webhook endpoint /stripe/webhook for Connect + payment events
- v2 Connect events configured manually in Stripe Dashboard (not via API)
- account.updated syncs charges_enabled/payouts_enabled via API retrieve
- Remove StripeSyncCommand and saveWebhookSecret (secret managed via Ansible vault)

Account page (/mon-compte):
- Buyer tabs: Billets, Achats, Factures, Parametres
- Organizer tabs: Evenements/Brocantes, Sous-comptes, Virements + buyer tabs
- Stripe Connect status banner: setup required, pending verification, active, refused
- Stripe Connect onboarding: create account, complete verification (GET links)
- Dashboard Stripe: opens in new tab via createLoginLink (Express dashboard)
- Cancel/close Stripe account: deletes via API + resets local fields
- Stripe required message on events/subaccounts/payouts tabs when not active
- Settings: organizer fields locked (name, address), email/phone editable
- Return/refresh routes for Stripe Connect onboarding flow
- Error handling with flash messages on all Stripe operations
- Auto-sync Stripe status on /mon-compte visit

StripeService cleanup:
- Remove syncWebhook, saveWebhookSecret, getWebhookUrl, projectDir
- Add deleteAccount method
- Keep: verifyWebhookSignature, createAccountConnect, createAccountLink, createLoginLink

Security:
- Add connect.stripe.com and dashboard.stripe.com to nelmio whitelist
- Add STRIPE_SK, STRIPE_WEBHOOK_SECRET, OUTSIDE_URL to .env.test

Tests: 19 AccountControllerTest, 4 StripeWebhookControllerTest, 1 StripeServiceTest

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 22:41:31 +01:00