fiddy/DEBUGGING_INSTRUCTIONS.md
2026-02-11 23:45:15 -08:00

4.6 KiB
Raw Permalink Blame History

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. Dont 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 46 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 35 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 its a test failure)

If scripts are needed, inspect package.json for actual script names (dont 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
  • Dont 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:

const { id } = await context.params;