Commit Graph

555 Commits

Author SHA1 Message Date
Alexander 6db928e524 feat: ExerciseDB integration with muscle heatmap, SVG body filter, and enriched exercises
Integrate ExerciseDB v2 data layer (muscleMap.ts, exercisedb.ts) to enrich
the 77 static exercises with detailed muscle targeting, similar exercises,
and expand the catalog to 254 exercises. Add interactive SVG muscle body
diagrams for both the stats page heatmap and exercise list filtering, with
split front/back views flanking the exercise list on desktop. Replace body
part dropdown with unified muscle group multi-select with pill tags.
2026-04-06 20:57:49 +02:00
Alexander 5ea795a745 fitness: add ExerciseDB v2 scrape data, media, and ID mapping
Scrape scripts for ExerciseDB v2 API (scrape-exercises.ts,
download-exercise-media.ts), raw data for 200 exercises with
images/videos, and a 1:1 mapping from ExerciseDB IDs to internal
kebab-case slugs (exercisedb-map.ts). 23 exercises matched to
existing internal IDs, 177 new slugs generated.
2026-04-06 15:46:29 +02:00
Alexander f4e0617fc7 feat: add period tracker with calendar, predictions, fertility tracking, and sharing
Full period tracking system for the fitness measure page:
- Period logging with start/end dates, edit/delete support
- EMA-based cycle and period length predictions (α=0.3, 12 future cycles)
- Calendar view with connected range strips, overflow days, today marker
- Fertility window, peak fertility, ovulation, and luteal phase visualization
- Period sharing between users with profile picture avatars
- Cycle/period stats with 95% CI below calendar
- Redesigned profile card as inline header metadata with Venus/Mars icons
- Collapsible weight and period history sections
- Full DE/EN i18n support
2026-04-06 15:12:03 +02:00
Alexander add05f0fad feat: add recipe and OpenFoodFacts search to nutrition food search
Recipes from /rezepte now appear in the food search on /fitness/nutrition,
with per-100g nutrition computed server-side from ingredient mappings.
Recipe results are boosted above BLS/USDA/OFF in search ranking.

OpenFoodFacts products are now searchable by name/brand via MongoDB
text index, alongside the existing barcode lookup.

Recipe and OFF queries run in parallel with in-memory BLS/USDA scans.
2026-04-06 15:09:56 +02:00
Alexander fac140b793 perf: optimize DB connections, queries, and indexes
Fix dev-mode reconnect storm by persisting mongoose connection state on
globalThis instead of a module-level flag that resets on Vite HMR.

Eliminate redundant in_season DB query on /rezepte — derive seasonal
subset from all_brief client-side. Parallelize all page load fetches.

Replace N+1 settlement queries in balance route with single batch $in
query. Parallelize balance sum and recent splits aggregations.

Trim unused dateModified/dateCreated from recipe brief projections.

Add indexes: Payment(date, createdAt), PaymentSplit(username),
Recipe(short_name), Recipe(season).
2026-04-06 12:42:54 +02:00
Alexander 1fa2e350d7 feat: major dependency upgrades, remove Redis, fix mongoose 9 types
Dependencies upgraded:
- svelte 5.38→5.55, @sveltejs/kit 2.37→2.56, adapter-node 5.3→5.5
- mongoose 8→9, sharp 0.33→0.34, typescript 5→6
- lucide-svelte → @lucide/svelte 1.7 (Svelte 5 native package)
- vite 7→8 with rolldown (build time 33s→14s)
- Removed terser (esbuild/oxc default minifier is 20-100x faster)

Infrastructure:
- Removed Redis/ioredis cache layer — MongoDB handles caching natively
- Deleted src/lib/server/cache.ts and all cache.get/set/invalidate usage
- Removed redis-cli from deploy workflow, Redis env vars from .env.example

