- README: v0.8.1 highlights, Node 18+ requirement + client install step for manual dev setup, health/genetics features listed, release summary updated - API.md: paginated response shapes for dogs/litters, validation + status-code behavior (400/404), full breeding heat-cycle CRUD, genetics PUT/DELETE, pedigree COI/relations/cancer-lineage endpoints, corrected Litter object - DEVELOPMENT.md: two-layer migration approach documented with schema-drift warning, heat_cycles/cancer_history tables, Toast/ConfirmDialog UI patterns (no alert/window.confirm), full env-var table, auth-deferred decision noted - INSTALL.md: fixed API smoke-test (old /api/health root path doesn't exist), master -> main - ROADMAP: v0.8.1 entry; Phase 4b checkboxes reconciled with what's actually built; Phase 6 progress; pre-deploy prod-DB check added to QA list Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8.9 KiB
BREEDR API Documentation (v0.8.1)
Base URL: /api
All endpoints return JSON responses. Errors follow the format { "error": "message" }.
Validation failures return 400, missing resources return 404.
1. Dogs (/api/dogs)
Manage individual dogs in the kennel.
GET /
Get active kennel dogs (paginated).
- Query Params:
include_external=1: Include external dogs (studs/others)external_only=1: Only show external dogspage(default 1),limit(default 50, max 200)search: Filter by name or registration numbersex:male|female
- Response:
{ "data": [Dog...], "total", "page", "limit", "stats": { "total", "males", "females" } }— each Dog hassireanddamattached.
GET /all
Get all active dogs (kennel + external, unpaginated). Used for dropdowns/pairing/pedigree.
GET /:id
Get single dog details.
- Response: Dog object including
sire,dam, andoffspringarray.404if not found.
POST /
Create a new dog.
- Body: See Dog fields.
name,breed,sexare required. - Validation: If
sire_id/dam_idare provided they must reference an existing dog of the correct sex (sire → male, dam → female), else400. The dog + parent links are written in a single transaction. - Response: The created Dog object (
201).
PUT /:id
Update an existing dog.
- Body: Dog fields to update.
- Validation:
404if the dog doesn't exist. Same sire/dam checks asPOST /, plus a dog cannot be its own parent. - Response: The updated Dog object.
DELETE /:id
Permanently delete a dog and its related records (health, heat cycles, parent links) in a single transaction.
- Response:
{ "success": true, "message": "..." }—404if not found.
POST /:id/photos
Upload a photo for a dog (JPEG/PNG/GIF/WebP, ≤ 10 MB).
- Form-Data:
photo(file) - Response:
{ "url": "...", "photos": [...] }
DELETE /:id/photos/:photoIndex
Delete a specific photo from a dog's photo array.
- Validation:
400ifphotoIndexis not an integer within the photo array's bounds. - Response:
{ "photos": [...] }
2. Litters (/api/litters)
Manage breeding litters and puppy logs.
GET /
Get all litters (paginated).
- Query Params:
page(default 1),limit(default 50) - Response:
{ "data": [Litter...], "total", "page", "limit" }with sire/dam names and puppies attached.
GET /:id
Get single litter details.
- Response: Litter object.
POST /
Create a new litter.
- Body:
sire_id,dam_id,breeding_date(required),whelping_date,puppy_count,notes. - Validation: Sire must be male, dam must be female.
- Response: The created Litter object.
PUT /:id
Update litter details (breeding_date, whelping_date, puppy_count, notes — parents cannot change).
DELETE /:id
Delete a litter. Puppies are unlinked (their dog records are kept).
POST /:id/puppies/:puppyId
Link a dog to a litter as a puppy.
- Side Effect: Automatically sets the litter's sire and dam as the puppy's parents.
DELETE /:id/puppies/:puppyId
Remove a puppy from a litter (sets litter_id to NULL).
GET /:litterId/puppies/:puppyId/logs
Get weight and health logs for a puppy.
POST /:litterId/puppies/:puppyId/logs
Add a weight/health log entry (stored in health_records; weights serialized into description).
- Body:
record_date(required),weight_oz,weight_lbs,notes,record_type(defaultweight_log).
DELETE /:litterId/puppies/:puppyId/logs/:logId
Delete a weight/health log entry.
3. Health (/api/health)
Manage OFA clearances and veterinary records.
Record types (record_type): ofa_clearance, vaccination, exam, surgery, medication, other.
Valid test_type values (OFA clearances only): hip_ofa, hip_pennhip, elbow_ofa, patella_ofa, heart_ofa, heart_echo, eye_caer, thyroid_ofa.
DNA is not a health test type — DNA panels are managed exclusively by the Genetics module (
/api/genetics).
GET /dog/:dogId
Get all health records for a dog.
GET /dog/:dogId/clearance-summary
Get GRCA core clearance status (Hip, Elbow, Heart, Eyes).
- Response:
{ summary, grca_eligible, age_eligible, chic_number } - Only recurring tests (CAER eyes, advanced/echo cardiac) carry an
expires_at; permanent certifications (hip, elbow, etc.) never reportexpired/expiring_soon.
GET /dog/:dogId/chic-eligible
Check if a dog has all required CHIC tests.
GET /:id
Get a single health record.
POST /
Create health record.
- Body:
dog_id,record_type,test_date(all required), plus optionaltest_type,test_name,ofa_result,ofa_number,performed_by,expires_at,result,next_due,document_url,notes. - Validation:
test_type, if present, must be one of the valid values above (else400). - Note:
performed_byis the single clinician field (the legacyvet_namecolumn is deprecated).
PUT /:id
Update an existing health record. Same body as POST / (minus dog_id).
DELETE /:id
Delete a health record.
- Response:
{ "message": "Health record deleted successfully" }
POST /upload
Upload a supporting document (PDF or image, ≤ 15 MB) and get back a URL to store in a record's document_url. Record-agnostic — works before the record itself is saved.
- Form-Data:
document(file) - Response:
{ "url": "/uploads/..." }
GET /dog/:dogId/cancer-history
Get cancer-history records for a dog.
POST /cancer-history
Add a cancer-history record.
- Body:
dog_id,cancer_type(required),age_at_diagnosis,age_at_death,cause_of_death,notes.
4. Genetics (/api/genetics)
Manage DNA panel results and breeding risks.
GET /dog/:dogId
Get the full genetic panel for a dog. Returns tests (actual records) and panel (full list including not_tested placeholders).
GET /pairing-risk?sireId=X&damId=Y
Check genetic compatibility between two dogs.
- Response:
{ risks: [...], safe_to_pair: boolean }
GET /:id
Get a single genetic test record.
POST /
Add a genetic test result.
- Body:
dog_id,marker,result(clear|carrier|affected|not_tested), plus optionaltest_provider,test_date,document_url,notes.
PUT /:id
Update a genetic test result.
DELETE /:id
Delete a genetic test result.
5. Breeding (/api/breeding)
Track heat cycles and whelping projections.
GET /heat-cycles
Get all heat cycles (with dog info). Optional ?year=YYYY&month=M filter.
GET /heat-cycles/active
Get currently active heat cycles.
GET /heat-cycles/dog/:dogId
Get all heat cycles for a specific dog.
GET /heat-cycles/:id/suggestions
Get optimal breeding window (days 9-15) and whelping projections.
POST /heat-cycles
Log a new heat cycle. Dog must be female.
- Body:
dog_id,start_date(required),end_date,breeding_date,breeding_successful,notes.
PUT /heat-cycles/:id
Update a heat cycle (same body as POST, minus dog_id).
DELETE /heat-cycles/:id
Delete a heat cycle.
GET /whelping-calculator?breeding_date=YYYY-MM-DD
Standalone tool to calculate expected whelping window.
6. Pedigree (/api/pedigree)
Advanced ancestry and COI calculations.
GET /:id?generations=N
Get an interactive pedigree tree (ancestors). Default 5 generations.
GET /:id/descendants?generations=N
Get a descendant tree. Default 3 generations.
POST /trial-pairing
Calculate Coefficient of Inbreeding (COI) for a hypothetical mating. (POST /coi is an alias.)
- Body:
sire_id,dam_id. - Response:
{ coi, commonAncestors, directRelation, recommendation }
GET /:id/coi
Get the COI for an existing dog (computed from its actual parents).
GET /relations/:sireId/:damId
Check the direct relationship between two dogs (parent/offspring, siblings, etc.).
GET /:id/cancer-lineage
Cancer history aggregated across a dog's lineage.
7. Settings (/api/settings)
GET /
Get kennel metadata (name, address, etc.).
PUT /
Update kennel settings.
Data Objects
Dog Object
{
"id": 1,
"name": "BREEDR Champion",
"registration_number": "AKC123456",
"breed": "Golden Retriever",
"sex": "male",
"birth_date": "2020-01-01",
"color": "Golden",
"microchip": "900123456789",
"is_active": 1,
"is_champion": 1,
"is_external": 0,
"photo_urls": ["/uploads/img.jpg"],
"notes": "Excellent temperament",
"sire": { "id": 10, "name": "Sire Name" },
"dam": { "id": 11, "name": "Dam Name" }
}
Litter Object
{
"id": 5,
"sire_id": 1,
"dam_id": 2,
"sire_name": "Sire Name",
"dam_name": "Dam Name",
"breeding_date": "2026-01-01",
"whelping_date": "2026-03-05",
"puppy_count": 8,
"notes": null,
"puppies": [ ... ],
"actual_puppy_count": 8
}