# Debug Protocol (Repo) > You are debugging an issue in this repo. Do **not** implement features unless required to fix the bug. ## 0) Non-negotiables - **Source of truth:** `PROJECT_INSTRUCTIONS.md` (repo root). If anything conflicts, follow it. - **No assumptions:** First scan the repo for existing patterns, locations, scripts, helpers, and conventions. Don’t invent missing files/endpoints unless truly necessary—and if needed, add minimally and consistently. - **External DB:** `DATABASE_URL` points to on-prem Postgres (**not** a container). Dev/Prod share schema via migrations in `packages/db/migrations`. - **Security:** Never log secrets, full invite codes, or receipt bytes. Invite codes in logs/audit: **last4 only**. - **No cron/worker jobs:** Any fix must work without background tasks. - **Server-side RBAC only:** Client checks are UX only. --- ## 1) Restate the bug precisely Start by writing a 4–6 line **Bug Definition**: - **Expected behavior** - **Actual behavior** - **Where it happens** (page / route / service) - **Impact** (blocker? regression? edge case?) If any of these are missing, ask for them explicitly. --- ## 2) Collect an evidence bundle before changing code Before editing anything, request/locate: ### A) Runtime signals - Exact error text + stack trace (server + browser console) - Network capture: request URL, method, status, response body - Any `request_id` returned by the API for failing calls ### B) Repo + environment - Current branch/commit - How app is started (`docker-compose` + which file) - Node version + package manager used - Relevant env vars (sanitized): `DATABASE_URL` **host/port/dbname only** (no password) ### C) Involved code paths Identify actual files by searching the repo: - The page/component triggering the request - The hook used (`hooks/use-*.ts`) - The client wrapper (`lib/client/*`) - The API route (`app/api/**/route.ts`) - The server service (`lib/server/*.ts`) **Do not guess file names. Use repo search.** --- ## 3) Determine failure class (choose ONE primary) Pick the most likely bucket and focus there first: - DB connectivity / docker networking - Migrations/schema mismatch - Auth/session cookie flow (HttpOnly cookies, session table, logout) - RBAC / group membership / active group - Request validation / parsing (route boundary) - Client fetch wrapper / hook state - UI behavior / event handling / mobile UX - Playwright test failure (timing, selectors, baseURL, auth state) Write a **3–5 bullet** hypothesis list ordered by likelihood. --- ## 4) Reproduce locally with the smallest surface area Prefer reproducing via: 1) A single API call (`curl` / minimal `fetch`) before full UI if possible 2) Then UI repro 3) Then Playwright repro (if it’s a test failure) If scripts are needed, inspect `package.json` for actual script names (**don’t assume**). Common ones may exist (`lint`, `test`, `db:migrate`) but confirm. --- ## 5) Add targeted observability (minimal + removable) If evidence is insufficient, add temporary, minimal logs in **server services** (not in UI): - Always include `request_id` - Log only safe metadata (`user_id`, `group_id`, route name, timing) - Never log secrets/full invite code/receipt bytes/passwords/tokens - If touching invite logic: log **last4 only** Prefer: - One log line at service entry (inputs summary) - One log line at decision points (auth fail / membership fail / db row missing) - One log line at service exit (success + timing) Remove or downgrade noisy logs before final PR unless clearly valuable. --- ## 6) Fix strategy rules - Make the smallest change that resolves the bug. - Respect layering: - **Route:** parse + validate shape - **Server service:** DB + authz + business rules - **Client wrapper:** typed fetch + error normalization - **Hook:** UI-facing API layer - Don’t introduce new dependencies unless absolutely necessary. - Keep touched files free of TS warnings and lint errors. --- ## 7) Verification checklist (must do) After the fix: - Re-run the minimal repro (API and/or UI) - Run relevant tests (unit + Playwright if applicable) - Add/adjust tests for the bug: - At least **1 positive** + **2 negatives** (unauthorized, not-a-member, invalid input) - Confirm contracts: - Spendings list never includes receipt bytes - Sessions are HttpOnly + DB-backed - Audit logs include `request_id` and never store full invite code --- ## 8) Next.js route params checklist (required) For `app/api/**/[param]/route.ts`: - Treat `context.params` as **async** and `await` it before reading properties. - If you see errors about sync dynamic APIs, update handlers to unwrap params: Example: ```ts const { id } = await context.params;