From 77cb71b7aad78e88e20e76f7c46f096e5d05188f Mon Sep 17 00:00:00 2001 From: fireshaper Date: Sun, 21 Jun 2026 23:33:49 -0400 Subject: [PATCH] Flesh out project README Co-Authored-By: Claude Opus 4.8 --- mykindlebox/README.md | 106 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/mykindlebox/README.md b/mykindlebox/README.md index bc2ccb2..f122b2c 100644 --- a/mykindlebox/README.md +++ b/mykindlebox/README.md @@ -1,3 +1,107 @@ # MyKindlebox -A self-hosted rabbitry (rabbit breeding herd) management web app. +A self-hosted rabbitry (rabbit breeding herd) management web app — track your +rabbits, their pedigrees, litters, and genetics. Single-user, self-hosted, and +designed to replace a legacy PHP herd-management site. + +The core differentiator: **adding a rabbit starts from a pedigree tree, not a +blank form.** The 3-generation ancestor tree (sire/dam and their sires/dams) is +the primary data-entry surface, with inline autocomplete against your existing +herd and graceful fallback to freeform text for bought-in or unknown ancestors. + +## Features + +- **Pedigree-first rabbit entry** — build the ancestor tree first, then fill in + details; unknown ancestors can be stored as plain text so entry is never + blocked by missing records. +- **Herd management** — name, sex, DOB, weight, and status + (`active` / `for_sale` / `on_hold` / `sold` / `deceased` / `other`). +- **Litters** — record kindle dates and kit counts; the kit list is derived + live from Rabbit records (no separate Kit table). +- **Genetics** — per-rabbit loci (`A/B/C/D/E/En/V`) and a session-only pairing + calculator for predicting offspring. +- **Dashboard** — herd counts derived live from rabbit status. +- **Pedigree printing**, CSV import/export, and a configurable weight display + (decimal lbs or lb + oz). +- **PWA-ready** with a mobile bottom nav, installable on phones/tablets. + +## Tech stack + +| Layer | Choice | +| -------- | ----------------------------------------------------- | +| Frontend | React 19 + Vite (PWA-ready) | +| Routing | React Router v7 | +| State | React Query (server sync) | +| Styling | Tailwind CSS | +| Backend | Node.js + Express 5 (REST API) | +| Database | SQLite via Drizzle ORM (single-file DB) | +| Auth | Single-user session token (optional password) | +| Hosting | Docker Compose (Nginx + Node + SQLite volume) | + +## Project layout + +``` +mykindlebox/ +├── client/ React + Vite frontend +├── server/ Express + SQLite/Drizzle API +└── docker-compose.yml Production stack (nginx + node + volume) +``` + +## Development + +Run the backend and frontend in two terminals. + +**Backend** (`server/`): + +```bash +cd server +npm install +npm run dev # API on http://localhost:3001 (tsx watch, hot reload) +``` + +Other scripts: `npm run build` (typecheck + compile to `dist/`), +`npm start` (run compiled server), `npm test`. + +**Frontend** (`client/`): + +```bash +cd client +npm install +npm run dev # Vite dev server on http://localhost:5173 +``` + +The dev server proxies `/api` and `/uploads` to `localhost:3001`. Other +scripts: `npm run build`, `npm run lint`, `npm test`. + +> The client talks to the API over **relative URLs** (`/api`, `/uploads`) so the +> app works over LAN and as an installed PWA — never hardcode a host. + +## Deployment (Docker Compose) + +From the `mykindlebox/` directory: + +```bash +docker compose up --build +``` + +The app is served on **http://localhost:8080** — nginx serves the built client +and reverse-proxies `/api` + `/uploads` to the Node server. The SQLite database +and uploaded photos live in the `server-data` Docker volume. + +### Authentication + +Auth is **optional** and off by default. To require a login, set +`MYKINDLEBOX_PASSWORD` (e.g. in a `.env` file next to `docker-compose.yml`): + +```env +MYKINDLEBOX_PASSWORD=your-password-here +``` + +If left unset, the app is open to anyone who can reach it — only acceptable on a +fully trusted network. + +## Data & backups + +The herd database (`server/data/`), uploaded photos, and `.env` files are +**gitignored** — they are never committed. In production they persist in the +`server-data` volume; back that volume up to preserve your data.