- Budget categories and subcategories moved to database tables (migration 15+16)
- Expense categories migrated from German strings to stable English slugs
- New `/budget/categories` and `/budget/categories/:key/subcategories` POST endpoints
- Budget modal now shows subcategory selector with inline add-new buttons
- Added 35 predefined subcategories across 8 expense categories (housing, food,
transport, personal_health, leisure, shopping_clothing, education, financial_other)
- CSV export updated to include subcategory column and English headers
- All server log messages and error strings translated to English
- i18n: all 14 non-German locales extended with new budget category/subcategory keys
- Service worker cache version bumped (v52/v47)
Contributed by @rafaelfoster
Co-Authored-By: Rafael Foster <rafaelfoster@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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 <noreply@anthropic.com>
* fix: add missing i18n keys for nav, search, tasks, calendar, settings, reminders in all locales
Resolves#82
nav.more, calendar.ics.reset/resetToast, settings.ics.*, tasks.filter*,
tasks.swiped*, search.* and reminders.* keys were missing in all 14
non-German locale files, causing the app to fall back to German strings.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: release v0.23.15
---------
Co-authored-by: Ulas Kalayci <ulas.kalayci@googlemail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolves#82
nav.more, calendar.ics.reset/resetToast, settings.ics.*, tasks.filter*,
tasks.swiped*, search.* and reminders.* keys were missing in all 14
non-German locale files, causing the app to fall back to German strings.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pull_request_target statt pull_request: GitHub stellt ACTIONS_ID_TOKEN_REQUEST_URL
nur im Basis-Repo-Kontext bereit. pull-requests: write ergänzt, damit die Aktion
Review-Kommentare posten kann.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When OPENWEATHER_UNITS=imperial, OpenWeatherMap returns wind speed in
mph directly — the server was incorrectly multiplying by 3.6 (m/s→km/h)
on top of that. All locale strings also hardcoded the unit label instead
of using a {{windUnit}} placeholder, so the label always read km/h.
Resolves#79
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevents unvalidated user input from reaching DOM sinks (href, template
literals). Host is checked against a strict hostname regex; port is
parsed as an integer and range-checked to 1-65535. An inline error
message is shown on validation failure.
Resolves CodeQL js/xss-through-dom alert #7.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add --color-warning-translucent and --color-soon tokens to tokens.css
- Replace hardcoded font-size 1.4rem with var(--text-xl) in dashboard.css
- Replace hardcoded rgba color with var(--color-warning-translucent)
- Remove duplicate .task-item__meta--overdue rule
- Fix hardcoded 'de-DE' locale: use formatTime() from i18n.js
- Fix formatDueDate: don't show time (23:59) when no due_time is set
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After navigating to tasks/calendar/shopping/notes via FAB, the page's
primary add-button is programmatically clicked so the new-item modal
opens without a second tap. FAB container right-margin doubled to avoid
overlap with the browser's edge-swipe gesture zone.
Header shows current date and time instead of user name + separate date line.
urgentCount replaced by overdueCount (overdue tasks) and dueSoonCount (due today/soon),
each with a distinct chip color. formatDueDate updated to accept due_time and return
accurate overdue/soon states against the current moment.
dashboard grid expands to 4 columns at 1280px instead of 1440px.
widgetHeader replaces <a href> with <button type="button"> so iOS Safari
does not intercept the touch event before the JS click handler fires.
widget__header gets position: relative; z-index: 2 to appear above the
backdrop-filter ::after pseudo-element stacking context.
Imports fmtLocation; renderUpcomingEvents adds event-item__cal span for
cal_name and shows location with normalized ICS escapes via fmtLocation().
Event color dot gets filter: saturate(0.4) to match calendar view style.
Page-in animations drop 'forwards' fill mode — a .page-transition base class
(opacity:0) serves as the initial state, and .page-transition--in-{left,right}
force opacity:1 after the animation ends, preventing a flash-back-to-invisible
on some WebKit versions. Sidebar expands at 1440px instead of 1280px.
Glass desktop toolbar loses the rounded card border in favour of a flat
accent-top-border + bottom border consistent with other module headers.