codeflash-internal/.codeflash/HANDOFF.md
Kevin Turcios d7a8b8f227
perf: fix CI build + lazy-load heavy libs + parallelize DB queries (#2601)
## Summary
- **Fix CI build failure**: Auth0Client crashes during Next.js
prerendering when env vars aren't set. Returns a no-op stub (`getSession
→ null`) when domain is missing — semantically correct for static
generation
- **Lazy-load markdown libs (~260kb)**: ReactMarkdown, remarkGfm, and
react-syntax-highlighter were eagerly imported in monaco-diff-viewer but
only rendered when user expands "Generated Tests". Extracted into a
dynamic component
- **Parallelize repo detail query**: `getRepositoryById` ran the
activity count sequentially after the repo lookup. Since `repoId` is
already available, all three queries now run in parallel

## Test plan
- [ ] CI `build` check passes (was failing since #2598)
- [ ] Trace page still renders generated tests correctly when expanded
- [ ] Repository detail page loads correctly with activity status
2026-04-13 11:03:05 -05:00

5.8 KiB

Handoff - Prisma Optimization Session (continued)

Environment

  • Node.js 25.8.1, npm 11.11.0
  • Next.js 16.2.3, Prisma 7.7.0, PostgreSQL
  • Branch: perf/absolute-performance
  • Tests: 39 pass (0 failures -- fixed 3 pre-existing failures in this session)
  • Types: clean (0 errors -- fixed 5 pre-existing TS2339 errors in this session)

Focus

Prisma query optimization in cf-webapp. Targeting: overfetching, missing select, redundant queries, permission-check full-table loads, and missing indexed lookups.

Session Tag

prisma-2026-04-11

Previous session commits (13b302a8 through 2444d1b4)

See full git log for details. Major optimizations:

  • findFirst->findUnique on composite indexes
  • Loading ALL members replaced with parallel indexed lookups
  • Set/Map-based lookups replacing Array.some/Array.find
  • Sequential Promise.all batches merged
  • DB indexes added for observability queries
  • "use cache" migration for observability pages
  • Layout query consolidation
  • Consolidated count queries, select narrowing, parallelized login callback
  • Dashboard CTE rewrite: UNION for personal accounts instead of 3-way OR
  • PR data query UNION CTE for personal accounts

This session commits

Commit: 6f9e81a6

perf: add select narrowing to organization queries and error fetches

  • cached-dashboard-data.ts: organizations select only id, name (skips description, website, github_org_id, auto_add_github_members, etc.)
  • dashboard/action.ts getUserOrganizations: same select narrowing
  • members/action.ts getOrganizationMembers: select only id + nested members
  • members/data.ts getMembersPageInitData: same select narrowing
  • llm-call/[id]/page.tsx: select 6 rendered fields from optimization_errors (skips stack_trace Text column)

Commit: 7221d448

perf: narrow optimization_features select in getTraceData, fix pre-existing type errors

  • optimization_features.findFirst: select only 12 consumed fields instead of all 30+ columns (skips optimizations_raw, speedup_ratio, experiment_metadata, original_runtime, approval_*, slack_message_ts, etc.)
  • optimization_errors.findMany: added id/created_at back to select (fixed 5 pre-existing TS2339 errors from previous session's aggressive narrowing)

Commit: 1ef61d1e

perf: add select narrowing to llm_calls.findUnique on detail page

  • Excludes 8 unused columns including large JSON blobs: messages, parsed_response, context, plus max_tokens, retry_count, user_id, python_version, is_async

Commit: bcaf08b5

perf: avoid intermediate Date objects in trace aggregation loop

  • Store first_seen/last_seen as numeric timestamps during aggregation
  • Convert to Date once per trace at the end
  • Sort on numeric timestamps instead of calling .getTime() in comparator
  • Use for-of loop instead of .forEach

Commit: f96fba76

perf: cache split("/")[0] result instead of calling twice

  • In getRepositoryById and getOptimizationRepositories

Commit: d6cab273

perf: add loading.tsx skeletons for observability detail pages

  • llm-calls/loading.tsx and llm-call/[id]/loading.tsx
  • These pages lack internal Suspense and make DB queries at server component level

Commit: ee535ae9

perf: restructure getOptimizationPRs to limit before joining

  • Both org and personal paths now use two-phase CTE: phase 1: identify page of event IDs using EXISTS (no full JOIN) phase 2: JOIN only ~10 result IDs with optimization_features and repositories
  • Removed unused dataWhereClause variable

Commit: 26307af8

fix: add missing _count to getRepositoryById test mock

  • Fixed all 3 pre-existing test failures (39/39 now pass)

Commit: 817e5884

fix: add defense-in-depth SQL interpolation guards to dashboard queries

  • sqlUuid(), sqlUserId(), sqlUsername(), sqlEventType() validation functions
  • Math.trunc() for numeric values

Not addressed (assessed and skipped)

  • get-trace-data.ts findFirst with startsWith -- cannot use findUnique (not unique key)
  • review-optimizations/[traceId]/action.ts:166 findFirst with complex OR -- correct as-is
  • repository-utils.ts sequential memoryCache operations -- in-memory, likely synchronous
  • getUserOrganizations vs getCachedDashboardData -- different caching layers for different purposes
  • update operations returning full rows (privacy-actions, member role, save-modified-code) -- write operations, infrequent, marginal savings from select narrowing
  • comments.findMany with include author -- already has select narrowing on author relation
  • getRepositoriesForAccountCached -- function from @codeflash-ai/common, cannot narrow from webapp side
  • 97 "use client" components -- all need interactivity; converting would be architectural change
  • Radix UI packages in optimizePackageImports -- already direct imports, not barrel exports
  • .map().filter(Boolean) chains -- all on small arrays, intermediate arrays negligible

Coverage summary

All Prisma queries in cf-webapp/src have been audited. Remaining queries are either:

  1. Already using select narrowing (traces page, llm-calls page, repository members)
  2. Cached with "use cache" (organizations list, trace data, call types, models)
  3. Using efficient patterns (findUnique on composite keys, groupBy, raw SQL with UNION)
  4. Detail pages that legitimately need full rows (llm-call detail page)
  5. Write operations (create, update, delete) where return data is discarded

Pre-submit review

  • Types: clean (tsc --noEmit passes with 0 errors)
  • Tests: 39 pass, 0 failures (fixed 3 pre-existing failures)
  • No behavior changes -- all permission checks preserve identical logic
  • No resource ownership issues
  • No concurrency concerns -- all queries are per-request, no shared mutable state
  • SQL interpolation defense-in-depth guards added for all raw SQL queries
  • getOptimizationPRs query restructured to LIMIT before JOINing large tables
  • Breadth scan completed across all 246 TypeScript files in cf-webapp/src