Add Web Vitals performance tracking (LCP, INP, CLS, FCP, TTFB)

End-to-end performance metrics tracking: dedicated database table with
percentile aggregation, tracker collection behind data-perf attribute,
/api/send handling, report API endpoints, and Performance dashboard page
with threshold-based metric cards, time-series chart, and per-page breakdown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Mike Cao 2026-02-08 19:25:20 -08:00
parent 8cd3c03702
commit ce9e2416fb
24 changed files with 1028 additions and 8 deletions

View file

@ -47,6 +47,7 @@ model Session {
websiteEvents WebsiteEvent[]
sessionData SessionData[]
performance Performance[]
revenue Revenue[]
@@index([createdAt])
@ -78,11 +79,12 @@ model Website {
user User? @relation("user", fields: [userId], references: [id])
createUser User? @relation("createUser", fields: [createdBy], references: [id])
team Team? @relation(fields: [teamId], references: [id])
eventData EventData[]
reports Report[]
revenue Revenue[]
segments Segment[]
sessionData SessionData[]
eventData EventData[]
performance Performance[]
reports Report[]
revenue Revenue[]
segments Segment[]
sessionData SessionData[]
@@index([userId])
@@index([teamId])
@ -338,6 +340,29 @@ model Board {
@@map("board")
}
model Performance {
id String @id() @map("performance_id") @db.Uuid
websiteId String @map("website_id") @db.Uuid
sessionId String @map("session_id") @db.Uuid
visitId String @map("visit_id") @db.Uuid
urlPath String @map("url_path") @db.VarChar(500)
lcp Decimal? @db.Decimal(10, 1)
inp Decimal? @db.Decimal(10, 1)
cls Decimal? @db.Decimal(10, 4)
fcp Decimal? @db.Decimal(10, 1)
ttfb Decimal? @db.Decimal(10, 1)
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
website Website @relation(fields: [websiteId], references: [id])
session Session @relation(fields: [sessionId], references: [id])
@@index([websiteId])
@@index([sessionId])
@@index([websiteId, createdAt])
@@index([websiteId, urlPath, createdAt])
@@map("performance")
}
model Share {
id String @id() @map("share_id") @db.Uuid
entityId String @map("entity_id") @db.Uuid