Files
eventify_command_center/prisma/schema.prisma

218 lines
5.1 KiB
Plaintext
Raw Normal View History

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// ===== ENUMS =====
enum CampaignStatus {
DRAFT
IN_REVIEW
ACTIVE
PAUSED
ENDED
REJECTED
}
enum BillingModel {
FIXED
CPM
CPC
}
enum CampaignObjective {
AWARENESS
SALES
}
enum SurfaceKey {
HOME_FEATURED_CAROUSEL
HOME_TOP_EVENTS
CATEGORY_FEATURED
CITY_TRENDING
SEARCH_BOOSTED
}
enum TrackingEventType {
IMPRESSION
CLICK
}
// ===== MODELS =====
model Campaign {
id String @id @default(uuid())
partnerId String
name String
objective CampaignObjective
status CampaignStatus @default(DRAFT)
startAt DateTime
endAt DateTime
billingModel BillingModel
totalBudget Decimal @db.Decimal(10, 2)
dailyCap Decimal? @db.Decimal(10, 2)
spent Decimal @default(0) @db.Decimal(10, 2)
// Targeting (stored as JSON)
targeting Json // { cityIds: [], categoryIds: [], countryCodes: [] }
frequencyCap Int @default(0) // 0 = unlimited
// Relations
placements SponsoredPlacement[]
events CampaignEvent[] // Many-to-many via join table or array of IDs
approvedBy String?
rejectedReason String?
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
auditLogs CampaignAuditLog[]
}
model SponsoredPlacement {
id String @id @default(uuid())
campaignId String
campaign Campaign @relation(fields: [campaignId], references: [id])
eventId String
surfaceKey SurfaceKey
priority String @default("SPONSORED")
bid Decimal @db.Decimal(10, 2)
status String @default("ACTIVE") // ACTIVE, PAUSED
rank Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([campaignId, eventId, surfaceKey])
}
model CampaignEvent {
id String @id @default(uuid())
campaignId String
campaign Campaign @relation(fields: [campaignId], references: [id])
eventId String // Reference to Event table (not shown here)
@@unique([campaignId, eventId])
}
model AdTrackingEvent {
id String @id @default(uuid())
type TrackingEventType
placementId String
campaignId String
surfaceKey SurfaceKey
eventId String
userId String?
anonId String
sessionId String
timestamp DateTime @default(now())
device String?
cityId String?
@@index([campaignId, type, timestamp])
@@index([anonId, timestamp]) // For frequency capping queries
}
model PlacementDailyStats {
id String @id @default(uuid())
campaignId String
placementId String
surfaceKey SurfaceKey
date DateTime @db.Date
impressions Int @default(0)
clicks Int @default(0)
spend Decimal @default(0) @db.Decimal(10, 2)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([campaignId, placementId, surfaceKey, date])
}
model CampaignAuditLog {
id String @id @default(uuid())
campaignId String
campaign Campaign @relation(fields: [campaignId], references: [id])
actorId String
action String // CREATED, UPDATED, SUBMITTED, APPROVED, REJECTED, PAUSED, RESUMED
details Json? // Changed fields, reason, etc.
createdAt DateTime @default(now())
}
// ===== PARTNER GOVERNANCE =====
enum KYCStatus {
PENDING
VERIFIED
REJECTED
}
enum KYCDocStatus {
PENDING
APPROVED
REJECTED
}
enum PartnerEventStatus {
PENDING_REVIEW
LIVE
DRAFT
COMPLETED
CANCELLED
REJECTED
}
model PartnerProfile {
id String @id @default(cuid())
userId String @unique // FK to User table
verification KYCStatus @default(PENDING)
riskScore Int @default(0)
documents PartnerDoc[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model PartnerDoc {
id String @id @default(cuid())
partnerId String
partner PartnerProfile @relation(fields: [partnerId], references: [id])
type String // "PAN", "GST", "AADHAAR", "CANCELLED_CHEQUE", "BUSINESS_REG"
name String
url String
status KYCDocStatus @default(PENDING)
mandatory Boolean @default(true)
adminNote String?
reviewedBy String?
reviewedAt DateTime?
uploadedBy String
uploadedAt DateTime @default(now())
@@index([partnerId, status])
}