627 Commits

Author SHA1 Message Date
Serreau Jovann
d5b08aaae2 Wrap deploy script in bash -c to bypass remote fish shell
Some checks failed
CI / sonarqube (push) Has been cancelled
Deploy to production / deploy (push) Failing after 3m23s
- .gitea/workflows/deploy.yml: the bot user on the new prod host has
  fish as its login shell, which rejects bash syntax (set -e, VAR=...,
  $(...), trap, process substitution). Wrap the entire deploy script
  in `bash -c '...'` so fish only spawns a bash subprocess and the
  script itself is parsed by bash.
- Forward DEPLOY_PATH alongside VAULT_PASS through appleboy/ssh-action
  envs: so the bash subprocess inherits both, instead of interpolating
  the secret directly into the rendered script (where masking would
  collide with the cd argument).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 18:08:30 +02:00
Serreau Jovann
c6d2c068d3 Pass ansible vault password via env var instead of process substitution
Some checks failed
CI / sonarqube (push) Has been cancelled
- .gitea/workflows/deploy.yml: stop interpolating ANSIBLE_VAULT_PASSWORD
  directly into the remote script (the runner masks the secret with ***
  which broke the <(echo '...') process substitution at runtime)
- inject the password as VAULT_PASS through appleboy/ssh-action's
  envs: forwarding so it never appears in the rendered script
- on the remote, write it to a mktemp file with chmod 600 and remove
  the file via trap on EXIT, then point ansible-playbook
  --vault-password-file at that temp file
- use printf '%s' instead of echo to avoid adding a stray newline to
  the vault password
- add set -e so the script fails fast if any step errors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 18:04:50 +02:00
Serreau Jovann
5449ab9d4d Migrate deploy workflow to appleboy/ssh-action
Some checks failed
CI / sonarqube (push) Has been cancelled
- .gitea/workflows/deploy.yml: replace manual ssh key setup + raw ssh
  command with the appleboy/ssh-action@v1.0.0 action
- host, user, key and deploy path are now read from Gitea secrets
  (SSH_HOST, SSH_USER, SSH_PRIVATE_KEY, DEPLOY_PATH) instead of being
  hard-coded in the workflow
- ansible-playbook command and vault password file (process substitution
  fed by ANSIBLE_VAULT_PASSWORD) are kept identical, only the transport
  changes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 18:01:58 +02:00
Serreau Jovann
92548920c2 Migrate SonarQube to sn.e-cosplay.fr, rotate badge token, drop OWASP Dependency-Check, update deploy host
Some checks failed
CI / sonarqube (push) Failing after 5m27s
- .env, .env.test, ansible/env.local.j2: point SONARQUBE_URL to https://sn.e-cosplay.fr
- ansible/vault.yml, .env: rotate sonarqube_badge_token to new value
- .gitea/workflows/ci.yml, sonarqube.yml: remove OWASP Dependency-Check steps and force sonar.host.url via CLI args
- sonar-project.properties: drop dependencyCheck report paths
- .gitea/workflows/deploy.yml: switch SSH target from 34.90.187.4 to 152.228.222.133

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:44:37 +02:00
Serreau Jovann
7c848bbdb0 Apply php-cs-fixer: remove trailing blank line in StripeSyncCommand
Some checks failed
CI / sonarqube (push) Failing after 5m27s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:32:36 +02:00
Serreau Jovann
eb884faea1 Align prod PHP container UID with bot user (1001) and harden restore.sh
Some checks failed
CI / sonarqube (push) Failing after 52s
Sur le serveur prod, l'utilisateur 'bot' (cree par Ansible) a UID 1001
alors que l'utilisateur 'appuser' du conteneur PHP etait hardcode a UID 1000,
ce qui causait des erreurs 'Unable to write in var/cache/prod' apres restore
ou deploiement: les fichiers du host appartenaient a bot:bot (1001) et
appuser (1000) ne pouvait pas y ecrire.

docker/php/prod/Dockerfile:
  - appuser UID/GID passe de 1000 a 1001 pour matcher bot
  - dev/Dockerfile reste a 1000 (les users dev sont generalement 1000)

