137 lines
4.4 KiB
Markdown
137 lines
4.4 KiB
Markdown
# 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.
|
|
|
|
```sql
|
|
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.
|
|
|
|
```sql
|
|
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).
|
|
|
|
```sql
|
|
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*
|