27 KiB
Phase 02 — Verification Report
Reviewer: Verifier-Subagent
Datum: 2026-05-16
Scope: README.md + 8 Detail-MDs (29 → 36) in docs/improvement-plan/02-observability/
Verdict: APPROVED WITH MINOR FIXES — Plan ist ausführungsreif; einige Pfad-/Konsistenz-Fixes vor Phase-Start nötig (siehe §11).
1. Template-Konformität (15 Sections, korrekte Reihenfolge)
Pflicht-Reihenfolge laut DETAIL-MD-TEMPLATE.md:
- Frontmatter (Status/Task-ID/Phase/Effort/Owner)
- Problem · 3. Depends on · 4. Blocks · 5. Approach · 6. Implementation Steps
- Test Requirements · 8. Acceptance Criteria · 9. Rollback Strategy · 10. Security Notes
- Subagent Recommendations · 12. Staging-Deployment-Steps · 13. Deviations from Plan
- Progress Log · 15. Lessons Learned (optional)
| Datei | 1-5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | OK? |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
sentry-selfhost-setup.md |
OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK |
sentry-wiring-api-worker.md |
OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK |
sentry-wiring-web.md |
OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK |
sentry-ci-integration.md |
OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK |
opentelemetry.md |
OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK |
logging-migration.md |
OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK |
metrics-grafana.md |
OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK |
performance-quickwins.md |
OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK | OK |
Alle 8 Files folgen der Pflicht-Reihenfolge. Keine fehlenden Sections, keine Reihenfolge-Verstöße.
2. Dependencies-Konsistenz (Depends on / Blocks vs. execution-order.md)
2.1 Phase-01-Verweise
Alle Detail-MDs verweisen auf 01-tech-debt-foundation/dep-updates.md. Diese Datei existiert (verifiziert: /docs/improvement-plan/01-tech-debt-foundation/dep-updates.md). OK.
2.2 Intra-Phase-2-Graph (lt. README.md)
#29 sentry-selfhost ──► #30 wiring-api-worker ─┐
└─► #31 wiring-web ────────┤
▼
#32 sentry-ci
│
▼
┌────────────────────┼────────────────────┐
▼ ▼ ▼
#33 opentelemetry #34 logging-migration #35 metrics-grafana
│
▼
#36 performance-quickwins
Cross-Check der Detail-MDs:
| Task | Depends on (declared) | Blocks (declared) | Konsistenz |
|---|---|---|---|
| #29 selfhost | dep-updates |
#30, #31, #32, #33, scaling-*, authentik | OK |
| #30 wiring-api-worker | #29, dep-updates |
#32, #33, scaling-* | OK |
| #31 wiring-web | #29, dep-updates |
#32, capacitor | OK |
| #32 sentry-ci | #29, #30, #31 | "Keine harten Blocks" | OK — konsistent mit "kein harter Block, aber Phase-03+ profitiert" |
| #33 opentelemetry | #29, #30, #31 | #35 (kein harter Block) + scaling/read-write-split | Abweichung: README ordnet #33 hinter #32 ein, aber #33 deklariert keine Dependency auf #32. Das ist OK weil #32 nur Release-Tagging ist und keine Wiring-Voraussetzung für OTel — der README-Graph ist Workflow-Reihenfolge, nicht harte Dependency. Kein Fix nötig, aber Hinweis an ausführenden Agent: parallel zu #32 startbar wenn #30/#31 grün. |
| #34 logging-migration | #30, #31 | "Keine harten Blocks" | OK |
| #35 metrics-grafana | #30, #34 | shared-store-migration, plugin-system | OK |
| #36 perf-quickwins | #35 | — | OK |
Finding F-1 (Minor): Cross-Phase-Block-Referenz in #29.Blocks: 09-authentik-admin-sso/authentik-setup.md — beide existieren laut PROGRESS-Logik. Kein Issue, sondern Plus.
Finding F-2 (Cosmetic): metrics-grafana.md deklariert #36 nicht explizit als blocked-by. Das passt zur Realität (perf-quickwins braucht metrics zum Messen, ist explizit als Depends-on in #36 deklariert).
3. Implementation-Steps-Qualität (Atomic-Commits, Tech-Korrektheit)
3.1 Atomic-Granularität
| Task | Anzahl Steps | Atomic? | Hinweis |
|---|---|---|---|
| #29 | 11 | OK | Step 7 (Backup-Container) ist groß aber legitim atomar; Step 11 ist Deployment (kein Commit) — sauber gekennzeichnet |
| #30 | 11 | OK | jede Datei einzeln, Sanitize-Refactor vor Wiring (Test-First-Ordnung) |
| #31 | 11 | OK | Step 1 (deps) vor Steps 2-11 — korrekt; Test-Route-Registration nur dev/staging — gut |
| #32 | 6 | OK | Shell-Helper vor Workflow-YAML — korrekt; Step 6 ist reine Operations |
| #33 | 13 | OK | Bootstrap-Module + Entry-Point-Anpassung pro Runtime jeweils 2 Commits — clean |
| #34 | 17 | OK | High-PII einzeln (5 Commits), Bulks in 3-Commit-Buckets — sicherer Ansatz |
| #35 | 18 | OK | Foundation (Packages) zuerst, dann pro Runtime, dann Business-Hooks, dann Infra |
| #36 | 9 (8 Items + Wrap-up) | OK | jeder Item-Fix ein Commit, sauber separierbar |
3.2 Tech-Korrektheit Cross-Check
React-Router-v7-Korrektheit (#31, #33):
apps/web/app/entry.client.tsx,entry.server.tsx,root.tsx— Pfade verifiziert (existieren). OK.ErrorBoundaryinroot.tsxmituseEffect(() => Sentry.captureException(error), [error])— korrekt; aber Hinweis: bei SSR-Errors ist React-Router-v7 die Convention, dass die Server-Integration viarequestDataIntegrationautomatisch captures. ManuelleruseEffect-Capture ist sinnvoll als Client-Side-Backup. OK.- Step 7 (#31): "Falls
@sentry/react-routerv8 verfügbar" — pragmatischer Decision-Punkt, gut dokumentiert. OK. - Finding F-3 (Minor):
#33Step 9 importiertimport './otel.server'(mit.server-Suffix), aber die Datei wird in Step 9 alsapps/web/app/lib/otel/server.tsangelegt — Pfad-Inkonsistenz. Fix vor Implementation: entweder Import-Pfad als./lib/otel/serverkorrigieren oder Datei alsentry.server.otel.tsbenennen. Kleiner Schönheitsfehler in Step-Beschreibung.
Hono-Korrektheit (#30, #35):
apps/api/src/app.ts:86ruftcreateErrorHandler({...})— verifiziert (app.onError(createErrorHandler())an Z. 86). OK.- Hono-Tracing-Middleware-Approach (Step 5) — korrekt, da Sentry kein offizielles Hono-Integrationspaket hat.
c.req.routePathfür Route-Pattern (#35 Lessons Learned erwähnt) — korrekt.
BullMQ-Korrektheit (#30):
- Step 9 erwähnt
Sentry.bunIntegrationals BullMQ-Integration — das ist falsch.bunIntegrationist die Bun-Runtime-Integration, nicht BullMQ. Sentry v8 hat keine offizielle BullMQ-Integration (Stand 2026-05). Der Step relativiert das mit "oder manuelle BullMQ-Hooks falls nicht offiziell" — der manuelle Wrapper-Approach in Step 9 ist der richtige Weg. - Finding F-4 (Minor): Falsche API-Namens-Referenz
Sentry.bunIntegrationmuss raus oder als "Platzhalter, prüfen obbullMQIntegrationexistiert; sonst manueller Wrapper" gekennzeichnet werden. Empfehlung: Step 9 vor Implementation umExplore-Subagent-Hinweis ergänzen: "Prüfe@sentry/nodev8.x changelog auf BullMQ-Integration; falls nicht vorhanden, manuellen Wrapper aus diesem Step nutzen".
Sentry-SDK-Korrektheit (#30, #31):
httpIntegration,prismaIntegration({ client: prisma }),requestDataIntegration({ include: { ip: false, ... } })— alle gültige Sentry-v8-Integrations. OK.replayIntegration({ maskAllText: false, maskAllInputs: true })— gültig. OK.browserTracingIntegration()— gültig. OK.
Prisma-Korrektheit (#33):
- Step 2 PII-Scrubber:
db.statementParam-Bindings strippen — Prisma's OTel-Integration setztdb.statementohne Param-Values (Default), aber defense-in-depth-Scrubbing ist korrekt.
4. Test-Requirements-Verifizierbarkeit
| Task | Unit | Integration | E2E | Coverage-Target | Verifizierbar? |
|---|---|---|---|---|---|
| #29 | N/A (Infra) | smoke.sh | manual staging | N/A | OK |
| #30 | sanitize, sentry-bootstrap, hono-mw, runtime | In-Memory-Sentry-Transport | manual staging | ≥90%/≥80% | OK |
| #31 | sentry-client/server, routeTracing | SSR-render | Playwright /__test/client-throw |
≥80% | OK |
| #32 | sentry-release.sh (bats) | test-workflow workflow_dispatch |
manual CI-run | N/A | OK |
| #33 | pii-span-processor, otel-bootstrap | mock-OTLP-endpoint | manual E2E-trace 4-spans | ≥85%/≥70% | OK |
| #34 | PII-mock-tests pro Service, eslint-rule-test | pre-commit-hook | staging-log-inspection | N/A (Migration) | OK |
| #35 | registry/auth/middleware/scheduler | in-process API | prom-targets + grafana-live | ≥80%/≥70% | OK |
| #36 | pro Item-Fix | regression (existing) | oha-load-test | nicht senken | OK |
Spezifisch zu den User-Fragen:
- Sentry-Tests verifizierbar? Ja — In-Memory-Transport (#30 Test-Reqs erwähnt
@sentry/coretestkit explizit) plus Staging-Smoke. Korrekt. - OTel-Spans testen? Ja — Mock-OTLP-Endpoint in Vitest-Suite (#33 Test-Reqs) + End-to-End-Trace-Verifikation auf Staging (Trace-ID-Korrelation über 4 Services). Korrekt.
- Pino-Redaction testen? Ja —
webLogger-Mock-Spy mitassertNotCalledfür PII-Keys (#34 Test-Reqs). Korrekt. Zusatz-Hinweis: ESLint-Rule selbst wird mit synthetischem Source-File + ESLint-API getestet — sauber.
Finding F-5 (Minor): #34 definiert keine konkrete Coverage-%-Zahl ("keine harte %-Zahl") — das ist akzeptabel für eine Migration-Task, aber die "Pflicht: Tests für die 5 High-PII-Services" ist eine implizite Coverage-Zusage und sollte als hartes Akzeptanz-Item bleiben (ist es bereits in Acceptance Criteria). OK.
5. Acceptance-Criteria-Verifizierbarkeit
Alle 8 Files haben Acceptance-Criteria mit:
- Konkreten Datei-Existenz-Checks (
infra/sentry/...,packages/metrics/...) - Endpoint-Behaviors (
/status→ 200/503,/metrics→ 401/200) - Staging-Verifikation (Test-Event in Sentry-UI, Trace mit N Spans, Dashboard-Live-Daten)
- Lint+Typecheck+Test-Gates
Objektiv prüfbar: Ja. Alle Criteria sind entweder Datei-Existenz, Endpoint-Response, Lint-Output oder UI-Sichtbarkeit. Kein "schöner Code"-Subjektiv-Kriterium.
Finding F-6 (Minor): #35 AC "Cardinality-Schutz aktiv (tenant_id-Bucketing dokumentiert)" ist etwas weich. Schärfer wäre: "Prom-Query count by (__name__)({__name__=~\"ai_.*\"}) liefert < 1000 Series auf Staging". Aber als Doku-Anforderung mit Verweis auf Approach-Section-Decision-Punkt (top-50 + other ab 1000 tenants) noch akzeptabel.
6. Staging-Deployment-Steps (Sentry-Selfhost auf Hetzner+Coolify)
6.1 Sizing-Empfehlungen — vorhanden?
Ja, in #29 Approach-Section:
- "16 GB RAM empfohlen (12 GB hartes Minimum, Clickhouse + Kafka sind RAM-hungrig)"
- "4 vCPU empfohlen"
- "~50 GB Disk für 90 Tage Event-Retention"
- "~10 Container" mit Liste
Plus GlitchTip-Alternative für 8-GB-Server in sentry-glitchtip-alternative.md dokumentiert (Step 10).
OK.
6.2 Backup-Restore-Drills — vorhanden?
Backup-Steps vorhanden (#29 Step 7: täglicher Cron-Container, postgres-dump + clickhouse-snapshot → S3, SENTRY_SECRET_KEY notieren).
Restore-Drill: AC enthält "docs/observability/sentry-selfhost.md enthält: Deploy-Schritte, Update-Strategie, Backup/Restore-Drill, Hardening-Checkliste, Ressourcen-Anforderungen". Step 8 dokumentiert Updates aber nicht explizit Restore.
Finding F-7 (Minor — actionable): Im Implementation-Step 8 oder neuem Step 8a sollte ein expliziter Punkt "Restore-Drill dokumentieren + auf Staging einmalig durchspielen" stehen. Aktuell ist es nur in AC erwähnt, ohne Implementation-Step. Fix: Step 8 erweitern um Bullet "Restore-Drill: Postgres-Dump auf parallelem Compose-Stack importieren, Clickhouse-Snapshot wiederherstellen, Login + 1 Test-Issue prüfen — Verfahren in Doku-File ergänzen".
6.3 Vollständigkeit Coolify-Deployment
Step-by-Step für Coolify-UI-Anlegen (#29 Staging-Deployment Step 2) ist konkret: Repo, Compose-Path, Domain, Env-Vars aus Vault. OK.
install.sh-Wrapper läuft beim ersten Deployment automatisch → Admin-User-Setup. OK.
Smoke-Tests sind konkret mit sentry shell -c "...", sentry-cli send-event, curl OTLP-Endpoint — verifizierbar.
OK.
7. Konsistenz mit User-Wünschen
7.1 "Sentry Selfhost und alles einbinden" — alle 3 Runtimes abgedeckt?
| Runtime | Init-Modul | Reporter | Tracing | E2E-Verifikation |
|---|---|---|---|---|
apps/api |
apps/api/src/sentry.ts (#30 Step 3) |
apiErrorReporter (Step 4) |
Hono-MW (Step 5-6) + Prisma-Auto | Smoke #30 Step 5 |
apps/worker |
apps/worker/src/sentry.ts (#30 Step 7) |
workerErrorReporter (Step 8) |
BullMQ-Wrapper (Step 9) + Prisma-Auto | Smoke #30 Step 5 |
apps/web (client) |
apps/web/app/sentry.client.ts (#31 Step 2) |
n/a (Sentry-API direkt) | Browser-Tracing + Route-Tracing (Step 7) | Playwright + manual |
apps/web (SSR) |
apps/web/app/sentry.server.ts (#31 Step 4) |
webErrorReporter (Step 4) |
requestDataIntegration | Manual SSR-throw |
Verdict: Alle 3 Runtimes (4 Wiring-Punkte) abgedeckt. OK.
7.2 "Full Auto-Instrumentation mit Sentry-OTLP-Backend" — korrekt?
@opentelemetry/auto-instrumentations-nodeals Meta-Package (HTTP/fetch/Prisma/BullMQ/Redis/fs/dns/net) — korrekt für Full-Auto-Instrumentation (#33 Step 1).fs-Instrumentation explizit disabled (Step 3: "'@opentelemetry/instrumentation-fs': { enabled: false }/* zu noisy */") — sinnvoller Default.- Sentry-Relay als OTLP-Ingestor: konfiguriert in
infra/sentry/relay/config.ymlmitrelay.ingest.otlp.enabled: true, max_payload_size: 5MiB(#33 Step 10). - Cross-Verifikation mit
#29 Step 6: "OTLP-Ingest aktivieren —relay/config.ymlso anpassen, dass Relay einen OTLP-HTTP-Endpoint (/api/{project}/integration/otlp/v1/traces) annimmt" — konsistent. OK. Update 2026-05-18: Sentry-Relay 25.x bietet OTLP-Ingest bereits out-of-the-box auf dem/integration/otlp/-Pfad an (keine config-Anpassung nötig); B-005 war ein Pfad-Mismatch, kein Relay-Bug.
Finding F-8 (Minor — Verifikations-Hinweis): Sentry-Relay OTLP-Ingest ist Beta-Feature (Stand Anfang 2026). Der Explore-Subagent-Hinweis im Subagent Recommendations (#33: "Sentry-Relay OTLP-Ingest-Config Stand 2026-05, gibt es Rate-Limits") greift das auf — gut. Empfehlung: Vor Implementation Decision-Punkt dokumentieren: "Falls OTLP-Ingest in v25.x noch nicht stabil → Fallback auf Jaeger/Tempo (Doku in docs/observability/otel.md als Alt-Exporter bereits vorgesehen)".
7.3 "no-console: error für alle server-side Code" — Erstphase Migration + Zweitphase ESLint klar getrennt?
#34 ist explizit in zwei Phasen geteilt:
- Phase 1 — Aufräumen (manuelle Migration) — Steps 1-13
- Phase 2 — Enforce (ESLint-Rule) — Steps 14-17
Reihenfolge ist korrekt: erst migrieren, dann Rule aktivieren (sonst würde Rule den eigenen Migration-Commit blocken). OK.
Override-Strategie:
- Server-Code (
**/*.server.ts(x),apps/api/src/**,apps/worker/src/**,packages/**/src/**) →error - Test-Files →
off - Client-Bundle (
apps/web/app/components/**,apps/web/app/routes/**ohne.server.) →off(Browser-Konsole legitim)
OK.
Finding F-9 (Pfad-Korrektur): Die im #34 erwähnten High-PII-Files-Pfade sind teilweise falsch:
| In Detail-MD | Tatsächlicher Pfad im Repo |
|---|---|
apps/web/app/utils/services/.server/authService.ts:99 |
apps/web/app/utils/services/authService.ts (kein .server-Subdir, 0 console-Calls beim Stichproben-grep) |
apps/web/app/utils/services/.server/EmailService.ts:29 |
apps/web/app/modules/emails/services/EmailService.ts (Pfad in modules/emails/, console-Call bestätigt: EmailService.ts:29 + :44) |
apps/web/app/utils/services/.server/CrmService.ts:433/445 |
apps/web/app/modules/crm/services/CrmService.ts (Pfad in modules/crm/, console-Calls bestätigt: :393, :421, :437, :449, :571-604) |
apps/web/app/utils/services/.server/PromptBuilderService.ts:185/256 |
apps/web/app/modules/promptBuilder/services/.server/PromptBuilderService.ts (Pfad in modules/promptBuilder/services/.server/, console-Calls bestätigt) |
apps/web/app/utils/services/.server/SeedService.ts:199-217 |
apps/web/app/utils/db/seed/SeedService.ts (Pfad in utils/db/seed/, nicht in services/.server/) |
Fix vor Implementation: Detail-MD Step 2-6 mit korrekten Pfaden updaten. Sonst greift ein Subagent ins Leere. Konkret: Inventar-Script aus Step 1 zuerst laufen lassen, das wird die Pfade automatisch korrigieren — Empfehlung an ausführenden Agent: Step 1 strikt vor Step 2 fertigstellen und Inventar als Source-of-Truth für die Reihenfolge nehmen (nicht die hier vorgeschlagenen statischen Pfade).
7.4 "/status + Prometheus + Grafana mit Business-Metriken" — Business-Metrics abgedeckt?
Final-Liste in #35 Approach-Section "Business":
active_tenants✓active_users_24h✓ai_tokens_consumed_total{provider, model, tenant_id}✓ (mit Cardinality-Bucketing-Decision)stripe_webhook_events_total{event_type, status}✓mail_sent_total{provider, status}✓webhook_delivery_attempts_total{status}✓csrf_token_rotation_total✓subscription_active{plan_id}✓
User-Wunsch explizit gefordert: active_tenants, ai_tokens, stripe_webhook_events — alle drei abgedeckt + zusätzlich Mail, Webhook-Delivery, CSRF-Rotation, Subscriptions. OK.
Instrumentierung als Implementation-Steps separiert (Step 10 AI-Cost, Step 11 Stripe, Step 12 Mail, Step 13 Webhook-Delivery) mit je einem atomic Commit. OK.
5 Grafana-Dashboards (Overview, API-Latency, Queue-Health, Business-KPI, AI-Cost-per-Tenant) — sinnvolle Aufteilung, deckt User-Wunsch ab.
OK.
8. Performance-Quickwins — Alle 8 Items mit file:line?
| # | Item | Datei | Line | Datei existiert? |
|---|---|---|---|---|
| 1 | N+1 Users-Admin | apps/web/app/routes/admin/accounts/users.tsx |
119-129 | ✓ existiert |
| 2 | currentTenant Doppel-Fetch | apps/web/app/utils/data/.server/rootData.ts |
30 | ✓ existiert |
| 3 | Storage Signed-URL-Cache | apps/api/src/storage.ts |
56-80, 82-131 | ✓ existiert |
| 4 | clearSubscriptionsCache Thrash | apps/web/app/utils/services/.server/subscriptionService.ts |
543-548 | ✓ existiert |
| 5 | CSRF Body-Clone | apps/web/app/utils/session.server.ts |
230-268 | ✓ existiert |
| 6 | Recovery-Code Rejection-Sampling | apps/web/app/utils/auth/mfa/recovery-codes.server.ts |
80-83 | ✓ existiert |
| 7 | UUID-Collision-Check | apps/api/src/auth/session/session-store.ts |
47-61 | ✓ existiert |
| 8 | CSRF-Token 100 → 32 Bytes | apps/web/app/utils/session.server.ts |
212-219 | ✓ existiert |
Alle 8 Items mit konkretem file:line + Problem-Description + Fix-Approach + Tests. Item 8 hat zusätzlich Rollback-Warnung (bestehende Sessions mit 100-Byte-Token) und Migration-Hinweis (beide Längen akzeptieren bis TTL ablauf). Sehr gründlich. OK.
Finding F-10 (Optional): Item 8 könnte vor Implementation in eigenen Folge-Task ausgegliedert werden (siehe Item-8-Subagent-Hinweis), falls Session-TTL > 24h ist. Die Detail-MD adressiert das bereits in Rollback-Strategy + Subagent-Plan-Hinweis. OK.
9. Phase-Reihenfolge (intern)
- #29 Sentry-Setup zuerst ✓ (Voraussetzung für DSNs)
- #30 / #31 parallel danach ✓ (unterschiedliche Apps, kein File-Konflikt)
- #32 nach #30+#31 ✓ (CI-Release-Tagging braucht Wiring)
- #33 OTel "später" ✓ (kann theoretisch parallel zu #34/#35, README ordnet sie parallel ein — OK weil #33 keinen #32-Block deklariert; OTel-Backend = Sentry-Relay aus #29, also nur #29 ist harte Voraussetzung)
- #34 logging-migration parallel zu #33/#35 ✓
- #35 metrics-grafana parallel zu #33/#34 ✓
- #36 perf-quickwins zuletzt ✓ (braucht #35 zum Messen)
OTel nutzt Sentry-Relay als Backend — bestätigt:
- #29 Step 6 aktiviert OTLP-Ingest in Relay
- #33 Step 10 verifiziert Relay-Config (idempotent zu #29 Step 6 — saubere Defense-in-Depth)
- #33 Default-Exporter zielt auf
https://sentry.<domain>/api/<project_id>/otlp
Reihenfolge ist korrekt. OK.
10. Fehlende Aspekte (Critical Gaps)
10.1 Geprüft — vorhanden ✓
- DSGVO/PII-Schutz (in #30 beforeSend, #31 Replay-Masking, #33 PII-Span-Processor, #34 Pino-Redaction)
- Rollback-Strategie pro Task
- Security Notes pro Task
- Cardinality-Schutz (#35)
- Self-Host vs SaaS-Entscheidung dokumentiert + Alternative (GlitchTip)
- TLS via Coolify-Traefik
- 2FA für Sentry-Admin
- Secret-Rotation (CI-Token, METRICS_TOKEN)
- Token-minimal-Scope (
project:releases) - Source-Maps werden gelöscht nach Upload (
filesToDeleteAfterUpload) - Sample-Rates env-konfigurierbar
- No-Op-Verhalten ohne DSN/Endpoint/Token
10.2 Fehlend / Verbesserungswürdig
Finding F-11 (Minor — Suggestion): Alerting ist nicht thematisiert. Phase 02 baut Metriken + Sentry, aber wer wird benachrichtigt wenn queue_jobs_failed_total spike oder stripe_webhook_events_total{status="failed"} > threshold? Empfehlung:
- In
#35 metrics-grafana.mdAcceptance-Criteria ergänzen: "Mindestens 1 Grafana-Alert-Rule definiert (z.B.up == 0 for 2mfür API/Worker/Web) mit Notification-Channel (Email oder Webhook)". - Optional: Sentry-Alerts (Issue-Frequency-Threshold) in
#29oder#30AC ergänzen.
Finding F-12 (Minor — Suggestion): Log-Aggregation (Loki o.ä.) ist nicht eingeplant. Pino schreibt JSON in stdout, Coolify aggregiert in Container-Logs — aber kein zentraler queryable Store. Phase-02 erwähnt es nur am Rand ("Loki/Grafana"). Für 10/10-Boilerplate wäre infra/loki/ mit Promtail-Sidecar sinnvoll. Empfehlung: Entweder in Phase 02 hinzufügen (eigener loki-stack.md-Task) oder in 11-backlog/ aufnehmen mit Begründung "Pino-JSON in Coolify-Container-Logs reicht für MVP".
Finding F-13 (Minor — Suggestion): Sentry-Sentry-Heartbeat / Dead-Man-Switch für den Sentry-Self-Host selbst nicht behandelt. Wenn Sentry down ist, weiß niemand davon. Empfehlung in #29 AC ergänzen: "Externer Uptime-Check (z.B. UptimeKuma in separatem Stack) prüft https://sentry.<domain>/_health/ alle 5 Min, alarmiert via Email bei Down".
Finding F-14 (Cosmetic): Web-Side OTel-Bootstrap in #33 Steps 7-9 erwähnt Browser+SSR getrennt, was korrekt ist, aber das Service-Naming-Schema sollte sauberer differenziert sein: boilerplate-web-client vs boilerplate-web-ssr. Aktuell beide unter boilerplate-web → in Traces nicht unterscheidbar. Empfehlung: Resource-Attribute-Liste in Approach-Section anpassen oder in Step 7/9 explizit dokumentieren.
Finding F-15 (Nice-to-have): Synthetic-Monitoring (z.B. ein Worker-Job alle 5 Min, der einen End-to-End-Flow simuliert und Metriken/Traces emittiert) wird nicht explizit besprochen. Wäre die natürliche Erweiterung von #36 aber out-of-scope für Phase 02. OK to defer.
11. Findings — Zusammenfassung & Priorität
Must-fix vor Implementation (3 Items)
- F-3 —
#33Step 9: Import-Pfad./otel.servervs Dateipfadlib/otel/server.tskonsistent machen. - F-4 —
#30Step 9: Falsche Sentry-API-ReferenzSentry.bunIntegrationfür BullMQ entfernen; durch "manueller Wrapper (Default-Approach in diesem Step)" ersetzen. - F-9 —
#34Steps 2-6: Pfade der 5 High-PII-Services korrigieren ODER explizit "Pfade sind Beispiele; Inventar aus Step 1 als Source-of-Truth nehmen" hinzufügen.
Should-fix (3 Items)
- F-7 —
#29Step 8: Restore-Drill als expliziten Implementation-Step ergänzen (nicht nur AC). - F-8 —
#33: OTLP-Ingest-Beta-Status erwähnen + Fallback-Pfad zu Tempo/Jaeger dokumentieren (ist in Doku-Plan, aber als Decision-Punkt im Approach gut sichtbar machen). - F-14 —
#33: Web-Service-Namingboilerplate-web-clientvsboilerplate-web-ssrdifferenzieren.
Nice-to-have (4 Items)
- F-11 —
#35AC: Mindestens 1 Grafana-Alert-Rule + Notification-Channel. - F-12 — Loki/Promtail-Sidecar als Phase-02-Erweiterung oder in
11-backlog/. - F-13 —
#29AC: Externer Uptime-Check für Sentry-Self-Host. - F-15 — Synthetic-Monitoring als zukünftige Erweiterung dokumentieren.
Reine Beobachtungen (keine Fixes nötig)
- F-1: Cross-Phase-Block
#29 → 09-authentik-setupkorrekt deklariert. - F-2:
#35bzgl.#36Symmetrie OK (Depends-on auf #36-Seite reicht). - F-5:
#34Coverage-Strategie OK (Migration-Task). - F-6:
#35Cardinality-AC etwas weich aber akzeptabel. - F-10:
#36Item 8 Risiko bereits in Rollback adressiert.
12. Quantitative Gesamt-Bewertung
| Dimension | Score (0-10) | Begründung |
|---|---|---|
| Template-Konformität | 10 | Alle 8 Files folgen Pflicht-Reihenfolge |
| Dependency-Korrektheit | 9.5 | Sauber deklariert, Cross-Phase-Refs gültig |
| Atomic-Commits-Eignung | 9 | Steps sind sauber separierbar, einige Bulk-Migrationen pragmatisch zusammengefasst |
| Tech-Korrektheit | 8.5 | -1.5 für F-3, F-4 (kleine API-Referenzen) |
| Test-Verifizierbarkeit | 9.5 | In-Memory-Transports + Staging-Smoke konkret |
| AC-Objektivität | 9 | Wenige weiche Items (Cardinality-Schutz) |
| Staging-Coverage | 9 | -1 für fehlenden Restore-Drill-Step (F-7) |
| User-Wunsch-Abdeckung | 9.5 | Alles drin; -0.5 für Pfad-Inkonsistenz F-9 |
| Performance-Quickwins-Konkretheit | 10 | Alle 8 file:line verifiziert, alle Dateien existieren |
| Phase-Reihenfolge-Sauberkeit | 10 | Saubere Topologie, parallelisierbar gut markiert |
| Security-Notes-Tiefe | 10 | PII, Token-Scopes, Cardinality, Allowlists durchgängig |
| Gesamtscore | 9.3 / 10 | Ausführungsreif nach 3 Must-fixes |
13. Empfehlung
APPROVED FOR EXECUTION nach Adressierung der 3 Must-fixes (F-3, F-4, F-9). Die 3 Should-fixes können während Implementation adressiert werden (im jeweiligen Step-Subagent-Brief erwähnt). Nice-to-haves sind echte Verbesserungen — wenn Zeit, in Phase 02 mitnehmen, sonst in 11-backlog/ aufnehmen.
Konkrete nächste Schritte für ausführenden Agent:
- Vor Phase-02-Start die 3 Must-fixes als kleinen Doku-Commit auf
agent/phase-02-prepeinarbeiten (5-Minuten-Edit auf den Detail-MDs). #29als Solo-Agent-Run starten (3-4d), parallel kann ein anderer Agent bereits#34-Inventar-Script (Step 1) bauen — das ist Pre-Migration-Vorbereitung ohne Wiring-Dependency.- Nach
#29grün:#30+#31parallel zwei Agents. - Nach
#30+#31grün:#32(Solo) +#33/#34/#35parallel drei Agents starten. - Zuletzt
#36mit#35-Baseline.