ansible/deploy.yml:
  - chown des dossiers public/uploads/* et var/payouts passe de 1000 a 1001

restore.sh:
  - Nouvelle option --owner USER:GRP (defaut: bot:bot, override via RESTORE_OWNER)
  - Chown automatique en fin de restore sur var/, public/uploads/, config/cert/, .env.local
  - Purge automatique de var/cache (sera reconstruit par PHP)
  - Verification root au demarrage (sudo requis pour chown)
  - Verification de l'existence du user et group cibles
  - Option --skip-chown pour bypass (deconseille)
  - Etapes post-migration mises a jour (ajout de make build_prod en premier)

Procedure de migration sur le serveur apres ce commit:
  cd /var/www/e-ticket
  git pull origin master
  make build_prod              # rebuild image PHP avec UID 1001
  make stop_prod
  sudo chown -R bot:bot var public/uploads config/cert .env.local
  sudo rm -rf var/cache
  make start_prod
  make clear_prod

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 14:04:14 +02:00
Serreau Jovann
238ded3f54 Fix cp recursive flag for config/cert/ in backup.sh and restore.sh
Remplace 'cp -p' par 'cp -rp' lors de la copie de config/cert/.
Sans l'option -r, cp omet le repertoire avec l'erreur:
  cp: -r non specifie ; omission du repertoire 'config/cert/.'

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:29:45 +02:00
Serreau Jovann
bb082c8368 Add server migration scripts: backup.sh (export) and restore.sh (import)
backup.sh genere un bundle de migration tar.gz autonome contenant:
- dump PostgreSQL gzippe (pg_dump --clean --if-exists --no-owner)
- archive public/uploads (events, billets, logos) repere via flysystem.yaml
- archive var/ (payouts, billets, invoices, unsubscribed.json)
- .env.local et config/cert/ (clef S/MIME), exclus si SKIP_SECRETS=1
- manifest.txt avec metadata (host, git commit/branche, date) et checksums SHA-256

restore.sh restaure un bundle sur un nouveau serveur:
- verifie les checksums SHA-256 avant toute action
- affiche un plan de restauration et demande confirmation (sauf --yes)
- options --skip-db, --skip-uploads, --skip-var, --skip-secrets
- cree des sauvegardes de securite avant ecrasement (.env.local, public/uploads, var/)
- verifie que le service db-master tourne avant restore PostgreSQL
- rappelle les etapes post-migration (migrate_prod, clear_prod)

Les deux scripts utilisent des variables d'env override (COMPOSE_FILE, DB_SERVICE,
DB_USER, DB_NAME) et s'appuient sur docker-compose-prod.yml par defaut.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:27:33 +02:00
Serreau Jovann
cda80990c7 Remove pending orders sync from StripeSyncCommand and add pessimistic lock to webhook payment handler
- Remove syncPendingOrders and its helpers (handleSucceeded, handleCancelled, handleFailed) from StripeSyncCommand
- Clean up unused dependencies (BilletOrderService, MailerService, AuditService, BilletBuyer)
- Add PESSIMISTIC_WRITE lock in handlePaymentIntentSucceeded to prevent duplicate ticket generation when Stripe sends concurrent webhook calls
- Update tests to match simplified command

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 10:19:40 +02:00
Serreau Jovann
e32a2a2722 Remove unsupported ping_threshold option from mailer config to fix Symfony 8 cache:clear error
The ping_threshold option is not a valid framework.mailer configuration key in Symfony Mailer.
This caused composer install to fail during cache:clear on deployment.
The option should be set as a DSN query parameter on the MAILER_DSN environment variable instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 21:52:32 +02:00
Serreau Jovann
240489d330 Add ping_threshold to mailer config to prevent SES SMTP timeout errors
Set ping_threshold to 10 seconds so Symfony checks and reconnects stale
SMTP connections before reuse, fixing "451 4.4.2 Timeout waiting for
data from client" errors from Amazon SES.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 21:46:15 +02:00
Serreau Jovann
7e2706b04f Pin Meilisearch image to v1.40.0 to match database version and prevent incompatible auto-upgrades
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:06:16 +02:00
Serreau Jovann
4b52b72266 Add attestation test with sold tickets to cover buildAttestationStats and buildAttestationTicketDetails
Creates a paid order with BilletOrder tickets before generating the
attestation, exercising the soldCounts loop (line 503) and ticket
details loop (lines 546-551) in AccountEventOperationsController.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 10:02:33 +02:00
Serreau Jovann
a11535726d Remove unused CONTENT_TYPE_PDF and PDF_SUFFIX constants from AccountController
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 10:01:16 +02:00
Serreau Jovann
0cf1160853 Reduce AccountController to 20 methods, remove unused AdminOrdersController constant
- Move export, exportPdf, payoutPdf from AccountController to
  AccountEventOperationsController (9 -> 12 methods)
- Remove getAllowedBilletTypes delegate from AccountController
- Update tests to reference AccountEventCatalogController for that method
- Remove unused DQL_EXCLUDE_INVITATIONS from AdminOrdersController

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:35:26 +02:00
Serreau Jovann
bc31040d81 Run php-cs-fixer: fix line endings and code style
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:40:15 +02:00
Serreau Jovann
7ec4e95a05 Extract duplicated slug regex into SLUG_PATTERN constant in HomeController
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:35:46 +02:00
Serreau Jovann
e04d615c6d Split AccountController (55 methods) and AdminController (30 methods) into smaller controllers
AccountController split into 3:
- AccountController (20 public methods): dashboard, settings, Stripe,
  sub-accounts, event CRUD, exports, payouts
- AccountEventCatalogController (13 public methods): categories, billets,
  design, event toggles, QR code
- AccountEventOperationsController (9 public methods): invitations,
  accreditations, ticket ops, attestation, order cancel/refund

AdminController split into 2:
- AdminController (20 public methods): dashboard, users, buyers,
  organizers, invitations, infra
- AdminOrdersController (10 public methods): orders, events, exports,
  logs, analytics

Shared helpers extracted to AccountEventOwnershipTrait (requireEventOwnership,
requireStripeReady). All route paths and names unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:28:47 +02:00
Serreau Jovann
7869e4e7d9 Exclude editor.js from SonarQube analysis
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:52:26 +02:00
Serreau Jovann
f9aaa45d4b Add analytics test with real data to cover visitor/pageview chart loops
Creates AnalyticsUniqId and AnalyticsEvent records in DB so the
daily chart aggregation loops (visitorsPerDay, pageviewsPerDay,
allDays merge, DateTimeInterface check) are fully exercised.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:02:54 +02:00
Serreau Jovann
5f685d9d1f Cover setIsInvitation loop in createAccreditation test
Mock generateOrderTickets to create a real BilletOrder in DB so the
foreach loop setting isInvitation=true is exercised and verified.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:02:10 +02:00
Serreau Jovann
4f055af3f1 Add <th> headers to API doc tables, ignore css:S4662 for Tailwind @source directive
- Add <thead>/<th> to rate limiting and error codes tables in doc.html.twig
- Ignore SonarQube css:S4662 rule on SCSS files (Tailwind v4 @source)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:01:35 +02:00
Serreau Jovann
8eb7d74445 Add <thead>/<th> headers to all email and PDF template tables, fix infra test snapshot data
- Add proper <thead> with <th> headers to tables in email templates:
  order_cancelled_orga, order_notification_orga, order_refunded,
  organizer_invitation, payment_failed, scan_force_notification
- Add proper <thead> with <th> headers to tables in PDF templates:
  attestation_ventes, billet, export_recap, invoice
- Fix testInfraPageWithSnapshotData: provide complete server data
  (os, uptime, cpu, ram, disk, services, ssl) required by the template

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 13:40:48 +02:00
Serreau Jovann
7b618a700f Add istanbul ignore comments alongside c8 for analytics.js coverage
Ensures 100% coverage regardless of which provider (c8/istanbul/v8)
is used by the CI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 13:13:26 +02:00
Serreau Jovann
83f2f40a91 Add missing test coverage for MeilisearchService, AnalyticsCryptoService, AccountController and AdminController
- MeilisearchServiceTest: add test for invalidateSearchCache()
- AnalyticsCryptoService: mark unreachable tryDecryptJsFormat guard
  with @codeCoverageIgnore (decrypt already checks strlen >= 28)
- AccountControllerTest: add test for tickets search query (tq param)
- AdminControllerTest: add test for infra page with snapshot data file

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 20:19:52 +02:00
Serreau Jovann
b1ec125bb9 Achieve 100% coverage on analytics.js
- Add test for navigator.language falsy branch
- Add test for retry getOrCreateVisitor failing on second attempt
- Mark unreachable defensive guards (encrypt/decrypt/send with null encKey)
  with c8 ignore since they cannot be triggered via public API

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 20:17:21 +02:00
Serreau Jovann
8b18617360 Fix AccountControllerTest: shorten order numbers to fit varchar(20) column
'2026-03-21-'.uniqid() was 24 chars, exceeding the 20-char limit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 20:04:21 +02:00
Serreau Jovann
bf0171b352 Fix AccountControllerTest: use uniqid() for order numbers to avoid unique constraint violations
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:47:43 +02:00
Serreau Jovann
2ffb407323 Fix failing tests: AttestationController payload keys and StripeSyncCommand event mock
- AttestationControllerTest: add required template keys (ref, organizer,
  generatedAt, etc.) to test payloads so check_ventes.html.twig renders
- StripeSyncCommandTest: add getAccount() mock to event in
  testPendingOrderFailedWithoutEmail so order is not skipped

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:34:37 +02:00
Serreau Jovann
534f67dfbe Fix testPendingOrderFailedWithoutEmail: add missing audit mock expectation
The audit->log() call in handleFailed was not configured on the mock,
causing an exception caught by the try/catch which prevented setStatus
from being called.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:23:34 +02:00
Serreau Jovann
03342e8303 Fix StripeSyncCommandTest: use Stripe\PaymentIntent::constructFrom instead of stdClass
PHPUnit strict mock validation rejects stdClass as return value for
retrievePaymentIntent which declares Stripe\PaymentIntent return type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:16:32 +02:00
Serreau Jovann
25354f9052 Fix decodeAndVerifyHash to have only 2 returns by merging base64 decode and pipe check guards
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:02:01 +02:00
Serreau Jovann
1b3371cb7f Add comprehensive test coverage for AttestationController, LegalController, AdminController, AccountController and AnalyticsEvent entity
- AttestationController: fix decodeAndVerifyHash to have max 3 returns, add 11 tests covering all routes (check, ventesRef, ventes) and all decodeAndVerifyHash branches (invalid base64, missing pipe, bad signature, bad JSON, valid hash with/without registered attestation), plus generateHash unit tests with unicode
- LegalController: add 6 tests for RGPD POST routes (rgpdAccess and rgpdDeletion) covering empty fields, data found, and no data found scenarios
- AdminController: add 10 tests for analytics page (all period filters + access denied) and orderTickets endpoint (single ticket PDF, multiple tickets ZIP, order not found, no tickets)
- AccountController: add 17 tests for downloadTicket (success/denied/404), resendTicket (success/denied/404), cancelTicket (success/denied/404), createAccreditation (staff/exposant/empty fields/no categories/invalid type), eventAttestation (with categories/billets/empty selection)
- AnalyticsEvent entity: new test file with 8 tests covering constructor defaults, all getters/setters, nullable fields, and fluent interface

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 18:41:18 +02:00
Serreau Jovann
a139feef07 init 2026-04-01 17:19:13 +02:00
Serreau Jovann
626510e692 Add force validate button in admin orders + fix Stripe Connect account in sync
- Add POST /admin/commandes/{id}/forcer-validation to force validate pending
  orders (generates tickets, sends emails, notifies organizer)
- Add "Forcer validation" button in orders template for pending orders
- Fix retrievePaymentIntent to query on organizer's Connect account
- Update stripe:sync to pass organizer stripeAccountId when checking payments
- Add 3 tests for force validation (pending, non-pending, not found)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:22:56 +02:00
Serreau Jovann
02519dcfa8 Add pending orders reconciliation to stripe:sync command
- Add retrievePaymentIntent() to StripeService
- StripeSyncCommand now checks pending orders against Stripe API:
  - succeeded: generates tickets, sends emails, notifies organizer
  - canceled: marks order as cancelled + audit log
  - requires_payment_method: marks as cancelled + audit + failure email
  - other statuses: logs as still pending
- Add 13 tests covering accounts sync + all pending order scenarios

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:14:29 +02:00
Serreau Jovann
381acd603e Split Stripe webhooks into 2 endpoints: insta (payments) and leger (Connect)
- /stripe/webhook → /webhooks/stripe/insta (paiements, payouts, disputes, subscriptions)
- /stripe/webhook/connect → /webhooks/stripe/leger (gestion comptes Connect)
- Rename env vars: STRIPE_WEBHOOK_SECRET → STRIPE_WEBHOOK_SECRET_INSTA,
  STRIPE_WEBHOOK_SECRET_CONNECT → STRIPE_WEBHOOK_SECRET_LEGER
- Update StripeService, CsrfProtectionSubscriber, vault, env files and all tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:07:49 +02:00
Serreau Jovann
1c559263a8 Add analytics.js test suite with 100% line/function coverage (16 tests)
Tests cover: init with missing config, importKey failure, visitor creation,
session reuse, sendBeacon usage, 403 retry flow, network errors, decrypt
failures, setAuth with/without session/key, and authenticated user tracking.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:54:43 +02:00
Serreau Jovann
97ef920514 Ignore CSP violations from browser userscripts (source-file: user-script)
Add 'user-script' to ignored source files in CspReportController to filter
out false positive CSP violations triggered by browser extensions/userscripts.
Add corresponding test case.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:33:09 +02:00
Serreau Jovann
622e1894ae aa 2026-03-30 13:43:06 +02:00
Serreau Jovann
918a52415d add new system for upgrade speed 2026-03-30 11:13:22 +02:00
Serreau Jovann
2f2da97f68 Fix code style: add blank line before constructor in AttestationController
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 08:58:07 +02:00
Serreau Jovann
fe91d26163 Add AnalyticsControllerTest with 100% coverage (19 tests, 70 assertions)
- Test token validation (invalid token returns 404)
- Test request validation (missing body, missing 'd' field, invalid JSON return 400)
- Test decryption validation (invalid encrypted data returns 403)
- Test new visitor creation with full fields, optional fields, mobile/tablet UA
- Test page view dispatch with valid hash, default values
- Test page view rejection with invalid/missing hash (403)
- Test setUser dispatch with valid hash
- Test visitor UID format (UUID v4), IP hash, UA truncation, language truncation
- Test response hash is verifiable by crypto service

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 08:48:03 +02:00
Serreau Jovann
3468b1288d Improve mobile/tablet responsive, fix structured data, update deploy schedule and fix HTML issues
- Add responsive breakpoints (sm/md) to event_detail.html.twig: adaptive titles, stacked ticket layout on mobile, reduced padding/spacing
- Add responsive breakpoints to order templates (guest, summary, public, payment, success): adaptive typography, padding, and layouts
- Fix BreadcrumbList JSON-LD: escape names with json_encode, remove item URL from last breadcrumb
- Update deploy.yml cron schedule from 3h/13h/19h/23h to 1h/22h
- Add <title> tags to rgpd_deletion.html.twig and rgpd_access.html.twig
- Add scope attributes to all <th> tags in rgpd_access.html.twig
- Replace deprecated width/cellpadding/cellspacing HTML attributes with CSS in scan_force_notification email

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 08:40:28 +02:00
Serreau Jovann
3a40de1ba0 Reduce return counts and fix code smells across controllers and services
- ApiAccountController::lookup: reduce from 4 to 3 returns via ternary
- AttestationController::ventes: reduce from 5 to 2 returns by extracting
  decodeAndVerifyHash() helper; add TPL_NOT_FOUND_VENTES constant for the
  template literal duplicated 5 times
- AnalyticsCryptoService::decrypt: reduce from 4 to 2 returns by extracting
  tryDecryptJsFormat() helper
- InfraService::fmtDuration: reduce from 4 to 1 return using match(true)
- InfraService: replace nested ternary with match(true) for SSL status

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 20:23:08 +01:00
Serreau Jovann
0df78f75ae Fix self-referencing constant NO_SNAPSHOT_MSG in AdminController
The constant was incorrectly defined as self::NO_SNAPSHOT_MSG = self::NO_SNAPSHOT_MSG
causing a PHP fatal error. Replace with the actual string value.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 19:06:51 +01:00
Serreau Jovann
ea50f8e740 Add POST /api/account/lookup route for account lookup by email
New API endpoint secured by X-App-Secret header (no JWT auth required).
Accepts an email in the request body and returns the user's id and
stripeAccountId if present. Includes 6 unit tests covering all cases
(success, missing secret, invalid secret, missing email, user not found).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 19:03:15 +01:00
Serreau Jovann
f2f8b31d6e Reduce method returns and cognitive complexity across controllers
- AnalyticsController::track: extract handleTrackData(), reduce from 7 to 3 returns
- ApiAuthController::ssoValidate: extract ssoError/ssoSuccess helpers, reduce from 6 to 3 returns
- ApiLiveController::scan: extract findTicketFromRequest(), reduce from 4 to 3 returns
- ApiLiveController::scanForce: flatten logic, reduce from 6 to 3 returns
- ApiLiveController::processScan: extract isAlwaysValidTicket, checkRefusal,
  markScannedAndRespond, reduce cognitive complexity from 16 to under 15

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:22:41 +01:00
Serreau Jovann
5062f356f1 Extract DQL_EXCLUDE_INVITATIONS and NO_SNAPSHOT_MSG constants in AdminController
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 22:20:36 +01:00
Serreau Jovann
b2c1cee51a Fix MeilisearchServiceTest: use ArrayAdapter instead of CacheInterface mock
ArrayAdapter implements both CacheInterface and CacheItemPoolInterface,
matching the intersection type on the constructor parameter.

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