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 - SQLite via **@libsql/client** + Drizzle ORM - Plain CSS (no framework), Vitest for tests, Prettier + ESLint flat config - **Flat design language** (Miniflux-inspired) — hairline separators instead of boxes, square corners, no shadows, no hover-lifts, instant state changes; tokens in `src/styles/`, utilities in `src/app.css` - `npm run dcd` scans source code for duplicate blocks (skips generated JSON) - Multi-stage Docker image - **@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. ## Usage Seed routines from the paper sheet (one-off, idempotent): ```bash docker compose exec home node --experimental-strip-types scripts/seed-sheet1-routines.ts ``` Pull a copy of the remote database into `data.db` for local testing: ```bash mise run db:backup ``` ## 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. ```bash # authenticate both Docker clients (once) docker login container.registry.kagamino.dev ssh ubuntu@feed.kagamino.dev "sudo docker login container.registry.kagamino.dev" # start the registry, build and push the image, restart `home` on the VPS mise run deploy ``` ## TODO - Live updates from server - Auto-categorize new items (LLM-assisted) - https://automerge.org/docs/tutorial/ - Shared > Modal actions - Input + buttons sizes (ajouter un article)