Mongoose 9 migration:
- Replaced deprecated `new: true` with `returnDocument: 'after'` (16 files)
- Fixed strict query filter types for ObjectId/paymentId fields
- Fixed season param type (string→number) in recipe API
- Removed unused @ts-expect-error in WorkoutSession model
2026-04-06 12:21:26 +02:00
Alexander 30d7f321d3 fix: timezone-safe streak continuity with 48h elapsed-time window
Use local dates instead of UTC for day boundaries, and store an epoch
timestamp alongside the date string. Streak alive check uses real
elapsed time (<48h) which covers dateline crossings. Old data without
timestamps falls back to date-string comparison so existing streaks
are preserved.
2026-04-06 00:36:10 +02:00
Alexander a4ea6c6e66 fix: add status bar shadow and safe-area offset for Android
Add drop shadow under the safe-area-inset-top zone to visually
separate Android status icons from page content. Adjust StickyImage
sticky positioning and max-height to account for safe-area-inset.
2026-04-06 00:10:08 +02:00
Alexander f508ba30cd fix: resolve Svelte build warnings
- Add keyboard handler to fab-modal and dialog overlays (a11y)
- Remove unused .btn-cancel CSS selector
- Wrap meal name input inside its label, use span for ingredients heading
- Change image-wrap-desktop from div to figure for valid figcaption
2026-04-06 00:06:59 +02:00
Alexander f61929a5f0 feat: add Latin route support, Angelus/Regina Caeli streak counter, and Eastertide liturgical adjustments
- Add /fides route with Latin-only mode for all faith pages (rosary, prayers, individual prayers)
- Add LA option to language selector for faith routes
- Add Angelus/Regina Caeli streak counter with 3x daily tracking (morning/noon/evening bitmask)
- Store streak data in localStorage (offline) and MongoDB (logged-in sync)
- Show Annunciation/Coronation paintings via StickyImage with artist captions
- Switch Angelus↔Regina Caeli in header and landing page based on Eastertide
- Fix Eastertide to end at Ascension (+39 days) instead of Pentecost
- Fix Lent Holy Saturday off-by-one with toMidnight() normalization
- Fix non-reactive typedLang in faith layout
- Fix header nav highlighting: exclude angelus/regina-caeli from prayers active state
2026-04-05 22:53:27 +02:00
Alexander 48b207b60e fix: smoother barcode scanner with validation and confirmation
- Use createImageBitmap for off-thread frame capture so video stays smooth
- Require 2 consecutive identical reads before accepting a barcode
- Validate EAN/UPC check digit and reject codes with invalid length
- Only accept 8, 12, or 13 digit codes (EAN-8, UPC-A, EAN-13)
2026-04-05 21:13:23 +02:00
Alexander 16b90da2cc fix: prefer native BarcodeDetector, fall back to WASM ponyfill
Native BarcodeDetector works in Chrome/Android WebView over HTTPS.
Only load the ZXing WASM ponyfill when native API is unavailable or
doesn't support the needed formats.
2026-04-05 12:35:44 +02:00
Alexander 76d0cd59ba fix: self-host ZXing WASM in static/ instead of ?url import
The zxing-wasm ?url import fails in Rollup production builds. Copy the
WASM binary to static/fitness/ and reference it via absolute path in
prepareZXingModule locateFile.
2026-04-05 12:28:12 +02:00
Alexander dcbe1d1a83 fix: barcode scanner WASM loading and Android camera permission
- Exclude barcode-detector from Vite optimizeDeps to prevent WASM mangling
- Self-host ZXing WASM via Vite ?url import with prepareZXingModule
- Use barcode-detector/ponyfill instead of deprecated /pure export
- Separate barcode-detector/zxing-wasm into own chunk
- Add CAMERA permission to Android manifest for Tauri app
2026-04-05 12:23:18 +02:00
Alexander 039d37b410 feat: add barcode scanner with OpenFoodFacts integration
- Camera-based barcode scanning in FoodSearch using barcode-detector (ZXing WASM)
- Import script to load OFF MongoDB dump into lean openfoodfacts collection
  with kJ→kcal fallback and dedup handling
- Barcode lookup API with live OFF API fallback that caches results locally,
  progressively enhancing the local database
- Add 'off' source to food log, custom meal, and favorite ingredient models
- OpenFoodFact mongoose model for the openfoodfacts collection
2026-04-05 11:57:28 +02:00
Alexander 23b45abc5a feat: add nutrition/food logging to fitness section
Daily food log with calorie and macro tracking against configurable diet
goals (presets: WHO balanced, cut, bulk, keto, etc.). Includes USDA/BLS
food search with portion-based units, favorite ingredients, custom
reusable meals, per-food micronutrient detail pages, and recipe-to-log
integration via AddToFoodLogButton. Extends FitnessGoal with nutrition
targets and adds birth year to user profile for BMR calculation.
2026-04-04 14:34:47 +02:00
Alexander 5d7a959355 nutrition: detect recipe refs in ingredients, show in edit UI with multiplier
Skip embedding matching for anchor-tag ingredients that reference other
recipes. Instead, mark them with recipeRef/recipeRefMultiplier fields so
their nutrition is resolved via resolveReferencedNutrition with a
user-configurable fraction. The edit UI shows these as teal REF badges
with an editable "Anteil" input.
2026-04-04 09:43:49 +02:00
Alexander b99333c889 nutrition: extract shared ref resolution, fix HTML in ingredient names
- Move parseAnchorRecipeRef and resolveReferencedNutrition from the
  items endpoint into nutritionMatcher.ts for reuse
