feat: add CoopCredits Solana media rewards ecosystem
Add complete token system with Plex/Tautulli/Overseer integration: - Anchor program for SPL token mint/burn/transfer - Express backend with OAuth, webhooks, Solana integration - Next.js frontend with dashboard, admin panel, wallet management - Docker deployment for 172.20.1.0/24 infrastructure - Production configs with SSL, Nginx, health monitoring Tautulli webhooks auto-mint on watch events. Overseer integration burns for content requests.
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(uuid())
|
||||
plexId String @unique @map("plex_id")
|
||||
plexUsername String @map("plex_username")
|
||||
email String?
|
||||
isAdmin Boolean @default(false) @map("is_admin")
|
||||
isActive Boolean @default(true) @map("is_active")
|
||||
|
||||
// Solana wallet
|
||||
walletAddress String? @unique @map("wallet_address")
|
||||
encryptedPrivateKey String? @map("encrypted_private_key")
|
||||
|
||||
// Stats
|
||||
totalEarned Int @default(0) @map("total_earned")
|
||||
totalSpent Int @default(0) @map("total_spent")
|
||||
watchTimeMinutes Int @default(0) @map("watch_time_minutes")
|
||||
|
||||
// Relations
|
||||
transactions Transaction[]
|
||||
watchEvents WatchEvent[]
|
||||
contentRequests ContentRequest[]
|
||||
sessions Session[]
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@index([plexId])
|
||||
@@index([walletAddress])
|
||||
@@map("users")
|
||||
}
|
||||
|
||||
model Transaction {
|
||||
id String @id @default(uuid())
|
||||
userId String @map("user_id")
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
|
||||
type TransactionType
|
||||
amount Int
|
||||
|
||||
// For earned transactions
|
||||
watchEventId String? @map("watch_event_id")
|
||||
watchEvent WatchEvent? @relation(fields: [watchEventId], references: [id])
|
||||
|
||||
// For spent transactions
|
||||
requestId String? @map("request_id")
|
||||
request ContentRequest? @relation(fields: [requestId], references: [id])
|
||||
|
||||
// Solana transaction reference
|
||||
solanaSignature String? @map("solana_signature")
|
||||
|
||||
// Metadata
|
||||
description String?
|
||||
contentTitle String? @map("content_title")
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
@@index([userId])
|
||||
@@index([type])
|
||||
@@index([createdAt])
|
||||
@@map("transactions")
|
||||
}
|
||||
|
||||
model WatchEvent {
|
||||
id String @id @default(uuid())
|
||||
userId String @map("user_id")
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
|
||||
// Tautulli data
|
||||
sessionId String @map("session_id")
|
||||
ratingKey String @map("rating_key")
|
||||
contentType String @map("content_type") // movie, episode
|
||||
title String
|
||||
grandparentTitle String? @map("grandparent_title") // Show name for episodes
|
||||
|
||||
// Watch stats
|
||||
duration Int // seconds watched
|
||||
percentComplete Int @map("percent_complete")
|
||||
|
||||
// Credits earned
|
||||
creditsEarned Int @map("credits_earned")
|
||||
isProcessed Boolean @default(false) @map("is_processed")
|
||||
|
||||
// Relations
|
||||
transactions Transaction[]
|
||||
|
||||
watchedAt DateTime @map("watched_at")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
@@unique([sessionId])
|
||||
@@index([userId])
|
||||
@@index([watchedAt])
|
||||
@@map("watch_events")
|
||||
}
|
||||
|
||||
model ContentRequest {
|
||||
id String @id @default(uuid())
|
||||
userId String @map("user_id")
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
|
||||
// Overseer data
|
||||
overseerRequestId Int @map("overseer_request_id")
|
||||
|
||||
// Content info
|
||||
mediaType String @map("media_type") // movie, tv
|
||||
tmdbId Int @map("tmdb_id")
|
||||
title String
|
||||
|
||||
// Cost
|
||||
creditsCost Int @map("credits_cost")
|
||||
|
||||
// Status
|
||||
status RequestStatus @default(PENDING)
|
||||
|
||||
// Relations
|
||||
transaction Transaction?
|
||||
|
||||
requestedAt DateTime @map("requested_at")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@index([userId])
|
||||
@@index([status])
|
||||
@@map("content_requests")
|
||||
}
|
||||
|
||||
model Session {
|
||||
id String @id @default(uuid())
|
||||
userId String @map("user_id")
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
|
||||
token String @unique
|
||||
expiresAt DateTime @map("expires_at")
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
@@index([userId])
|
||||
@@index([token])
|
||||
@@map("sessions")
|
||||
}
|
||||
|
||||
model SystemSettings {
|
||||
id String @id @default(cuid())
|
||||
|
||||
// Minting settings
|
||||
creditsPerMinute Int @default(10) @map("credits_per_minute")
|
||||
minWatchPercent Int @default(80) @map("min_watch_percent")
|
||||
minWatchMinutes Int @default(5) @map("min_watch_minutes")
|
||||
|
||||
// Spending settings
|
||||
movieRequestCost Int @default(100) @map("movie_request_cost")
|
||||
tvRequestCost Int @default(200) @map("tv_request_cost")
|
||||
tvPerSeasonCost Int @default(50) @map("tv_per_season_cost")
|
||||
|
||||
// Multipliers
|
||||
newReleaseMultiplier Decimal @default(1.5) @map("new_release_multiplier") @db.Decimal(3, 2)
|
||||
bonusMultiplierActive Boolean @default(false) @map("bonus_multiplier_active")
|
||||
bonusMultiplier Decimal @default(2.0) @map("bonus_multiplier") @db.Decimal(3, 2)
|
||||
|
||||
// System state
|
||||
mintingPaused Boolean @default(false) @map("minting_paused")
|
||||
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String? @map("updated_by")
|
||||
|
||||
@@map("system_settings")
|
||||
}
|
||||
|
||||
enum TransactionType {
|
||||
EARN
|
||||
SPEND
|
||||
BONUS
|
||||
ADJUSTMENT
|
||||
}
|
||||
|
||||
enum RequestStatus {
|
||||
PENDING
|
||||
APPROVED
|
||||
DECLINED
|
||||
COMPLETED
|
||||
}
|
||||
Reference in New Issue
Block a user