From 3b02cb1aeeed1e0447a6401f55a2d17bca905149 Mon Sep 17 00:00:00 2001 From: Ulas Kalayci Date: Fri, 1 May 2026 20:16:26 +0200 Subject: [PATCH] docs: update BACKLOG, SPEC, README, and CONTRIBUTING to v0.41.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - BACKLOG: added completed entries for v0.38.2–v0.41.0 (loans, widget sizes, date formats, birthday badge, calendar improvements, typography, reminders) - SPEC: added Budget Loans and Budget Loan Payments data-model tables; updated Budget module description with Loans tab and API; updated Dashboard with widget size presets; corrected Settings tab count from 8 to 9 - README: Budget feature row now mentions the loans tracker - CONTRIBUTING: added test:kitchen-tabs and test:setup to individual suite list Co-Authored-By: Claude Sonnet 4.6 --- BACKLOG.md | 16 ++++++++++++++++ CONTRIBUTING.md | 1 + README.md | 2 +- docs/SPEC.md | 32 +++++++++++++++++++++++++++++++- 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/BACKLOG.md b/BACKLOG.md index ab0343e..cab2c43 100644 --- a/BACKLOG.md +++ b/BACKLOG.md @@ -103,3 +103,19 @@ New suggestion? → [Open an issue](https://github.com/ulsklyc/oikos/issues/new? | - | UX: `friendlyError()` helper — unhandled promise rejections show status-code-aware messages instead of raw error text | v0.36.0 | | - | Date input: default format changed to DMY with dot separator; dot-separated dates accepted everywhere | v0.36.1 | | - | Microinteraction long loops: FAB entry animation stops after 5 views; keyboard shortcut hint hides after first use; success toasts suppressed after 50 saves; empty-state CTA delayed fade-in | v0.38.0 | +| - | Calendar: recurring events with `FREQ=WEEKLY;INTERVAL=N;BYDAY` now correctly skip N−1 weeks between occurrences | v0.38.2 | +| - | Dashboard portrait mode on mobile: horizontal scrollbar and overflow bugs fixed | v0.38.3 / v0.38.4 | +| - | Settings: 24-hour / AM·PM time format toggle, persisted globally; calendar remembers last selected view | v0.39.0 | +| - | Swedish (sv) translation completed by @olsson82; i18n gap-fill for 13 non-German locales | v0.39.1 | +| - | Budget date picker: native `type="date"` input on iOS and Android instead of plain text field | v0.39.2 | +| - | Budget loans tracker: instalment-based loans, per-payment records, remaining balance, auto-close when paid off (PR #117 by @rafaelfoster) | v0.40.0 | +| - | Dashboard: configurable widget sizes via named presets (Tiny, Narrow, Standard, Large, Full), persisted in user preferences | v0.40.0 | +| - | Settings: four additional date formats — MM.DD.YYYY, YYYY.MM.DD, YYYY/MM/DD, DD/MM/YYYY | v0.40.0 | +| - | Typography: tighter letter-spacing on page/modal titles, `text-wrap: balance`; warm-tinted shadows; larger button radius (--radius-md); module-accent empty-state icons; sentence-case search section labels | v0.40.1 | +| - | Tabular figures: `font-variant-numeric: tabular-nums` on all numeric displays (budget, weather, dashboard, calendar) | v0.40.1 | +| - | Birthdays: nav badge when any family member has a birthday within the next 3 days | v0.41.0 | +| - | Tasks: up to three recently-used filter chips, persisted in localStorage | v0.41.0 | +| - | Calendar: live keyword search in the icon picker; icons grouped into labelled categories | v0.41.0 | +| - | Calendar: repeat indicator icon on recurring events in month and week views | v0.41.0 | +| - | Calendar: 3-day week view on screens narrower than 640 px | v0.41.0 | +| - | Forms: required-field asterisk via `.required-marker` CSS class; enlarged modal drag-handle hit area (44 px); budget tab minimum height 40 px | v0.41.0 | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 79c4c51..0a8b7cd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -55,6 +55,7 @@ npm run test:meals && npm run test:calendar && npm run test:ncb npm run test:reminders && npm run test:dashboard && npm run test:api npm run test:ics-parser && npm run test:ics-sub npm run test:modal-utils && npm run test:ux-utils +npm run test:kitchen-tabs && npm run test:setup ``` Tests use the Node.js built-in test runner with in-memory SQLite (`--experimental-sqlite`). No running server or database required — tests import route handlers directly. diff --git a/README.md b/README.md index bea4e4b..1131022 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ The goal is a single, private place for everything that keeps a household runnin | **Recipes** | Create, duplicate, and scale reusable recipes. Pre-fill meal slots from a recipe or save any meal as a recipe. | | **Calendar** | Two-way sync with Google Calendar (OAuth) and Apple iCloud (CalDAV). Subscribe to any public ICS/webcal URL with per-subscription color and visibility. Overlapping timed events render side-by-side. Events support file attachments (images, PDFs, Office documents). | | **Documents** | Upload and manage family files (PDF, images, Office documents up to 5 MB). Grid/list view, drag-and-drop upload, 14 category tags (medical, school, identity, finance, and more), per-document visibility (family, selected members, private), archive and download. | -| **Budget** | Track income and expenses with recurring entries, monthly trends, and CSV export. 35 predefined categories plus custom ones. Supports 15 currencies. | +| **Budget** | Track income and expenses with recurring entries, monthly trends, and CSV export. 35 predefined categories plus custom ones. Supports 15 currencies. Loans tab for instalment-based loan tracking with per-payment history and automatic paid-off detection. | | **Notes & Contacts** | Colored sticky notes with Markdown support. Contact directory with vCard import/export. | | **Birthdays** | Birthday tracker with automatic annual calendar events, age display, profile photos, and 1-day-before reminders. | | **Reminders** | Time-based reminders on tasks and calendar events. In-app notification badge. | diff --git a/docs/SPEC.md b/docs/SPEC.md index 393e6d2..49588fe 100644 --- a/docs/SPEC.md +++ b/docs/SPEC.md @@ -281,6 +281,32 @@ Allowlist for `visibility = 'restricted'` documents — only listed users can se | user_id | INTEGER | FK → Users (CASCADE delete), NOT NULL | | PRIMARY KEY | | (document_id, user_id) | +### Budget Loans +Instalment-based loans with per-payment tracking. Active loans show remaining balance and due months; paid-off loans are automatically closed. + +| Column | Type | Constraint | +|--------|------|-----------| +| title | TEXT | NOT NULL | +| borrower | TEXT | NOT NULL | +| total_amount | REAL | NOT NULL CHECK(> 0) | +| installment_count | INTEGER | NOT NULL CHECK(> 0) | +| start_month | TEXT | YYYY-MM, NOT NULL | +| notes | TEXT | nullable | +| status | TEXT | 'active' (default) or 'paid' | +| created_by | INTEGER | FK → Users (CASCADE delete), NOT NULL | + +### Budget Loan Payments +Individual payment records for a budget loan. Each installment number is unique per loan. + +| Column | Type | Constraint | +|--------|------|-----------| +| loan_id | INTEGER | FK → Budget Loans (CASCADE delete), NOT NULL | +| installment_number | INTEGER | NOT NULL CHECK(> 0), UNIQUE per loan | +| amount | REAL | NOT NULL CHECK(> 0) | +| paid_date | TEXT | DATE, NOT NULL | +| budget_entry_id | INTEGER | FK → Budget Entries (SET NULL on delete), nullable | +| created_by | INTEGER | FK → Users (CASCADE delete), NOT NULL | + ### Sync Config Key-value table for OAuth tokens and CalDAV credentials. @@ -306,6 +332,8 @@ Responsive grid: 1 column on mobile, 2 on tablet, 3 on desktop. - Pinboard preview: 2–3 pinned notes - FAB (quick actions): + Task, + Event, + Shopping list item, + Note +**Widget sizes:** each widget has a configurable size using named presets (Tiny, Narrow, Standard, Large, Full) that map to `columns × rows` in the CSS grid. Sizes are persisted in user preferences and survive page reloads. + Skeleton loading instead of spinners. Clicking any widget navigates to that module. ### Tasks (`/tasks`) @@ -428,7 +456,7 @@ User management and app configuration. Logged-in users only. - **Language:** System (follows `navigator.language`), German, English, Spanish, French, Italian, Swedish, Greek, Russian, Turkish, Chinese, Japanese, Arabic, Hindi, Portuguese - via `oikos-locale-picker` web component; switch without page reload - **API Tokens (admin):** create named Bearer / X-API-Key tokens for external integrations; the full token value is shown only once immediately after creation; tokens can be revoked at any time; support optional expiry and track last-used timestamp - **Backup Management (admin):** download the current database as a file (`GET /api/v1/backup/database`) or restore from a backup file (`POST /api/v1/backup/restore`, drag-and-drop supported). Validates that the uploaded file is a valid Oikos database. A rollback copy is created automatically before restore. -- **Tab navigation:** Settings is organized in eight tabs (General, Meals, Budget, Shopping, Calendar, Family, API Tokens, Account). Admin-only tabs: Family, API Tokens, Backup. Sticky tab bar, active tab persists in sessionStorage, Calendar tab auto-activates after OAuth callbacks. +- **Tab navigation:** Settings is organized in nine tabs (General, Meals, Budget, Shopping, Calendar, Family, API Tokens, Backup, Account). Admin-only tabs: Family, API Tokens, Backup. Sticky tab bar, active tab persists in sessionStorage, Calendar tab auto-activates after OAuth callbacks. - **Family management (admin):** assign a `family_role` (Dad, Mom, Parent, Child, Grandparent, Relative, Other) to each user, and set per-member phone, email, and birthday — automatically synced to Contacts and Birthdays. Displayed in the family member list and profile views. - **Profile picture:** users can upload a personal avatar (PNG/JPEG/WebP/GIF, ≤ 5 MB), stored as a Base64 data URL in `avatar_data`. Displayed alongside display name across the app. - **App info:** version, license @@ -445,7 +473,9 @@ User management and app configuration. Logged-in users only. - Recurring entries - Monthly comparison (current vs. previous month) - CSV export includes a subcategory column and English column headers +- **Loans tab:** create instalment-based loans (borrower, total amount, number of instalments, start month); record individual payments; remaining balance and due months shown automatically; paid-off loans marked as closed; filter budget transactions by loan - API: `GET /api/v1/budget/categories`, `GET /api/v1/budget/categories/:key/subcategories` (optional `?lang=` localisation), `POST /api/v1/budget/categories`, `POST /api/v1/budget/categories/:key/subcategories` +- Loans API: `GET /api/v1/budget/loans`, `POST /api/v1/budget/loans`, `GET /api/v1/budget/loans/:id`, `PUT /api/v1/budget/loans/:id`, `DELETE /api/v1/budget/loans/:id`, `GET /api/v1/budget/loans/:id/payments`, `POST /api/v1/budget/loans/:id/payments`, `DELETE /api/v1/budget/loans/:id/payments/:paymentId` ### Birthdays (`/birthdays`)