- JSON-LD endpoint now includes nutrition from referenced recipes
  (base recipe refs and anchor-tag ingredient refs)
- Strip HTML tags in normalizeIngredientName/De before matching to
  prevent regex crash on ingredients containing anchor tags
- Escape regex special chars in substringMatchScore word-boundary check
2026-04-03 11:15:55 +02:00
Alexander 04b6e0a739 nutrition: include NutritionInformation in recipe JSON-LD
Compute macro/micro totals from stored nutrition mappings and emit a
schema.org NutritionInformation block in the JSON-LD output. Values are
per-serving when portions are defined, otherwise recipe totals.
2026-04-03 11:15:49 +02:00
Alexander a1bebc1a76 fix: nutrition coverage double-counting excluded ingredients
Excluded (manually disregarded) ingredients were incrementing the total
count twice — once in the loop body and again in the exclusion check —
deflating the displayed coverage percentage.
2026-04-03 09:00:27 +02:00
Alexander b7905b94fe chore: Svelte 5 syntax updates, a11y fixes, and dead CSS removal
Replace deprecated svelte:component with direct component invocation,
use span instead of label for non-input controls with role="group",
remove unused imports and dead CSS rules.
2026-04-03 08:44:36 +02:00
Alexander 54a345224e nutrition: use SvelteKit read() for embedding files instead of fs
Replace fragile CWD-based readFileSync path resolution with SvelteKit's
read() + Vite ?url asset imports. This lets the build system manage the
embedding files as hashed immutable assets, fixing ENOENT errors in
production where the working directory didn't match expectations.
2026-04-03 08:43:12 +02:00
Alexander b356689572 fitness: compute kcal server-side and store in session document
Previously kcal was computed on-the-fly in 3 places with inconsistent
inputs (hardcoded 80kg, missing GPS data, no demographics). Now a
shared computeSessionKcal() helper runs server-side using the best
available method (GPS + real demographics) and stores the result in
a new kcalEstimate field on WorkoutSession.

Kcal is recomputed on save, recalculate, GPX upload, and GPX delete.
The stats overview uses stored values with a legacy fallback for
sessions saved before this change.
2026-04-03 08:24:45 +02:00
Alexander d41416e9f3 nutrition: fix embedding file paths for production and copy to dist
resolve() uses CWD which in production (adapter-node) is dist/, not the
project root. Detect the correct data directory at startup and add a
postbuild step to copy the embedding JSON files into dist/data/.
2026-04-02 21:08:54 +02:00
Alexander 07610a498f theming: migrate cospend to semantic CSS variables, extract SaveFab, refactor measure page
Replace hardcoded Nord colors with semantic CSS variables across all cospend
pages and shared components (FormSection, ImageUpload, SplitMethodSelector,
UsersList, PaymentModal, BarChart). Remove all dark mode override blocks.
Make BarChart font colors theme-reactive via isDark() + MutationObserver.

Extract reusable SaveFab component and use it on recipe edit and all cospend
edit/add pages. Remove Cancel buttons and back links in favor of browser
navigation. Replace raw checkboxes with Toggle component.

Move fitness measurement add/edit forms to separate routes with SaveFab.
Collapse profile section (sex/height) by default on the measure page.

Document theming rules in CLAUDE.md for future reference.
2026-04-02 20:38:33 +02:00
Alexander 08a26ff4ac Merge branch 'recipes-calories'
recipes: nutrition calculator with BLS/USDA matching, manual overwrites, and skip

Dual-source nutrition system using BLS (German, primary) and USDA (English, fallback)
with ML embedding matching (multilingual-e5-small / all-MiniLM-L6-v2), hybrid
substring-first search, and position-aware scoring heuristics.

Includes per-recipe and global manual ingredient overwrites, ingredient skip/exclude,
referenced recipe nutrition (base refs + anchor tags), section-name dedup,
amino acid tracking, and reactive client-side calculator with NutritionSummary component.

recipes: overhaul nutrition editor UI and defer saves to form submission

- Nutrition mappings and global overwrites are now local-only until
  the recipe is saved, preventing premature DB writes on generate/edit
- Generate endpoint supports ?preview=true for non-persisting previews
- Show existing nutrition data immediately instead of requiring generate
- Replace raw checkboxes with Toggle component for global overwrites,
  initialized from existing NutritionOverwrite records
