#4 cleanup + Tony's house structure.
- Task.locationId (migration): reminders can attach to a place, not just a
plant/item/animal. Add one from a location's menu (e.g. clean gutters on House >
Exterior); the Reminders page + tasks service surface the linked location/item/
animal.
- Locations "Quick setup": paste/confirm an indented outline → creates the nested
tree (find-or-create by name+parent, idempotent), pre-filled with the Moon
homestead house layout. Optional "sweep existing garden areas under Yard" moves
every top-level place that holds plants under a new Yard parent — the
'move all the yard stuff to a new top level' ask.
- Pure outline parser (src/lib/locations/outline.ts, +4 tests); bulk setup service
+ /api/locations/bulk. Verified end-to-end: nested tree + paths, garden sweep,
place reminder.
Yard sub-bucketing deferred per Tony.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rounds out Inventory toward HomeBox, and gives Locations a real home.
Inventory:
- Attach manuals, receipts, and warranty docs (any file), not just photos —
attachment uploader now has a kind picker; WARRANTY kind added
- Richer purchase/warranty: purchasedFrom, warrantyDetails, lifetimeWarranty,
insured (item dialog + detail facts + header badge)
- Schedule recurring maintenance from an item (creates a Task linked via
itemId); item detail shows its maintenance with overdue flagged. Task create
now accepts itemId/animalId
Locations:
- New Locations page + nav: browse/add/rename/move/delete the whole place tree
(LocationManager over the existing /api/locations routes); shows plant/item
counts per place. The spot to merge near-dupes before dropping legacy zone
Verified end-to-end against a running server (new fields round-trip, maintenance
task links to item, MANUAL attachment stored). tsc + 33 tests + build green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A bidirectional API so other apps (Home Assistant, phone shortcuts, scripts,
and the coming MCP server) can read and update the homestead.
- ApiToken model (sha256-hashed, scoped, with prefix/lastUsed/expiry/revoke)
- authenticateRequest() accepts EITHER a NextAuth cookie session OR a Bearer
PAT; cookie sessions get full access, tokens are limited to their scopes
(write implies read; resource and global wildcards). ApiError + handleApiError
- Shared service layer (plants/tasks/locations/plant-types) reused by every
endpoint and, later, the MCP server — logic lives once
- /api/v1: plants (read + add log), plant-types, locations, tasks (read/create/
complete), and a whoami/discovery root
- Settings → API tokens: create with per-resource read/write checkboxes, raw
token shown once, revoke; tokens added to backup/restore
- Pure tests for scope matching + token hashing; verified end-to-end (401/403/
201, lastUsedAt) against a running server
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>