Files
oysqn.app/docs/archive/handoffs/handoff-2026-04-20-integration-test-debugging.md
Patrick Toal 108c042921 fix(edge-fn): replace getClaims with adminClient.auth.getUser(token)
fix(edge-fn): use user.id instead of claims.sub; fixes 500s and false cert_required
fix(migrations): drop broad reservations SELECT policy; add reservation_slots view with security_invoker=false
fix(tests): correct weekSlot() keys from start/end to start_time/end_time
fix(tests): spread overlap test slots across separate ISO weeks
fix(tests): update e2e assertion to match actual authenticated home text
fix(app): hide IonMenu before user is authenticated
feat(dx): add test:all script running unit, integration, and e2e in sequence
docs(claude-md): document SELinux fix, Edge Function auth pattern, security_invoker behaviour
2026-04-20 14:32:37 -04:00

8.7 KiB

Session Handoff: Integration Test Debugging

Date: 2026-04-20 Session Duration: ~1.5 hours Session Focus: Debug and fix failing integration tests for auth and booking-constraints suites; fix Edge Function boot failure; fix members RLS infinite recursion Context Usage at Handoff: High

What Was Accomplished

  1. Fixed verifyOtp API misuse in both test filestoken param is for 6-digit OTP codes; token_hash param is for hashed magic link tokens. Changed in both test files.

    • tests/integration/auth-session.test.ts (2 call sites)
    • tests/integration/booking-constraints.test.ts (1 call site in getSessionToken)
  2. Fixed futureSlot() key mismatch in booking-constraints test — returned { start, end } but callCreateReservation expected { start_time, end_time }. Renamed keys in futureSlot() return value; updated 2 directInsertReservation call sites that used slot.start/slot.end.

  3. Added @types/node and test tsconfig — Nuxt-generated tsconfig has "types": [], causing process to be unresolved in test files.

    • Added @types/node as dev dependency
    • Created tests/tsconfig.json extending root with "types": ["node", "vitest/globals"]
    • Added typecheck: { tsconfig: './tests/tsconfig.json' } to vitest.integration.config.ts
  4. Fixed members RLS infinite recursion (42P17) — Policies "Admins can read all members" and "Admins can manage all members" queried members from within a members RLS policy, causing infinite recursion. Created new migration with two SECURITY DEFINER helper functions:

    • public.current_user_role() → text
    • public.current_user_has_role(roles text[]) → boolean
    • Replaced all inline EXISTS (SELECT 1 FROM members WHERE ...) admin checks in ALL tables with public.current_user_has_role(...) calls
    • Migration: supabase/migrations/20260420170418_fix_members_rls_recursion.sql
  5. Removed broken import from Edge Functionimport "@supabase/functions-js/edge-runtime.d.ts" is not a valid Deno runtime import. Removed it. Also tried /// <reference types="..." /> which also failed.

  6. Switched Edge Function import from jsr: to npm:jsr:@supabase/supabase-js@2 cache is lost on container restart in the podman-based local dev setup. Changed to npm:@supabase/supabase-js@2.

  7. Removed entrypoint from config.tomlentrypoint field may not be supported/correctly handled by supabase-edge-runtime 1.73.3 (podman variant). Removed it; function now relies on default index.ts convention.

  8. Set verify_jwt = false in config.toml — Edge runtime 1.73.3 verifyHybridJWT fails with TypeError: Invalid Token or Protected Header formatting on ES256 JWTs (new sb_publishable_* / sb_secret_* key format). Disabled edge-level JWT verification; the function handles auth itself via userClient.auth.getUser().

Exact State of Work in Progress

  • Edge Function still returns BOOT_ERROR — Even after all the above changes, the edge runtime container still fails with worker boot error: failed to bootstrap runtime: failed to determine entrypoint. Investigation showed the function source files are NOT mounted inside the container (find / -name index.ts inside the container showed only Deno npm cache, no project files). Root cause: likely a podman volume mount issue specific to this host environment. Session was interrupted before resolving this.

  • Integration tests NOT yet passing — All 15 booking-constraints tests still fail with 503 (Edge Function BOOT_ERROR). The auth-session tests (5 tests) status is unknown for this session.

