# 🥚 Yolkbook A self-hosted, multi-user web app for backyard chicken keepers to track egg production, flock size, feed costs, and egg economics over time. ## Features - **Dashboard** — at-a-glance stats: total eggs, 7/30-day totals, averages (green), flock size (orange), cost per egg and per dozen - **Daily log** — record egg collections with one entry per day; includes full collection history with date filtering, edit, and delete below the form - **Flock management** — track changes to your flock size over time so per-hen averages stay accurate - **Feed tracking** — log feed purchases (bags + price per bag) - **Budget** — cost per egg and cost per dozen, all-time and over the last 30 days - **Monthly summary** — month-by-month breakdown of production, averages, feed cost, and cost per egg - **Multi-user** — each user has their own isolated data; self-registration on the login page - **Admin panel** — view all users, reset passwords, disable/enable accounts, delete accounts, and log in as any user - **Timezone support** — each user sets their own timezone so dates and stat windows are always accurate ## Tech Stack | Layer | Technology | |----------|-------------------------| | Frontend | Vanilla HTML/CSS/JS | | Backend | FastAPI (Python) | | Database | MySQL 8.0 | | Server | Nginx (static + proxy) | | Runtime | Docker Compose | ## Getting Started ### Prerequisites - Docker and Docker Compose ### Setup 1. Clone the repo: ```bash git clone https://git.chns.tech/CooperandGoodman/yolkbook.git cd yolkbook ``` 2. Create a `.env` file in the project root: ```env # MySQL MYSQL_ROOT_PASSWORD=your_root_password MYSQL_DATABASE=eggtracker MYSQL_USER=eggtracker MYSQL_PASSWORD=your_db_password # Super admin account (created/synced automatically on every startup) ADMIN_USERNAME=admin ADMIN_PASSWORD=your_admin_password # JWT signing secret — generate with: openssl rand -hex 32 JWT_SECRET=your_long_random_secret ``` 3. Start the stack: ```bash docker compose up -d --build ``` 4. Open your browser at `http://localhost:8056/login` and sign in with the admin credentials you set in `.env`. The database schema is applied automatically on first start via `mysql/init.sql`. The admin user is created (or synced) automatically every time the API starts. ## Authentication - **Login / Register** — the landing page (`/login`) has both a sign-in form and a self-registration link so users can create their own accounts. - **JWT tokens** — stored in `localStorage`, valid for 30 days. - **Admin password** — always sourced from the `ADMIN_PASSWORD` env var. Changing it in `.env` and restarting will update the admin's password. ## Admin Panel Accessible at `/admin` for admin accounts. Features: | Action | Description | |--------|-------------| | Reset password | Set a new password for any user | | Disable / Enable | Block or restore a user's access | | Delete | Permanently remove a user and all their data | | Login As | Impersonate a user to view or edit their data directly | When impersonating a user, an amber banner appears in the nav with a **Return to Admin** button. ## User Settings The gear icon (⚙) in the top-right nav opens the Settings panel: - **Timezone** — choose from a full list of IANA timezones or click *Detect automatically*. Affects what "today" is when pre-filling date fields and the 30-day/7-day windows on the dashboard and budget pages. - **Change Password** — update your own password (requires current password). ## Migrating an Existing Install (pre-multi-user) If you have an existing single-user install, run the migration script before rebuilding: ```bash # 1. Run the migration while the database is still running docker compose exec db mysql -u root -p"${MYSQL_ROOT_PASSWORD}" eggtracker < mysql/migrate_v2.sql # 2. Rebuild and restart docker compose up -d --build ``` All existing data will be automatically assigned to the admin account on first startup. ## API The FastAPI backend is available at `/api`. Interactive docs (Swagger UI) are at `/api/docs`. | Prefix | Description | |------------------|------------------------------------------| | `/api/auth` | Login, register, change password, timezone | | `/api/admin` | User management (admin only) | | `/api/eggs` | Egg collection records | | `/api/flock` | Flock size history | | `/api/feed` | Feed purchase records | | `/api/other` | Other purchases (bedding, snacks, etc.) | | `/api/stats` | Dashboard, budget, and monthly summary | All data endpoints require a valid JWT (`Authorization: Bearer `). Data is always scoped to the authenticated user. ## Project Structure ``` yolkbook/ ├── backend/ │ ├── main.py # FastAPI app entry point + startup seeding │ ├── auth.py # JWT utilities, password hashing, auth dependencies │ ├── models.py # SQLAlchemy models │ ├── schemas.py # Pydantic schemas │ ├── database.py # DB connection │ ├── routers/ │ │ ├── auth_router.py # /api/auth — login, register, settings │ │ ├── admin.py # /api/admin — user management │ │ ├── eggs.py │ │ ├── flock.py │ │ ├── feed.py │ │ ├── other.py │ │ └── stats.py │ ├── requirements.txt │ └── Dockerfile ├── nginx/ │ ├── html/ # Frontend (HTML, CSS, JS) │ │ ├── login.html │ │ ├── admin.html │ │ ├── index.html # Dashboard │ │ ├── log.html # Log Eggs + full collection history │ │ ├── js/ │ │ │ ├── api.js # Shared fetch helpers │ │ │ ├── auth.js # Auth utilities, nav, settings modal │ │ │ ├── history.js # Collection history table (used on log page) │ │ │ └── dashboard.js │ │ └── css/style.css │ └── nginx.conf ├── mysql/ │ ├── init.sql # Schema for fresh installs │ └── migrate_v2.sql # Migration for pre-multi-user installs ├── docker-compose.yml └── .env # Secrets — not committed ```