ShieldAI waitlist landing page and analytics infrastructure FRE-5274
Build waitlist landing page with Solid.js (hero, features, tier comparison, waitlist signup form, blog preview, footer). Create waitlist signup and blog API endpoints in Fastify. Add WaitlistEntry and BlogPost models to Prisma schema. Create analytics hooks for GA4 and Mixpanel tracking. Fix pre-existing Prisma schema issue (AnalysisJob relation missing User field). - Landing page: responsive Solid.js app with hero, 6 feature cards, 3-tier pricing comparison table, blog preview, and full waitlist signup form with interest tier selection - API: POST /api/waitlist/signup, GET /api/waitlist/count, GET /api/blog, GET /api/blog/:slug, CRUD /api/admin/blog - DB models: WaitlistEntry (with UTM params, conversion tracking, source), BlogPost (with tags, view count, publish scheduling) - Analytics: useAnalytics hook with initAnalytics(), trackEvent(), trackWaitlistSignup(), trackPageView() — GA4 and Mixpanel dual-tracking - Blog: listing, detail, and admin CRUD routes; seed.ts with 3 starter articles - Fix: AnalysisJob.analysisJobId missing @unique constraint, missing analysisJobs[] on User model Delegated to CMO: FRE-5280 (GA4 config), FRE-5281 (Mixpanel config), FRE-5282 (email marketing platform) Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -36,6 +36,7 @@ model User {
|
||||
normalizedAlerts NormalizedAlert[]
|
||||
correlationGroups CorrelationGroup[]
|
||||
securityReports SecurityReport[]
|
||||
analysisJobs AnalysisJob[]
|
||||
|
||||
// Audit
|
||||
createdAt DateTime @default(now())
|
||||
@@ -376,7 +377,7 @@ model AnalysisJob {
|
||||
|
||||
model AnalysisResult {
|
||||
id String @id @default(uuid())
|
||||
analysisJobId String
|
||||
analysisJobId String @unique
|
||||
syntheticScore Float
|
||||
verdict DetectionVerdict
|
||||
confidence Float
|
||||
@@ -626,3 +627,52 @@ model SecurityReport {
|
||||
@@index([periodStart, periodEnd])
|
||||
@@index([createdAt])
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Waitlist & Marketing Models
|
||||
// ============================================
|
||||
|
||||
model WaitlistEntry {
|
||||
id String @id @default(uuid())
|
||||
email String
|
||||
name String?
|
||||
source String? // landing_page, blog, referral, social, paid_search
|
||||
tier SubscriptionTier? // interest level
|
||||
utmSource String?
|
||||
utmMedium String?
|
||||
utmCampaign String?
|
||||
metadata Json? // Browser, device, location, etc.
|
||||
|
||||
// Conversion tracking
|
||||
convertedAt DateTime?
|
||||
convertedToUserId String?
|
||||
convertedToSubscriptionId String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([email])
|
||||
@@index([source])
|
||||
@@index([createdAt])
|
||||
}
|
||||
|
||||
model BlogPost {
|
||||
id String @id @default(uuid())
|
||||
slug String @unique
|
||||
title String
|
||||
excerpt String?
|
||||
content String
|
||||
authorName String?
|
||||
coverImageUrl String?
|
||||
tags String[] // Array of tag strings
|
||||
published Boolean @default(false)
|
||||
publishedAt DateTime?
|
||||
viewCount Int @default(0)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([slug])
|
||||
@@index([published, publishedAt])
|
||||
@@index([tags])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user