Marijn 88cff7f480 feat: Sentry User Feedback in backoffice (#178) (#180)
* feat: add Sentry User Feedback widget to backoffice (#178)

Install @sentry/browser via AssetMapper and initialize the feedback
integration on all backoffice pages. The CDN loader script is moved to
an overridable block so backoffice pages use the npm SDK without
double-initialising Sentry.

Sentry is initialised only when a DSN is configured (SENTRY_DSN env
var). When a user is logged in their email is pre-filled in the feedback
form via Sentry.setUser(); both name and email remain optional so
anonymous submissions are supported by simply leaving those fields empty.

* feat: add Spotlight sidecar for local Sentry development testing

Add the Spotlight container to compose.override.yaml so the feedback
widget and error events can be inspected locally without sending anything
to Sentry. The JS SDK switches to spotlight mode automatically when no
SENTRY_DSN is configured.

* feat: route PHP Sentry events to Spotlight in dev

Add a when@dev block to sentry.yaml that initialises the PHP Sentry SDK
with a placeholder DSN and forwards all events to the Spotlight sidecar
over the internal Docker network (http://spotlight:8969/stream).

The JS SDK already uses localhost:8969 via spotlight:true when no real
SENTRY_DSN is set, which is correct since the browser cannot reach the
internal Docker hostname.

* fix: use spotlight_url to route PHP dev errors to Spotlight sidecar

* fix: manually mount Sentry feedback widget to work around v10 setupOnce guard

Sentry v10's setupOnce() is skipped when the integration name is already
in the module-level guard array, so autoInject never mounts the widget.
Switching to autoInject: false and calling createWidget() directly is
reliable and confirmed working in the browser.

Also use the tunnel option to forward JS events to the local Spotlight
sidecar when no real DSN is configured, and enable SentryBundle in dev
so PHP errors are also routed to Spotlight.
2026-07-05 23:27:49 +02:00
2025-09-28 18:14:58 +02:00
2025-09-28 18:14:58 +02:00
2026-03-22 22:40:25 +01:00
2024-12-29 14:58:03 +01:00
2026-01-25 19:58:39 +01:00
2026-02-18 16:20:14 +01:00
WIP
2025-06-01 15:40:47 +02:00
2026-02-18 16:20:14 +01:00
2026-03-22 22:40:25 +01:00
2026-03-22 22:40:25 +01:00
2026-02-18 16:50:04 +01:00
2026-05-25 13:56:46 +00:00
2026-03-22 22:40:25 +01:00
2026-02-18 16:20:14 +01:00

Tijd voor de test

CI

PHP/Symfony application for WIDM-style quiz management. Built with FrankenPHP, PostgreSQL, and Docker.

Disclaimer: This is an unofficial, non-commercial, open-source fan project. It is not affiliated with, endorsed by, or associated with Wie is de Mol? (produced by IDTV, broadcast by AVROTROS/NPO) or De Mol (produced by Woestijnvis, broadcast by Play/De Vijver Media). Wie is de Mol? and De Mol are trademarks of their respective rights holders. No copyright infringement is intended.

Requirements

  • Docker
  • Just (brew install just)

Local development

just up        # Start PHP + PostgreSQL containers
just migrate   # Run pending database migrations
just fixtures  # Load dev fixtures (truncates first)

The app is available at https://localhost (self-signed cert — run just trust-cert on macOS to trust it).

Useful commands

just shell              # Shell inside the running PHP container
just shell-run          # Shell in a fresh one-off container
just stop               # Stop containers (keep volumes)
just down               # Stop and remove containers
just clean              # Nuclear: remove containers + volumes + generated files
just exec <cmd>         # Run any command inside the PHP container

Environment

Copy .env and override locally via .env.local (not committed):

Variable Description
APP_SECRET Symfony app secret
DATABASE_URL PostgreSQL DSN (auto-set in Docker)
SENTRY_DSN Sentry error tracking
DEFAULT_URI Base URL for CLI-generated links

Testing

just test                                   # Full PHPUnit suite
just test tests/Path/To/TestFile.php        # Single file
just test --coverage-html var/coverage      # HTML coverage report
just reload-tests             # Drop/recreate test DB + migrate + test fixtures

Tests use a separate database configured via .env.test. The DAMA Doctrine bundle wraps each test in a transaction that is rolled back after. just reload-tests loads the --group=test fixtures; just fixtures loads the dev group and is unrelated to the test database.

Code quality

All checks run in CI and must pass before merging.

just fix-cs              # Auto-fix PHP-CS-Fixer + Twig-CS-Fixer
just phpstan             # PHPStan static analysis (level 8)
just rector              # Apply Rector modernizations
just rector --dry-run    # Preview Rector changes without applying

Database

just migrate                      # Run pending migrations
just fixtures                     # Load dev fixtures
bin/console make:migration        # Generate a new migration (inside container)

Migrations live in migrations/ (namespace DoctrineMigrations). Test fixtures are in src/DataFixtures/ loaded with --group=test.

Translations

just translations    # Extract/update nl translation strings into translations/

Contributing

  1. Create a branch from main — use a prefix like feat/, fix/, or docs/.
  2. Open a pull request; CI must pass before merging.
  3. Install the pre-commit hook (see below) to catch issues before pushing.

Pre-commit hook

A pre-commit hook lives in .githooks/pre-commit. Install it once after cloning:

just install-hooks

On every commit it runs automatically, only on staged files:

Staged file type Tools run
.php Rector → PHP-CS-Fixer (auto-fix + re-stage), then PHPStan (blocks on errors)
.twig Twig-CS-Fixer (auto-fix + re-stage)
Other (docs, config, …) Nothing — commit proceeds immediately

If the PHP container is not running, the hook falls back to docker compose run --rm so checks still execute. PHPUnit is not run in the hook; CI covers that.

Deployment

Docker images are published to ghcr.io/marijndoeve/tijdvoordetest for each tagged release.

First-time setup

  1. Copy compose.yaml and compose.prod.yaml to your server.
  2. Create a .env.prod.local file with the required variables (see below).
  3. Start the stack — migrations run automatically on container start:
IMAGE_TAG=latest docker compose -f compose.yaml -f compose.prod.yaml up -d

Updating to a new version

IMAGE_TAG=<tag> docker compose -f compose.yaml -f compose.prod.yaml pull
IMAGE_TAG=<tag> docker compose -f compose.yaml -f compose.prod.yaml up -d

Required environment variables

Variable Description
IMAGE_TAG Image tag to run (e.g. 1.2.3 or latest)
APP_SECRET Random secret string for Symfony
CADDY_MERCURE_JWT_SECRET JWT secret for the Mercure hub
POSTGRES_PASSWORD PostgreSQL password
MAILER_DSN Mailer transport DSN
MAILER_SENDER From address for emails
SENTRY_DSN Sentry project DSN (optional)

The compose.prod.yaml configures Traefik labels for TLS termination at tijdvoordetest.nl. Adjust the traefik labels in that file if you're hosting on a different domain or using a different reverse proxy.

License

MIT

S
Description
No description provided
Readme AGPL-3.0 20 MiB
Languages
PHP 77.1%
Twig 16.8%
JavaScript 2.3%
Shell 2.1%
Dockerfile 0.7%
Other 1%