Files
eventify_command_center/prisma/schema.prisma
2026-02-10 15:44:35 +05:30

161 lines
3.9 KiB
Plaintext

// 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())
}