Commit graph

6458 commits

Author SHA1 Message Date
Kevin Turcios
0cbd8e0b6c
Adopt shared CI workflow for aiservice (#2609)
## Summary

- Add `aiservice-ci.yml` using the shared reusable workflow from
`codeflash-ai/github-workflows`
- Remove old `django-unit-tests.yaml` and `mypy_aiservice.yml` (both
replaced by the new unified workflow)
- **Typecheck job**: uses the shared workflow
(`codeflash-ai/github-workflows/.github/workflows/uv-mypy.yml`)
- **Test job**: defined locally in `aiservice-ci.yml` (needs repository
secrets that can't be passed to reusable workflows in other repos)

## What changed

| Before | After |
|---|---|
| `django-unit-tests.yaml` (standalone) | `aiservice-ci.yml` — test job
|
| `mypy_aiservice.yml` (standalone) | `aiservice-ci.yml` — typecheck job
(shared workflow) |
2026-04-15 02:32:22 -05:00
Kevin Turcios
4c9cdff1b0
fix: replace hardcoded edit secret with session auth (#2608)
## Summary
- Replace hardcoded `"codeflash-edit-2025"` string authentication in the
`save-modified-code` API route with Auth0 session check
- Remove the secret prompt modal from the Monaco diff viewer — editing
is now gated by the user's existing login session
- Remove unused `Lock` import, dead `console.log`, and unused `result`
variable

## Test plan
- [ ] Verify the edit code button works without prompting for a secret
- [ ] Verify saving modified code succeeds for logged-in users
- [ ] Verify unauthenticated requests to
`/api/traces/:id/save-modified-code` return 401
2026-04-14 21:59:58 -05:00
Kevin Turcios
e5374c3f50
fix: provide JWT_SECRET to CI build workflows (#2607)
## Summary
- Reverts lazy JWT_SECRET initialization — keeps eager fail-fast at
module load
- Adds `JWT_SECRET` secret to both `deploy_cfwebapp_to_azure.yml` and
`nextjs-build.yaml` CI workflows so `next build` page data collection
succeeds for the `/codeflash/auth/oauth/token` route

## Context
The deploy workflow ([run
#24425211765](https://github.com/codeflash-ai/codeflash-internal/actions/runs/24425211765/job/71357530269))
was failing because `JWT_SECRET` isn't available during CI build,
causing an eager throw at module load time. The secret already exists as
a GitHub repo secret.
2026-04-14 19:25:41 -05:00
Kevin Turcios
e6cec80c9d
Merge pull request #2606 from codeflash-ai/fix/cf-webapp-security-hardening
fix: harden cf-webapp security across auth, XSS, and headers
2026-04-14 17:04:44 -05:00
Kevin Turcios
1fada04c22 fix: repair bad merge in review-optimizations authorization checks
Duplicate and mangled if-blocks from the merge of #2605 caused a syntax
error that broke type-checking.
2026-04-13 19:38:24 -05:00
Kevin Turcios
91b692c1a0 fix: harden cf-webapp security across auth, XSS, and headers
- Add auth0.getSession() to unauthenticated observability endpoints
  (llm-call-debug, llm-export, observability chat)
- Remove hardcoded JWT_SECRET fallback; require env var
- Sanitize markdown HTML with DOMPurify before innerHTML assignment
- Escape user data in Intercom boot snippet via JSON.stringify
- Add security headers (CSP, HSTS, X-Frame-Options, X-Content-Type-Options,
  Referrer-Policy, Permissions-Policy) via next.config.mjs
- Move OAuth params from sessionStorage to signed HttpOnly cookie
- Add input validation: clamp page/pageSize bounds, allowlist sort fields
- Stop leaking error.message to clients in API responses
- Remove ~40 console.log/error statements that logged user IDs, org IDs,
  PKCE params, and OAuth flow details
- Delete unused api-client.ts (NEXT_PUBLIC_CF_API_KEY never imported)
2026-04-13 19:25:19 -05:00
Kevin Turcios
80d10762ff
Merge pull request #2605 from codeflash-ai/fix/security-authorization-bugs
fix: close authorization bypass and data-integrity bugs
2026-04-13 17:30:45 -05:00
Kevin Turcios
e82dab3c13
Update js/cf-webapp/src/app/(dashboard)/review-optimizations/[traceId]/action.ts
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
2026-04-13 17:30:33 -05:00
Kevin Turcios
0fe3ca8c0a Harden dashboard authorization flows 2026-04-13 16:07:39 -05:00
Kevin Turcios
4269ec0275 fix: use upsert to prevent race condition in addOrganizationMember
Concurrent invites for the same user could both pass the existence check
and then the second create() would throw a unique constraint violation.
2026-04-13 15:17:44 -05:00
Kevin Turcios
8202ea512c fix: close authorization bypass and data-integrity bugs across dashboard
Security (critical):
- Scope member lookups to parent resource (repository_id / organization_id)
  in updateRepositoryMemberRole, removeRepositoryMember,
  updateOrganizationMemberRole, and removeOrganizationMember to prevent
  cross-tenant escalation via crafted memberId
- Replace unvalidated currentOrganizationId cookie reads with
  getAccountContext() (validates org membership) in review page and
  repo detail data loaders

Bugs:
- Add missing string-UUID branch in repository_id filter (raw SQL paths)
- Pass actual username to RepoDetailClient instead of empty string
- Remove misleading React.cache() on getAllOptimizationEventsImpl (object
  arg means reference equality never hits)
- Use create() result directly in addOrganizationMember to avoid NPE
  from unnecessary re-fetch
- Separate null-session redirect from null-event 404 in profiler page

Tests:
- Rewrite action.test.ts: org payload for Prisma findMany path, proper
  $queryRaw tagged-template mock for raw SQL path, verify repository_id
  filter is actually applied
2026-04-13 14:56:12 -05:00
Kevin Turcios
71127055f3 fix: redirect remaining auth throws that crash prerendering
getUserIdAndUsername() and getAccountContext() also threw generic
errors when no session exists. Same fix as apikeys: use redirect()
which Next.js handles as a prerender bailout signal.
2026-04-13 12:38:16 -05:00
Kevin Turcios
09ed4d4b44 fix: use redirect instead of throw for auth failures during prerender
Pages that throw Error("Authentication required") crash the Next.js
build during static prerendering (no auth session at build time).
redirect("/login") is a proper Next.js bailout signal that skips
prerendering and marks the route as dynamic.
2026-04-13 12:30:22 -05:00
Kevin Turcios
c1b0076cb8 fix: align TypeScript versions to deduplicate @prisma/client in pnpm
Root cause: cf-webapp used typescript@~5.4.5 while common used
typescript@^5.9.3. Since @prisma/client has typescript as a peer
dep, pnpm created two separate instances. prisma generate wrote to
one, but Next.js resolved the other — causing "Cannot find module
'.prisma/client/default'" at build time.

Fix: upgrade cf-webapp to typescript@^5.9.3 to match common. This
deduplicates @prisma/client to a single pnpm instance.

Also fixes cf-api deploy: exclude node_modules from copyfiles glob
and use cp -rL to dereference pnpm symlinks.
2026-04-13 12:10:16 -05:00
Kevin Turcios
b656bb1de8 fix: cf-api deploy broken by pnpm workspace migration
1. copyfiles "**/*.json" copies node_modules json into dist/ —
   exclude with -e flag
2. cp -r doesn't dereference pnpm symlinks — use cp -rL
3. Remove redundant node_modules copy into deployment/dist/
2026-04-13 11:58:37 -05:00
Kevin Turcios
c372b6bc32
Merge pull request #2603 from codeflash-ai/fix/deploy-build-common
fix: build common package before app in deploy workflows
2026-04-13 11:54:43 -05:00
Kevin Turcios
6e9519ff23 fix: build common package before app in deploy workflows
Both deploy workflows (cf-webapp and cf-api) fail with
"Can't resolve '@codeflash-ai/common'" because the workspace
dependency isn't built before the app build. Same fix already
applied to the CI quality-gate workflows.
2026-04-13 11:53:01 -05:00
Kevin Turcios
48b5e2b46d
fix: make tree-sitter WASM build failure non-fatal when cache exists (#2602)
## Summary
- If the WASM build fails (e.g. GitHub CDN outage for tree-sitter-cli or
wasi-sdk) but a cached `.wasm` file already exists, warn instead of
crashing `pnpm install`
- Only hard-fail when no cached WASM exists at all

This prevents transient CDN outages from blocking deploys when the WASM
artifacts are already cached.

## Test plan
- [ ] CI passes on this PR (validates the postinstall script doesn't
crash)
- [ ] Verify deploy workflow can proceed when WASM cache hits
2026-04-13 11:43:07 -05:00
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
Kevin Turcios
ec39cd5190
perf: upgrade dependencies across common, cf-webapp, and cf-api (#2599)
## Summary
- **common**: Upgraded to Prisma 6.19.3, TypeScript 5.9.3, Prettier
3.8.2. Published as `@codeflash-ai/common@1.0.31` — fixes Prisma type
widening caused by cross-package version mismatch
- **cf-webapp**: 20+ dependency upgrades including posthog-js
(1.127→1.367), lucide-react (0.563→1.8), tailwind-merge (2→3), marked
(16→18), react-markdown (9→10), zod (3→4). Fixes lucide v1 icon renames
and react-markdown v10 API changes
- **cf-api**: 30+ dependency upgrades aligned with common. Prisma
6.19.3, Sentry 10.48, posthog-node 5.29, marked 18, resend 6.10

## Motivation
Testing hypothesis that outdated dependencies cause bundle bloat and
runtime regressions. posthog-js alone was 240 minor versions behind and
loads on every page. lucide-react v1 rewrote the icon system with better
tree-shaking. tailwind-merge v3 has a smaller/faster runtime used in
every `cn()` call.

## Root cause fix
The Prisma type widening errors (`string | Date | null` instead of
`string`) were caused by `@codeflash-ai/common` being published with
Prisma ^6.13 types while consumers installed a different version.
Aligning all packages to ^6.19.3 and republishing common fixed it
properly.

## Test plan
- [ ] cf-webapp builds and type-checks cleanly
- [ ] cf-api builds cleanly
- [ ] No runtime regressions in dashboard, observability pages
- [ ] Prisma types resolve correctly (no widening)
2026-04-10 15:49:09 -05:00
Kevin Turcios
f9d78e5cf2
fix: lazily instantiate Auth0Client to fix CI build failure (#2600)
## Summary
- Auth0Client was constructed at module import time, crashing during
`next build` static analysis of `/_not-found` when `AUTH0_DOMAIN` isn't
set in CI
- Wraps the client in a lazy Proxy that defers construction to first
method call
- Zero API change — all callers still do `auth0.getSession()`,
`auth0.handleAuth()`, etc.

## Context
This broke in #2598 when the layout restructure caused `/_not-found` to
evaluate the root layout's auth0 import during build. The `build` CI
check has been failing on all PRs since.

## Test plan
- [ ] `build` CI check passes (was failing on #2598, #2593, #2599)
- [ ] Auth flows still work at runtime (login, logout, callback)
2026-04-10 15:48:58 -05:00
Kevin Turcios
3b1398973e
perf: Sentry-driven optimizations across all services (#2593)
## Summary

Comprehensive performance and reliability fixes driven by Sentry trace
data and error monitoring across aiservice, cf-api, and cf-webapp.

### Error Reduction
- **UUID validation (1,459 errors/month)**: Add `normalize_trace_id()`
to handle EXP0/EXP1 experiment suffixes instead of crashing. Add
`validate_trace_id` checks to 4 endpoints that were missing them. Fix
bare `UUID()` call in `log_event.py` (960 errors/month). Return 400
instead of 500 for invalid trace IDs in `log_features`.
- **CodeValidationError (1,068 errors/month)**: Add `repair_preamble()`
to fix broken LLM-generated test preambles that were causing all tests
to be discarded. 9 new tests.

### Speed Improvements
- **create-pr (11.8s → ~6s)**: Parallelize auth lookups and
post-PR-creation work (DB updates + GitHub API calls) with
`Promise.all`.
- **apikeys LCP (5,084ms → ~2s)**: Replace 5 sequential client-side
server actions with a single server-side `getDashboardInitData()` that
runs queries in parallel. Context providers accept initial data props to
skip client fetches.
- **optimization-prs (7.2s → ~3s)**: Replace `LEFT JOIN COUNT` on huge
JSONB table with `EXISTS` semi-join. Add composite indexes on
`optimization_events` for org-scoped and user-scoped queries.

### Web Vitals
- **Dashboard CLS (2.114 → ~0)**: Add matching skeleton for
OptimizationPRsTable, add `min-h-[420px]` to prevent layout shift.
- **Onboarding LCP (11.9s → ~6s)**: Reduce intro animation from 2400ms
to 1200ms, add `optimizePackageImports` for 12 heavy packages.
- **Trace page CLS (0.463 → ~0)**: Add `flex-shrink-0` to Monaco diff
viewer headers.
- Lazy-load Intercom/Crisp scripts, swap font display, reduce font
weights.

### Files Changed (19)
**aiservice (8):** common_utils.py, optimization_review.py,
code_validator.py, log_event.py, log_features.py, repair.py, review.py,
test_validate_code.py
**cf-api (1):** create-pr.ts
**cf-webapp (9):** layout.tsx, init-data-action.ts,
PrivacyModeContext.tsx, ViewModeContext.tsx, sidebar.tsx,
conditional-layout.tsx, action.ts, OptimizationPRsTable.tsx,
OptimizationsTable.tsx
**common (1):** schema.prisma

## Test plan
- [ ] Run aiservice tests: `cd django/aiservice && uv run pytest
tests/testgen_postprocessing/test_validate_code.py -v`
- [ ] Run aiservice type check: `cd django/aiservice && uv run mypy .`
- [ ] Verify cf-webapp builds: `cd js/cf-webapp && npm run build`
- [ ] Verify cf-api builds: `cd js/cf-api && npm run build`
- [ ] Run Prisma migration for new composite indexes
- [ ] Verify dashboard loads without CLS regression
- [ ] Verify create-pr endpoint still works end-to-end
- [ ] Monitor Sentry for UUID and CodeValidationError reduction after
deploy

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-04-10 15:39:44 -05:00
Kevin Turcios
552647b2c3
perf: webapp CWV optimization — layout restructure + render-blocking fixes (#2598)
## Summary
- Remove 6 render-blocking font `@import` URLs from onboarding CSS,
replace with `next/font` CSS variables
- Delete dead `tailwind.css` (not imported anywhere)
- Scope Crisp chat widget to dashboard routes only (was loading on every
page)
- Add `preconnect`/`dns-prefetch` hints for Intercom
- Add `serverExternalPackages` for `@anthropic-ai/sdk` and `sharp`
- **Restructure layout hierarchy**: move `ViewModeProvider`,
`PrivacyModeProvider`, and sidebar shell out of root layout into
`(dashboard)` group — non-dashboard pages (auth, onboarding,
observability, trace) are now pure server-rendered
- Move `/dashboard` route into `(dashboard)` group, remove duplicate
onboarding guard
- Update semver-compatible dependencies (~30 patch/minor bumps)

## Test plan
- [ ] `npm run build` passes (32 routes, 0 errors)
- [ ] Dashboard pages show sidebar, breadcrumb, org switcher, privacy
toggle
- [ ] `/dashboard` still accessible and shows sidebar
- [ ] Auth/onboarding pages render without sidebar
- [ ] Observability pages render with ObservabilityNav (no sidebar)
- [ ] `/` redirects to `/apikeys`
- [ ] Fonts render correctly on onboarding pages
- [ ] Crisp chat loads on dashboard pages only
- [ ] Intercom loads on all pages
2026-04-10 08:40:59 -05:00
Kevin Turcios
0ebc109a88
fix: resolve npm audit vulnerabilities in cf-webapp (#2592)
## Summary
- Run `npm audit fix` to resolve 12 of 14 vulnerabilities
- Fixed: axios (critical), brace-expansion, defu, effect/prisma,
minimatch, picomatch, qs, rollup, vite, yaml
- Remaining 2 moderate (`dompurify` via `monaco-editor`) have no
upstream fix yet

## Test plan
- [ ] Verify cf-webapp builds successfully
- [ ] Verify no regressions in dev server
2026-04-10 04:25:01 -05:00
Kevin Turcios
60ba2d44ac
fix: upgrade Next.js to 16.2.3 and fix theme/roadmap issues (#2591)
## Summary
- Upgrade Next.js from 16.1.6 to 16.2.3
- Add `suppressHydrationWarning` to `<html>` tag to fix `next-themes`
hydration mismatch
- Remove unnecessary `isClient` guard in `ThemeProvider` that caused
script tag warning
- Redirect unauthenticated `/roadmap` visitors to `/login` instead of
`/`

## Test plan
- [ ] Verify `/roadmap` redirects to `/login` when not logged in
- [ ] Verify `/roadmap` loads correctly when logged in as team member
- [ ] Verify no hydration warnings in browser console
- [ ] Verify dark/light theme switching still works
2026-04-10 03:51:28 -05:00
Kevin Turcios
e8561b9485
feat: add internal team-only roadmap page (#2590)
## Summary

- Adds `/roadmap` page with visual flowchart showing codeflash-python
and codeflash-agent planned work
- Gated behind `isTeamMemberCheck` (same auth pattern as
`/observability`)
- Sidebar link visible only to team members
- Status tracking with distinct visual treatments: compact left-accent
for shipped, hero cards with glow for in-progress, dashed wireframe for
planned

## Test plan

- [ ] Visit `/roadmap` as a team member — page renders with status cards
- [ ] Visit `/roadmap` as a non-team member — redirects to `/`
- [ ] Sidebar shows roadmap link only for team members
- [ ] Build passes (`npm run build`)
- [ ] All tests pass (`npm test` — 39/39)
2026-04-09 15:54:43 -05:00
Hesham Mohamed
b43e9ba648
fix: remove console.log that leaks API key in token exchange endpoint (#2589)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 15:48:14 +02:00
Kevin Turcios
a2dae4b60c
ci: fix deploy path filter, Claude Code paths, disable PyPI (#2588)
## CI Waste Cleanup

### Changes

1. **Deploy AI Service path filter** — narrowed `.github/workflows/**`
to `.github/workflows/deploy_aiservice_to_azure.yml`
- Previously, editing *any* workflow file triggered an AI service deploy
- The other deploy workflows (CFAPI, CF-WEB-APP) are already scoped
correctly

2. **Claude Code paths-ignore** — added `paths-ignore` for
`.github/workflows/**`, `*.md`, `docs/**`
- Currently fires on every PR regardless of files changed (85% failure
rate)
- The `codeflash` repo's Claude Code workflow already has these filters

3. **Publish to PyPI** — disabled via API
   - Had `if: false` hardcoded with a TODO comment
   - Was creating a skipped run on every push to main (pure noise)

### Context

Part of the Codeflash org CI audit. See also:
- codeflash-ai/codeflash#2025 (E2E path filters)
- codeflash-ai/codeflash#2026 (claude-code-action pin)
2026-04-09 02:37:58 -05:00
Kevin Turcios
0bef49265a
ci: pin claude-code-action to v1.0.89 (fix Bedrock auth) (#2587)
## Summary
- Pin `anthropics/claude-code-action` from `@v1` to `@v1.0.89` in both
`claude.yml` and `duplicate-code-detector.yml`

## Why
v1.0.90 (released Apr 8) broke Bedrock OIDC auth. Every Claude Code and
Duplicate Code Detector run has been failing with:

```
403 Authorization header requires 'Credential' parameter.
Authorization header requires 'Signature' parameter.
```

**Upstream issue:** anthropics/claude-code-action#1196

v1.0.89 was the last working version (confirmed: all runs succeeded on
Apr 7, all failed starting Apr 8).

## Test plan
- [ ] Merge and verify Claude Code workflow passes on next PR
- [ ] Verify Duplicate Code Detector passes on next PR
- [ ] Unpin to `@v1` once anthropics/claude-code-action#1196 is resolved
2026-04-09 02:16:09 -05:00
Hesham Mohamed
c02a4e6b5d
fix: stop dashboard and review-optimizations infinite refetch loops (#2584)
Summary
                                                                  
- Replace server action calls with API Route Handlers in
OptimizationPRsTable and OptimizationsTable to break the Next.js RSC
refresh cycle that caused continuous endpoint polling
- Create /api/optimization-prs and /api/optimization-events route
handlers that read auth from session cookies
- Remove accountPayload prop threading from both table components and
their parent pages
- Add key-based remount on OptimizationsTable to ensure data refreshes
correctly on org switch
Root Cause
Next.js server actions always trigger an RSC page refresh (GET) after
completion. When a client component calls a server action inside a
useEffect, it creates an infinite loop: server action POST → RSC refresh
→ component
re-renders → effect fires again → repeat. This was happening in both
OptimizationPRsTable (dashboard) and OptimizationsTable
(review-optimizations).
Solution
   
Regular fetch() calls to Route Handlers do not trigger RSC refreshes,
breaking the loop entirely. Auth is handled server-side in the route
handlers by reading the session cookie — same mechanism as
getAccountContext().

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Codeflash Bot <bot@codeflash.ai>
Co-authored-by: Kevin Turcios <106575910+KRRT7@users.noreply.github.com>
2026-04-08 23:26:35 -05:00
Aseem Saxena
22317c04a4
Merge pull request #2586 from codeflash-ai/fix/tracer-webapp-after-optimziation
Fix: Trace page in web app
2026-04-08 16:25:25 -07:00
Codeflash Bot
7bdb95e000 fix trace page in web app 2026-04-09 01:21:50 +02:00
Hesham Mohamed
f4412246e5
FIx(auth): enhance OAuth handling and improve code structure (#2585)
---
  Summary

- Fixes OAuth authentication flow reliability by preventing duplicate
auth
checks caused by React Strict Mode / Suspense remounts using a useRef
guard
- Extracts useSearchParams() values into stable string primitives
outside the
effect, removing searchParams from the dependency array to avoid
unnecessary
  re-runs
- Adds /codeflash/auth/oauth to the proxy ignore paths so OAuth token
exchange
   requests are not intercepted by the auth middleware
  - Adds debug logging for the API key returned during token exchange
  - Adds codeflash configuration block to the root package.json

  Test plan

- Verify CLI OAuth login flow completes successfully end-to-end (auth
page →
  GitHub → redirect → token exchange)
- Confirm the auth page does not trigger duplicate API calls in React
Strict
  Mode (check network tab)
  - Verify VSCode extension OAuth login still works
- Confirm /codeflash/auth/oauth/token endpoint is reachable and not
blocked by
   proxy middleware

  ---
  Want me to push the branch and create the PR?

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 22:40:42 +02:00
Kevin Turcios
996c82ac4c
feat: add internal /report page for optimization results (#2576)
## Summary
- Adds `/report` page showing results of the 20-PR webapp optimization
sprint
- Team-member only access (guarded in `proxy.ts` + server component
`isTeamMember()` check)
- Full-width layout (no sidebar), matching `/roadmap` and
`/observability` patterns
- Dual-view toggle: Executive Summary / Engineering Details
- chart.js charts with datalabels matching the original Plotly Dash
report
- Full light/dark theme support via Tailwind `dark:` variants

## Files
- **New**: `src/app/report/page.tsx`,
`src/components/report/report-charts.tsx`,
`src/components/report/report-toggle.tsx`
- **Modified**: `proxy.ts` (added `/report` + `/roadmap` to team-member
guard), `conditional-layout.tsx` (hide sidebar for `/report`)
- **Dep**: `chartjs-plugin-datalabels` for bar/pie chart value labels

## Test plan
- [ ] Visit `/report` as a CF team member — page renders with all
sections
- [ ] Toggle between Executive Summary and Engineering Details
- [ ] Charts display with value labels and correct colors
- [ ] Visit `/report` as a non-team-member — redirected to `/`
- [ ] Light and dark mode both render correctly
2026-04-04 23:55:12 -05:00
Kevin Turcios
c8c4608d1d
fix: add chartjs-plugin-datalabels to dependencies (#2579)
## Summary
- Adds `chartjs-plugin-datalabels` to `package.json` — was installed
locally but missing, causing CI build failure for both `/report` and
`/membench` chart components

## Test plan
- [ ] CI build passes
- [ ] `/report` and `/membench` deploy successfully to staging
2026-04-04 23:46:38 -05:00
Kevin Turcios
475ecf37c8
feat: add /membench page for Unstructured memory benchmark (#2577)
## Summary
- Ports the Unstructured Core Product memory benchmark Dash app into
cf-webapp as `/membench`
- Green accent theme, exec/eng dual view, 4 charts (peak memory,
allocators, headroom, max alloc)
- Access restricted to Codeflash team + `@unstructured.io` emails via
`isMembenchAllowed()` domain check

## Changes
- `src/app/membench/page.tsx` — Server component with all benchmark data
hardcoded
- `src/components/membench/membench-charts.tsx` — 4 chart.js charts with
datalabels
- `src/components/membench/membench-toggle.tsx` — Green-accent exec/eng
view toggle
- `src/lib/team-members.ts` — Added `isMembenchAllowed()` (CF team OR
`@unstructured.io`)
- `src/app/utils/auth.ts` — Added `canAccessMembench()` server-side
helper
- `src/proxy.ts` — Added `/membench` route guard
- `src/components/conditional-layout.tsx` — Added `/membench` to
full-width layout

## Test plan
- [ ] `npm run build` passes
- [ ] `/membench` renders for CF team member
- [ ] `/membench` renders for `@unstructured.io` user
- [ ] Non-authorized user redirected to `/`
- [ ] Exec/eng toggle switches views
- [ ] Charts render with hover tooltips
- [ ] Light and dark mode both look correct
2026-04-04 23:33:00 -05:00
Kevin Turcios
c8a66b5ec6
fix: stop dashboard sidebar infinite refetch loop (#2564)
## Summary
- Fix infinite refetch loop in the dashboard sidebar that fires hundreds
of POST+GET requests per second
- The `subscriptionFetchRef` was reset in `finally()`, allowing
re-entrancy: fetch → `setSubscription` → re-render → ref is `false` →
fetch again → infinite loop
- Move the ref reset to the effect cleanup function so it only resets
when `mode` actually changes

## Note: Auth0 favicon 404
The Auth0 login page at `codeflash-ai.us.auth0.com` returns a 404 for
`/favicon.ico`. This is configured in **Auth0 Dashboard > Branding >
Universal Login**, not in application code. Upload the Codeflash favicon
there to resolve.

## Test plan
- [ ] Navigate to dashboard, open Network tab — confirm no repeated
POST/GET polling
- [ ] Switch between personal/org mode — confirm subscription data still
loads correctly
- [ ] Verify sidebar subscription usage display still renders
2026-04-04 12:46:56 -05:00
Kevin Turcios
f6a7d9b29d
chore: add cf-webapp quality gates CI workflow (#2563)
## Summary
- Adds GitHub Actions workflow that runs on PRs touching
`js/cf-webapp/**`
- Runs type-check (`tsc --noEmit`), tests (`vitest run`), and build
(`next build`)
- Posts a PR comment with results table and collapsible route size
details
- Fails the check if any gate fails

## Evidence
- Proof doc: `js/cf-webapp/proof/20-quality-gates.md`

## Test plan
- [ ] `bash js/cf-webapp/proof/reproducers/20-quality-gates.sh` — 10/10
checks pass
- [ ] Workflow triggers on a PR touching cf-webapp files
- [ ] PR comment appears with quality report
2026-04-04 11:43:02 -05:00
Kevin Turcios
0c37015650
chore: remove unused dependencies and replace react-papaparse with papaparse (#2562)
## Summary
- Removes `@azure/msal-node` (unused — Auth0 is the auth provider)
- Removes `github-markdown-css` (not imported anywhere)
- Replaces `react-papaparse` with `papaparse` (only core parser needed,
not React wrapper)
- Adds `@types/papaparse` for TypeScript types

## Evidence
- No imports of removed packages exist in source
- Proof doc: `js/cf-webapp/proof/18-remove-unused-deps.md`

## Test plan
- [ ] `bash js/cf-webapp/proof/reproducers/18-remove-unused-deps.sh` —
7/7 checks pass
- [ ] `npm run build` succeeds
- [ ] CSV parsing functionality still works
2026-04-04 11:42:18 -05:00
Kevin Turcios
87db8f6026
perf: parallelize LLM call detail and errors queries (#2561)
## Summary
- Runs `llm_calls.findUnique` and `optimization_errors.findMany` in
parallel via `Promise.all`
- Both queries use `params.id` directly — no data dependency between
them
- Page load time reduced from sum to max of both queries

## Evidence
- Proof doc: `js/cf-webapp/proof/17-parallel-llm-call-detail.md`

## Test plan
- [ ] `bash
js/cf-webapp/proof/reproducers/17-parallel-llm-call-detail.sh` — 5/5
checks pass
- [ ] LLM call detail page renders correctly with error list
2026-04-04 11:41:16 -05:00
Kevin Turcios
94b9de946e
perf: deduplicate trace page Prisma query with React cache() (#2560)
## Summary
- Wraps `optimization_features.findUnique` in `React.cache()` so
`generateMetadata()` and the page component share one DB hit
- Eliminates redundant query — before: 2 identical queries per page
load, after: 1
- Replaces inline type annotation with `Awaited<ReturnType<...>>` for
DRY types

## Evidence
- Proof doc: `js/cf-webapp/proof/16-react-cache-dedup.md`

## Test plan
- [ ] `bash js/cf-webapp/proof/reproducers/16-react-cache-dedup.sh` —
5/5 checks pass
- [ ] Trace detail page renders correctly with metadata title
2026-04-04 11:41:05 -05:00
Kevin Turcios
c7df7bf27c
perf: parallelize event + features queries in getOptimizationEventById (#2559)
## Summary
- Runs `optimization_events.findFirst` and
`optimization_features.findUnique` in parallel via `Promise.all`
- The features query only needs `trace_id` (a parameter), not the event
result, making the queries independent
- Wall-clock time goes from sum of both queries to max of either

## Evidence
- Proof doc: `js/cf-webapp/proof/15-parallel-optimization-event.md`

## Test plan
- [ ] `bash
js/cf-webapp/proof/reproducers/15-parallel-optimization-event.sh` — 6/6
checks pass
- [ ] Optimization review page loads correctly with review quality data
2026-04-04 11:40:10 -05:00
Kevin Turcios
dc684b9a28
perf: use PostHog singleton and replace shutdown() with flush() (#2558)
## Summary
- Converts `PostHogClient()` to singleton pattern — reuses one `PostHog`
instance instead of creating new ones per call
- Replaces `shutdown()` with `flush()` across 5 files (6 call sites) —
flush sends events without destroying the shared client

## Evidence
- Before: each call to `PostHogClient()` creates new HTTP connection +
event queue
- After: single instance reused across all server components/actions in
the same process
- Proof doc: `js/cf-webapp/proof/14-posthog-singleton.md`

## Test plan
- [ ] `bash js/cf-webapp/proof/reproducers/14-posthog-singleton.sh` —
9/9 checks pass
- [ ] PostHog events still appear in PostHog dashboard after deployment
2026-04-04 11:37:05 -05:00
Kevin Turcios
67ec032429
perf: dynamic-import LineProfilerView to defer prism-react-renderer (#2557)
## Summary
- Replaces static import of `LineProfilerView` with `next/dynamic` +
`ssr: false`
- Defers loading of `prism-react-renderer` (~100KB+) until user
navigates to profiler tab
- Adds `<Skeleton>` loading fallback for smooth UX

## Evidence
- Proof doc: `js/cf-webapp/proof/13-dynamic-import-line-profiler.md`

## Test plan
- [ ] `bash
js/cf-webapp/proof/reproducers/13-dynamic-import-line-profiler.sh` — 7/7
checks pass
- [ ] `npm run build` succeeds
- [ ] Profiler page loads and renders LineProfilerView correctly
2026-04-04 11:36:59 -05:00
Kevin Turcios
fbedf0c1ee
perf: migrate framer-motion to motion/react for smaller bundle (#2556)
## Summary
- Replaces `framer-motion` with `motion` (the official tree-shakeable
successor)
- Updates import in onboarding page from `"framer-motion"` to
`"motion/react"`
- Enables better tree-shaking: only `AnimatePresence` + `motion`
component are imported

## Evidence
- `motion` uses ESM-first exports with `sideEffects: false`
- Same API, officially recommended migration path
- Proof doc: `js/cf-webapp/proof/12-framer-motion-migration.md`

## Test plan
- [ ] `bash
js/cf-webapp/proof/reproducers/12-framer-motion-migration.sh` — 6/6
checks pass
- [ ] `npm run build` in cf-webapp succeeds
- [ ] Onboarding page animations work correctly
2026-04-04 11:36:54 -05:00
Kevin Turcios
eed0646f32
fix: use @sentry/nextjs instead of @sentry/node in repository action (#2555)
## Summary

Replace `@sentry/node` import with `@sentry/nextjs` in the repository
action. `@sentry/nextjs` already re-exports all server-side APIs, so
importing `@sentry/node` separately pulls in a duplicate SDK.

## How to Verify

```bash
cd js/cf-webapp
bash proof/reproducers/11-sentry-nextjs-consistency.sh
```

3 checks: no @sentry/node in app/, repository action uses
@sentry/nextjs, all app/ Sentry imports consistent.
2026-04-04 11:36:48 -05:00
Kevin Turcios
6ebff6f079
perf: lazy-load Sentry Replay integration to reduce initial bundle ~600KB (#2554)
## Summary

- Move `replayIntegration` from eager initialization to
`lazyLoadIntegration()`
- Removes ~300KB per copy (two copies were shipped) from the critical
path
- Replay still activates after page is interactive via
`Sentry.addIntegration`

## How to Verify

```bash
cd js/cf-webapp
bash proof/reproducers/10-lazy-sentry-replay.sh
```

6 checks: lazyLoadIntegration used, empty init integrations,
addIntegration for deferred loading, maskAllText/blockAllMedia
preserved.

## Test Plan

- [ ] Run reproducer (6/6 pass)
- [ ] Verify Sentry Replay still works after page load
2026-04-04 11:36:41 -05:00
Kevin Turcios
278aab2b11
test: add test coverage for server actions and withTiming (#2553)
## Summary

- Add 90 unit tests across 4 test files covering server action timing,
members, repository, and review-optimizations
- Add Vitest configuration with `@/` path alias matching Next.js
tsconfig
- Add global mock setup for Prisma, Sentry (nextjs + node), and
analytics

## Test Files

| File | Tests |
|------|-------|
| `server-action-timing.test.ts` | 24 (timing, slow detection, error
handling, Sentry spans) |
| `members/action.test.ts` | 14 (access control, member mapping, error
handling) |
| `repositories/action.test.ts` | 20 (parallel fetch, auth, is_active,
analytics) |
| `review-optimizations/action.test.ts` | 32 (both code paths, N+1 fix,
raw SQL, pagination, search, filter) |

## How to Verify

```bash
cd js/cf-webapp
bash proof/reproducers/09-test-coverage.sh
```

## Test Plan

- [ ] Run reproducer (11/11 pass)
- [ ] Run `npm test` to execute all tests
2026-04-04 11:35:19 -05:00
Kevin Turcios
566424e97f
feat: add server action timing and expand PostHog analytics (#2552)
## Summary

- Add `withTiming()` wrapper for server actions with Sentry span
reporting and slow action warnings (>1s)
- Add centralized `captureEvent()` helper for PostHog tracking
- Add 5 new PostHog tracking events: optimization_reviewed,
repository_connected, api_key_created, member_invited,
billing_page_viewed
- Instrument 4 server actions with `withTiming()`:
getOrganizationMembers, getRepositoryById,
getRepositoriesWithStagingEvents, getAllOptimizationEvents

## Proof of Correctness

See
[`js/cf-webapp/proof/08-server-action-timing.md`](js/cf-webapp/proof/08-server-action-timing.md)

## How to Verify

```bash
cd js/cf-webapp
bash proof/reproducers/08-server-action-timing.sh
```

21 checks verify: withTiming utility, 4 instrumented actions,
captureEvent helper, 5 tracking functions, and all tracking calls wired
into action files.

## Test Plan

- [ ] Run reproducer: `bash
proof/reproducers/08-server-action-timing.sh` (21/21 pass)
- [ ] Verify server actions still work correctly
- [ ] Check Sentry for `server.action` spans after deployment
2026-04-04 11:34:53 -05:00
Kevin Turcios
e0d76d4338
feat: add observability stack (OTel, Sentry tuning, Prisma logging, bundle-analyzer) (#2547)
## Summary

- Add OpenTelemetry distributed tracing with Sentry bridge
(`instrumentation.ts`) — dynamic imports so OTel is only loaded when
active
- Reduce Sentry `tracesSampleRate` from 100% to 10% in production
(server + client), cutting event volume ~90%
- Add `skipOpenTelemetrySetup` to prevent duplicate OTel SDK
initialization
- Add `browserTracingIntegration` with long animation frame detection
for Web Vitals
- Add Prisma slow query logging (>500ms) and error forwarding to Sentry
- Add `@next/bundle-analyzer` for on-demand CI bundle tracking
(`ANALYZE=true npm run build`)
- Fix Edge-incompatible OTel exports (`SentryContextManager`,
`validateOpenTelemetrySetup`)

## Proof of Correctness

See
[`js/cf-webapp/proof/07-observability-stack.md`](js/cf-webapp/proof/07-observability-stack.md)
for detailed analysis.

## How to Verify

```bash
cd js/cf-webapp
bash proof/reproducers/07-observability-stack.sh
```

The reproducer verifies (24 checks):
1. OTel SDK configured with Sentry bridge (NodeSDK, SentrySpanProcessor,
SentryPropagator, PrismaInstrumentation)
2. Dynamic imports (4 packages only loaded when tracing active)
3. Noisy instrumentations disabled (fs, dns, net)
4. Sentry 10% production sampling (server + client)
5. `skipOpenTelemetrySetup: true` prevents duplicate OTel
6. Prisma slow query logging + Sentry error forwarding
7. `@next/bundle-analyzer` wired into next.config.mjs
8. All 5 required packages in package.json
9. `browserTracingIntegration` with long animation frame detection

## New Dependencies

| Package | Purpose |
|---------|---------|
| `@opentelemetry/sdk-node` | OTel Node.js SDK |
| `@opentelemetry/auto-instrumentations-node` | Auto-instrumentation for
HTTP, Express, etc. |
| `@prisma/instrumentation` | Prisma query spans |
| `@sentry/opentelemetry` | OTel → Sentry bridge |
| `@next/bundle-analyzer` (dev) | Interactive bundle treemap |

## Test Plan

- [ ] Run reproducer: `bash proof/reproducers/07-observability-stack.sh`
(24/24 pass)
- [ ] Verify `npm run build` succeeds
- [ ] Verify `npm run analyze` generates bundle treemap
- [ ] Confirm no Edge runtime build errors
(SentryContextManager/validateOpenTelemetrySetup removed)
2026-04-04 11:27:10 -05:00