# Sproutly 🌱 A self-hosted plant growth tracking web app designed to help home gardeners manage their seed starting schedules, growing cycles, and garden transitions — all anchored to their local last frost date. ## Overview Sproutly takes the guesswork out of seed starting. Enter your plant varieties once with their frost-relative timing (e.g. "start 8 weeks before last frost"), set your last frost date, and Sproutly calculates exactly when to start seeds, move to the greenhouse, and transplant to the garden. A daily push notification via [ntfy](https://ntfy.sh) keeps you on track without having to check the app. ## Features - **Multi-user** — each user has their own account with fully isolated data - **Admin panel** — manage all user accounts: view content, reset passwords, disable, or delete; shows each user's join date and last login - **Dashboard** — at-a-glance view of overdue, today's, and upcoming tasks with a full year planting timeline - **Seed Library** — manage plant varieties with frost-relative timing, germination days, sun/water requirements - **Garden Tracker** — log growing batches and track status from `planned` → `germinating` → `seedling` → `potted up` → `hardening off` → `garden` → `harvested` - **Smart date auto-fill** — when logging a new batch, sow date defaults to today and all subsequent dates (germination, greenhouse, transplant) are calculated automatically from the selected variety's timing - **Year Timeline** — visual calendar showing when each variety's stages fall across the year - **Ntfy Notifications** — per-user daily summary push notifications to your phone, configurable time, topic, and authentication - **Settings** — set your last frost date, fall frost date, location, timezone, and notification preferences ## Stack | Layer | Technology | |-----------|-------------------------| | Frontend | Nginx (static HTML/CSS/JS SPA) | | Backend | FastAPI (Python) | | Database | MySQL 8.0 | | Auth | JWT (python-jose + bcrypt) | | Notifications | Ntfy | | Runtime | Docker Compose | ## Getting Started ### Prerequisites - Docker and Docker Compose ### Run ```bash git clone https://git.chns.tech/CooperandGoodman/sproutly.git cd sproutly cp .env.example .env # set a strong SECRET_KEY and DB credentials docker compose up --build -d ``` Access the app at **http://localhost:8053** — create an account to get started. ### First Steps 1. Register an account on the login screen 2. Go to **Settings** and enter your last frost date — this anchors the planting timeline and dashboard calculations 3. Optionally configure an [ntfy](https://ntfy.sh) topic for push notifications 4. Add varieties to your **Seed Library** — each variety stores its frost-relative week offsets and germination days 5. Head to **My Garden** and log a batch — dates auto-fill based on today and the selected variety's timing ## Environment Variables Copy `.env.example` to `.env` and fill in all values: ```env MYSQL_ROOT_PASSWORD=sproutly_root_secret MYSQL_USER=sproutly MYSQL_PASSWORD=sproutly_secret SECRET_KEY=your-secret-key-change-this ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=change-this-password ``` `SECRET_KEY` is used to sign JWT tokens. Generate a secure value with: ```bash python3 -c "import secrets; print(secrets.token_hex(32))" ``` `ADMIN_EMAIL` and `ADMIN_PASSWORD` define the super admin account. This account is created (or updated) automatically every time the backend starts — changing these values in `.env` and restarting is all that's needed to update the credentials. ## Project Structure ``` sproutly/ ├── docker-compose.yml ├── .env ├── mysql/ │ └── init.sql # Schema (multi-user) ├── backend/ # FastAPI application │ ├── main.py │ ├── auth.py # JWT + bcrypt utilities │ ├── models.py │ ├── schemas.py │ ├── database.py │ └── routers/ │ ├── auth.py # /auth/register, /auth/login, /auth/me │ ├── admin.py # /admin/users — admin-only user management │ ├── varieties.py │ ├── batches.py │ ├── dashboard.py │ ├── settings.py │ └── notifications.py └── nginx/ ├── nginx.conf └── html/ # Static frontend SPA ├── index.html ├── css/style.css └── js/app.js ``` ## API The FastAPI backend is available at `/api/` and includes automatic docs at **http://localhost:8053/api/docs** All endpoints except `/auth/register` and `/auth/login` require a `Authorization: Bearer ` header. Key endpoints: - `POST /api/auth/register` — create account - `POST /api/auth/login` — get JWT token - `GET /api/auth/me` — current user info - `GET /api/dashboard/` — dashboard data, tasks, and timeline - `GET/POST/PUT/DELETE /api/varieties/` — seed variety management - `GET/POST/PUT/DELETE /api/batches/` — growing batch management - `GET/PUT /api/settings/` — app settings - `POST /api/notifications/test` — send test ntfy notification - `POST /api/notifications/daily` — trigger daily summary - `GET /api/notifications/log` — recent notification history - `GET /api/admin/users` — list all users with stats (admin only) - `GET /api/admin/users/{id}/varieties` — view a user's seed library (admin only) - `GET /api/admin/users/{id}/batches` — view a user's batches (admin only) - `POST /api/admin/users/{id}/reset-password` — reset a user's password (admin only) - `POST /api/admin/users/{id}/disable` — toggle account disabled state (admin only) - `DELETE /api/admin/users/{id}` — delete a user and all their data (admin only) ## Admin Panel Log in with the `ADMIN_EMAIL` / `ADMIN_PASSWORD` credentials from your `.env`. Once logged in, an **Admin** link appears in the sidebar. From there you can: - View all registered users with join date, last login, variety count, and batch count - Browse any user's seed library and growing batches - Reset a user's password - Disable or re-enable an account - Permanently delete an account and all associated data The admin account itself cannot be disabled or deleted through the panel. ## Ntfy Authentication For private ntfy servers or access-controlled topics, the Settings page supports three auth modes: | Mode | When to use | |------|-------------| | None | Public ntfy.sh topics | | Username & Password | ntfy server with basic auth enabled | | API Key / Token | ntfy account access token (generate in ntfy account settings) | ## Batch Date Auto-fill When logging a new batch, Sproutly pre-fills all date fields based on the selected variety's timing offsets, using **today as the sow date**: | Field | Calculation | |-------|-------------| | Sow date | Today | | Germination date | Sow date + `days_to_germinate` | | Greenhouse / pot-up date | Sow date + (`weeks_to_start` − `weeks_to_greenhouse`) × 7 | | Garden transplant date | Sow date + (`weeks_to_start` + `weeks_to_garden`) × 7 | All dates remain fully editable. Fields are left blank if the variety is missing the relevant timing value. ## Status Core infrastructure is functional. UI design and feature set are evolving based on user feedback.