From ddb8294effce4f4dd2385c6bf8c95859ef2fc990 Mon Sep 17 00:00:00 2001 From: Ulas Date: Mon, 13 Apr 2026 10:35:33 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20update=20BACKLOG,=20SPEC,=20and=20desig?= =?UTF-8?q?n=20system=20to=20reflect=20v0.9.0=E2=80=93v0.16.3=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - BACKLOG: add completed features from v0.7.1 through v0.16.3 (shopping widget, priority none, kanban persistence, meal visibility, currency, custom categories, recipe links, Spanish/FR/TR/RU/EL/ZH locales, settings tabs, CNY/TRY/RUB currencies) - SPEC: add recipe_url field to Meals table (v0.13.0) - SPEC: add shopping_categories table (v0.12.0) - SPEC: fix i18n fallback language from de to en (v0.16.1) - SPEC: update locale file list to include all 10 languages - SPEC: document Settings tab navigation (v0.16.0) - design/system.md: fix priority levels from 4 to 5 (none added v0.9.0) --- .interface-design/system.md | 2 +- BACKLOG.md | 14 ++++++++++++++ docs/SPEC.md | 19 ++++++++++++++++--- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/.interface-design/system.md b/.interface-design/system.md index d02a97f..effff32 100644 --- a/.interface-design/system.md +++ b/.interface-design/system.md @@ -163,5 +163,5 @@ Two triggers: `prefers-color-scheme: dark` (system) or `data-theme="dark"` (manu - **Module-specific CSS:** Each page has its own stylesheet loaded dynamically - keeps initial bundle minimal - **Page transitions:** Directional slide animations based on navigation order (left/right) - **Glass overlays:** `rgba(255, 255, 255, 0.18)` surfaces for elements on colored backgrounds (e.g., action buttons on module headers) -- **Priority system:** Four levels (urgent/high/medium/low) with dedicated color + translucent background tokens +- **Priority system:** Five levels (none/low/medium/high/urgent) with dedicated color + translucent background tokens. "None" is the default for new tasks and hides the priority badge entirely. - **Swipe gestures:** Touch-friendly item interactions (swipe to delete/complete) on mobile diff --git a/BACKLOG.md b/BACKLOG.md index 8ce01d2..a69b7c6 100644 --- a/BACKLOG.md +++ b/BACKLOG.md @@ -37,3 +37,17 @@ New suggestion? → [Open an issue](https://github.com/ulsklyc/oikos/issues/new? | - | Security hardening: XSS, rate limiter bypass, OAuth CSRF, CSV injection, session invalidation | v0.5.9 | | - | Budget: Fix update failing when category changes | v0.6.0 | | - | Upgrade bcrypt 5 → 6, ESM migration, structured logger, remove SESSION_SECRET fallback | v0.7.0 | +| - | XSS fix: shared esc() utility, deduplicate escHtml across all modules | v0.7.1 | +| - | Dashboard: Shopping list widget (lists with open items, progress bar, item preview) | v0.8.0 | +| - | Tasks: optional "None" priority level (default for new tasks, hides badge) | v0.9.0 | +| - | Tasks: persist kanban/list view in localStorage; ?view=kanban URL parameter | v0.9.1 | +| - | Meals: customizable meal type visibility (breakfast/lunch/dinner/snack toggles in Settings) | v0.10.0 | +| - | Budget: configurable currency (13 currencies selectable in Settings → Budget) | v0.11.2 | +| - | Swedish (sv) translation contributed by @olsson82 | v0.11.3 | +| - | Shopping: custom categories - add, rename, delete, reorder in Settings | v0.12.0 | +| - | Meals: optional recipe link per meal (recipe_url field, link icon on card) | v0.13.0 | +| - | Spanish (es) translation - all sections fully translated | v0.14.0 | +| - | Settings: categorized tab navigation (General, Meals, Budget, Shopping, Calendar, Account) | v0.16.0 | +| - | Budget: CNY (Chinese Yuan) added to currency list (#42) | v0.16.2 | +| - | i18n: French (fr), Turkish (tr), Russian (ru), Greek (el), Chinese Simplified (zh) locales | v0.16.3 | +| - | Budget: TRY (Turkish Lira) and RUB (Russian Ruble) added to currency list | v0.16.3 | diff --git a/docs/SPEC.md b/docs/SPEC.md index f90a7b2..a4b6962 100644 --- a/docs/SPEC.md +++ b/docs/SPEC.md @@ -44,10 +44,21 @@ Every table: `id INTEGER PRIMARY KEY`, `created_at TEXT`, `updated_at TEXT` (ISO | list_id | INTEGER | FK → Shopping Lists, NOT NULL | | name | TEXT | NOT NULL | | quantity | TEXT | e.g. "500g", "2 pieces" | -| category | TEXT | Fruit & Vegetables, Dairy, Meat & Fish, Bakery, Drinks, Frozen, Household, Drugstore, Other | +| category | TEXT | FK → Shopping Categories (by name) | | is_checked | INTEGER | 0/1 | | added_from_meal | INTEGER | FK → Meals, nullable | +### Shopping Categories +Custom, household-wide category list for shopping items. Replaces the old hardcoded category set. + +| Column | Type | Constraint | +|--------|------|-----------| +| id | INTEGER | PRIMARY KEY | +| name | TEXT | NOT NULL | +| sort_order | INTEGER | NOT NULL | +| created_at | TEXT | | +| updated_at | TEXT | | + ### Meals | Column | Type | Constraint | |--------|------|-----------| @@ -55,6 +66,7 @@ Every table: `id INTEGER PRIMARY KEY`, `created_at TEXT`, `updated_at TEXT` (ISO | meal_type | TEXT | breakfast, lunch, dinner, snack | | title | TEXT | NOT NULL | | notes | TEXT | | +| recipe_url | TEXT | nullable, URL to recipe | | created_by | INTEGER | FK → Users, NOT NULL | ### Meal Ingredients @@ -235,6 +247,7 @@ User management and app configuration. Logged-in users only. - **Calendar integration:** connect/disconnect Google Calendar OAuth, store Apple Calendar (CalDAV) credentials, configure sync interval - **Weather:** configure OpenWeatherMap location - **Language:** System (follows `navigator.language`), German, English, Spanish, French, Italian, Swedish, Greek, Russian, Turkish, Chinese - via `oikos-locale-picker` web component; switch without page reload +- **Tab navigation:** Settings is organized in six tabs (General, Meals, Budget, Shopping, Calendar, Account). Sticky tab bar, active tab persists in sessionStorage, Calendar tab auto-activates after OAuth callbacks. - **App info:** version, license ### Budget (`/budget`) @@ -327,7 +340,7 @@ All UI strings are managed via `public/i18n.js`. No hardcoded text in JS files o ### Architecture - **Module:** `public/i18n.js` - exports: `initI18n()`, `setLocale()`, `t(key, params?)`, `getLocale()`, `getSupportedLocales()`, `formatDate(date)`, `formatTime(date)` -- **Locale files:** `public/locales/de.json` (reference), `public/locales/en.json`, `public/locales/it.json`, `public/locales/sv.json` - structure: `{ "module.camelCaseKey": "Value" }` +- **Locale files:** `public/locales/de.json` (reference), `public/locales/en.json`, `public/locales/es.json`, `public/locales/fr.json`, `public/locales/it.json`, `public/locales/sv.json`, `public/locales/el.json`, `public/locales/ru.json`, `public/locales/tr.json`, `public/locales/zh.json` - structure: `{ "module.camelCaseKey": "Value" }` - **Variables:** `{{variable}}` syntax in translation strings, e.g. `t('tasks.assignedTo', { name: 'Anna' })` - **Fallback chain:** active locale → German (`de`) → key itself - **Date format:** `Intl.DateTimeFormat` with current locale - use `formatDate()` and `formatTime()` from `i18n.js` @@ -336,7 +349,7 @@ All UI strings are managed via `public/i18n.js`. No hardcoded text in JS files o 1. `localStorage` entry `oikos-locale` (manual selection) 2. `navigator.languages[0]` (browser language) -3. Fallback: `de` +3. Fallback: `en` ### Supported Languages