import { integer, sqliteTable, text, real, unique } from 'drizzle-orm/sqlite-core'; import { user } from './auth.schema'; import type { InferSelectModel } from 'drizzle-orm'; // Define devil fruit types export type DevilFruitType = 'Paramecia' | 'Zoan' | 'Logia' | 'Smile' | 'Unknown'; export type Status = 'Alive' | 'Dead' | 'Unknown'; export type FriendshipStatus = 'pending' | 'accepted' | 'declined'; // Define the site config table schema export const config = sqliteTable('config', { key: text('key').primaryKey(), value: text('value') }); // Define the arc table schema export const arc = sqliteTable('arc', { id: text('id').primaryKey(), name: text('name').notNull(), frName: text('fr_name'), startChapter: integer('start_chapter').notNull(), endChapter: integer('end_chapter'), url: text('url') }); export type Arc = InferSelectModel; // Define the devil fruit table schema export const devilFruit = sqliteTable('devil_fruit', { id: text('id').primaryKey(), name: text('name').notNull().unique(), type: text('type').$type(), url: text('url') }); export type DevilFruit = InferSelectModel; // Define the character table schema export const character = sqliteTable('character', { id: text('id').primaryKey(), name: text('name').notNull(), frName: text('fr_name'), gender: text('gender'), age: integer('age'), affiliations: text('affiliations', { mode: 'json' }).$type(), devilFruitId: text('devil_fruit_id').references(() => devilFruit.id), hakiObservation: integer('haki_observation', { mode: 'boolean' }).default(false), hakiArmament: integer('haki_armament', { mode: 'boolean' }).default(false), hakiConqueror: integer('haki_conqueror', { mode: 'boolean' }).default(false), bounty: integer('bounty').default(0), height: real('height'), origin: text('origin'), frOrigin: text('fr_origin'), firstAppearance: integer('first_appearance').notNull(), pictureUrl: text('picture_url'), epithets: text('epithets', { mode: 'json' }).$type(), frEpithets: text('fr_epithets', { mode: 'json' }).$type(), status: text('status').$type(), arcId: text('arc_id').references(() => arc.id, { onDelete: 'set null' }), url: text('url'), frUrl: text('fr_url'), isInDailyMode: integer('is_in_daily_mode', { mode: 'boolean' }).default(false) }); export type Character = InferSelectModel; // Define the character override table schema export const characterOverride = sqliteTable('character_override', { characterId: text('character_id').primaryKey().references(() => character.id, { onDelete: 'cascade' }), name: text('name'), gender: text('gender'), age: integer('age'), affiliations: text('affiliations', { mode: 'json' }).$type(), devilFruitId: text('devil_fruit_id').references(() => devilFruit.id, { onDelete: 'set null' }), hakiObservation: integer('haki_observation', { mode: 'boolean' }), hakiArmament: integer('haki_armament', { mode: 'boolean' }), hakiConqueror: integer('haki_conqueror', { mode: 'boolean' }), bounty: integer('bounty'), height: real('height'), origin: text('origin'), firstAppearance: integer('first_appearance'), pictureUrl: text('picture_url'), epithets: text('epithets', { mode: 'json' }).$type(), status: text('status').$type(), arcId: text('arc_id').references(() => arc.id, { onDelete: 'set null' }), url: text('url'), frUrl: text('fr_url'), notes: text('notes') }); export type CharacterOverride = InferSelectModel; // Define the character scrape validation table schema export const characterScrapeValidation = sqliteTable('character_scrape_validation', { id: text('id').primaryKey(), name: text('name').notNull(), frName: text('fr_name'), gender: text('gender'), age: integer('age'), affiliations: text('affiliations', { mode: 'json' }).$type(), devilFruitId: text('devil_fruit_id').references(() => devilFruit.id, { onDelete: 'set null' }), hakiObservation: integer('haki_observation', { mode: 'boolean' }).default(false), hakiArmament: integer('haki_armament', { mode: 'boolean' }).default(false), hakiConqueror: integer('haki_conqueror', { mode: 'boolean' }).default(false), bounty: integer('bounty'), height: real('height'), origin: text('origin'), frOrigin: text('fr_origin'), firstAppearance: integer('first_appearance').notNull(), pictureUrl: text('picture_url'), epithets: text('epithets', { mode: 'json' }).$type(), frEpithets: text('fr_epithets', { mode: 'json' }).$type(), status: text('status').$type(), arcId: text('arc_id').references(() => arc.id, { onDelete: 'set null' }), url: text('url'), frUrl: text('fr_url') }); export type CharacterScrapeValidation = InferSelectModel; // Define the character history table schema export const characterHistory = sqliteTable('character_history', { id: text('id') .primaryKey() .$defaultFn(() => crypto.randomUUID()), characterId: text('character_id').references(() => character.id, { onDelete: 'cascade' }), date: integer('date').notNull().unique(), won: integer('won').notNull().default(0), createdAt: integer('created_at').notNull().$default(() => Date.now()), updatedAt: integer('updated_at').notNull().$default(() => Date.now()), }); export type CharacterHistory = InferSelectModel; // Define the user character history table schema export const userCharacterHistory = sqliteTable('user_character_history', { id: text('id') .primaryKey() .$defaultFn(() => crypto.randomUUID()), userId: text('user_id').references(() => user.id, { onDelete: 'cascade' }), characterHistoryId: text('character_history_id').references(() => characterHistory.id, { onDelete: 'cascade' }), tryCount: integer('try_count').notNull(), triedCharacterIds: text('tried_character_ids', { mode: 'json' }).$type(), createdAt: integer('created_at').notNull().$default(() => Date.now()) }, (table) => [ unique().on(table.userId, table.characterHistoryId) ]); export type UserCharacterHistory = InferSelectModel; // Define the friendship table schema (friend requests + accepted friends) export const friendship = sqliteTable('friendship', { id: text('id') .primaryKey() .$defaultFn(() => crypto.randomUUID()), requesterId: text('requester_id') .notNull() .references(() => user.id, { onDelete: 'cascade' }), addresseeId: text('addressee_id') .notNull() .references(() => user.id, { onDelete: 'cascade' }), status: text('status').$type().notNull().default('pending'), createdAt: integer('created_at').notNull().$default(() => Date.now()), updatedAt: integer('updated_at').notNull().$default(() => Date.now()), }, (table) => [ unique().on(table.requesterId, table.addresseeId) ]); export type Friendship = InferSelectModel; export * from './auth.schema';