From 777569a21afb417e9c077b89548aab07d4b3491a Mon Sep 17 00:00:00 2001 From: tonym Date: Tue, 16 Jun 2026 00:18:06 -0500 Subject: [PATCH] docs: add README, refresh CLAUDE.md for current modules + git-checkout deploy Co-Authored-By: Claude Opus 4.8 (1M context) --- CLAUDE.md | 108 +++++++++++++++++++++++++++--------------------------- README.md | 77 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 53 deletions(-) create mode 100644 README.md diff --git a/CLAUDE.md b/CLAUDE.md index c97adeb..21033d7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,73 +1,75 @@ # Moon Base — Project Notes -Property management for the Moon homestead (Eau Claire, WI) — food forest plant -registry, home maintenance tracking, and equipment logs. Next.js 14 + Prisma + +Property management for the Moon homestead (Eau Claire, WI). Next.js 14 + Prisma + 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. -- **Home maintenance** — planned next: systems, recurring tasks, repair history. -- **Equipment** — planned: tools/machines, service intervals, maintenance logs. +- **Garden** — Plant registry + care/harvest logs, plant **groups**, reusable + **PlantType** records, Wikipedia photos. Plants sit on the shared location tree. +- **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 -- DB: `postgresql://tonym@localhost:5432/moonbase_dev` -- Copy `.env.example` → `.env` and fill in values. -- `npm install` then `npm run dev` (port 3000) -- After schema edits: `npx prisma generate` then restart dev server. -- Seed demo data: `npm run db:seed` (creates Bonna + Tony accounts + sample plants) -- Minimal seed (admin accounts only): `SEED_MODE=minimal npm run db:seed` -- Apply migrations: `npx prisma migrate deploy` +- DB: `postgresql://tonym@localhost:5432/moonbase_dev`; copy `.env.example` → `.env`. +- `npm install`, `npm run dev` (3000). After schema edits: `npx prisma generate`. +- `npx prisma migrate deploy` provisions Bonna + Tony. `npm run db:seed` for demo + data (`SEED_MODE=minimal` = accounts only). +- Backfills for the location/plant-type refactors: `npm run db:backfill-locations`, + `npm run db:backfill-plant-types`. -## First-run setup (brand new machine / fresh DB) +## Deploy — git checkout on the NAS (NOT rsync) -1. `npm install` -2. Create `.env` from `.env.example` -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. +The NAS appdata (`/mnt/user/appdata/moonbase`) is a real **git checkout** tracking +`origin/master` (remote URL carries the token). Deploy by: + +```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) - **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, - patch for fixes. Write changelog for Bonna, not engineers. -- **AuditEvent on every mutation** — append-only, never delete. -- **Soft-delete** via `active=false` for Plant (keeps log history intact). -- **Pure core + colocated test** — new logic goes in `src/lib/...` as a pure - 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- -b `) 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 -``` + entry atop `src/lib/changelog.ts` (the footer shows it + an "update available" + badge from `src/lib/update-check.ts`). Minor for features/migrations, patch for fixes. +- **AuditEvent on every mutation** — append-only. +- **Soft-delete** via `active=false`. +- **Pure core + colocated test** — logic in `src/lib/...` with a `.test.ts`; routes thin. ## Auth -- Username OR email login (same as FMB). Accounts: `bonna` / `tony`, role ADMIN. -- `mustChangePassword=true` on provisioned accounts — user is prompted on next login - (add that redirect to `src/app/(dashboard)/layout.tsx` when implementing it). -- `getSession()` / `isAdmin()` in `src/lib/auth.ts`. - -## Garden module — data model - -- **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). +- Username OR email login. Accounts `bonna` / `tony`, role `ADMIN`. +- `getSession()` / `requireAuth()` / `isAdmin()` in `src/lib/auth.ts`. +- **Forced password change is wired** (provisioned accounts ship `moonbase!` + + `mustChangePassword=true`): the dashboard layout redirects to `/change-password` + (outside the layout group; backed by `/api/account/change-password`). Don't + remove that redirect. +- `NEXTAUTH_SECRET` is asserted at runtime in production (skipped during build). ## Color palette -Forest / earth theme. Key CSS variables: -- `--canopy` — dark forest green sidebar -- `--leaf` — fresh green accent -- `--soil` / `--soil-muted` — body text -- `--dew` — pale sage background -- `--ember` — red for destructive actions +Forest / earth theme: `--canopy` (sidebar), `--leaf` (accent), `--soil` (text), +`--dew` (bg), `--ember` (destructive). diff --git a/README.md b/README.md new file mode 100644 index 0000000..6adc7ca --- /dev/null +++ b/README.md @@ -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`.