Files
breedr/FEATURE_IMPLEMENTATION.md

9.1 KiB

Feature Implementation: Litter Management & Interactive Pedigree

Overview

This feature branch implements two major enhancements to the BREEDR system:

  1. Complete Litter Management System - Fixes the puppy addition issue and provides full litter tracking
  2. Interactive Pedigree Tree Visualization - Beautiful, zoomable pedigree trees using react-d3-tree

Problem Solved

Original Issue

When attempting to add a puppy, users encountered the error:

no such column: sire

This occurred because:

  • The dogs table uses a parents relationship table for lineage
  • The litters table existed but had no linkage mechanism to puppies
  • The DogForm tried to reference non-existent direct parent columns

Implementation

1. Database Migration

File: server/db/migrate_litter_id.js

Adds a litter_id column to the dogs table to link puppies to their litters:

ALTER TABLE dogs ADD COLUMN litter_id INTEGER;
CREATE INDEX idx_dogs_litter ON dogs(litter_id);

To run the migration:

node server/db/migrate_litter_id.js

2. Enhanced Litter API

File: server/routes/litters.js

New endpoints:

  • POST /api/litters/:id/puppies/:puppyId - Link puppy to litter
  • DELETE /api/litters/:id/puppies/:puppyId - Remove puppy from litter
  • Enhanced GET /api/litters - Returns litters with puppy counts

Auto-linking logic:

  • When a puppy is linked to a litter, sire/dam relationships are automatically created in the parents table
  • Prevents orphaned data when litters are deleted

3. Updated DogForm Component

File: client/src/components/DogForm.jsx

Key Features:

  • Dual Parent Selection Mode:
    • Option 1: Link to existing litter (auto-populates parents)
    • Option 2: Manual parent selection (traditional method)
  • Radio button toggle for selection mode
  • Litter dropdown shows "Sire x Dam - Date" format
  • Automatic breed inheritance from litter parents

4. New LitterForm Component

File: client/src/components/LitterForm.jsx

Features:

  • Create/edit litter records
  • Select sire and dam from dropdown lists
  • Track breeding date, whelping date, expected puppy count
  • Notes field for breeding details
  • Validation: ensures sire is male, dam is female

5. Interactive Pedigree Visualization

Files:

  • client/src/components/PedigreeView.jsx
  • client/src/components/PedigreeView.css

Features:

  • Beautiful Tree Visualization:

    • Horizontal tree layout (left to right)
    • Color-coded nodes: Blue for males, Pink for females
    • Shows 5 generations by default
  • Interactive Controls:

    • Zoom in/out buttons
    • Reset view button
    • Mouse wheel zoom support
    • Click and drag to pan
    • Click nodes for details
  • Node Information:

    • Dog name (primary)
    • Registration number
    • Birth year
    • Sex indicator (♂/♀)
  • Uses COI Calculator Backend:

    • Leverages existing /api/pedigree/:id endpoint
    • Recursive ancestor tree building
    • Supports configurable generation depth

Usage

Adding a Puppy from a Litter

  1. Create a litter first:

    • Navigate to Litters section
    • Click "Add New Litter"
    • Select sire and dam
    • Enter breeding date
    • Save
  2. Add puppies to the litter:

    • Click "Add New Dog"
    • Enter puppy details
    • Select "Link to Litter" radio button
    • Choose the litter from dropdown
    • Parents are auto-populated
    • Save

Viewing Pedigree Trees

  1. From any dog detail page:
    • Click "View Pedigree" button
    • Interactive tree opens in modal
    • Use zoom/pan controls to navigate
    • Click nodes to see details

Manual Parent Assignment

For dogs not part of a formal litter:

  1. Click "Add New Dog"
  2. Enter dog details
  3. Select "Manual Parent Selection"
  4. Choose sire and dam from dropdowns
  5. Save

Technical Details

Data Flow: Litter to Puppy

1. User creates litter (sire_id, dam_id, breeding_date)
   ↓
2. Litter gets unique ID
   ↓
3. User adds puppy with litter_id
   ↓
4. Backend auto-creates parent relationships:
   - INSERT INTO parents (puppy_id, sire_id, 'sire')
   - INSERT INTO parents (puppy_id, dam_id, 'dam')
   ↓
5. Puppy linked to litter and parents

Pedigree Tree Data Structure

{
  name: "Dog Name",
  attributes: {
    sex: "male",
    birth_date: "2020-01-15",
    registration: "AKC12345",
    breed: "Golden Retriever",
    generation: 0
  },
  children: [
    { /* Sire node */ },
    { /* Dam node */ }
  ]
}

