Garden Almanac is a full-stack project consisting of a React frontend (almanac-client) and a Node/Express backend (almanac-server) powered by MongoDB. It helps track plants, categories, events, and seasonal tips β with extras like Unsplash image integration and email-based authentication.
- almanac-client β React frontend
- almanac-server β Express + MongoDB backend
- almanac-shared β Shared constants and helpers (password rules, validation, etc.)
- π± JWT-based authentication (signup with email activation, login, forgot/reset password)
- π¦ Climate zone lookup (future: weather forecast proxy)
- π Event and plant management with categories
- π· Unsplash proxy endpoint (safe keys, cache-friendly)
- π§ Email delivery with Nodemailer (App Password or SMTP)
- π Validators, CORS, and logger utility for cleaner DX
- Frontend: React (Vite), Axios, TailwindCSS
- Backend: Node.js 18+, Express, MongoDB (Mongoose), JWT, Nodemailer
- Shared: npm package
@daidensacha/almanac-shared
cd almanac-server
npm install
cp .env.example .env
npm startRequirements:
- Node.js 18+
- MongoDB (local or Atlas cluster)
- Gmail App Password (or SMTP credentials)
cd almanac-client
npm install
npm start# App
PORT=8000
NODE_ENV=development
CLIENT_URL=http://localhost:3000
# Database
DATABASE_URL=mongodb://127.0.0.1:27017/garden_almanac
# JWT
JWT_SECRET=super_secret_for_auth_tokens
JWT_ACCOUNT_ACTIVATION=activation_secret_for_signup
# Email
EMAIL_FROM=[email protected]
EMAIL_TO=[email protected]
GMAIL_PASSWORD=your_gmail_app_password
# Unsplash
UNSPLASH_ACCESS_KEY=your_unsplash_keyBase URL: /api
POST /signup+POST /account-activationPOST /signinPUT /forgot-passwordPUT /reset-password
GET /user/:idPUT /user/update
GET /categoriesGET /plantsGET /events- CRUD variants for each
GET /climate-zone/:lat/:lonGET /unsplash/photos?query=β¦
# Request reset
domain/api/forgot-password { email }
# User clicks emailed link β frontend route `/reset-password/:token`
# Confirm reset
domain/api/reset-password { token, newPassword }almanac-shared provides reusable constants and validation rules.
Exports:
PASSWORD_REGEXPASSWORD_MESSAGE
Usage:
// Client (ESM)
import { PASSWORD_REGEX, PASSWORD_MESSAGE } from '@daidensacha/almanac-shared';
// Server (CommonJS)
const { PASSWORD_REGEX } = require('@daidensacha/almanac-shared');See Branching & Deploy Playbook and CONTRIBUTING.
- Protected branch: main
- Branches:
feature/<name>orfix/<name> - Use conventional commits
- PRs should link issues and show testing steps
- Weather API proxy (Open-Meteo) + caching
- Recurrence rules (RRULE) for events
- Agenda/cron reminders (email β push)
- Security hardening (Helmet, rate-limit, deeper validation)
- Advanced dashboard features (charts, plant insights)
See CONTRIBUTING.md
- Comment or open an issue before starting
- Use feature branches from
main - Keep PRs focused & small
- Add screenshots/gifs when relevant
Quick Links:
MIT Β© Daiden Sacha
