import { sql } from 'drizzle-orm'; import { sqliteTable, text, integer, real, check } from 'drizzle-orm/sqlite-core'; export const rabbits = sqliteTable( 'rabbits', { id: integer('id').primaryKey({ autoIncrement: true }), name: text('name').notNull(), farm: text('farm'), sex: text('sex').notNull().default('unknown'), dob: text('dob'), weightLbs: real('weight_lbs'), earNumber: text('ear_number'), location: text('location'), status: text('status').notNull().default('active'), colorName: text('color_name'), photoPath: text('photo_path'), registrationNumber: text('registration_number'), gcNumber: text('gc_number'), sireId: integer('sire_id').references((): any => rabbits.id), damId: integer('dam_id').references((): any => rabbits.id), // Genetics loci locusA: text('locus_a'), locusB: text('locus_b'), locusC: text('locus_c'), locusD: text('locus_d'), locusE: text('locus_e'), locusEn: text('locus_en'), locusV: text('locus_v'), // Chain-authority freeform ancestor text (see memory-bank/architecture.md) // Generation 1 (parents) sireNameText: text('sire_name_text'), damNameText: text('dam_name_text'), // Generation 2 (grandparents) paternalGrandsireNameText: text('paternal_grandsire_name_text'), paternalGranddamNameText: text('paternal_granddam_name_text'), maternalGrandsireNameText: text('maternal_grandsire_name_text'), maternalGranddamNameText: text('maternal_granddam_name_text'), // Generation 3 (great-grandparents) ppGrandsireNameText: text('pp_grandsire_name_text'), ppGranddamNameText: text('pp_granddam_name_text'), pmGrandsireNameText: text('pm_grandsire_name_text'), pmGranddamNameText: text('pm_granddam_name_text'), mpGrandsireNameText: text('mp_grandsire_name_text'), mpGranddamNameText: text('mp_granddam_name_text'), mmGrandsireNameText: text('mm_grandsire_name_text'), mmGranddamNameText: text('mm_granddam_name_text'), createdAt: text('created_at').notNull().default(sql`(current_timestamp)`), updatedAt: text('updated_at').notNull().default(sql`(current_timestamp)`), }, (table) => [ check('sex_check', sql`${table.sex} in ('buck', 'doe', 'unknown')`), check( 'status_check', sql`${table.status} in ('active', 'for_sale', 'on_hold', 'sold', 'deceased', 'other')` ), ] ); export const litters = sqliteTable('litters', { id: integer('id').primaryKey({ autoIncrement: true }), sireId: integer('sire_id').references(() => rabbits.id), damId: integer('dam_id').references(() => rabbits.id), // A litter record spans the breeding→kindle lifecycle: `breedDate` is set when // the pairing is recorded; `kindleDate` (nullable until the doe kindles) and // `kitCount` are filled in later. At least one of the two dates is required — // enforced in routes/litters.ts, not by the schema. breedDate: text('breed_date'), kindleDate: text('kindle_date'), kitCount: integer('kit_count'), notes: text('notes'), createdAt: text('created_at').notNull().default(sql`(current_timestamp)`), }); export const settings = sqliteTable('settings', { key: text('key').primaryKey(), value: text('value'), });