- Fix search dropdown readability (solid backgrounds, proper theming)
- Use fuzzy search (fzf-style) for manual nutrition ingredient lookup
- Swap ingredient display: German primary, English in brackets
- Allow editing g/u on manually mapped ingredients
- Make translation optional: separate save (FAB) and translate buttons
- "Vollständig neu übersetzen" now triggers actual full retranslation
- Show existing translation inline instead of behind a button
- Replace nord0 dark backgrounds with semantic theme variables
2026-04-02 19:47:12 +02:00
Alexander 8f3a3035f0 recipes: overhaul nutrition editor UI and defer saves to form submission
- Nutrition mappings and global overwrites are now local-only until
  the recipe is saved, preventing premature DB writes on generate/edit
- Generate endpoint supports ?preview=true for non-persisting previews
- Show existing nutrition data immediately instead of requiring generate
- Replace raw checkboxes with Toggle component for global overwrites,
  initialized from existing NutritionOverwrite records
- Fix search dropdown readability (solid backgrounds, proper theming)
- Use fuzzy search (fzf-style) for manual nutrition ingredient lookup
- Swap ingredient display: German primary, English in brackets
- Allow editing g/u on manually mapped ingredients
- Make translation optional: separate save (FAB) and translate buttons
- "Vollständig neu übersetzen" now triggers actual full retranslation
- Show existing translation inline instead of behind a button
- Replace nord0 dark backgrounds with semantic theme variables
2026-04-02 19:46:03 +02:00
Alexander a866d10ac1 tasks: use Toggle component for recurring task switch 2026-04-02 17:29:35 +02:00
Alexander c2007aaa4a tasks: add refresh mode toggle (completion date vs planned date)
Recurring tasks can now calculate next due date from either the
completion time (default) or the planned due date, catching up
if overdue.
2026-04-02 17:29:08 +02:00
Alexander 81c70df78e tasks: shared task board with sticker rewards, difficulty levels, and calendar
Complete household task management system behind task_users auth group:
- Task CRUD with recurring schedules, assignees, tags, and optional difficulty
- Blobcat SVG sticker rewards on completion, rarity weighted by difficulty
- Sticker collection page with calendar view and progress tracking
- Redesigned cards with left accent urgency strip, assignee PFP, round check button
- Weekday-based due date labels for tasks within 7 days
- Tasks link added to homepage LinksGrid
2026-04-02 07:32:55 +02:00
Alexander d2a0411937 recipes: nutrition calculator with BLS/USDA matching, manual overwrites, and skip
Dual-source nutrition system using BLS (German, primary) and USDA (English, fallback)
with ML embedding matching (multilingual-e5-small / all-MiniLM-L6-v2), hybrid
substring-first search, and position-aware scoring heuristics.

Includes per-recipe and global manual ingredient overwrites, ingredient skip/exclude,
referenced recipe nutrition (base refs + anchor tags), section-name dedup,
amino acid tracking, and reactive client-side calculator with NutritionSummary component.
2026-04-01 13:00:55 +02:00
Alexander c76c6e8cbe recipes: revert to substring search, keep fuzzy for prayers/exercises 2026-03-30 13:29:45 +02:00
Alexander f649b94e9d fitness: GPS workout templates with interval pre-selection
Enable creating templates for GPS-tracked workouts with activity type
and optional interval training. GPS templates show activity/interval
info instead of exercise lists in cards, modals, and schedule. Starting
a GPS template pre-selects the interval and jumps to the map screen.
2026-03-30 13:24:58 +02:00
Alexander bdaae6d7dc fitness: use time-scale x-axis for weight chart to handle date gaps
Weight chart now spaces data points proportionally to actual dates
instead of evenly. Days without a weight log no longer compress adjacent
points together. Uses Chart.js time scale with chartjs-adapter-date-fns.
2026-03-30 09:00:17 +02:00
Alexander e152219c5b fitness: TTS volume control, audio ducking, and workout start/finish announcements
Add TTS volume slider (default 80%) and audio duck toggle to voice
guidance settings. Announce "Workout started" when TTS initializes and
speak a full workout summary (time, distance, avg pace) on finish.
The finish summary reuses the existing TTS instance via handoff so it
plays fully without blocking the completion screen.
2026-03-30 08:49:14 +02:00
Alexander dfe056d650 fitness: shorter strings for main activity buttons, add missing pages 2026-03-26 15:04:42 +01:00
Alexander e607c9a375 fintess: WIP: interval setup and TTS 2026-03-26 14:11:07 +01:00
Alexander 1e2422bbb1 feat: GPS workout UI polish and voice guidance improvements
- Start native GPS service in paused state during pre-start (notification
  shows "Waiting to start..." instead of running timer)
