## 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
116 lines
5.8 KiB
Markdown
116 lines
5.8 KiB
Markdown
# 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
|