aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: d8062fec8792e52086bfbff7a5e6c6345688e53b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

A simple webapp for the family, regrouping tailor made tools (groceries,
chores).

## Architecture

- SvelteKit (Svelte 5 runes) + adapter-node, no separate front/back. Mobile-first CSS
- SQLite via **@libsql/client** + Drizzle ORM
- Plain CSS (no framework), Vitest for tests, Prettier + ESLint flat config
- Multi-stage Docker image

## Notable choices

- **@libsql/client over better-sqlite3**: Node 26 removed V8 API surface
  (`GetPrototype`, `This` on PropertyCallbackInfo) that better-sqlite3's
  native addon depends on. @libsql/client is pure JS and works out of the
  box.
- **Plain CSS over Tailwind**: smaller dependency footprint, no build
  step for styles.

## Product

### Groceries

Two core concepts: the **catalog** (every item you've ever added) and the
**list** (unchecked items — what to buy next). Adding an item creates it (or
unchecks an existing one). Checking an item off simply marks it done; it
remains visible in the catalog with a strikethrough. Unchecked items persist
on the list for the next shopping trip — there is only one persistent list.

**Three modes of use:**

1. **Quick add** — during the week, you run out of milk or need an ingredient.
   Open the app, type the name, tap to add. An autocomplete dropdown surfaces
   existing catalog items as you type, so "citron" does not become "citrons".
   Tapping a suggestion re-adds the existing item; typing a new name creates it.

2. **Planning** — before shopping, sit down with your partner and browse the
   catalog. Tap unchecked items to add them back to the list. Multi-select
   and bulk-update category for several items at once. The page does not
   reload, so going through 20–30 items is not frustrating. Stale one-off
   items can be deleted from the catalog.

3. **Shopping** — items are grouped by category (matching store aisles).
   Check off as you grab them. Multiple devices can use the same list,
   but live sync is not implemented yet — refresh to see your partner's
   changes.

**Product references** — some items like "coffee" or "pasta" aren't generic.
For these you can record one or more reference brands, each with a name,
price per unit (€/kg or €/L), and a quality score (0–100). In the store, if
you're unsure which brand you usually buy or you spot an alternative, you
can compare against your references right from the item. If a new brand
wins, you can add it or switch the reference.

**Categories** — items are manually assigned to categories. Categories
correspond to physical store aisles for an efficient shopping walk. Drag
categories to reorder them so the list matches your actual store layout.

**PWA** — installed as a standalone app via `@vite-pwa/sveltekit`. Service
worker precaches assets; works offline after first visit.

## TODO

### Bugs / Polish

### Features

- [ ] Live updates from server
- [ ] Auto-categorize new items (LLM-assisted)
- [ ] Chores module (intro already promises "groceries, chores")

## Deploy

```bash
docker build -t home-sveltekit .
docker save home-sveltekit | gzip | pv | ssh ubuntu@feed.kagamino.dev "gunzip | sudo docker load"
```