Report Bug

Report Bug

When something on the app goes wrong — a screen renders broken, a button doesn't do what it should, an AI reply lands in the wrong language — you can file a bug report directly from the app, without leaving the page.

Bug reports go to a triage queue. A Claude Code agent attempts to reproduce on preprod, analyzes the codebase, and files a GitHub issue with everything needed to fix it. You don't need to switch contexts to write a report.

Where the button lives

The Report Bug button sits in the top header on V28, to the right of the Pulse Copilot icon (gh#358 — earlier it floated at bottom-right and collided with Pulse Copilot; it's now in the header).

Keyboard shortcut: Cmd/Ctrl + Shift + B opens the capture modal from anywhere.

On mobile, the button is in the More menu.

What you can capture

The capture modal has three tabs you can combine:

1. Screenshot

Captures the current screen using DOM-to-image. This is a snapshot of what you currently see — it includes open dropdowns, hover states, and modals.

The Report Bug button itself is hidden from the capture so it doesn't occlude the area of interest.

Drag-rectangle region select (gh#465) — to capture just a piece of the screen instead of the full viewport, drag a rectangle over the area before tapping CAPTURE. The screenshot zooms to that region. Earlier the capture included the REPORT BUG dialog itself, occluding the bug; the region-select fixes that.

2. Video (up to 60 s)

Uses browser screen-recording. Default duration 30 s, max 60 s. Records the active tab only. Audio capture is optional.

Useful when the bug is a sequence — a hover state that breaks something three clicks later, an animation that stalls, a notification flood you can only show in motion.

3. Voiceover (up to 2 minutes)

Records audio narration. Transcribed server-side to text via Whisper or Claude.

The transcription appears in the report alongside the screenshot/video — you don't have to type your description if you'd rather talk through it.

You can also write a text description in the same modal — text + screenshot, text + video, voiceover + screenshot, etc., in any combination.

Auto-collected context

When you submit, the app automatically attaches:

  • Current URL + route params
  • Last 20 tRPC queries with timing + status
  • Last 100 console log lines (in-app ring buffer)
  • Last 20 failed network calls
  • Last 20 user actions (route changes, clicks)
  • Browser, viewport, build SHA, env (prod / preprod)
  • React error-boundary errors from the current session
  • Server-side log trace for the report submission's own request

You don't have to copy/paste any of this. It's bundled and stored with the report.

Anonymize PII toggle

The capture modal has an Anonymize PII toggle.

  • For non-admin users, it's ON by default.
  • For admin users, it's OFF by default but always visible.

When ON:

  • Screenshots are run through OCR + PII regex; phone numbers, emails, IBANs, and guest names are blacked out before storage.
  • Videos get the same redaction at 5 fps. The audio track from screen-recording is stripped entirely.
  • Voiceover audio is not stored in anonymized mode — only the redacted transcript text.
  • All log lines and context are passed through the PII scrubber (the same one used in server logs).
  • Tenant ID and user ID are replaced with deterministic hashes — the triage agent can run as that role in preprod without knowing who you are.

What's kept regardless:

  • The URL path (route is essential for reproduction).
  • Hashed user ID (so the triage agent can run with the same permissions).
  • Browser / OS / viewport.
  • Stack traces, error messages, status codes.
  • Click breadcrumb categories (e.g. nav:click property-tab).

What happens after you submit

Submitted reports land in the bug_reports table with status new.

A Claude Code triage agent (gh#168) picks them up:

  1. Reads the description / transcript + the auto-collected context.
  2. Spins up a preprod environment seeded to the captured state (where possible).
  3. Attempts to reproduce the bug.
  4. Reads the codebase to find the relevant files.
  5. Files a GitHub issue with the screenshot / video / context + a reproducer.

The GitHub issue URL is written back to bug_reports.githubIssueUrl once filed.

Where to see your filed reports

Admin users can see the report queue and triage state at Admin → Bug Reports (gh#343). Each row shows:

  • Status: new / triaging / reproduced / filed / wontfix
  • Capture preview (screenshot thumbnail)
  • Transcript snippet
  • Linked GitHub issue (once filed)

Retention

Reports auto-expire 30 days after creation (gh#344) — they're hard-deleted at expiry to keep the bug_reports table from accumulating PII.

A tenant admin can extend the expiry on a per-report basis from the admin viewer if they need a longer window to follow up.


Implements: gh#167 (in-app Report Bug feature). Related: gh#168 (triage agent), gh#342 (capture wiring), gh#343 (admin viewer), gh#344 (retention sweep), gh#358 (move button to top header), gh#465 (drag-rectangle region select).

Source: the FlatsBratislava operator manual.