Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Moon Base
Property management for the Moon homestead (Eau Claire, WI). A single place to track the food forest, household inventory, and recurring upkeep — built as a Next.js 14 + Prisma + Postgres app, deployed self-hosted on the home NAS.
Live at http://192.168.0.5:8053.
Modules
- Garden — plant registry with care/harvest/observation logs, plant groups, reusable plant types (the "kind" record: care notes, sun/water, bloom & harvest months, pet toxicity), Wikipedia photos, and plants placed on the shared location tree.
- Inventory — durable items that nest (boxes within rooms within buildings), with labels, attachments, and logs. Shares the same location spine as the garden.
- Reminders — one-off or recurring tasks (every N days / monthly / yearly), optionally linked to a plant.
- REST API (
/api/v1/*) — personal access tokens with per-scope permissions (read plants, log harvests, …) for phone shortcuts, Home Assistant, and automation. - Suggestions — in-app feedback that files issues to Gitea (
@otm/account-panel). - Backup & Restore — download/restore the whole dataset as a zip (admin only).
- Self-update — admins get a "Pull & rebuild" button that updates the running app to the latest pushed version (see Deploy).
Tech
Next.js 14 (App Router) · Prisma · PostgreSQL · NextAuth (credentials) · Tailwind + shadcn/ui · Docker Compose.
Local dev
npm install
cp .env.example .env # fill in DATABASE_URL + NEXTAUTH_SECRET
npx prisma migrate deploy # schema + provisions bonna/tony accounts
npm run db:seed # optional demo data (SEED_MODE=minimal for accounts only)
npm run dev # http://localhost:3000
After schema edits: npx prisma generate then restart. Data backfills for the
location/plant-type refactors: npm run db:backfill-locations,
npm run db:backfill-plant-types.
Auth / first run
Username or email login. Provisioned accounts bonna / tony (role ADMIN)
ship with the default password moonbase! and mustChangePassword=true — the app
forces a password change on first sign-in.
Deploy
The NAS appdata (/mnt/user/appdata/moonbase) is a git checkout of this repo.
Two ways to ship a change:
- In-app (admins): Settings → Updates → Pull & rebuild. A privileged
updatersidecar runsgit pull && docker compose up -d --build appand the UI reloads on the new version. - Manual:
git push origin master ssh root@192.168.0.5 'cd /mnt/user/appdata/moonbase && git pull && docker compose up -d --build'
Do not rsync over the appdata dir — it would fight the checkout. Secrets
(NEXTAUTH_SECRET, GITEA_TOKEN, UPDATER_SECRET) live in a gitignored host
.env next to the compose file, never committed. Migrations apply automatically
on container start.
Conventions
Every commit bumps APP_VERSION (src/lib/version.ts) + a plain-English entry in
src/lib/changelog.ts (written for Bonna, shown in the footer). AuditEvent on
every mutation. Soft-delete via active=false. Pure logic in src/lib/* with
colocated tests; API routes stay thin. Repo on Gitea: bonna61/Moonbase.