Files
breedr/DATABASE.md
2026-03-12 07:37:20 -05:00

4.4 KiB

BREEDR Database Schema

Overview

This document describes the database schema for BREEDR. The application uses SQLite via better-sqlite3.

Safe Migrations: The schema is maintained in server/db/init.js. On startup, the application automatically ensures all tables exist and all necessary columns are present using safe ALTER TABLE guards.

Schema Design

Core Principle: Parents Table Approach

The dogs table does NOT have sire/dam columns. Parent relationships are stored in a separate parents table. This design:

  • Keeps the core dog data normalized.
  • Allows for flexible parent relationships.
  • Supports historical mapping where ancestors might not have full profiles initially.

Tables

dogs

Core registry for all dogs (both in-kennel and external).

Column Type Description
id INTEGER Primary Key
name TEXT Dog's call name or registered name
registration_number TEXT Unique registration (AKC, etc.)
breed TEXT Breed name
sex TEXT 'male' or 'female'
birth_date TEXT Date string
color TEXT Coat color/markings
microchip TEXT Identification number
litter_id INTEGER FK to litters.id
is_active INTEGER 1 = Active in kennel, 0 = Retired/Old
is_champion INTEGER 1 = Titled champion
is_external INTEGER 1 = External dog (pedigree only), 0 = Kennel dog
chic_number TEXT CHIC certification number
age_at_death TEXT Age if deceased
cause_of_death TEXT Cause if deceased
photo_urls TEXT JSON array of photo paths
notes TEXT General observations

parents

Stores sire/dam relationships for every dog.

CREATE TABLE parents (
  id          INTEGER PRIMARY KEY AUTOINCREMENT,
  dog_id      INTEGER NOT NULL,  -- The puppy/child
  parent_id   INTEGER NOT NULL,  -- The parent dog
  parent_type TEXT NOT NULL CHECK(parent_type IN ('sire', 'dam')),
  FOREIGN KEY (dog_id)    REFERENCES dogs(id),
  FOREIGN KEY (parent_id) REFERENCES dogs(id),
  UNIQUE(dog_id, parent_type)
);

breeding_records

Tracks mating attempts/plans.

Column Type Description
sire_id INTEGER FK to dogs.id
dam_id INTEGER FK to dogs.id
breeding_date TEXT Date of mating
due_date TEXT Estimated whelp date
conception_method TEXT 'natural', 'ai', 'frozen', 'surgical'

litters

Tracks successfully produced litters.

CREATE TABLE litters (
  id              INTEGER PRIMARY KEY AUTOINCREMENT,
  breeding_id     INTEGER, -- Optional link to breeding_record
  sire_id         INTEGER NOT NULL,
  dam_id          INTEGER NOT NULL,
  whelp_date      TEXT,
  total_count     INTEGER DEFAULT 0,
  male_count      INTEGER DEFAULT 0,
  female_count    INTEGER DEFAULT 0,
  stillborn_count INTEGER DEFAULT 0,
  notes           TEXT,
  FOREIGN KEY (breeding_id) REFERENCES breeding_records(id),
  FOREIGN KEY (sire_id)     REFERENCES dogs(id),
  FOREIGN KEY (dam_id)      REFERENCES dogs(id)
);

health_records (OFA & General)

Tracks medical tests and certifications (Hips, Elbows, Heart, Eyes, etc).

Column Type Description
record_type TEXT 'test', 'vaccination', 'exam', 'treatment', 'certification'
test_type TEXT 'hip_ofa', 'eye_caer', etc.
ofa_result TEXT Official rating (Excellent, Good, etc.)
ofa_number TEXT Certification number
expires_at TEXT Expiry for annual tests
document_url TEXT Link to PDF or image scan

genetic_tests

DNA panel results (Embark, etc).

CREATE TABLE genetic_tests (
  id              INTEGER PRIMARY KEY AUTOINCREMENT,
  dog_id          INTEGER NOT NULL,
  test_provider   TEXT,   -- Embark, PawPrint, etc.
  marker          TEXT NOT NULL, -- PRA1, ICH1, etc.
  result          TEXT NOT NULL CHECK(result IN ('clear', 'carrier', 'affected', 'not_tested')),
  FOREIGN KEY (dog_id) REFERENCES dogs(id)
);

heat_cycles

Female heat cycle tracking.

settings

Global kennel configuration (Single-row table).

  • kennel_name, kennel_tagline, kennel_address, owner_name, etc.

Migration Policy

BREEDR uses a Migration-Free sync approach:

  1. init.js defines the latest CREATE TABLE statements.
  2. An ADD COLUMN loop checks for existing columns.
  3. If a column is missing, it is injected via ALTER TABLE.
  4. This ensures users can pull latest code and restart without losing data.

Last Updated: March 12, 2026