blackmistcode's picture
Add files using upload-large-folder tool
71b8eb2 verified
Raw
History Blame Contribute Delete
5.22 kB
/**
* Schema de Prisma ORM para base de datos SQLite.
*
* Define 6 modelos: User, Market, AISignal, Position, Watchlist, Alert.
* Relaciones:
* - Market 1:N AISignal, Position, Watchlist, Alert
* - User 1:N Position, Watchlist, Alert
*
* No modificar sin consenso del equipo. Generar migraciones con:
* npx prisma migrate dev
* npx prisma generate
*/
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
passwordHash String
isActive Boolean @default(true)
telegramChatId String? // Configurado manualmente para demo
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
positions Position[]
watchlist Watchlist[]
alerts Alert[]
}
model Market {
id String @id // ID nativo de Polymarket
question String // Texto de la pregunta del mercado
category String? // politics | crypto | economics | sports
countryCode String? // ISO2 — usado por Leaflet para burbujas
yesPrice Float? // Precio YES: 0.0 a 1.0
noPrice Float? // Precio NO: 0.0 a 1.0
volumeEur Float? // Volumen en Eur
liquidityEur Float? // Liquidez en Eur
spread Float? // Bid/ask spread (0-1, ej 0.02 = 2c)
bestBid Float? // Mejor oferta de compra
bestAsk Float? // Mejor oferta de venta
clobTokenId String? // YES outcome CLOB token ID (para prices-history)
analyzable Boolean @default(true) // Si la IA tiene edge plausible aqui
status String @default("active") // active | closed | resolved
closesAt DateTime? // Fecha de cierre del mercado
lastSynced DateTime @default(now()) // Ultima sincronizacion de precios
signals AISignal[]
positions Position[]
watchlist Watchlist[]
alerts Alert[]
}
model AISignal {
id Int @id @default(autoincrement())
marketId String
market Market @relation(fields: [marketId], references: [id], onDelete: Cascade)
signal String // bullish | bearish | neutral
confidence Float // 0.0 a 1.0
summary String? // 2 frases generadas por Qwen3
keyRisk String? // 1 frase de riesgo principal
newsCount Int @default(0) // Titulares relevantes usados
modelVersion String @default("Qwen3-8B") // Modelo LLM que genero la senal
impliedProb Float? // Probabilidad implicita YES al generar (0-1)
fairProb Float? // Probabilidad "justa" segun IA (0-1)
edgePoints Float? // (fairProb - impliedProb) * 100, signo conserva direccion
generatedAt DateTime @default(now())
@@index([marketId, generatedAt])
}
model Position {
id Int @id @default(autoincrement())
userId Int
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
marketId String
market Market @relation(fields: [marketId], references: [id], onDelete: Cascade)
outcome String // YES | NO
amountEur Float // Capital virtual apostado
entryPrice Float // Precio al abrir la posicion
currentPrice Float? // Precio actual (actualizado por scheduler)
pnl Float @default(0) // Profit and Loss calculado
kellyFraction Float? // Fraccion de Kelly al abrir
status String @default("open") // open | closed
openedAt DateTime @default(now())
closedAt DateTime?
@@index([userId, status])
@@index([marketId])
}
model Watchlist {
id Int @id @default(autoincrement())
userId Int
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
marketId String
market Market @relation(fields: [marketId], references: [id], onDelete: Cascade)
alertThreshold Float? // Umbral de precio para alerta Telegram
createdAt DateTime @default(now())
@@unique([userId, marketId])
@@index([userId])
}
model Alert {
id Int @id @default(autoincrement())
userId Int
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
marketId String
market Market @relation(fields: [marketId], references: [id], onDelete: Cascade)
type String // price_threshold | signal_change
message String // Texto enviado por Telegram
sentAt DateTime @default(now())
@@index([userId, sentAt])
@@index([marketId])
}