Docs: bring all documentation current with v0.8.1
Build and Push Docker Image / build (push) Successful in 16s
Build and Push Docker Image / build (push) Successful in 16s
- 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>
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
# BREEDR API Documentation (v0.8.0)
|
# BREEDR API Documentation (v0.8.1)
|
||||||
|
|
||||||
Base URL: `/api`
|
Base URL: `/api`
|
||||||
|
|
||||||
All endpoints return JSON responses. Errors follow the format `{ "error": "message" }`.
|
All endpoints return JSON responses. Errors follow the format `{ "error": "message" }`.
|
||||||
|
Validation failures return `400`, missing resources return `404`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -11,37 +12,46 @@ All endpoints return JSON responses. Errors follow the format `{ "error": "messa
|
|||||||
Manage individual dogs in the kennel.
|
Manage individual dogs in the kennel.
|
||||||
|
|
||||||
### `GET /`
|
### `GET /`
|
||||||
Get active kennel dogs.
|
Get active kennel dogs (paginated).
|
||||||
- **Query Params**:
|
- **Query Params**:
|
||||||
- `include_external=1`: Include external dogs (studs/others)
|
- `include_external=1`: Include external dogs (studs/others)
|
||||||
- `external_only=1`: Only show external dogs
|
- `external_only=1`: Only show external dogs
|
||||||
- **Response**: Array of [Dog](#dog-object) objects with `sire` and `dam` attached.
|
- `page` (default 1), `limit` (default 50, max 200)
|
||||||
|
- `search`: Filter by name or registration number
|
||||||
|
- `sex`: `male` | `female`
|
||||||
|
- **Response**: `{ "data": [Dog...], "total", "page", "limit", "stats": { "total", "males", "females" } }` — each Dog has `sire` and `dam` attached.
|
||||||
|
|
||||||
|
### `GET /all`
|
||||||
|
Get all active dogs (kennel + external, unpaginated). Used for dropdowns/pairing/pedigree.
|
||||||
|
|
||||||
### `GET /:id`
|
### `GET /:id`
|
||||||
Get single dog details.
|
Get single dog details.
|
||||||
- **Response**: [Dog](#dog-object) object including `sire`, `dam`, and `offspring` array.
|
- **Response**: [Dog](#dog-object) object including `sire`, `dam`, and `offspring` array. `404` if not found.
|
||||||
|
|
||||||
### `POST /`
|
### `POST /`
|
||||||
Create a new dog.
|
Create a new dog.
|
||||||
- **Body**: See [Dog](#dog-object) fields. `name`, `breed`, `sex` are required.
|
- **Body**: See [Dog](#dog-object) fields. `name`, `breed`, `sex` are required.
|
||||||
- **Response**: The created Dog object.
|
- **Validation**: If `sire_id`/`dam_id` are provided they must reference an existing dog of the correct sex (sire → male, dam → female), else `400`. The dog + parent links are written in a single transaction.
|
||||||
|
- **Response**: The created Dog object (`201`).
|
||||||
|
|
||||||
### `PUT /:id`
|
### `PUT /:id`
|
||||||
Update an existing dog.
|
Update an existing dog.
|
||||||
- **Body**: Dog fields to update.
|
- **Body**: Dog fields to update.
|
||||||
|
- **Validation**: `404` if the dog doesn't exist. Same sire/dam checks as `POST /`, plus a dog cannot be its own parent.
|
||||||
- **Response**: The updated Dog object.
|
- **Response**: The updated Dog object.
|
||||||
|
|
||||||
### `DELETE /:id`
|
### `DELETE /:id`
|
||||||
Permanently delete a dog and its related records (health, heat, parents).
|
Permanently delete a dog and its related records (health, heat cycles, parent links) in a single transaction.
|
||||||
- **Response**: `{ "success": true, "message": "..." }`
|
- **Response**: `{ "success": true, "message": "..." }` — `404` if not found.
|
||||||
|
|
||||||
### `POST /:id/photos`
|
### `POST /:id/photos`
|
||||||
Upload a photo for a dog.
|
Upload a photo for a dog (JPEG/PNG/GIF/WebP, ≤ 10 MB).
|
||||||
- **Form-Data**: `photo` (file)
|
- **Form-Data**: `photo` (file)
|
||||||
- **Response**: `{ "url": "...", "photos": [...] }`
|
- **Response**: `{ "url": "...", "photos": [...] }`
|
||||||
|
|
||||||
### `DELETE /:id/photos/:photoIndex`
|
### `DELETE /:id/photos/:photoIndex`
|
||||||
Delete a specific photo from a dog's photo array.
|
Delete a specific photo from a dog's photo array.
|
||||||
|
- **Validation**: `400` if `photoIndex` is not an integer within the photo array's bounds.
|
||||||
- **Response**: `{ "photos": [...] }`
|
- **Response**: `{ "photos": [...] }`
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -51,8 +61,9 @@ Delete a specific photo from a dog's photo array.
|
|||||||
Manage breeding litters and puppy logs.
|
Manage breeding litters and puppy logs.
|
||||||
|
|
||||||
### `GET /`
|
### `GET /`
|
||||||
Get all litters.
|
Get all litters (paginated).
|
||||||
- **Response**: Array of [Litter](#litter-object) objects with sire/dam names and puppies.
|
- **Query Params**: `page` (default 1), `limit` (default 50)
|
||||||
|
- **Response**: `{ "data": [Litter...], "total", "page", "limit" }` with sire/dam names and puppies attached.
|
||||||
|
|
||||||
### `GET /:id`
|
### `GET /:id`
|
||||||
Get single litter details.
|
Get single litter details.
|
||||||
@@ -61,10 +72,14 @@ Get single litter details.
|
|||||||
### `POST /`
|
### `POST /`
|
||||||
Create a new litter.
|
Create a new litter.
|
||||||
- **Body**: `sire_id`, `dam_id`, `breeding_date` (required), `whelping_date`, `puppy_count`, `notes`.
|
- **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.
|
- **Response**: The created Litter object.
|
||||||
|
|
||||||
### `PUT /:id`
|
### `PUT /:id`
|
||||||
Update litter details.
|
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`
|
### `POST /:id/puppies/:puppyId`
|
||||||
Link a dog to a litter as a puppy.
|
Link a dog to a litter as a puppy.
|
||||||
@@ -77,8 +92,11 @@ Remove a puppy from a litter (sets `litter_id` to NULL).
|
|||||||
Get weight and health logs for a puppy.
|
Get weight and health logs for a puppy.
|
||||||
|
|
||||||
### `POST /:litterId/puppies/:puppyId/logs`
|
### `POST /:litterId/puppies/:puppyId/logs`
|
||||||
Add a weight/health log entry.
|
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`.
|
- **Body**: `record_date` (required), `weight_oz`, `weight_lbs`, `notes`, `record_type` (default `weight_log`).
|
||||||
|
|
||||||
|
### `DELETE /:litterId/puppies/:puppyId/logs/:logId`
|
||||||
|
Delete a weight/health log entry.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -143,9 +161,18 @@ Get the full genetic panel for a dog. Returns `tests` (actual records) and `pane
|
|||||||
Check genetic compatibility between two dogs.
|
Check genetic compatibility between two dogs.
|
||||||
- **Response**: `{ risks: [...], safe_to_pair: boolean }`
|
- **Response**: `{ risks: [...], safe_to_pair: boolean }`
|
||||||
|
|
||||||
|
### `GET /:id`
|
||||||
|
Get a single genetic test record.
|
||||||
|
|
||||||
### `POST /`
|
### `POST /`
|
||||||
Add a genetic test result.
|
Add a genetic test result.
|
||||||
- **Body**: `dog_id`, `marker`, `result` (clear|carrier|affected|not_tested).
|
- **Body**: `dog_id`, `marker`, `result` (clear|carrier|affected|not_tested), plus optional `test_provider`, `test_date`, `document_url`, `notes`.
|
||||||
|
|
||||||
|
### `PUT /:id`
|
||||||
|
Update a genetic test result.
|
||||||
|
|
||||||
|
### `DELETE /:id`
|
||||||
|
Delete a genetic test result.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -153,14 +180,27 @@ Add a genetic test result.
|
|||||||
|
|
||||||
Track heat cycles and whelping projections.
|
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 /heat-cycles/active`
|
||||||
Get currently active heat cycles.
|
Get currently active heat cycles.
|
||||||
|
|
||||||
|
### `GET /heat-cycles/dog/:dogId`
|
||||||
|
Get all heat cycles for a specific dog.
|
||||||
|
|
||||||
### `GET /heat-cycles/:id/suggestions`
|
### `GET /heat-cycles/:id/suggestions`
|
||||||
Get optimal breeding window (days 9-15) and whelping projections.
|
Get optimal breeding window (days 9-15) and whelping projections.
|
||||||
|
|
||||||
### `POST /heat-cycles`
|
### `POST /heat-cycles`
|
||||||
Log a new heat cycle. Dog must be female.
|
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`
|
### `GET /whelping-calculator?breeding_date=YYYY-MM-DD`
|
||||||
Standalone tool to calculate expected whelping window.
|
Standalone tool to calculate expected whelping window.
|
||||||
@@ -178,10 +218,19 @@ Get an interactive pedigree tree (ancestors). Default 5 generations.
|
|||||||
Get a descendant tree. Default 3 generations.
|
Get a descendant tree. Default 3 generations.
|
||||||
|
|
||||||
### `POST /trial-pairing`
|
### `POST /trial-pairing`
|
||||||
Calculate Coefficient of Inbreeding (COI) for a hypothetical mating.
|
Calculate Coefficient of Inbreeding (COI) for a hypothetical mating. (`POST /coi` is an alias.)
|
||||||
- **Body**: `sire_id`, `dam_id`.
|
- **Body**: `sire_id`, `dam_id`.
|
||||||
- **Response**: `{ coi, commonAncestors, directRelation, recommendation }`
|
- **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`)
|
## 7. Settings (`/api/settings`)
|
||||||
@@ -223,9 +272,13 @@ Update kennel settings.
|
|||||||
"id": 5,
|
"id": 5,
|
||||||
"sire_id": 1,
|
"sire_id": 1,
|
||||||
"dam_id": 2,
|
"dam_id": 2,
|
||||||
"breeding_date": "2023-01-01",
|
"sire_name": "Sire Name",
|
||||||
"whelp_date": "2023-03-05",
|
"dam_name": "Dam Name",
|
||||||
"total_count": 8,
|
"breeding_date": "2026-01-01",
|
||||||
"puppies": [ ... ]
|
"whelping_date": "2026-03-05",
|
||||||
|
"puppy_count": 8,
|
||||||
|
"notes": null,
|
||||||
|
"puppies": [ ... ],
|
||||||
|
"actual_puppy_count": 8
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
+27
-16
@@ -5,10 +5,10 @@ This document provides technical details and guidelines for developing and maint
|
|||||||
## Tech Stack Overview
|
## Tech Stack Overview
|
||||||
|
|
||||||
### Backend
|
### Backend
|
||||||
- **Node.js & Express**: Core API server.
|
- **Node.js & Express**: Core API server. Node 18+ required (better-sqlite3 v11 prebuilds cover Node 18–24; Docker runs node:18).
|
||||||
- **better-sqlite3**: High-performance SQLite driver.
|
- **better-sqlite3**: High-performance SQLite driver. Multi-step writes use `db.transaction()`.
|
||||||
- **Multer**: Multi-part form data handling for photo uploads.
|
- **Multer**: Multi-part form data handling for photo and document uploads (type + size limits enforced).
|
||||||
- **Bcrypt & JWT**: (Planned) Authentication and security.
|
- **Authentication**: Deliberately not implemented — BREEDR is a self-hosted LAN app. Revisit as its own feature if exposure changes (decision: July 2026).
|
||||||
|
|
||||||
### Frontend
|
### Frontend
|
||||||
- **React 18 & Vite**: Modern reactive UI with fast HMR.
|
- **React 18 & Vite**: Modern reactive UI with fast HMR.
|
||||||
@@ -22,7 +22,7 @@ This document provides technical details and guidelines for developing and maint
|
|||||||
## Database Architecture
|
## Database Architecture
|
||||||
|
|
||||||
### SQLite Implementation
|
### SQLite Implementation
|
||||||
The database is a single file located at `data/breedr.db`. This directory is automatically created on startup.
|
The database is a single file at `data/breedr.db` by default; both the migration runner and the app honor `DB_PATH`, and the containing directory is created automatically on startup.
|
||||||
|
|
||||||
### "Parents Table" Approach
|
### "Parents Table" Approach
|
||||||
Parent relationships are managed in a dedicated `parents` table rather than columns in the `dogs` table.
|
Parent relationships are managed in a dedicated `parents` table rather than columns in the `dogs` table.
|
||||||
@@ -33,17 +33,20 @@ Parent relationships are managed in a dedicated `parents` table rather than colu
|
|||||||
**Benefits**: Supports recursive lookups, avoids `ALTER TABLE` complexity for lineage changes, and allows historical mapping of ancestors without full profiles.
|
**Benefits**: Supports recursive lookups, avoids `ALTER TABLE` complexity for lineage changes, and allows historical mapping of ancestors without full profiles.
|
||||||
|
|
||||||
### Safe Migrations
|
### Safe Migrations
|
||||||
BREEDR use a migration-free synchronization approach:
|
BREEDR uses a two-layer synchronization approach, both run at startup (`server/index.js`):
|
||||||
1. `server/db/init.js` defines the latest table structures.
|
1. `server/db/migrations.js` — a versioned migration runner for structural rewrites (e.g. moving sire/dam into the `parents` table). Migrations no-op on a fresh/empty database.
|
||||||
2. Safe `ALTER TABLE` guards inject missing columns on startup.
|
2. `server/db/init.js` — defines the latest table structures (`CREATE TABLE IF NOT EXISTS`) and injects missing columns with safe `ALTER TABLE` guards.
|
||||||
3. This ensures data persistence across updates without manual migration scripts.
|
|
||||||
|
> ⚠️ **Keep init.js in sync with the routes.** The schema drifted once (routes wrote columns init.js never defined) and only worked because the live Docker volume carried an older ad-hoc schema — fresh installs were broken. When adding a column a route writes, add it to the `CREATE TABLE` *and* the ALTER-if-missing list. Verify by booting against a deleted/renamed dev DB.
|
||||||
|
|
||||||
### Key Tables
|
### Key Tables
|
||||||
- `dogs`: Registry for kennel and external dogs.
|
- `dogs`: Registry for kennel and external dogs.
|
||||||
- `parents`: Ancestry relationships.
|
- `parents`: Ancestry relationships.
|
||||||
- `litters`: Produced breeding groups.
|
- `litters`: Produced breeding groups.
|
||||||
- `health_records`: OFA clearances and vet records.
|
- `heat_cycles`: Female heat cycle tracking (calendar + whelping projections).
|
||||||
|
- `health_records`: OFA clearances, vet records, and puppy weight logs.
|
||||||
- `genetic_tests`: DNA panel results.
|
- `genetic_tests`: DNA panel results.
|
||||||
|
- `cancer_history`: Cancer/longevity lineage records.
|
||||||
- `settings`: Kennel-wide configuration (single row).
|
- `settings`: Kennel-wide configuration (single row).
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -70,23 +73,31 @@ The UI follows a modern dark-theme aesthetic using **CSS Variables** defined in
|
|||||||
### Key Components
|
### Key Components
|
||||||
- **PedigreeTree**: horizontal, D3-powered tree with zoom/pan.
|
- **PedigreeTree**: horizontal, D3-powered tree with zoom/pan.
|
||||||
- **DogForm**: Dual-mode (Kennel/External) dog entry with parent selection.
|
- **DogForm**: Dual-mode (Kennel/External) dog entry with parent selection.
|
||||||
|
- **Toast** (`components/Toast.jsx`): `ToastProvider` + `useToast()` — success/error toasts. **Never use `alert()`**; call `toast.error(err.response?.data?.error || 'fallback')`.
|
||||||
|
- **ConfirmDialog** (`components/ConfirmDialog.jsx`): `ConfirmProvider` + `useConfirm()` — promise-based destructive-action confirmation. **Never use `window.confirm()`**; call `if (!(await confirm({ title, message }))) return`.
|
||||||
|
- Both providers wrap the app in `App.jsx`. Page loaders should use `Promise.allSettled` + an error banner with Retry rather than silently swallowing fetch failures (see `Dashboard.jsx`, `BreedingCalendar.jsx`).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## API & Backend Development
|
## API & Backend Development
|
||||||
|
|
||||||
### Route Modules (`server/routes/`)
|
### Route Modules (`server/routes/`)
|
||||||
- `/api/dogs`: Dog registry and photo uploads.
|
- `/api/dogs`: Dog registry and photo uploads (paginated list, parent validation, transactional writes).
|
||||||
- `/api/litters`: Litter management and puppy linking.
|
- `/api/litters`: Litter management, puppy linking, and puppy weight/health logs.
|
||||||
- `/api/pedigree`: Recursive ancestry/descendant tree generation.
|
- `/api/health`: OFA clearances, vet records, clearance summaries, document upload.
|
||||||
|
- `/api/genetics`: DNA panel results and pairing-risk checks.
|
||||||
|
- `/api/pedigree`: Recursive ancestry/descendant tree generation and COI.
|
||||||
- `/api/breeding`: Heat cycle tracking and whelping projections.
|
- `/api/breeding`: Heat cycle tracking and whelping projections.
|
||||||
|
- `/api/settings`: Kennel-wide configuration.
|
||||||
|
|
||||||
### Environment Variables
|
### Environment Variables
|
||||||
| Variable | Description | Default |
|
| Variable | Description | Default |
|
||||||
|----------|-------------|---------|
|
|----------|-------------|---------|
|
||||||
| `PORT` | Server port | `3000` |
|
| `PORT` | Server port | `3000` |
|
||||||
| `DB_PATH` | Path to .db file | `../data/breedr.db` |
|
| `DB_PATH` | Path to .db file (honored by both migrations and the app) | `data/breedr.db` |
|
||||||
| `UPLOAD_PATH`| Path to photo storage| `../uploads` |
|
| `DATA_DIR` | Data directory (created on boot) | `data/` |
|
||||||
|
| `UPLOAD_PATH`| Path to photo/document storage | `uploads/` |
|
||||||
|
| `STATIC_PATH`| Path to branded static assets | `static/` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -98,4 +109,4 @@ For deeper technical dives into specific features, refer to the `docs/` director
|
|||||||
- [Microchip Field Unique Constraint Fix](docs/MICROCHIP_FIX.md)
|
- [Microchip Field Unique Constraint Fix](docs/MICROCHIP_FIX.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
*Last Updated: March 12, 2026*
|
*Last Updated: July 6, 2026*
|
||||||
|
|||||||
+5
-5
@@ -113,14 +113,14 @@ Access: http://localhost:3000
|
|||||||
================================
|
================================
|
||||||
```
|
```
|
||||||
|
|
||||||
### Test Health Endpoint
|
### Test the API
|
||||||
```bash
|
```bash
|
||||||
curl http://localhost:3000/api/health
|
curl http://localhost:3000/api/settings
|
||||||
```
|
```
|
||||||
|
|
||||||
Should return:
|
Should return the kennel settings JSON, e.g.:
|
||||||
```json
|
```json
|
||||||
{"status":"ok","timestamp":"..."}
|
{"id":1,"kennel_name":"BREEDR", ...}
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -136,7 +136,7 @@ docker rm breedr
|
|||||||
|
|
||||||
# Pull latest code
|
# Pull latest code
|
||||||
cd /tmp/breedr
|
cd /tmp/breedr
|
||||||
git pull origin master
|
git pull origin main
|
||||||
|
|
||||||
# Rebuild image
|
# Rebuild image
|
||||||
docker build -t breedr:latest .
|
docker build -t breedr:latest .
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ A reactive, interactive dog breeding genealogy mapping system for professional k
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🌟 Recent Highlights (v0.8.0)
|
## 🌟 Recent Highlights (v0.8.1 — July 2026)
|
||||||
- **✅ Reverse Pedigree** — Toggle between ancestors and descendants view for full lineage tracking.
|
- **✅ Fresh-install fix** — Schema definitions reconciled with the routes; a brand-new database now boots with heat cycles, litters, and puppy logs fully working.
|
||||||
- **✅ External Dog Mapping** — Assign parents to external dogs, allowing for full genealogy of outside lines.
|
- **✅ Health Records overhaul** — Per-type record forms (OFA / vaccination / exam / surgery / medication), document upload (PDF/image), OFA age validation, and delete actions.
|
||||||
- **✅ Universal Parent Selection** — Select any dog (kennel or external) as a sire/dam from any profile.
|
- **✅ UX layer** — Toast notifications, proper confirmation dialogs, load-error banners with retry, a 404 page, and mobile-friendly layouts across all pages.
|
||||||
|
- **✅ Hardened API** — Sire/dam sex validation, transactional writes, and safe photo handling.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -22,11 +23,13 @@ docker-compose up -d --build
|
|||||||
Access at: `http://localhost:3000`
|
Access at: `http://localhost:3000`
|
||||||
|
|
||||||
### 2. Manual Development Setup
|
### 2. Manual Development Setup
|
||||||
|
Requires **Node.js 18+** (better-sqlite3 v11 ships prebuilds for Node 18–24).
|
||||||
```bash
|
```bash
|
||||||
npm install
|
npm install
|
||||||
npm run dev
|
cd client && npm install && cd ..
|
||||||
|
npm run dev # runs API (nodemon, :3000) + client (vite, :5173) together
|
||||||
```
|
```
|
||||||
> **Note:** The database initializes automatically on first boot. No manual migrations are required.
|
> **Note:** The database initializes automatically on first boot — tables and columns are created/added via safe guards. No manual migrations are required.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -42,6 +45,8 @@ npm run dev
|
|||||||
- **Interactive Pedigree**: 5-generation trees with zoom/pan. Toggle the **Reverse Pedigree** switch to see descendant lineage.
|
- **Interactive Pedigree**: 5-generation trees with zoom/pan. Toggle the **Reverse Pedigree** switch to see descendant lineage.
|
||||||
- **Trial Pairing Simulator**: Calculate Wright's Inbreeding Coefficient (COI) instantly. Identifies common ancestors and providing risk badges (Low/Moderate/High).
|
- **Trial Pairing Simulator**: Calculate Wright's Inbreeding Coefficient (COI) instantly. Identifies common ancestors and providing risk badges (Low/Moderate/High).
|
||||||
- **Heat Cycles**: Track female cycles on the calendar. Includes **projected whelping alerts** (indigo windows) and expected due dates.
|
- **Heat Cycles**: Track female cycles on the calendar. Includes **projected whelping alerts** (indigo windows) and expected due dates.
|
||||||
|
- **Health Records**: OFA clearances (hip, elbow, patella, heart, eyes, thyroid), GRCA/CHIC clearance summaries, vaccinations, exams, surgeries, and medications — with supporting-document upload.
|
||||||
|
- **DNA Panel**: Golden Retriever genetic markers (PRA, ICH, NCL, DM, MD) with carrier-risk checks on trial pairings.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -69,8 +74,9 @@ breedr/
|
|||||||
|
|
||||||
## 🕒 Release Summary
|
## 🕒 Release Summary
|
||||||
|
|
||||||
|
- **v0.8.1** (Jul 2026): Fresh-install schema fix, health record overhaul, toast/dialog UX layer, API hardening, mobile responsiveness.
|
||||||
- **v0.8.0** (Mar 2026): Reverse Pedigree & External dog parentage.
|
- **v0.8.0** (Mar 2026): Reverse Pedigree & External dog parentage.
|
||||||
- **v0.7.0** (In Progress): Health & Genetics (OFA clearances, DNA panels).
|
- **v0.7.0**: Health & Genetics (OFA clearances, DNA panels, cancer history).
|
||||||
- **v0.6.1**: COI calculation fix for direct parent×offspring relations.
|
- **v0.6.1**: COI calculation fix for direct parent×offspring relations.
|
||||||
- **v0.6.0**: Champion status tracking & Kennel settings API.
|
- **v0.6.0**: Champion status tracking & Kennel settings API.
|
||||||
|
|
||||||
|
|||||||
+48
-36
@@ -1,39 +1,39 @@
|
|||||||
# BREEDR Development Roadmap (v0.8.0)
|
# BREEDR Development Roadmap (v0.8.1)
|
||||||
|
|
||||||
## 🚀 Current Status: v0.8.0 (Active Development)
|
## 🚀 Current Status: v0.8.1 (Active Development)
|
||||||
|
|
||||||
### 🔜 Next Up — Phase 4b: Health & Genetics Build Order
|
### 🔜 Next Up — Phase 4b: Health & Genetics (remaining items)
|
||||||
> **Context:** Golden Retriever health clearances follow GRCA Code of Ethics and OFA/CHIC standards.
|
> **Context:** Golden Retriever health clearances follow GRCA Code of Ethics and OFA/CHIC standards.
|
||||||
|
|
||||||
#### Step 1: DB Schema Extensions
|
#### Step 1: DB Schema Extensions ✅
|
||||||
- [ ] Extend `health_records` table with OFA-specific columns (test_type, result, ofa_number, chic_number, expires_at, document_url)
|
- [x] Extend `health_records` table with OFA-specific columns (test_type, result, ofa_number, expires_at, document_url)
|
||||||
- [ ] Create `genetic_tests` table (PRA, ICH, NCL, DM, MD, GR-PRA variants)
|
- [x] Create `genetic_tests` table (PRA, ICH, NCL, DM, MD, GR-PRA variants)
|
||||||
- [ ] Create `cancer_history` table
|
- [x] Create `cancer_history` table
|
||||||
- [ ] Add `chic_number`, `age_at_death`, `cause_of_death` to `dogs` table
|
- [x] Add `chic_number`, `age_at_death`, `cause_of_death` to `dogs` table
|
||||||
- [ ] All changes via safe ALTER TABLE / CREATE TABLE IF NOT EXISTS guards
|
- [x] All changes via safe ALTER TABLE / CREATE TABLE IF NOT EXISTS guards
|
||||||
|
|
||||||
#### Step 2: API Layer
|
#### Step 2: API Layer ✅
|
||||||
- [ ] `GET|POST|PUT|DELETE /api/health/:dogId` (OFA records)
|
- [x] Health record CRUD (`/api/health`) + document upload (`POST /api/health/upload`)
|
||||||
- [ ] `GET /api/health/:dogId/clearance-summary`
|
- [x] `GET /api/health/dog/:dogId/clearance-summary`
|
||||||
- [ ] `GET /api/health/:dogId/chic-eligible`
|
- [x] `GET /api/health/dog/:dogId/chic-eligible`
|
||||||
- [ ] `GET|POST|PUT|DELETE /api/genetics/:dogId`
|
- [x] Genetics CRUD (`/api/genetics`)
|
||||||
- [ ] `GET /api/genetics/pairing-risk` (sire + dam carrier check)
|
- [x] `GET /api/genetics/pairing-risk` (sire + dam carrier check)
|
||||||
- [ ] Cancer history endpoints
|
- [x] Cancer history endpoints
|
||||||
|
|
||||||
#### Step 3: Core UI — Health Records
|
#### Step 3: Core UI — Health Records
|
||||||
- [ ] `HealthRecordForm` modal (test type, result, OFA#, expiry, doc upload)
|
- [x] `HealthRecordForm` modal (per-type fields, result, OFA#, expiry, doc upload, age validation)
|
||||||
- [ ] `HealthTimeline` on DogDetail page
|
- [ ] `HealthTimeline` on DogDetail page (records list exists; timeline view pending)
|
||||||
- [ ] `ClearanceSummaryCard` 2×2 grid (Hip / Elbow / Heart / Eyes)
|
- [x] `ClearanceSummaryCard` 2×2 grid (Hip / Elbow / Heart / Eyes)
|
||||||
- [ ] `ChicStatusBadge` on dog cards
|
- [ ] `ChicStatusBadge` on dog cards
|
||||||
- [ ] Expiry alert badges (90-day warning, expired)
|
- [x] Expiry logic for recurring tests (CAER, echo) in clearance summary
|
||||||
|
|
||||||
#### Step 4: Core UI — Genetics Panel
|
#### Step 4: Core UI — Genetics Panel ✅
|
||||||
- [ ] `GeneticTestForm` modal
|
- [x] `GeneticTestForm` modal
|
||||||
- [ ] `GeneticPanelCard` on DogDetail (color-coded markers)
|
- [x] `GeneticPanelCard` on DogDetail (color-coded markers)
|
||||||
- [ ] Pairing risk overlay on Trial Pairing Simulator
|
- [x] Pairing risk overlay on Trial Pairing Simulator
|
||||||
|
|
||||||
#### Step 5: Eligibility Checker
|
#### Step 5: Eligibility Checker
|
||||||
- [ ] Eligibility logic (`grca_eligible`, `chic_eligible` computed fields)
|
- [x] Eligibility logic (`grca_eligible` computed in clearance summary)
|
||||||
- [ ] Eligibility badge on dog cards
|
- [ ] Eligibility badge on dog cards
|
||||||
- [ ] Pre-litter eligibility warning modal
|
- [ ] Pre-litter eligibility warning modal
|
||||||
|
|
||||||
@@ -41,7 +41,15 @@
|
|||||||
|
|
||||||
## 🕒 Version History & Recent Progress
|
## 🕒 Version History & Recent Progress
|
||||||
|
|
||||||
- **v0.8.0** (March 12, 2026) - Reverse Pedigree & External Parentage (LATEST)
|
- **v0.8.1** (July 6, 2026) - Sanity, Hardening & UX Pass (LATEST)
|
||||||
|
- [x] **Fresh-install fix**: `heat_cycles` table + litters/health_records columns added to init.js (schema had drifted from route usage); migration runner no-ops on empty DBs; `DB_PATH` honored consistently
|
||||||
|
- [x] **Deps**: better-sqlite3 9→11 (Node 18–24 prebuilds); removed unused auth deps (bcrypt, jsonwebtoken, express-validator, express-rate-limit) — auth deliberately deferred
|
||||||
|
- [x] **API hardening**: sire/dam existence + sex validation, 404 on missing-dog updates, transactional multi-step writes, safe `photo_urls` parsing, photo-index bounds check
|
||||||
|
- [x] **UX layer**: toast notifications (replaces all `alert()`), ConfirmDialog (replaces all `window.confirm()`), load-error banners with Retry (`Promise.allSettled` loaders), 404 page, nav active-state on detail routes
|
||||||
|
- [x] **Fixes**: Start Heat Cycle female list was always empty (wrong response key); live OFA age warning in health form; puppy sorting; mobile responsiveness (375px clean on all pages)
|
||||||
|
- [x] Removed dead debug scripts (`test_app.js`, `test_express.js`)
|
||||||
|
|
||||||
|
- **v0.8.0** (March 12, 2026) - Reverse Pedigree & External Parentage
|
||||||
- [x] **Reverse Pedigree** (descendants view) toggle on Pedigree page
|
- [x] **Reverse Pedigree** (descendants view) toggle on Pedigree page
|
||||||
- [x] **External dog parentage** improvements (allowed assigning sire/dam to external dogs)
|
- [x] **External dog parentage** improvements (allowed assigning sire/dam to external dogs)
|
||||||
- [x] **Universal parent selection** (sire/dam dropdowns now include all dogs)
|
- [x] **Universal parent selection** (sire/dam dropdowns now include all dogs)
|
||||||
@@ -95,10 +103,13 @@
|
|||||||
- [ ] Multi-generation COI analysis
|
- [ ] Multi-generation COI analysis
|
||||||
|
|
||||||
### 📅 Phase 6: Polish & Optimization
|
### 📅 Phase 6: Polish & Optimization
|
||||||
- [ ] **User Experience**: Loading states, better error messages, undo functionality
|
- [x] **User Experience**: Toasts, confirmation dialogs, load-error banners with retry (v0.8.1)
|
||||||
- [ ] **Performance**: Image optimization, lazy loading, API caching
|
- [ ] **User Experience**: Undo functionality
|
||||||
- [ ] **Mobile**: Touch-friendly interface, mobile photo capture
|
- [ ] **Performance**: Image optimization, lazy loading, API caching, pedigree recursive-CTE query (known N+1 on deep trees)
|
||||||
- [ ] **Documentation**: API technical docs, video tutorials
|
- [x] **Mobile**: Responsive layouts across all pages at phone width (v0.8.1)
|
||||||
|
- [ ] **Mobile**: Mobile photo capture
|
||||||
|
- [x] **Documentation**: API reference kept current (API.md)
|
||||||
|
- [ ] **Security**: Authentication/rate limiting if the app is ever exposed beyond the LAN (deps intentionally removed in v0.8.1)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -127,21 +138,22 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
## 🏃 Testing & Quality Assurance
|
## 🏃 Testing & Quality Assurance
|
||||||
- [x] Database schema initialization guards
|
- [x] Database schema initialization guards (verified against a virgin database, v0.8.1)
|
||||||
- [x] Pedigree tree rendering & zoom/pan
|
- [x] Pedigree tree rendering & zoom/pan
|
||||||
- [x] Parent relationship creation logic
|
- [x] Parent relationship creation logic (+ sex/existence validation, v0.8.1)
|
||||||
- [x] Static asset serving (prod/dev)
|
- [x] Static asset serving (prod/dev)
|
||||||
|
- [x] Heat cycle CRUD on fresh DB (v0.8.1)
|
||||||
|
- [x] Health records CRUD + document upload (v0.8.1)
|
||||||
- [ ] Champion toggle load/save trip
|
- [ ] Champion toggle load/save trip
|
||||||
- [ ] Heat cycle calendar whelping logic
|
- [ ] Boot against a copy of the production DB after schema changes (pre-deploy check)
|
||||||
- [ ] Health records OFA clearance CRUD (Upcoming)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## How to Contribute
|
## How to Contribute
|
||||||
1. Pick a feature from "Next Up" above
|
1. Pick a feature from "Next Up" above
|
||||||
2. Create a feature branch off `master`: `feat/feature-name`
|
2. Create a feature branch off `main`: `feat/feature-name`
|
||||||
3. Implement with tests and update this roadmap
|
3. Implement with tests and update this roadmap
|
||||||
4. Submit PR for review
|
4. Submit PR for review
|
||||||
|
|
||||||
---
|
---
|
||||||
*Last Updated: March 12, 2026*
|
*Last Updated: July 6, 2026*
|
||||||
|
|||||||
Reference in New Issue
Block a user