diff --git a/.githooks/pre-commit b/.githooks/pre-commit index bc6ea31..7e5a4de 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -4,7 +4,7 @@ setopt ERR_EXIT PIPE_FAIL NOUNSET # Collect staged PHP and Twig files STAGED_PHP=() while IFS= read -r file; do - [[ -n "$file" ]] && STAGED_PHP+=("$file") + [[ -n "$file" && "$file" != "config/reference.php" ]] && STAGED_PHP+=("$file") done < <(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.php$' || true) STAGED_TWIG=() @@ -32,7 +32,7 @@ if [[ ${#STAGED_PHP[@]} -gt 0 ]]; then git add "${STAGED_PHP[@]}" echo " → PHP-CS-Fixer" - "${DOCKER_CMD[@]}" vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php "${STAGED_PHP[@]}" + "${DOCKER_CMD[@]}" vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --path-mode=intersection "${STAGED_PHP[@]}" git add "${STAGED_PHP[@]}" echo " → PHPStan" diff --git a/CLAUDE.md b/CLAUDE.md index 4827ccf..8897dc6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -148,6 +148,11 @@ tests/ - Coverage excluded from: `src/DataFixtures/` - Test environment: `APP_ENV=test` (set in phpunit.dist.xml) +### Testing Conventions (TDD) +- **Write the failing test first.** When fixing any PHP-reachable bug, write a PHPUnit test that reproduces the failure before touching the production code. Fix the code until the test passes. +- Only skip a test if the bug is purely in JavaScript/frontend where PHPUnit cannot reach it. +- Follow the pattern in `tests/Controller/Backoffice/` for controller/integration tests: log in, GET for CSRF token, POST form data, assert redirect, clear entity manager, assert DB state. + ### Code Style & Standards - **PHP-CS-Fixer**: Symfony ruleset + risky rules enabled - Strict types declaration required diff --git a/Dockerfile b/Dockerfile index 75b90d6..967e614 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,7 +32,6 @@ RUN set -eux; \ opcache \ zip \ gd \ - excimer \ ; # https://getcomposer.org/doc/03-cli.md#composer-allow-superuser diff --git a/assets/backoffice.js b/assets/backoffice.js index de391c0..af1dcdf 100644 --- a/assets/backoffice.js +++ b/assets/backoffice.js @@ -1,6 +1,7 @@ import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap-icons/font/bootstrap-icons.min.css'; import './styles/backoffice.scss'; +import '@hotwired/turbo'; import './stimulus.js'; import './bootstrap.js'; import * as Sentry from '@sentry/browser'; @@ -16,11 +17,13 @@ const effectiveDsn = dsn || 'https://0@o0.ingest.sentry.io/0'; const feedbackIntegration = Sentry.feedbackIntegration({ colorScheme: 'system', - showName: true, + showName: false, showEmail: true, - isNameRequired: false, isEmailRequired: false, autoInject: false, + triggerLabel: 'Report feedback', + formTitle: 'Report Feedback', + submitButtonLabel: 'Send Feedback', }); Sentry.init({ diff --git a/assets/controllers/bo/form_collection_controller.js b/assets/controllers/bo/form_collection_controller.js index e7a7d4c..e4e973a 100644 --- a/assets/controllers/bo/form_collection_controller.js +++ b/assets/controllers/bo/form_collection_controller.js @@ -6,8 +6,31 @@ export default class extends Controller { connect() { this.index = this.collectionTarget.children.length; - this._setupDrag(); this._syncOrdering(); + + if (this.index === 0) { + this.addItem(); + } + + // `submit` fires on the ancestor