- Bump notification importance to IMPORTANCE_DEFAULT for lock screen
- Theme-aware glass blur overlay matching header style (dark/light mode)
- Dark Nord blue background for activity picker, audio stats panel
- Transparent overlay in pre-start, gradient fade for cancel button
- Use Toggle component for voice announcements checkbox
- Persist voice guidance settings to localStorage
- Derive voice language from page language, remove language selector
2026-03-26 10:45:42 +01:00
Alexander 47e85587dc feat: redesign GPS workout UI with Runkeeper-style map overlay
- Full-screen fixed map with controls overlaid at the bottom
- Activity type selector (running/walking/cycling/hiking) with proper
  exercise mapping for history display
- GPS starts immediately on entering workout screen for faster lock
- GPS track attached to cardio exercise (like GPX upload) so history
  shows distance, pace, splits, and map
- Add activityType field to workout state, session model, and sync
- Cancel button appears when workout is paused
- GPS Workout button only shown in Tauri app
2026-03-25 19:54:30 +01:00
Alexander 1a2ec40e7a feat: add TTS voice guidance during GPS-tracked workouts
Voice announcements run entirely in the Android foreground service
(works with screen locked). Configurable via web UI before starting
GPS: time-based or distance-based intervals, selectable metrics
(total time, distance, avg/split/current pace), language (en/de).

Also syncs workout pause/resume state to the native service — pausing
the workout timer now freezes the Android-side elapsed time, distance
accumulation, and TTS triggers.

Includes TTS engine detection with install prompt if none found, and
Android 11+ package visibility query for TTS service discovery.
2026-03-25 13:13:04 +01:00
Alexander d40a7fe7c5 fix: resolve all 58 TypeScript errors across codebase
- Add SvelteKit PageLoad/LayoutLoad/Actions types to recipe route files
- Fix possibly-undefined access on recipe.images, translations.en
- Fix parseFloat on number types in cospend split validation
- Use discriminated union guards for IngredientItem/InstructionItem
- Fix cache invalidation Promise<number> vs Promise<void> mismatch
- Suppress Mongoose model() complex union type error in WorkoutSession
2026-03-25 07:58:13 +01:00
Alexander 45bc9fca29 feat: add toast notification system, replace all alert() calls
Create shared toast store and Toast component mounted in root layout.
Wire toast.error() into all fitness API calls that previously failed
silently, and replace all alert() calls across recipes and cospend.
2026-03-25 07:40:52 +01:00
Alexander a904a2bce8 fix: shorten dashboard labels to "Burned" and "Covered"
Values already include units (kcal, km), so verbose labels were redundant.
Remove unused distance_covered i18n key.
2026-03-25 07:18:57 +01:00
Alexander 540c9ae2dd feat: add cardio PRs for longest distance and fastest pace by range
Track longestDistance and fastestPace PRs for cardio exercises with
activity-specific distance ranges: running (0-3, 3-7, 7-21.1, 21.1-42.2,
42.2+ km), swimming (0-0.4, 0.4-1.5, 1.5-5, 5-10, 10+ km), cycling
(0-15, 15-40, 40-100, 100-200, 200+ km), hiking (0-5, 5-15, 15-30,
30-50, 50+ km), rowing (0-2, 2-5, 5-10, 10-21.1, 21.1+ km).

Shared detection logic in cardioPrRanges.ts used by both session save
and recalculate endpoints. Display support in history detail and workout
completion summary.
2026-03-24 20:41:23 +01:00
Alexander 2ac7cdc9f7 fitness: match WorkoutFab rest timer style to active page RestTimer 2026-03-23 22:18:22 +01:00
Alexander 19ac60c6f2 fitness: add offline support with session queue and shell caching
Cache fitness page shells and data routes in the service worker so
pages load offline. Queue finished workouts in IndexedDB when the
POST fails and auto-flush them on reconnect. Show an offline banner
on the completion screen so the user knows their workout will sync.
2026-03-23 22:15:42 +01:00
Alexander 82b6d7c15f faith: fix typos in confiteor 2026-03-23 19:55:39 +01:00
Alexander 4579d5f76e fix: resolve Svelte a11y and reactivity build warnings 2026-03-23 17:45:27 +01:00
Alexander 81a1d25e5f android: enable offline sync and hide theme toggle in Tauri app
Detect Tauri via __TAURI__ in pwaStore so the offline recipe sync,
image caching, and auto-sync activate in the Android shell.
2026-03-23 17:38:29 +01:00
Alexander fa6e7c8d1f app: follow system theme, remove toggle 2026-03-23 17:37:04 +01:00