feat: sentry-laravel install + scrubber + ignored exceptions

WS-7 PR-2 commit 1. Wires sentry-laravel into the app behind a
config-only no-op when SENTRY_DSN_BACKEND is empty (RFC §3.3).

- composer require sentry/sentry-laravel ^4.15 (resolved 4.25.1)
- config/sentry.php: DSN env mapped to SENTRY_DSN_BACKEND, environment
  falls back to APP_ENV, traces/profiles forced to 0.0 (RFC §2
  amendment B), send_default_pii hard-pinned false, before_send to
  SentryEventScrubber, ignore_exceptions covers ValidationException /
  AuthenticationException / AuthorizationException.
- app/Services/Observability/SentryEventScrubber.php: recursive body /
  header / query-string scrubber + form_values wholesale replacement +
  HttpException sub-500 drop (status filter that ignore_exceptions
  cannot do class-only). Max-depth guard against malicious payloads.
- app/Enums/Observability/ActorType.php: enum + resolver for §3.6
  actor_type tag (consumed by BindSentryContext in commit 2).
- tests/Feature/Observability/PiiScrubbingTest.php: 20 cases.
- api/.env.example: SENTRY_DSN_BACKEND + SENTRY_RELEASE entries.

Larastan: clean. Test count: 1487 to 1507.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-06 08:55:50 +02:00
parent d4b785a2c9
commit bdb89a2479
7 changed files with 1079 additions and 1 deletions

View File

@@ -78,3 +78,14 @@ SANCTUM_STATEFUL_DOMAINS=localhost:5174,localhost:5175
# env-gate + this flag) keeps Telescope out even if one layer is
# breached. See /dev-docs/TELESCOPE.md.
TELESCOPE_ENABLED=false
# Sentry / GlitchTip (RFC-WS-7 §3.3, §3.4).
# DSN routes events to the self-hosted GlitchTip project crewli-api.
# Empty = SDK no-op — leave blank in local development. Source the real
# value from the 1Password vault entry "Crewli / GlitchTip / DSNs"
# (key SENTRY_DSN_BACKEND) for staging / production.
SENTRY_DSN_BACKEND=
# Release identifier in the form crewli-api@<short-sha>. The deploy
# pipeline injects this per build; leave blank locally. Empty release
# means events are still captured but won't carry release context.
SENTRY_RELEASE=