diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 146 |
1 files changed, 48 insertions, 98 deletions
@@ -1,6 +1,35 @@ A simple webapp for the family, regrouping tailor made tools (groceries, chores). +## Features + +- **Refocus refresh** — returning to the app after 10 seconds away refetches + the current page's data; edit pages are left untouched. +- **Groceries** — two concepts: the **catalog** (every item ever added) and + the **list** (unchecked items — what to buy next). Quick add with + autocomplete, bulk category updates while planning, aisle-grouped view + while shopping. Shared across devices, but live sync is not implemented — + refresh to see your partner's changes. +- **Product references** — for items like "coffee" or "pasta": one or more + reference brands with a price per unit (€/kg or €/L) and a quality score + (0–100), comparable from the item while in the store. +- **Categories** — items assigned to store aisles, drag to reorder the list + to match the physical layout. +- **Projects & routines** — projects ("Household", "Personal growth", …) + group recurring routines with a frequency: an interval like `2w`, or a + quota like `5/2w` (5 completions per 2-week window anchored on creation — + a closed window left unmet makes the routine En retard). Project pages + sort routines most-urgent first (À jour / À faire / En retard / Très en + retard) with one-tap "Fait", live search, and a health score (0–100) per + project and per routine, charted over time. Routines show the age of the + last completion ("fait hier", "fait il y a 5 jours") or the lateness ("3 + jours de retard"); completions can be backdated to the day they actually + happened. Editing creates immutable versions and each completion records + its version — the past is never rewritten. Archiving keeps a read-only + page whose chart runs to the archive date. +- **PWA** — standalone install via `@vite-pwa/sveltekit`; works offline + after the first visit. + ## Architecture - SvelteKit (Svelte 5 runes) + adapter-node, no separate front/back. Mobile-first CSS @@ -8,118 +37,39 @@ chores). - Plain CSS (no framework), Vitest for tests, Prettier + ESLint flat config - `npm run dcd` scans source code for duplicate blocks (skips generated JSON) - Multi-stage Docker image - -## Notable choices - -- **@libsql/client over better-sqlite3**: Node 26 removed V8 API surface +- **@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 - -**Refocus refresh** — returning to the app after 10 seconds away refetches -the current page's data; edit pages are left untouched. - -### 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. + 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. -**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. +## Usage -**PWA** — installed as a standalone app via `@vite-pwa/sveltekit`. Service -worker precaches assets; works offline after first visit. +Seed routines from the paper sheet (one-off, idempotent): -### Projects & routines - -**Projects** ("Household", "Personal growth", …) group recurring **routines** -— chores are just routines in the household project. Each routine has a -frequency spec: an interval like `2w` (every 2 weeks), or a quota like `5/2w` -(5 completions counted per 2-week window anchored on the routine's creation -day — a closed window left unmet makes the routine En retard). The home page -lists projects with a -health score (0–100); each project page shows its routines sorted most-urgent -first (À jour / À faire / En retard / Très en retard) with one-tap "Fait" -completion. Next to each routine's frequency, the age of the last completion -replaces its date — "fait hier", "fait il y a 5 jours" — and once the -deadline has passed the stamp switches to the lateness ("3 jours de -retard"). A search box above the list filters it live — type `Cuisine/` to -see every `Cuisine/…` routine — matching case- and accent-insensitively. -Editing a routine creates a new immutable version, and every completion -records the exact version it was made against, so the past is never rewritten. -Each routine has its own page (the name links from the project) with an -editable description, a chart of its health score over time, -and its completion log. That page's "Fait" form also carries the day the -routine was actually done — prefilled with today, earlier days allowed — so a -chore remembered two days late lands on the right day. Archiving a routine -stamps the date it was archived -and removes it from the active list: it stays reachable in a collapsible -"Archivées" section on its project page (with a fuzzy search) and opens as a -read-only page whose health chart runs from creation to the archive date. -Seed from the paper sheet (one-off, idempotent): -`docker compose exec app node --experimental-strip-types scripts/seed-sheet1-routines.ts`. - -## TODO - -### Features - -- [ ] Live updates from server -- [ ] Auto-categorize new items (LLM-assisted) -- [ ] https://automerge.org/docs/tutorial/ -- [ ] Style like feed.kagamino.dev? -- [ ] Shared > Modal actions +```bash +docker compose exec app node --experimental-strip-types scripts/seed-sheet1-routines.ts +``` -## Deploy +## Release / Deploy Images are published to the private registry at `container.registry.kagamino.dev`. The app password is supplied at runtime as `AUTH_PASSWORD` in the VPS Docker Compose deployment. -Authenticate both Docker clients once: - ```bash +# authenticate both Docker clients (once) docker login container.registry.kagamino.dev ssh ubuntu@feed.kagamino.dev "sudo docker login container.registry.kagamino.dev" -``` - -Build, push, and deploy the latest image with: -```bash +# start the registry, build and push the image, restart `home` on the VPS mise run deploy ``` -The deploy script starts the registry, builds and pushes the image, then pulls -and restarts only the `home` service on the VPS. +## TODO + +- Live updates from server +- Auto-categorize new items (LLM-assisted) +- https://automerge.org/docs/tutorial/ +- Style like feed.kagamino.dev? +- Shared > Modal actions |
