codeflash-internal/js/common/prisma/schema.prisma
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

374 lines
13 KiB
Text

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model cf_api_keys {
id Int @id @default(autoincrement())
key String @unique @db.VarChar(255)
suffix String @db.VarChar(4)
name String @db.VarChar(255)
created_at DateTime @default(now()) @db.Timestamptz(6)
last_used DateTime? @db.Timestamptz(6)
user_id String?
organization_id String?
tier String?
user users? @relation(fields: [user_id], references: [user_id])
organization organizations? @relation(fields: [organization_id], references: [id], onDelete: SetNull)
optimization_events optimization_events[]
@@index([user_id])
@@index([organization_id])
}
model users {
user_id String @id
github_username String @unique
email String?
name String?
onboarding_completed Boolean @default(false)
privacy_mode Boolean @default(false)
created_at DateTime @default(now()) @db.Timestamptz(6)
referral_source String? @db.VarChar(255)
additional_comments String? @db.Text
api_keys cf_api_keys[]
subscriptions subscriptions?
optimization_events optimization_events[]
comments comments[]
repository_members repository_members[]
organization_members organization_members[]
}
model optimization_features {
trace_id String @id @db.Char(36)
original_code String?
optimizations_raw Json?
optimizations_post Json?
explanations_post Json?
speedup_ratio Json?
optimized_line_profiler_results Json? @default("{}")
original_runtime Float?
optimized_runtime Json?
is_correct Json?
generated_test String[]
test_framework String?
created_at DateTime? @default(now()) @db.Timestamptz(6)
aiservice_commit_id String?
metadata Json?
explanations_raw Json?
user_id String?
experiment_metadata Json?
instrumented_generated_test String[]
instrumented_perf_test String[]
pull_request Json?
dependency_code String?
line_profiler_results String?
final_explanation String?
approval_required Boolean @default(false)
approval_status String? // "pending", "approved", "rejected"
approval_user String?
approval_timestamp DateTime?
slack_message_ts String?
organization String?
repository String?
ranking Json?
optimizations_origin Json?
review_quality String? // Hight, Med, low
review_explanation String?
calling_fn_details String?
@@index([approval_status])
@@index([approval_required])
}
model subscriptions {
id String @id @default(uuid())
user_id String @unique
stripe_customer_id String? @unique
stripe_subscription_id String?
plan_type String
optimizations_used Int @default(0)
optimizations_limit Int
total_lifetime_optimizations Int @default(0)
subscription_status String
current_period_start DateTime?
current_period_end DateTime?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
cancel_at_period_end Boolean @default(false)
cancellation_request_date DateTime?
user users @relation(fields: [user_id], references: [user_id])
}
model django_content_type {
id Int @id @default(autoincrement())
app_label String @db.VarChar(100)
model String @db.VarChar(100)
@@unique([app_label, model], map: "django_content_type_app_label_model_76bd3d3b_uniq")
}
model django_migrations {
id BigInt @id @default(autoincrement())
app String @db.VarChar(255)
name String @db.VarChar(255)
applied DateTime @db.Timestamptz(6)
}
model pr_code_context_hash_cache {
id Int @id @default(autoincrement())
repo String
owner String
pr_number Int
context_hash String
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@unique([repo, owner, pr_number, context_hash], name: "repo_owner_pr_number_context_hash")
}
model cf_app_installations {
id String @id @default(uuid())
installation_id Int @unique
account_id Int
account_login String
account_type String // 'User' or 'Organization'
created_at DateTime @default(now()) @db.Timestamptz(6)
updated_at DateTime @updatedAt
is_active Boolean @default(true)
repositories repositories[]
}
model repositories {
id String @id @default(uuid())
github_repo_id String @unique
installation_id Int
name String
full_name String @unique
is_private Boolean
is_active Boolean @default(true)
has_github_action Boolean @default(false)
created_at DateTime @default(now()) @db.Timestamptz(6)
last_optimized DateTime?
organization_id String?
optimizations_limit Int? // Custom limit for this repository
optimizations_used Int @default(0) // Track usage
added_by String?
installation_info cf_app_installations @relation(fields: [installation_id], references: [installation_id], onDelete: Cascade)
organization organizations? @relation(fields: [organization_id], references: [id], onDelete: SetNull)
optimization_events optimization_events[]
repository_members repository_members[]
@@index([installation_id])
@@index([organization_id])
}
model repository_members {
id String @id @default(uuid())
repository_id String
user_id String
role String // 'owner', 'admin', 'member'
added_at DateTime @default(now()) @db.Timestamptz(6)
added_by String?
repository repositories @relation(fields: [repository_id], references: [id], onDelete: Cascade)
user users @relation(fields: [user_id], references: [user_id], onDelete: Cascade)
@@unique([repository_id, user_id])
@@index([user_id])
@@index([repository_id])
}
model optimization_events {
id String @id @default(uuid())
event_type String // 'pr_created', 'pr_merged', 'pr_closed', 'no-pr'
user_id String? // Can be null for system events
repository_id String?
baseBranch String?
trace_id String @unique
pr_id String? @unique
pr_url String?
api_key_id Int?
metadata Json?
is_optimization_found Boolean?
is_staging Boolean? @default(false)
staging_storage_type String? // "plain_text", "git_branch"
status String? // "approved", "rejected"
current_username String? // for the current user who did this event, we create this to know the active user in github action
function_name String?
file_path String?
speedup_x Float?
speedup_pct Float?
llm_cost Float?
feedback Json?
created_at DateTime @default(now()) @db.Timestamptz(6)
// Relations
user users? @relation(fields: [user_id], references: [user_id], onDelete: SetNull)
repository repositories? @relation(fields: [repository_id], references: [id], onDelete: SetNull)
api_key cf_api_keys? @relation(fields: [api_key_id], references: [id], onDelete: SetNull)
comments comments[]
@@index([event_type, created_at])
@@index([repository_id, event_type])
@@index([user_id, event_type])
@@index([trace_id])
@@index([current_username])
@@index([current_username, event_type])
@@index([repository_id, user_id])
@@index([api_key_id])
@@index([is_staging])
// Covers the optimization-prs query: filter by repo + optimization found + event type, sort by created_at DESC
@@index([repository_id, is_optimization_found, event_type, created_at(sort: Desc)])
@@index([is_optimization_found, event_type, created_at(sort: Desc)])
}
model comments {
id String @id @default(uuid())
optimization_event_id String
content String @db.Text
created_at DateTime @default(now()) @db.Timestamptz(6)
author_user_id String?
optimization_event optimization_events @relation(fields: [optimization_event_id], references: [id], onDelete: Cascade)
author users? @relation(fields: [author_user_id], references: [user_id], onDelete: SetNull)
@@index([optimization_event_id])
@@index([author_user_id])
}
model organizations {
id String @id @default(uuid())
name String @unique
github_org_id String? @unique
description String?
website String?
created_at DateTime @default(now()) @db.Timestamptz(6)
updated_at DateTime @updatedAt
auto_add_github_members Boolean @default(true)
added_by String?
privacy_mode Boolean @default(false)
subscription Boolean @default(false)
repositories repositories[]
organization_members organization_members[]
api_keys cf_api_keys[]
@@index([github_org_id])
@@index([name])
}
model organization_members {
id String @id @default(uuid())
organization_id String
user_id String
role String
added_at DateTime @default(now()) @db.Timestamptz(6)
added_by String?
organization organizations @relation(fields: [organization_id], references: [id], onDelete: Cascade)
user users @relation(fields: [user_id], references: [user_id], onDelete: Cascade)
@@unique([organization_id, user_id])
@@index([user_id])
@@index([organization_id])
}
// ==================== Observability Tables ====================
model llm_calls {
id String @id @default(uuid()) @db.Uuid
trace_id String @db.Char(36)
call_type String @db.VarChar(50) // 'optimization', 'test_generation', 'ranking', 'refinement'
model_name String @db.VarChar(100) // 'gpt-4', 'gpt-3.5-turbo', etc.
// Prompt capture (full content for prompt engineering analysis)
system_prompt String @db.Text
user_prompt String @db.Text
messages Json // Full messages array sent to LLM
// Request configuration
temperature Float?
n_candidates Int? // Number of completions requested
max_tokens Int?
// Response capture
raw_response String? @db.Text // Full LLM response before parsing
parsed_response Json? // Structured parsed response
// Token usage and cost
prompt_tokens Int?
completion_tokens Int?
total_tokens Int?
llm_cost Float?
// Timing
latency_ms Int?
// Status and errors
status String @db.VarChar(20) // 'success', 'failed', 'partial_success'
retry_count Int @default(0)
error_type String? @db.VarChar(50)
error_message String? @db.Text
// Parsing results
parsing_status String? @db.VarChar(20) // 'success', 'failed', 'partial'
candidates_generated Int? @default(0)
candidates_valid Int? @default(0) // Passed syntax validation
parsing_errors Json? // Details of parsing failures
// Context
user_id String?
python_version String? @db.VarChar(20)
is_async Boolean @default(false)
context Json? // Additional metadata (optimization_id, speedup, etc.)
created_at DateTime @default(now()) @db.Timestamptz(6)
// Relations
optimization_errors optimization_errors[]
@@index([trace_id])
@@index([call_type])
@@index([model_name])
@@index([status])
@@index([created_at(sort: Desc)])
@@index([call_type, status])
@@index([parsing_status])
}
model optimization_errors {
id String @id @default(uuid())
trace_id String @db.Char(36)
llm_call_id String? @db.Uuid
// Error classification
error_type String @db.VarChar(50) // 'validation', 'llm_api', 'llm_parsing', 'test_failure', 'compilation'
error_category String @db.VarChar(50) // 'user_error', 'system_error', 'llm_error', 'infrastructure'
severity String @db.VarChar(20) // 'critical', 'error', 'warning', 'info'
// Error details
error_message String @db.Text
error_code String? @db.VarChar(50)
stack_trace String? @db.Text
context Json? // Additional error context including test failure details
created_at DateTime @default(now()) @db.Timestamptz(6)
// Relations
llm_call llm_calls? @relation(fields: [llm_call_id], references: [id], onDelete: SetNull)
@@index([trace_id])
@@index([error_type])
@@index([error_category])
@@index([severity])
@@index([llm_call_id])
}