Commit Graph

13 Commits

Author SHA1 Message Date
josh 5fa1e34914 Split audits into Weigh Ins (bulk) and Bin Checks (discrete)
Build and push image / build (push) Successful in 57s
Replaces the unified audit system with two purpose-built flows:
- Weigh Ins: rebranded audit flow for bulk products (Flower, Concentrate,
  Tincture) with scale weigh, container weigh, and estimate modes
- Bin Checks: new bin-level presence check — select a bin, scan every item,
  resolve discrepancies (wrong bin, unknown, missing), auto-records presence
  audits on verified items

Adds cadence_days and last_checked to bins table, with per-bin overdue
tracking on the dashboard and bins view.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-06 18:28:55 -04:00
josh fc7b3d5de2 Remove estimated remaining decay, use audit values directly
Build and push image / build (push) Successful in 1m6s
Replace burn-rate estimation (linear decay between audits) with actual
last audit values. Remaining is now always the last weigh-in value or
original weight if no audits exist — no more speculative daily decay.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 19:12:09 -04:00
josh 538e5079ab Fix 18 UX issues: confirmations, undo, drawer nav, empty states, and polish
Build and push image / build (push) Successful in 54s
Comprehensive UX audit covering modals, drawers, dashboard, and inventory.
Key changes: confirmation steps before destructive actions, undo via toast
for consume/gone/checkout, back-navigation across entity drawers, optional
ratings, discrete item count field, audit progress bar, and sortable column
affordance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-08 16:25:41 -04:00
josh 564cae253a Only estimate remaining after first audit, not from purchase date
Build and push image / build (push) Successful in 53s
Before any audit, bulk items show their full original weight with no
decay applied. The linear decay model only kicks in after the first
audit provides an actual data point. This prevents freshly added,
unopened items from showing misleading consumption estimates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-08 09:36:29 -04:00
josh a1be29ab6e Add container weight tracking for weigh-based concentrate audits
Build and push image / build (push) Successful in 1m6s
Record the total weight of a jar (product + container) at acquisition so
audits can be done by simply re-weighing the sealed jar. The tare is
derived (containerWeight − productWeight), and the audit flow offers a
"Weigh container" toggle that auto-calculates remaining product from the
scale reading.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-07 23:11:39 -04:00
josh 4044de7bfc Add timezone preference and fix all date handling to be timezone-aware
Build and push image / build (push) Successful in 56s
Dates were computed using browser/server local time with no explicit timezone,
causing inconsistencies when server runs in UTC. Now all "today" computations
and date formatting use the user's chosen IANA timezone, persisted in
localStorage and selectable from Settings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-07 22:30:01 -04:00
josh 9aea9535e6 Tailor edible ingestion flow: use mg units and hide cannabinoid % fields
Build and push image / build (push) Successful in 59s
Edibles are dosed in milligrams, not grams, and percentage-based cannabinoid
profiles don't apply. Adds weightUnit and showCannabinoidPct to TypeConfig so
the add/edit/detail views adapt per product type.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-07 21:12:28 -04:00
josh e7fd9af62c Add checkout/custody feature for tracking items in personal possession
Build and push image / build (push) Successful in 1m8s
Items can now be checked out of their bin into "my custody" and later
checked back in or marked consumed. Adds checkout/checkin API endpoints,
a My Custody sidebar page, CheckoutFlow and CheckinFlow modals, and
updates ProductDetail, Inventory, ConsumeFlow, and MarkGoneFlow to
handle the new checked-out status. Bulk items prompt for remaining
weight on check-in.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-07 20:49:58 -04:00
josh 80034b47c5 User-supplied asset ids; brand on product; strain is the name
Build and push image / build (push) Successful in 48s
Four UX changes after using the rework for a bit:

1. Asset ids are 6-digit numbers from a roll of physical labels — server
   no longer generates them. POST /api/inventory requires assetId; the
   add-inventory form has a digits-only input that auto-focuses on entry.
2. Strain and product name are the same thing. Drop products.name; the
   strain's name supplies the display. Product creation just asks for
   "Name (strain)" and matches/creates a strain by that name.
3. Brand moves from inventory_items to products. SKUs are brand-specific,
   so all instances of a product share the brand. Brand selector lives
   on the product create/edit form, not the per-instance form.
4. Scanning an unknown SKU on the add-inventory step now opens the
   create-product subform with the SKU prefilled — one less click.

Migration: detect prior shape (products.name column present) and rename
products/inventory_items/audits to *_v1 archives, recreate empty.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 18:17:12 -04:00
josh 02dc6e523f Track inventory at the instance level, not by product
Build and push image / build (push) Successful in 46s
The products table conflated catalog ("kind of thing you scan") with
instance ("this jar I bought") — splitting it lets us record every
purchase as its own asset and autofill brand/shop/price/THC from the
last instance when scanning a known SKU.

- products: sku + strain + name + type + kind (catalog only)
- inventory_items: physical jars with short-UUID asset ids, per-batch
  brand/shop/bin/price/cannabinoids/weight, audits, lifecycle
- audits now key on inventory_id; strains lose brand_id and type
- migration: rename existing products/audits/strains to *_legacy on
  first boot so users keep historical reference, fresh start otherwise
- two-step add flow: scan SKU → select/create product → instance
  details (autofilled from last instance) → generated asset id shown
- ScanField matches asset id first, falls back to SKU
- inventory list defaults flat, "By product" toggle groups instances

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 05:59:46 -04:00
josh 1abfda7989 Use the real today everywhere
Build and push image / build (push) Successful in 53s
The client constant TODAY_STR and the bootstrap response's today field
were both hardcoded to 2026-04-25, leaving date inputs in the New
product, Audit, and Mark consumed flows seeded with a stale date and
quietly staling out every "days since" / audit-overdue calculation
across the app.

TODAY_STR now resolves at module load from new Date() in local time,
and bootstrap returns new Date().toISOString().slice(0, 10).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 22:20:24 -04:00
josh d335525073 Group bins by letter, sort by number, drop location
Build and push image / build (push) Successful in 46s
Bins follow an A1/A2/B1 naming convention, so the Bins page now parses
the leading letter prefix as a row group and the trailing number as the
within-row order. Each letter starts a fresh grid section; bins whose
names don't match the pattern fall into a trailing "Other" bucket
sorted alphabetically.

Removes the optional location field from bins end to end: the API
client signatures, server POST/PATCH routes, both product-flow inline
creates, the dropdown labels, the ProductDetail bin row, and the
BinsView header line. The bootstrap query explicitly projects only
id/name/capacity so the dead column doesn't leak through.

The location column stays in the bins table on disk to avoid a
migration on existing deployments — it just isn't read or written.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 22:07:12 -04:00
josh 027cf032be Initial commit: Apothecary v0.4.0 2026-05-03 20:19:26 -04:00