Skip to content

๐Ÿ—ฃ๏ธ User Feedback

๐Ÿ“‹ Overview

Covers the architecture of the Give Feedback feature.

The system collects written, audio, and video feedback with optional screen snips or recordings, preserving runtime context for debugging, product analysis, and traceability.


๐ŸŽฌ Supported Modes

โœ๏ธ Text

  • Plain text input
  • Optional attachments
    • ๐Ÿ–ผ๏ธ Image snip
    • ๐Ÿ–ฅ๏ธ Screen recording (tab or region)

๐ŸŽ™๏ธ Audio

  • Microphone recording
  • Optional attachment
    • ๐Ÿ–ฅ๏ธ Screen recording (tab or region)

๐Ÿ“… Meet Us

  • Schedule a session with the team
  • Separate entry point
  • Outside the feedback pipeline

๐Ÿ”„ How It Works

The flow has two stages:

Stage 1 โ€” ๐Ÿ“ค Upload

Frontend requests a presigned S3 URL from the backend, then uploads the binary directly to S3 via HTTP PUT. Uploads begin immediately after capture, not at submit time.

Stage 2 โ€” ๐Ÿ“จ Submit

After uploads complete, the frontend sends a compact JSON metadata payload to the backend. The backend validates it and writes a manifest JSON to S3 as the durable record.

โš ๏ธ Submit is blocked until all required uploads finish.


๐Ÿ—๏ธ Responsibilities

Frontend - Renders feedback modal and capture flows - Records audio, screen video, region recordings, and screen snips - Uploads binaries directly to S3 (background, post-capture) - Submits final metadata payload - Cleans up streams, tracks, object URLs, and animation frames aggressively

Backend - Issues presigned upload URLs with category + MIME validation - Validates and sanitizes incoming metadata (text stripping, key format checks, correlation ID validation) - Writes feedback manifest to S3


โš™๏ธ Key Design Decisions

1. ๐Ÿ“ค Presigned Uploads Instead Of Server-Side Multipart

Why: Keeps large binaries off the Node server, isolates upload failures from submission failures, and delegates scalability to S3.

2. ๐Ÿ—‚๏ธ Manifest-Based Storage

Why: The backend stores a manifest JSON referencing uploaded media rather than one combined blob. Text and media are validated independently; the record stays inspectable and easy to process downstream.

3. ๐Ÿ”— Correlation ID As Feedback ID

Why: Format: userId-sessionId-uuid. One identifier links frontend activity, backend logs, and stored artifacts. If not supplied, the backend generates a safe fallback.

4. โšก Background Uploads After Capture

Why: Uploads start as soon as media is captured, making the final submit step lightweight and reducing perceived wait time.

5. ๐Ÿช Capture Logic In Focused Hooks

Why: Recording, screen capture, and upload lifecycle are encapsulated in reusable hooks, keeping modal components readable and making cleanup explicit.


๐Ÿ“ฆ Manifest Shape

{
  "feedbackId": "userId-sessionId-uuid",
  "type": "text | audio | video",
  "text": "...",
  "currentUrl": "...",
  "userAgent": "...",
  "timestamp": "...",
  "userId": "...",
  "files": { "mediaKey": "...", "imageKey": "..." },
  "createdAt": "..."
}

๐Ÿ”’ Security

Concern Mitigation
Unsafe text HTML/control char stripping, whitespace cleanup, hard length cap
Invalid uploads Category + MIME + compatibility validation before issuing presigned URL
Malformed S3 keys Key format validated against expected feedback path patterns on submit
Untrusted correlation IDs Validated on receipt; invalid values replaced with a backend-generated fallback
S3 redirect attacks Fetch uses redirect: 'error' โ€” presigned URLs are host-bound, silent redirects would silently fail PUT requests