Add Equipment page: owned brewers and grinders filter the Brews UI
Test and deploy / test-and-deploy (push) Successful in 59s

- user_gear table (migration 008) + GET/PUT /api/gear (brewer keys
  validated against the taxonomy, grinders deduped/trimmed)
- /gear page: silhouette multi-select for owned brewers (autosaves) and
  a grinder list; nav gains Brewing → Equipment
- Brews page: with gear configured, the picker shows only owned brewers
  (plus the edited brew's method) with a show-all toggle; grinder field
  suggests your grinders; empty-gear state links to /gear
- Included in full backups, per-user export, and the OpenAPI spec

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Shane Maynard
2026-08-09 08:08:32 -04:00
co-authored by Claude Fable 5
parent 3bceb44ae3
commit e62b9601a2
10 changed files with 433 additions and 4 deletions
+4
View File
@@ -146,6 +146,10 @@ export function buildOpenApiSpec({ origin = "" } = {}) {
put: { tags: ["beans"], summary: "Update a bean", parameters: [idParam], requestBody: jsonBody(beanBody), responses: { 200: ok("Updated"), 404: err("Not found") } },
delete: { tags: ["beans"], summary: "Delete a bean", parameters: [idParam], responses: { 200: ok("Deleted"), 404: err("Not found") } },
},
"/api/gear": {
get: { tags: ["brews"], summary: "Owned equipment (brewers + grinders)", responses: { 200: ok("Gear", obj({ ok: bool, gear: obj({ brewers: arr(str), grinders: arr(str) }) })) } },
put: { tags: ["brews"], summary: "Set owned equipment", requestBody: jsonBody(obj({ brewers: arr({ ...str, description: "brew-method keys" }), grinders: arr(str) }, ["brewers", "grinders"])), responses: { 200: ok("Saved"), 400: err("Unknown brewer key") } },
},
"/api/brew-methods": { get: { tags: ["brews"], summary: "Brew-method taxonomy (categories + methods)", responses: { 200: ok("Methods", obj({ ok: bool, categories: arr(obj({ key: str, name: str })), methods: arr(obj({ key: str, name: str, category: str })) })) } } },
// ── Brews ──