React-D3-Tree Configuration

<Tree
  orientation="horizontal"     // Left to right
  pathFunc="step"             // Orthogonal lines
  separation={{ siblings: 2 }} // Node spacing
  nodeSize={{ x: 200, y: 100 }} // Node dimensions
  collapsible={false}          // Always show all
  zoomable={true}             // Enable zoom
  draggable={true}            // Enable pan
/>

Database Schema Updates

Before

CREATE TABLE dogs (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  -- ... other fields
  -- NO litter_id column
);

CREATE TABLE parents (
  dog_id INTEGER,
  parent_id INTEGER,
  parent_type TEXT  -- 'sire' or 'dam'
);

After

CREATE TABLE dogs (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  -- ... other fields
  litter_id INTEGER  -- NEW: Links to litters table
);

CREATE INDEX idx_dogs_litter ON dogs(litter_id);

API Changes

New Endpoints

POST   /api/litters/:id/puppies/:puppyId
DELETE /api/litters/:id/puppies/:puppyId

Modified Endpoints

GET /api/litters
  Response now includes:
  - actual_puppy_count: Real count from database
  - puppies: Array of linked puppies

POST /api/dogs
  Accepts new field:
  - litter_id: Optional litter association

Dependencies

New npm packages added:

  • react-d3-tree@^3.6.2 - Tree visualization library

Existing dependencies leveraged:

  • lucide-react - Icons for UI controls
  • axios - API communication
  • react - Component framework

Testing Checklist

  • Run database migration
  • Create a new litter
  • Add puppies to litter via DogForm
  • Verify parent relationships auto-created
  • View pedigree tree for a dog with 3+ generations
  • Test zoom/pan controls in pedigree view
  • Add dog with manual parent selection
  • Edit existing dog and change litter assignment
  • Delete litter and verify puppies remain (litter_id set to NULL)

Future Enhancements

  1. Litter Dashboard:

    • Visual cards for each litter
    • Photos of puppies
    • Whelping countdown
  2. Enhanced Pedigree Features:

    • Print to PDF
    • Color coding by health clearances
    • COI display on tree nodes
    • Descendant tree (reverse pedigree)
  3. Batch Operations:

    • Add multiple puppies at once
    • Bulk photo upload for litter
    • Auto-naming scheme (Litter Letter + Name)
  4. Analytics:

    • Average litter size by pairing
    • Color distribution predictions
    • Genetic diversity metrics

Migration Path

From Current System

  1. Pull feature branch
  2. Run migration: node server/db/migrate_litter_id.js
  3. Install dependencies: cd client && npm install
  4. Restart server
  5. Existing dogs remain unchanged
  6. Start creating litters for new puppies

Rollback Plan

If issues arise:

  1. The litter_id column can remain NULL
  2. System continues to work with manual parent selection
  3. No data loss occurs
  4. Simply don't use litter feature until fixed

Architecture Decisions

Why litter_id Column?

Considered alternatives:

  1. ✗ Bridge table litter_puppies - Adds complexity, same result
  2. ✗ JSON array in litters.puppy_ids - Poor query performance
  3. Foreign key in dogs table - Simple, performant, standard pattern

Why Radio Button Toggle?

User Experience:

  • Clear visual distinction between modes
  • Prevents accidental litter/manual mixing
  • Familiar UI pattern
  • Easy to understand for non-technical users

Why react-d3-tree?

Alternatives evaluated:

  • D3.js directly - Too much custom code required
  • vis.js - Not React-friendly
  • react-family-tree - Less flexible
  • react-d3-tree - ✓ React-native, customizable, maintained

Performance Considerations

  1. Pedigree Loading:

    • Recursive queries limited to 5 generations
    • Indexes on parents table ensure fast lookups
    • Tree data cached in component state
  2. Litter Queries:

    • New index on dogs.litter_id enables fast filtering
    • Puppy counts calculated efficiently via JOIN
  3. Frontend Rendering:

    • React-d3-tree uses virtual DOM for smooth updates
    • Lazy loading prevents rendering off-screen nodes

Security Notes

  • All parent/litter relationships validated server-side
  • Gender validation prevents invalid pairings
  • Foreign key relationships ensure referential integrity
  • SQL injection prevented via parameterized queries

Contributing

When extending these features:

  1. Backend changes: Update server/routes/litters.js
  2. Frontend forms: Modify client/src/components/LitterForm.jsx or DogForm.jsx
  3. Visualization: Edit client/src/components/PedigreeView.jsx
  4. Database: Create new migration file following naming convention

Questions?

See ROADMAP.md for feature priorities or check README.md for general project info.