File size: 5,222 Bytes
71b8eb2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | /**
* 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])
}
|