From 95934bac2340f228abbcce6836a49e0114c2e818 Mon Sep 17 00:00:00 2001 From: Ulas Kalayci Date: Sat, 25 Apr 2026 17:01:06 +0200 Subject: [PATCH 1/2] fix: review corrections for PR #86 - Remove .codex (Codex CLI artifact, not part of project) - Restore CHANGELOG.md v0.23.17 entry (was deleted by contributor's fork) - Restore version to 0.23.17 in package.json and package-lock.json - Restore native translations for catFood, catLeisure, catEducation in ar, el, hi, ja, ru, sv, tr, uk, zh (PR had replaced them with English strings) - Replace Portuguese seed names in migration 16 with English (housing, food, transport, personal_health, leisure, shopping_clothing, education, financial_other and all subcategory display names) Co-Authored-By: Claude Sonnet 4.6 --- .codex | 0 CHANGELOG.md | 5 +++ package-lock.json | 4 +-- package.json | 2 +- public/locales/ar.json | 6 ++-- public/locales/el.json | 6 ++-- public/locales/hi.json | 6 ++-- public/locales/ja.json | 6 ++-- public/locales/ru.json | 6 ++-- public/locales/sv.json | 6 ++-- public/locales/tr.json | 6 ++-- public/locales/uk.json | 6 ++-- public/locales/zh.json | 6 ++-- server/db.js | 80 +++++++++++++++++++++--------------------- 14 files changed, 75 insertions(+), 70 deletions(-) delete mode 100644 .codex diff --git a/.codex b/.codex deleted file mode 100644 index e69de29..0000000 diff --git a/CHANGELOG.md b/CHANGELOG.md index 80e02e8..e2d4a45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.23.17] - 2026-04-25 + +### Fixed +- Italian (it) locale: translated all missing strings in the recipes section (`nav.recipes`, `meals.savedRecipeLabel`, `meals.savedRecipePlaceholder`, `meals.saveAsRecipe`, `meals.recipeScaleLabel`, and all `recipes.*` keys) — contributed by @albanobattistella + ## [0.23.16] - 2026-04-24 ### Changed diff --git a/package-lock.json b/package-lock.json index 4235aea..814c504 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "oikos", - "version": "0.23.16", + "version": "0.23.17", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "oikos", - "version": "0.23.16", + "version": "0.23.17", "license": "MIT", "dependencies": { "bcrypt": "^6.0.0", diff --git a/package.json b/package.json index 806b999..41b5b8f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "oikos", - "version": "0.23.16", + "version": "0.23.17", "description": "Self-hosted family planner - calendar, tasks, shopping, meal planning, budget and more. Private, open-source, no subscription.", "main": "server/index.js", "type": "module", diff --git a/public/locales/ar.json b/public/locales/ar.json index a6b8a9d..c436961 100644 --- a/public/locales/ar.json +++ b/public/locales/ar.json @@ -463,14 +463,14 @@ "trendNeutral": "- مثل {{month}}", "validAmountRequired": "أدخل مبلغاً صحيحاً", "dateRequired": "التاريخ مطلوب", - "catFood": "Food", + "catFood": "الطعام", "catRent": "الإيجار", "catInsurance": "التأمين", "catMobility": "التنقل", - "catLeisure": "Leisure and Entertainment", + "catLeisure": "الترفيه", "catClothing": "الملابس", "catHealth": "الصحة", - "catEducation": "Education", + "catEducation": "التعليم", "catMisc": "متنوع", "catEarnedIncome": "دخل العمل", "catInvestmentIncome": "دخل الاستثمار", diff --git a/public/locales/el.json b/public/locales/el.json index fbfc4f8..309c515 100644 --- a/public/locales/el.json +++ b/public/locales/el.json @@ -463,14 +463,14 @@ "trendNeutral": "- ίδιο με {{month}}", "validAmountRequired": "Παρακαλώ εισαγάγετε έγκυρο ποσό", "dateRequired": "Η ημερομηνία είναι υποχρεωτική", - "catFood": "Food", + "catFood": "Τρόφιμα", "catRent": "Ενοίκιο", "catInsurance": "Ασφάλεια", "catMobility": "Μεταφορές", - "catLeisure": "Leisure and Entertainment", + "catLeisure": "Ελεύθερος χρόνος", "catClothing": "Ρουχισμός", "catHealth": "Υγεία", - "catEducation": "Education", + "catEducation": "Εκπαίδευση", "catMisc": "Διάφορα", "catEarnedIncome": "Εισόδημα από εργασία", "catInvestmentIncome": "Επενδυτικό εισόδημα", diff --git a/public/locales/hi.json b/public/locales/hi.json index 70d6c99..fdb4036 100644 --- a/public/locales/hi.json +++ b/public/locales/hi.json @@ -463,14 +463,14 @@ "trendNeutral": "- {{month}} जैसा", "validAmountRequired": "वैध राशि दर्ज करें", "dateRequired": "तारीख आवश्यक है", - "catFood": "Food", + "catFood": "भोजन", "catRent": "किराया", "catInsurance": "बीमा", "catMobility": "परिवहन", - "catLeisure": "Leisure and Entertainment", + "catLeisure": "मनोरंजन", "catClothing": "कपड़े", "catHealth": "स्वास्थ्य", - "catEducation": "Education", + "catEducation": "शिक्षा", "catMisc": "विविध", "catEarnedIncome": "कमाई आय", "catInvestmentIncome": "निवेश आय", diff --git a/public/locales/ja.json b/public/locales/ja.json index 806f6d7..6cf9582 100644 --- a/public/locales/ja.json +++ b/public/locales/ja.json @@ -463,14 +463,14 @@ "trendNeutral": "- {{month}} と同じ", "validAmountRequired": "有効な金額を入力してください", "dateRequired": "日付は必須です", - "catFood": "Food", + "catFood": "食費", "catRent": "家賃", "catInsurance": "保険", "catMobility": "交通費", - "catLeisure": "Leisure and Entertainment", + "catLeisure": "娯楽", "catClothing": "衣服", "catHealth": "医療", - "catEducation": "Education", + "catEducation": "教育", "catMisc": "その他", "catEarnedIncome": "給与・報酬", "catInvestmentIncome": "投資収入", diff --git a/public/locales/ru.json b/public/locales/ru.json index dca2ff4..01762ca 100644 --- a/public/locales/ru.json +++ b/public/locales/ru.json @@ -463,14 +463,14 @@ "trendNeutral": "— как в {{month}}", "validAmountRequired": "Введите корректную сумму", "dateRequired": "Дата обязательна", - "catFood": "Food", + "catFood": "Продукты", "catRent": "Аренда", "catInsurance": "Страховка", "catMobility": "Транспорт", - "catLeisure": "Leisure and Entertainment", + "catLeisure": "Досуг", "catClothing": "Одежда", "catHealth": "Здоровье", - "catEducation": "Education", + "catEducation": "Образование", "catMisc": "Разное", "catEarnedIncome": "Трудовой доход", "catInvestmentIncome": "Инвестиционный доход", diff --git a/public/locales/sv.json b/public/locales/sv.json index 5d36878..0ddfd0b 100644 --- a/public/locales/sv.json +++ b/public/locales/sv.json @@ -463,14 +463,14 @@ "trendNeutral": "- samma som {{month}}", "validAmountRequired": "Ange ett giltigt belopp", "dateRequired": "Datum krävs", - "catFood": "Food", + "catFood": "Specerier", "catRent": "Hyra", "catInsurance": "Försäkring", "catMobility": "Transport", - "catLeisure": "Leisure and Entertainment", + "catLeisure": "Fritid", "catClothing": "Kläder", "catHealth": "Hälsa", - "catEducation": "Education", + "catEducation": "Utbildning", "catMisc": "Diverse", "catEarnedIncome": "Arbetsinkomst", "catInvestmentIncome": "Investeringsinkomst", diff --git a/public/locales/tr.json b/public/locales/tr.json index bd0d42d..4f98a3f 100644 --- a/public/locales/tr.json +++ b/public/locales/tr.json @@ -463,14 +463,14 @@ "trendNeutral": "- {{month}} ile aynı", "validAmountRequired": "Lütfen geçerli bir tutar girin", "dateRequired": "Tarih zorunludur", - "catFood": "Food", + "catFood": "Market", "catRent": "Kira", "catInsurance": "Sigorta", "catMobility": "Ulaşım", - "catLeisure": "Leisure and Entertainment", + "catLeisure": "Eğlence", "catClothing": "Giyim", "catHealth": "Sağlık", - "catEducation": "Education", + "catEducation": "Eğitim", "catMisc": "Diğer", "catEarnedIncome": "Kazanç Geliri", "catInvestmentIncome": "Yatırım Geliri", diff --git a/public/locales/uk.json b/public/locales/uk.json index 1cff39c..31c9cb9 100644 --- a/public/locales/uk.json +++ b/public/locales/uk.json @@ -463,14 +463,14 @@ "trendNeutral": "— так само, як у {{month}}", "validAmountRequired": "Будь ласка, введіть коректну суму", "dateRequired": "Дата є обов'язковою", - "catFood": "Food", + "catFood": "Продукти", "catRent": "Оренда", "catInsurance": "Страхування", "catMobility": "Транспорт", - "catLeisure": "Leisure and Entertainment", + "catLeisure": "Дозвілля", "catClothing": "Одяг", "catHealth": "Здоров'я", - "catEducation": "Education", + "catEducation": "Освіта", "catMisc": "Різне", "catEarnedIncome": "Трудовий дохід", "catInvestmentIncome": "Інвестиційний дохід", diff --git a/public/locales/zh.json b/public/locales/zh.json index 539bf8b..20d2d7f 100644 --- a/public/locales/zh.json +++ b/public/locales/zh.json @@ -463,14 +463,14 @@ "trendNeutral": "- 与 {{month}} 相同", "validAmountRequired": "请输入有效金额", "dateRequired": "日期为必填项", - "catFood": "Food", + "catFood": "食品", "catRent": "租金", "catInsurance": "保险", "catMobility": "出行", - "catLeisure": "Leisure and Entertainment", + "catLeisure": "休闲", "catClothing": "服装", "catHealth": "健康", - "catEducation": "Education", + "catEducation": "教育", "catMisc": "其他", "catEarnedIncome": "劳动收入", "catInvestmentIncome": "投资收入", diff --git a/server/db.js b/server/db.js index 05d6f8c..4ef2853 100644 --- a/server/db.js +++ b/server/db.js @@ -606,14 +606,14 @@ const MIGRATIONS = [ ); INSERT OR IGNORE INTO budget_categories (key, name, type, sort_order) VALUES - ('housing', 'Habitação / Casa', 'expense', 0), - ('food', 'Alimentação', 'expense', 1), - ('transport', 'Transporte', 'expense', 2), - ('personal_health', 'Cuidados Pessoais / Saúde', 'expense', 3), - ('leisure', 'Lazer e Entretenimento', 'expense', 4), - ('shopping_clothing', 'Compras e Vestuário', 'expense', 5), - ('education', 'Educação', 'expense', 6), - ('financial_other', 'Serviços Financeiros e Outros', 'expense', 7), + ('housing', 'Housing / Home', 'expense', 0), + ('food', 'Food', 'expense', 1), + ('transport', 'Transport', 'expense', 2), + ('personal_health', 'Personal Care / Health', 'expense', 3), + ('leisure', 'Leisure and Entertainment', 'expense', 4), + ('shopping_clothing', 'Shopping and Clothing', 'expense', 5), + ('education', 'Education', 'expense', 6), + ('financial_other', 'Financial Services and Other', 'expense', 7), ('Erwerbseinkommen', 'Erwerbseinkommen', 'income', 0), ('Kapitalerträge', 'Kapitalerträge', 'income', 1), ('Geschenke & Transfers', 'Geschenke & Transfers', 'income', 2), @@ -621,40 +621,40 @@ const MIGRATIONS = [ ('Sonstiges Einkommen', 'Sonstiges Einkommen', 'income', 4); INSERT OR IGNORE INTO budget_subcategories (key, category_key, name, sort_order) VALUES - ('rent_mortgage', 'housing', 'Aluguel / Prestação', 0), - ('condominium', 'housing', 'Condomínio', 1), - ('utilities', 'housing', 'Luz / Água / Gás', 2), - ('internet_tv_phone', 'housing', 'Internet / TV / Telefone', 3), - ('renovation_maintenance', 'housing', 'Reforma / Manutenção', 4), - ('cleaning', 'housing', 'Limpeza', 5), - ('groceries', 'food', 'Supermercado', 0), - ('restaurants_bars', 'food', 'Restaurante / Bares', 1), - ('snacks_fast_food', 'food', 'Lanches / Fast Food', 2), - ('bakery', 'food', 'Padaria', 3), - ('fuel', 'transport', 'Combustível', 0), - ('parking_tolls', 'transport', 'Estacionamento / Pedágio', 1), - ('public_transport', 'transport', 'Transporte Público', 2), - ('apps_taxi', 'transport', 'Aplicativos / Táxi', 3), - ('maintenance_insurance', 'transport', 'Manutenção / Seguro', 4), - ('pharmacy', 'personal_health', 'Farmácia', 0), - ('health_insurance', 'personal_health', 'Plano de Saúde', 1), - ('gym_sports', 'personal_health', 'Academia / Esportes', 2), - ('beauty_cosmetics', 'personal_health', 'Beleza / Cosméticos', 3), - ('travel', 'leisure', 'Viagens', 0), + ('rent_mortgage', 'housing', 'Rent / Mortgage', 0), + ('condominium', 'housing', 'Condominium fees', 1), + ('utilities', 'housing', 'Electricity / Water / Gas', 2), + ('internet_tv_phone', 'housing', 'Internet / TV / Phone', 3), + ('renovation_maintenance', 'housing', 'Renovation / Maintenance', 4), + ('cleaning', 'housing', 'Cleaning', 5), + ('groceries', 'food', 'Groceries', 0), + ('restaurants_bars', 'food', 'Restaurants / Bars', 1), + ('snacks_fast_food', 'food', 'Snacks / Fast Food', 2), + ('bakery', 'food', 'Bakery', 3), + ('fuel', 'transport', 'Fuel', 0), + ('parking_tolls', 'transport', 'Parking / Tolls', 1), + ('public_transport', 'transport', 'Public transport', 2), + ('apps_taxi', 'transport', 'Apps / Taxi', 3), + ('maintenance_insurance', 'transport', 'Maintenance / Insurance', 4), + ('pharmacy', 'personal_health', 'Pharmacy', 0), + ('health_insurance', 'personal_health', 'Health insurance', 1), + ('gym_sports', 'personal_health', 'Gym / Sports', 2), + ('beauty_cosmetics', 'personal_health', 'Beauty / Cosmetics', 3), + ('travel', 'leisure', 'Travel', 0), ('streaming', 'leisure', 'Streaming', 1), - ('events', 'leisure', 'Eventos', 2), + ('events', 'leisure', 'Events', 2), ('hobbies', 'leisure', 'Hobbies', 3), - ('clothes_shoes', 'shopping_clothing', 'Roupas / Calçados', 0), - ('electronics', 'shopping_clothing', 'Eletrônicos', 1), - ('gifts', 'shopping_clothing', 'Presentes', 2), - ('courses_college', 'education', 'Cursos / Faculdade', 0), - ('school_supplies', 'education', 'Material Escolar', 1), - ('languages', 'education', 'Idiomas', 2), - ('loans_interest', 'financial_other', 'Empréstimos / Juros', 0), - ('bank_fees', 'financial_other', 'Tarifas Bancárias', 1), - ('insurance_other', 'financial_other', 'Seguros', 2), - ('investments', 'financial_other', 'Investimentos', 3), - ('taxes', 'financial_other', 'Impostos', 4); + ('clothes_shoes', 'shopping_clothing', 'Clothes / Shoes', 0), + ('electronics', 'shopping_clothing', 'Electronics', 1), + ('gifts', 'shopping_clothing', 'Gifts', 2), + ('courses_college', 'education', 'Courses / College', 0), + ('school_supplies', 'education', 'School supplies', 1), + ('languages', 'education', 'Languages', 2), + ('loans_interest', 'financial_other', 'Loans / Interest', 0), + ('bank_fees', 'financial_other', 'Bank fees', 1), + ('insurance_other', 'financial_other', 'Insurance', 2), + ('investments', 'financial_other', 'Investments', 3), + ('taxes', 'financial_other', 'Taxes', 4); INSERT OR IGNORE INTO budget_categories (key, name, type, sort_order) SELECT category, category, CASE WHEN amount < 0 THEN 'expense' ELSE 'income' END, 1000 From e31f5d3b609c2e86fc2ac4c5203c93a2d81a9ec4 Mon Sep 17 00:00:00 2001 From: Ulas Kalayci Date: Sat, 25 Apr 2026 17:01:52 +0200 Subject: [PATCH 2/2] chore: release v0.24.0 --- CHANGELOG.md | 15 +++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2d4a45..32e116c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.24.0] - 2026-04-25 + +### Added +- Budget: expense categories are now stored in the database (`budget_categories` table) as stable English slugs, replacing hardcoded German strings +- Budget: subcategory support for all expense entries — 35 predefined subcategories across 8 top-level categories (housing, food, transport, personal_health, leisure, shopping_clothing, education, financial_other) +- Budget: users can add custom categories and subcategories directly from the entry modal via inline "+ category" / "+ subcategory" buttons +- Budget: new API endpoints `POST /api/v1/budget/categories` and `POST /api/v1/budget/categories/:key/subcategories` for custom category/subcategory creation +- Budget: subcategory displayed alongside category in each entry's metadata line +- Budget: CSV export now includes a subcategory column and English column headers +- i18n: all 14 non-German locales extended with new budget category keys (`catHousing`, `catTransport`, `catPersonalHealth`, `catShoppingClothing`, `catFinancialOther`) and all 35 subcategory label keys +- All server-side log messages and API error strings translated from German to English — contributed by @rafaelfoster + +### Changed +- Budget category labels for existing entries migrated to new slug keys via DB migration 15; display names remain fully localised through the i18n system + ## [0.23.17] - 2026-04-25 ### Fixed diff --git a/package-lock.json b/package-lock.json index 814c504..243af0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "oikos", - "version": "0.23.17", + "version": "0.24.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "oikos", - "version": "0.23.17", + "version": "0.24.0", "license": "MIT", "dependencies": { "bcrypt": "^6.0.0", diff --git a/package.json b/package.json index 41b5b8f..6baa4d4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "oikos", - "version": "0.23.17", + "version": "0.24.0", "description": "Self-hosted family planner - calendar, tasks, shopping, meal planning, budget and more. Private, open-source, no subscription.", "main": "server/index.js", "type": "module",