docs: add README, refresh CLAUDE.md for current modules + git-checkout deploy

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-16 00:18:06 -05:00
parent b0118d3fec
commit 777569a21a
2 changed files with 132 additions and 53 deletions

108
CLAUDE.md
View File

@@ -1,73 +1,75 @@
# Moon Base — Project Notes # Moon Base — Project Notes
Property management for the Moon homestead (Eau Claire, WI) — food forest plant Property management for the Moon homestead (Eau Claire, WI). Next.js 14 + Prisma +
registry, home maintenance tracking, and equipment logs. Next.js 14 + Prisma +
Postgres. Same conventions as FMB (`/Users/bonnamoon/Projects/fullmoonbakehouse`). Postgres. Same conventions as FMB (`/Users/bonnamoon/Projects/fullmoonbakehouse`).
Repo on Gitea: **`bonna61/Moonbase`**. Live at NAS:8053. See `README.md` for the
user-facing overview.
## Modules ## Modules (all live)
- **v0.1 — Garden:** food forest plant registry + care/harvest log. Live. - **Garden** — Plant registry + care/harvest logs, plant **groups**, reusable
- **Home maintenance** — planned next: systems, recurring tasks, repair history. **PlantType** records, Wikipedia photos. Plants sit on the shared location tree.
- **Equipment** — planned: tools/machines, service intervals, maintenance logs. - **Inventory** — durable **Item**s that nest (`parentItemId`), with **Label**s
(M:N via `LabelOnItem`), `ItemAttachment`, and `ItemLog`. Shares the Location spine.
- **Locations** — `Location` tree (self-ref `parentId`) shared by plants + items.
- **Reminders** — `Task` + `TaskCompletion`; recurrence in `src/lib/tasks/schedule.ts`.
- **REST API** — `/api/v1/*` authed by `ApiToken` (per-scope; logic in `src/lib/api/`).
- **Suggestions** — `@otm/account-panel` (Gitea npm registry) → files issues to the repo.
- **Backup & Restore** — `/api/admin/backup` + `/api/admin/restore` (admin only).
- **Self-update** — admin "Pull & rebuild" (see Deploy).
## Local dev ## Local dev
- DB: `postgresql://tonym@localhost:5432/moonbase_dev` - DB: `postgresql://tonym@localhost:5432/moonbase_dev`; copy `.env.example``.env`.
- Copy `.env.example``.env` and fill in values. - `npm install`, `npm run dev` (3000). After schema edits: `npx prisma generate`.
- `npm install` then `npm run dev` (port 3000) - `npx prisma migrate deploy` provisions Bonna + Tony. `npm run db:seed` for demo
- After schema edits: `npx prisma generate` then restart dev server. data (`SEED_MODE=minimal` = accounts only).
- Seed demo data: `npm run db:seed` (creates Bonna + Tony accounts + sample plants) - Backfills for the location/plant-type refactors: `npm run db:backfill-locations`,
- Minimal seed (admin accounts only): `SEED_MODE=minimal npm run db:seed` `npm run db:backfill-plant-types`.
- Apply migrations: `npx prisma migrate deploy`
## First-run setup (brand new machine / fresh DB) ## Deploy — git checkout on the NAS (NOT rsync)
1. `npm install` The NAS appdata (`/mnt/user/appdata/moonbase`) is a real **git checkout** tracking
2. Create `.env` from `.env.example` `origin/master` (remote URL carries the token). Deploy by:
3. `npx prisma migrate deploy` — creates the DB schema + provisions Bonna and Tony accounts
4. Default password for both is `moonbase!` with `mustChangePassword=true` — change on first login. ```sh
git push origin master
ssh root@192.168.0.5 'cd /mnt/user/appdata/moonbase && git pull && docker compose up -d --build'
```
Or admins click **Settings → Updates → Pull & rebuild**, which signals the
privileged `updater` sidecar (docker socket + adnanh/webhook) to run the same
`git pull && compose up -d --build app` detached; the UI polls `/api/version` and
reloads. **Never rsync over the appdata dir** — it fights the checkout.
- **Secrets** (`NEXTAUTH_SECRET`, `GITEA_TOKEN`, `UPDATER_SECRET`) live in a
gitignored host `.env` next to the compose file, interpolated in — never committed.
- **Docker runtime** mirrors FMB: `node:20-bookworm-slim` + openssl, runs as root,
full `node_modules`, `next start`. Migrations run on container start via the
entrypoint (waits for Postgres first). Image gotcha: don't let `npx prisma`
resolve at runtime — with no local prisma on PATH it pulls Prisma 7, which
rejects `url` in the datasource.
## Conventions (same as FMB) ## Conventions (same as FMB)
- **Every commit bumps APP_VERSION** in `src/lib/version.ts` + a plain-English - **Every commit bumps APP_VERSION** in `src/lib/version.ts` + a plain-English
entry at the top of `src/lib/changelog.ts`. Minor (0.X.0) for features/migrations, entry atop `src/lib/changelog.ts` (the footer shows it + an "update available"
patch for fixes. Write changelog for Bonna, not engineers. badge from `src/lib/update-check.ts`). Minor for features/migrations, patch for fixes.
- **AuditEvent on every mutation** — append-only, never delete. - **AuditEvent on every mutation** — append-only.
- **Soft-delete** via `active=false` for Plant (keeps log history intact). - **Soft-delete** via `active=false`.
- **Pure core + colocated test** — new logic goes in `src/lib/...` as a pure - **Pure core + colocated test** — logic in `src/lib/...` with a `.test.ts`; routes thin.
function with a `.test.ts` next to it; API routes stay thin.
- **Worktrees for parallel sessions** — same pattern as FMB. Use a worktree
(`git worktree add ../moonbase-<slug> -b <slug>`) if running two Claude sessions.
## Git remote
Add Gitea remote once the repo is created there:
```sh
git remote add gitea http://192.168.0.5:3022/tonym/moonbase.git
git push gitea main
```
## Auth ## Auth
- Username OR email login (same as FMB). Accounts: `bonna` / `tony`, role ADMIN. - Username OR email login. Accounts `bonna` / `tony`, role `ADMIN`.
- `mustChangePassword=true` on provisioned accounts — user is prompted on next login - `getSession()` / `requireAuth()` / `isAdmin()` in `src/lib/auth.ts`.
(add that redirect to `src/app/(dashboard)/layout.tsx` when implementing it). - **Forced password change is wired** (provisioned accounts ship `moonbase!` +
- `getSession()` / `isAdmin()` in `src/lib/auth.ts`. `mustChangePassword=true`): the dashboard layout redirects to `/change-password`
(outside the layout group; backed by `/api/account/change-password`). Don't
## Garden module — data model remove that redirect.
- `NEXTAUTH_SECRET` is asserted at runtime in production (skipped during build).
- **Plant** — commonName, species (scientific), variety, category (PlantCategory enum),
zone (freeform text: "Back yard north fence"), plantedAt, source, notes, active.
- **PlantLog** — per-plant log: type (OBSERVATION / CARE / HARVEST / TREATMENT /
TRANSPLANT / DIED), date, notes, quantity (freeform, for harvests).
- Category labels + log type labels/colors live in `src/lib/garden/categories.ts`.
- API: `POST /api/plants` (create plant), `POST /api/plants/[id]/logs` (add log entry).
## Color palette ## Color palette
Forest / earth theme. Key CSS variables: Forest / earth theme: `--canopy` (sidebar), `--leaf` (accent), `--soil` (text),
- `--canopy` — dark forest green sidebar `--dew` (bg), `--ember` (destructive).
- `--leaf` — fresh green accent
- `--soil` / `--soil-muted` — body text
- `--dew` — pale sage background
- `--ember` — red for destructive actions

77
README.md Normal file
View File

@@ -0,0 +1,77 @@
# 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
```sh
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:
1. **In-app (admins):** Settings → Updates → **Pull & rebuild**. A privileged
`updater` sidecar runs `git pull && docker compose up -d --build app` and the
UI reloads on the new version.
2. **Manual:**
```sh
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`.