2026-03-06 16:27:54 +00:00
|
|
|
import { sqliteTable, text, integer, real } from 'drizzle-orm/sqlite-core'
|
|
|
|
|
|
|
|
|
|
export const bots = sqliteTable('bots', {
|
|
|
|
|
id: text('id').primaryKey(),
|
|
|
|
|
name: text('name').notNull().unique(),
|
|
|
|
|
webhookUrl: text('webhook_url').notNull(),
|
|
|
|
|
avatarSeed: text('avatar_seed').notNull(),
|
2026-03-06 22:13:19 +00:00
|
|
|
archetype: text('archetype').notNull().default('standard'),
|
2026-03-06 16:27:54 +00:00
|
|
|
secretHash: text('secret_hash').notNull(),
|
|
|
|
|
publicKey: text('public_key'),
|
2026-03-06 22:13:19 +00:00
|
|
|
profilePicUrl: text('profile_pic_url'),
|
2026-03-06 16:27:54 +00:00
|
|
|
eloRating: real('elo_rating').notNull().default(1200),
|
|
|
|
|
wins: integer('wins').notNull().default(0),
|
|
|
|
|
losses: integer('losses').notNull().default(0),
|
|
|
|
|
winStreak: integer('win_streak').notNull().default(0),
|
|
|
|
|
bestStreak: integer('best_streak').notNull().default(0),
|
|
|
|
|
tier: integer('tier').notNull().default(0),
|
|
|
|
|
isActive: integer('is_active', { mode: 'boolean' }).notNull().default(true),
|
2026-03-07 00:14:46 +00:00
|
|
|
lastFightAt: text('last_fight_at'),
|
|
|
|
|
consecutiveErrors: integer('consecutive_errors').notNull().default(0),
|
|
|
|
|
lastErrorAt: text('last_error_at'),
|
2026-03-07 08:52:24 +00:00
|
|
|
customization: text('customization'),
|
2026-03-06 16:27:54 +00:00
|
|
|
createdAt: text('created_at').notNull(),
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
export const fights = sqliteTable('fights', {
|
|
|
|
|
id: text('id').primaryKey(),
|
|
|
|
|
botAId: text('bot_a_id').notNull().references(() => bots.id),
|
|
|
|
|
botBId: text('bot_b_id').notNull().references(() => bots.id),
|
|
|
|
|
arena: text('arena').notNull(),
|
|
|
|
|
status: text('status', { enum: ['scheduled', 'live', 'finished', 'cancelled'] }).notNull().default('scheduled'),
|
|
|
|
|
winnerId: text('winner_id').references(() => bots.id),
|
2026-03-06 22:13:19 +00:00
|
|
|
botAHp: integer('bot_a_hp').notNull().default(200),
|
|
|
|
|
botBHp: integer('bot_b_hp').notNull().default(200),
|
2026-03-06 16:27:54 +00:00
|
|
|
totalRounds: integer('total_rounds').notNull().default(0),
|
|
|
|
|
scheduledAt: text('scheduled_at'),
|
|
|
|
|
startedAt: text('started_at'),
|
|
|
|
|
endedAt: text('ended_at'),
|
|
|
|
|
createdAt: text('created_at').notNull(),
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
export const rounds = sqliteTable('rounds', {
|
|
|
|
|
id: text('id').primaryKey(),
|
|
|
|
|
fightId: text('fight_id').notNull().references(() => fights.id),
|
|
|
|
|
roundNumber: integer('round_number').notNull(),
|
|
|
|
|
challengeType: text('challenge_type').notNull(),
|
|
|
|
|
challengeData: text('challenge_data').notNull(),
|
|
|
|
|
botAResponse: text('bot_a_response'),
|
|
|
|
|
botATimeMs: integer('bot_a_time_ms'),
|
|
|
|
|
botAScore: real('bot_a_score'),
|
|
|
|
|
botBResponse: text('bot_b_response'),
|
|
|
|
|
botBTimeMs: integer('bot_b_time_ms'),
|
|
|
|
|
botBScore: real('bot_b_score'),
|
|
|
|
|
winnerId: text('winner_id').references(() => bots.id),
|
|
|
|
|
narration: text('narration'),
|
|
|
|
|
createdAt: text('created_at').notNull(),
|
|
|
|
|
})
|
2026-03-08 00:33:08 +00:00
|
|
|
|
|
|
|
|
export const bets = sqliteTable('bets', {
|
|
|
|
|
id: text('id').primaryKey(),
|
|
|
|
|
fightId: text('fight_id').notNull().references(() => fights.id),
|
|
|
|
|
bettorPubkey: text('bettor_pubkey').notNull(),
|
|
|
|
|
botId: text('bot_id').notNull().references(() => bots.id),
|
|
|
|
|
amountSats: integer('amount_sats').notNull(),
|
|
|
|
|
oddsAtPlacement: real('odds_at_placement').notNull(),
|
|
|
|
|
cashuToken: text('cashu_token').notNull(),
|
|
|
|
|
status: text('status', {
|
|
|
|
|
enum: ['pending', 'locked', 'won', 'lost', 'refunded', 'paid'],
|
|
|
|
|
}).notNull().default('pending'),
|
|
|
|
|
payoutSats: integer('payout_sats'),
|
|
|
|
|
payoutToken: text('payout_token'),
|
|
|
|
|
createdAt: text('created_at').notNull(),
|
|
|
|
|
settledAt: text('settled_at'),
|
|
|
|
|
})
|