aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 7101a5ba5e0c5014a260c910074607bfe3fa9ff4 (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

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 (node:26-slim), served behind Caddy

## 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** (what to buy next). Adding an item puts it on the list; checking it
off moves it back to the catalog. Items already on the list are marked as
such in the catalog. Unchecked items stay 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, search, tap to add. As frictionless as possible so you
   build the habit.

2. **Planning** — before shopping, sit down with your partner and browse the
   catalog. Re-add whatever you're missing. The catalog view stays open
   after each add (sticky mode), 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, same list — both partners
   can check things off in sync.

**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 auto-categorized (LLM-assisted) and can be
manually adjusted. Categories correspond to physical store aisles for an
efficient shopping walk.

## TODO

- [ ] Weird form stickyness that collapse the gap with the navbar
- [ ] Edit grocery category
- [ ] Keyboard focus
- [ ] PWA
- [ ] Live updates from server
- [ ] Extract color palette

## Deploy

```bash
docker build -t home-sveltekit .
docker save home-sveltekit | ssh user@vps docker load
```