Files
ClaudeMarketing/prisma/schema.prisma
T
Trey t 80a1ffbe4d feat: add multi-app support with app switcher, per-app branding, and filtered queries
Apps share the same backend, API keys, and publishing flow but each gets its own
branding (name, colors, icon, app URL), knowledge files (brand identity, product
info, platform guidelines), and campaigns. The pipeline dynamically writes
_knowledge/ files and copies app assets before each run.

- Add App model with slug, colors, appUrl, and knowledge markdown fields
- Add appId FK to Campaign, seed honeyDue as first app with existing knowledge
- App switcher dropdown in sidebar with icon previews
- Filter campaigns, stats, and assets by active app (cookie-based)
- De-hardcode lib/claude.ts: AppConfig interface, templated prompts, dynamic
  _knowledge/ and Remotion asset copying
- App management pages (list, create, edit) with icon upload and color pickers
- Asset library sort options (newest, oldest, name, platform, type)
- Asset cards show creation date
- Remotion HoneyDueAd accepts colors/appName props

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 22:21:45 -05:00

112 lines
3.4 KiB
Plaintext

generator client {
provider = "prisma-client"
output = "../lib/generated/prisma"
}
datasource db {
provider = "sqlite"
}
model User {
id String @id @default(cuid())
email String @unique
password String
name String?
createdAt DateTime @default(now())
}
model App {
id String @id @default(cuid())
name String
slug String @unique
description String?
primaryColor String @default("#0079FF")
accentColor String @default("#FF9400")
darkBg String @default("#1a1a2e")
appUrl String?
brandIdentity String?
productInfo String?
platformGuidelines String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
campaigns Campaign[]
}
model Campaign {
id String @id @default(cuid())
name String
status String @default("draft") // draft, running, review, approved, published
prompt String?
platforms String // JSON array: ["instagram","tiktok","nextdoor"]
config String? // JSON: full campaign config from form
outputPath String?
appId String?
app App? @relation(fields: [appId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
agentRuns AgentRun[]
assets Asset[]
claudeSessions ClaudeSession[]
}
model AgentRun {
id String @id @default(cuid())
campaignId String
campaign Campaign @relation(fields: [campaignId], references: [id])
agentName String
status String @default("pending") // pending, running, completed, failed
startedAt DateTime?
completedAt DateTime?
durationMs Int?
outputSummary String?
outputPath String?
tokenUsage Int?
error String?
assets Asset[]
createdAt DateTime @default(now())
}
model Asset {
id String @id @default(cuid())
campaignId String
campaign Campaign @relation(fields: [campaignId], references: [id])
agentRunId String?
agentRun AgentRun? @relation(fields: [agentRunId], references: [id])
type String // image, video, copy, research, script
platform String? // instagram, tiktok, nextdoor, all
format String? // png, mp4, json, txt, html, md
filePath String
fileName String
dimensions String? // 1080x1080, 1080x1920, etc.
metadata String? // JSON: caption, hashtags, hook text, scene plan
status String @default("draft") // draft, approved, rejected, published
publishedTo String? // JSON array of platforms published to
postizPostId String?
postizMediaId String?
createdAt DateTime @default(now())
}
model ClaudeSession {
id String @id @default(cuid())
campaignId String
campaign Campaign @relation(fields: [campaignId], references: [id])
sessionId String?
messages String? // JSON array of conversation history
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model TrendReport {
id String @id @default(cuid())
name String
filePath String
summary String?
createdAt DateTime @default(now())
}
model Setting {
key String @id
value String
updatedAt DateTime @updatedAt
}