Decisions Made This Session

  • verify_jwt = false for create-reservation BECAUSE: edge-runtime 1.73.3 with podman does not correctly verify ES256 JWTs from new sb_publishable_* key format; function verifies auth internally via auth.getUser() anyway — STATUS: confirmed
  • npm: over jsr: for supabase-js import BECAUSE: JSR cache is not persistent across podman container restarts in this local dev setup — STATUS: confirmed
  • SECURITY DEFINER functions for role checks BECAUSE: inline EXISTS (SELECT 1 FROM members ...) in members RLS policies causes infinite recursion — STATUS: confirmed, migration applied

Key Numbers Generated or Discovered This Session

  • supabase-js SDK version installed: 2.100.0
  • Supabase CLI version: 2.92.1
  • supabase-edge-runtime version: 1.73.3 (compatible with Deno v2.1.4)
  • Publishable key prefix: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH
  • Secret key prefix: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz
  • Access tokens are ES256 (not HS256) — eyJhbGciOiJFUzI1NiIs...
  • New migration timestamp: 20260420170418

Files Created or Modified

File Path Action Description
tests/integration/auth-session.test.ts Modified Fixed verifyOtp to use token_hash (2 call sites)
tests/integration/booking-constraints.test.ts Modified Fixed verifyOtp to use token_hash; renamed futureSlot keys to start_time/end_time; removed unused beforeEach import
tests/tsconfig.json Created Test-scoped tsconfig adding node + vitest/globals types
vitest.integration.config.ts Modified Added typecheck.tsconfig pointing to tests/tsconfig.json
supabase/migrations/20260420170418_fix_members_rls_recursion.sql Created SECURITY DEFINER helpers + fixed RLS policies for all tables
supabase/functions/create-reservation/index.ts Modified Removed bad import; changed jsr:npm: for supabase-js
supabase/functions/create-reservation/deno.json Modified Updated import map to npm:@supabase/supabase-js@^2
supabase/config.toml Modified verify_jwt = false; removed entrypoint field

What the NEXT Session Should Do

  1. Diagnose Edge Function mount issue first — Run podman inspect supabase_edge_runtime_oysqn.app and check the Mounts array. The function source files (supabase/functions/) must be visible inside the container. If they are not mounted, this is likely a podman rootless socket or SELinux label issue on the host. Try npx supabase stop && npx supabase start to re-create the container with correct mounts.

  2. If supabase restart doesn't fix mounts — Try npx supabase functions serve in a separate terminal (it spins up its own Deno process outside Docker, bypassing the container). Then run yarn test:integration — this tests the exact same function code via the same URL. If this works, the issue is confirmed as a container mount problem, not a code problem.

  3. After Edge Function works — Run yarn test:integration and expect all 15 booking-constraints tests + all auth-session tests to pass. Fix any remaining failures (expected to be minor after the above fixes).

  4. Then: build /admin/reservations view — list all upcoming reservations with boat/time/member/status; ability to confirm, cancel, or modify

  5. Then: test full member booking flow in browser (yarn dev, create test intervals via admin, attempt booking as member, verify Edge Function error messages surface correctly)

Open Questions Requiring User Input

  • Why are supabase function files not mounted in podman container? — May require --security-opt label=disable or :z volume label for SELinux compatibility. Impacts all Edge Function development.
  • Adjacent-session double-booking (Rule 6) — exact logic needed (carried over from previous session)
  • useSupabaseClient typing — all admin pages use as any cast (carried over)
  • Crew requirement (Rule 8) — not implemented (carried over)
  • PCOC / cert code strings — values for boats.required_certs not defined (carried over)

Assumptions That Need Validation

  • ASSUMED: npm:@supabase/supabase-js@2 is resolvable in the podman edge runtime container (npm cache may also be missing) — validate by getting the function to boot
  • ASSUMED: verify_jwt = false is acceptable for production deployment (auth is validated in function code) — validate with security review before prod
  • ASSUMED: tests/tsconfig.json approach for @types/node is the right fix and doesn't break other test types — validate by running full test suite
  • All assumptions from previous session still apply (half-open interval semantics, ISO week definition, 2026-01-05 period epoch)

Files to Load Next Session

  • supabase/functions/create-reservation/index.ts — to debug boot issue or extend
  • supabase/config.toml — to review/revert verify_jwt setting after boot is fixed
  • supabase/migrations/20260420170418_fix_members_rls_recursion.sql — if RLS issues resurface
  • tests/integration/booking-constraints.test.ts — to run and review after boot fix