Commit Graph

589 Commits

Author SHA1 Message Date
Alexander 6c4367b939 feat: add 7 new shopping icons and deploy hook
Add Gemini-generated icons: aperol, bulgur, emmentaler, magerquark,
quinoa, raeucherlachs, tortilla_wraps. Update catalog with 11 new
entries (including aliases), regenerate embeddings and categories.
Add post-commit hook to rsync shopping icons to bocken.org.
2026-04-09 23:09:09 +02:00
Alexander c439f2f6b0 feat: redesign LinksGrid with semantic theming, rounded corners, and new layout
- Use semantic CSS variables (--color-surface, --shadow-sm, etc.) instead
  of hardcoded Nord values and manual dark mode overrides
- Add border-radius and overflow:hidden for rounded card corners
- Move icon fill variables (--grid-fill-*) into app.css theme system:
  colorful (red/orange/green) in light, cool blues in dark
- Mottled fill distribution via prime-offset nth-child selectors
- Reorder homepage links: Recipes, Shopping, Fitness, Faith, Tasks first
- Add Nutrition direct link with heart-pulse icon
- Document site-wide design language in CLAUDE.md
2026-04-09 22:05:09 +02:00
Alexander a7491d6f08 fix: extend recipe hero images into status bar safe area
Account for env(safe-area-inset-top) in the hero negative margin-top
so images fill the status bar area on edge-to-edge Android instead of
leaving empty space.
2026-04-09 21:33:53 +02:00
Alexander f3f55f1cae feat: replace P/F/C text labels with Lucide macro icons across fitness routes
Use Beef (protein), Droplet (fat), Wheat (carbs) icons consistently in
ring graphs, macro bars, food cards, detail rows, ingredient lists, and
stats page. Add labelIcon snippet prop to RingGraph/StatsRingGraph. Show
macro split legend always (was hidden on mobile) and group it with the
title in horizontal layout.
2026-04-09 21:00:46 +02:00
Alexander 1e23ed02c2 feat: add "round off this day" nutrition suggestions
Suggest optimal 1-3 food combinations to fill remaining macro budget using
weighted least-squares solver over a curated pantry (~55 foods) plus user
favorites/recents. Recipes scored individually (no combining). Features:

- Combinatorial solver (singles, pairs, triples) with macro-weighted scoring
- MealTypePicker component (extracted from quick-log, shared)
- Hero card with fit%, macro delta icons (Beef/Droplet/Wheat), ingredient
  cards, animated +/X toggle for logging
- Responsive layout: sidebar on mobile, center column on desktop
- MongoDB cache with ±5% tolerance, SSR on cache hit, TTL auto-expiry
- Cache invalidation on food-log/favorites/custom-meals CRUD
- Recipe per100g backfill admin endpoint
2026-04-09 20:47:32 +02:00
Alexander 6029cfe18c feat: add food detail pages for OFF and custom meal sources
Extend the nutrition detail page to support OpenFoodFacts items (looked up
by barcode) and custom meals (with ingredient breakdown). All food diary
cards and search results now link to detail pages regardless of source.
2026-04-09 18:17:43 +02:00
Alexander 765fbf4613 feat: add muscle visualization to exercise detail page
New MuscleMap component highlights primary muscles at full opacity and
secondary muscles at 40% using the existing body SVG diagrams. Only
renders front/back views that have active muscles.

Responsive layout: centered inline on mobile, sticky sidebar on desktop.
2026-04-09 00:27:05 +02:00
Alexander 234c3adcf3 feat: add concise bilingual overviews for all 254 exercises
- Fix ExerciseDB data quality (remove empty calf raise, fix Wall Sit,
  correct muscles, typos)
- Rewrite verbose AI-generated English overviews to concise one-sentence
  descriptions
- Add German translations for all 199 EDB exercises (name, instructions,
  overview)
- Add English and German overviews for 55 static-only exercises
- Display overview above instructions on exercise detail page
2026-04-09 00:21:10 +02:00
Alexander c2af12c8d7 refactor: extract RingGraph, StatsRingGraph, MacroBreakdown components
Consolidate 6 duplicated instances of the SVG arc ring pattern into a
composable component hierarchy: RingGraph (base ring), StatsRingGraph
(ring with target markers), and MacroBreakdown (3 rings + kcal + detail
table). Removes ~400 lines of duplicated SVG/CSS from FoodSearch,
nutrition page, meals page, stats page, food detail page, and recipe
NutritionSummary.
2026-04-08 22:21:24 +02:00
Alexander fb0a33daa3 feat: custom meal detail screen, favorites tab, enhanced food search detail
- Replace inline amount row with full detail screen for custom meals
  showing calorie headline, macro rings, macro breakdown, and ingredients
- Add Favorites tab (with filter) between Search and Custom Meals tabs
- Search tab no longer prepends unmatched favorites
- Enhance FoodSearch selected view with macro rings and nutrient breakdown
- Add filter input to custom meals tab
- Document --color-primary/--color-text-on-primary in CLAUDE.md
2026-04-08 21:38:49 +02:00
Alexander 1f20601103 feat: add Today quick-navigate button to nutrition and period tracker
Shows a Today button when not viewing current date/month. Nutrition
page button appears right-aligned in the date nav. Period tracker
button appears top-right of the calendar header with centered
month title and chevrons.
2026-04-08 20:46:58 +02:00
Alexander a0eecbbbeb fix: remove tap highlight on interactive mobile elements
Add -webkit-tap-highlight-color: transparent to muscle heatmap,
water cups, exercise filter pills, and flip stats legend target
triangle 180 degrees.
2026-04-08 20:34:10 +02:00
Alexander 376fbf1ba7 feat: replace browser confirm() with reusable ConfirmDialog component
Promise-based modal dialog with backdrop, keyboard support, and animations,
replacing all 18 native confirm() call sites across fitness, cospend, recipes,
and tasks pages.
2026-04-08 16:47:22 +02:00
Alexander 9af36b0c14 feat: add EN/DE internationalization to cospend section
Move cospend routes to parameterized [cospendRoot=cospendRoot] supporting
both /cospend (DE) and /expenses (EN). Add cospendI18n.ts with 100+
translation keys covering all pages, components, categories, frequency
descriptions, and error messages. Translate BarChart legend, ImageUpload,
UsersList, SplitMethodSelector, DebtBreakdown, EnhancedBalance, and
PaymentModal. Update LanguageSelector and hooks.server.ts for /expenses.
2026-04-08 15:46:01 +02:00
Alexander b7c7b37c94 feat: add Swiss German aliases for shopping list categorization
Add Rahm, Rüebli, Poulet, Cervelat, Crevetten, Weggli, Bürli, Zopf,
Glacé, Konfitüre, Nüsslisalat, Federkohl, Peperoni, and other Swiss
German terms to category items and alias map so they categorize correctly
instead of falling back to embedding similarity (e.g. Rahm→Schwamm).
2026-04-08 14:15:24 +02:00
Alexander 39ffe1732f fix: eliminate all 167 svelte-check warnings
Refactor page components to use $derived + invalidateAll() where data
is read-only or re-fetched after mutations. Suppress state_referenced_locally
for intentional patterns (form state, optimistic updates, pagination).
Fix a11y issues with role="presentation", add standard line-clamp properties,
remove unused CSS selectors and empty rulesets.
2026-04-08 14:06:15 +02:00
Alexander 4bbd733968 feat: inline custom meals, calorie ring overflow animation, theme fixes
Add custom meals tab to inline food add section with search/meals toggle.
Animate calorie ring overflow (red) after primary fill completes, with
separate glow elements so red overflow glows red independently. Apply same
delayed overflow animation to macro progress bars. Replace hardcoded nord8
with --color-primary throughout nutrition page (today badge, ring, tabs,
buttons). Add custom clear button to FoodSearch, hide number input spinners
globally.
2026-04-08 13:15:48 +02:00
Alexander f4cb56291a feat: add nutrition statistics to fitness stats page
Add protein g/kg (7-day avg using trend weight), calorie balance
(surplus/deficit vs goal), diet adherence (since first tracked day),
and macro split rings with target markers to the stats dashboard.
2026-04-08 12:39:03 +02:00
Alexander 0cca6948e6 fix: period tracker day count off by one due to timezone mismatch
ongoingDay compared today (local time with hours) against startDate
parsed as UTC midnight, causing Math.floor to undershoot by 1 day.
Use todayMidnight and parseLocal to normalize both to local midnight.
2026-04-08 11:28:02 +02:00
Alexander aaaff031ef fix: barcode scanner WASM initialization with eager loading and error handling
Use fireImmediately: true to load WASM eagerly during init instead of
lazily on first detect() call, catching load errors immediately. Bail
out after 5 consecutive detection errors instead of looping forever.
Remove verbose debug messages, keeping only error output.
2026-04-08 11:11:56 +02:00
Alexander cf62ce00fa fix: correct BLS 4.0 category mapping for food search results
The CATEGORY_MAP was based on BLS 3.x letter codes which were completely
reshuffled in version 4.0. This caused wrong categories like Schwarztee
showing "Wurstwaren" instead of "Getränke". Remapped all 20 letter codes
to match actual BLS 4.0 Hauptlebensmittelgruppen and regenerated blsDb.
2026-04-08 10:40:26 +02:00
Alexander 27a6e42f03 fix: reorder shopping list categories 2026-04-08 09:13:46 +02:00
Alexander e92fc1cc25 feat: shareable shopping list links with token-based guest access
- Generate temporary share links (default 24h) that allow unauthenticated
  users to view and edit the shopping list
- Share token management modal: create, copy, delete, and adjust TTL
- Token auth bypasses hooks middleware for /cospend/list routes only
- Guest users see only the Liste nav item, other cospend tabs are hidden
- All list API endpoints accept ?token= query param as alternative auth
- MongoDB TTL index auto-expires tokens
2026-04-08 09:04:58 +02:00
Alexander 270c72f80b fix: move shopping catalog.json to src/lib/data to fix import resolution 2026-04-08 05:47:23 +02:00
Alexander 5e161c4b0c feat: add real-time collaborative shopping list at /cospend/list
Real-time shopping list with SSE sync between multiple clients, automatic
item categorization using embedding-based classification + Bring icon
matching, and card-based UI with category grouping.

- SSE broadcast for live sync (add/check/remove items across tabs)
- Hybrid categorizer: direct catalog lookup → category-scoped embedding
  search → per-category default icons, with DB caching
- 388 Bring catalog icons matched via multilingual-e5-base embeddings
- 170+ English→German icon aliases for reliable cross-language matching
- Move cospend dashboard to /cospend/dash, /cospend redirects to list
- Shopping icon on homepage links to /cospend/list
2026-04-07 23:50:54 +02:00
Alexander 2b85d3f2a1 fix: restore backdrop-filter blur in production builds
Lightning CSS was deduplicating manually written backdrop-filter +
-webkit-backdrop-filter to just the webkit version, breaking blur on
Firefox. Remove manual webkit prefixes and let Lightning CSS auto-prefix
via browser targets in vite.config.ts.
2026-04-07 21:46:05 +02:00
Alexander 973783cf53 feat: tap-to-preview stickers in gallery with glow effect
Add full rarity glow to gallery stickers matching the reward popup style.
Tapping an owned sticker opens a large preview card. Allow calendar
stickers to overdraw their cell on hover.
2026-04-07 20:38:06 +02:00
Alexander 0b67f5b687 fix: period end date set to yesterday and show fertile range during ongoing period
Clicking "Period Ended" now records yesterday as the end date, since
you only know the period ended the day after. Also added the missing
fertile date range to the ongoing-period status view.
2026-04-07 20:14:21 +02:00
Alexander 02bb889629 security: enforce auth on all API write endpoints, remove mario-kart
- Remove all mario-kart routes and model (zero auth, unused)
- Add requireGroup() helper to auth middleware
- Recipe write APIs (add/edit/delete/img/*): require rezepte_users group
- Translate endpoint: require rezepte_users (was fully unauthenticated)
- Nutrition overwrites: require auth (was no-op)
- Nutrition generate-all: require rezepte_users (was no-op)
- Alt-text/color endpoints: require rezepte_users group
- Image delete/mv: add path traversal protection
- Period shared endpoint: normalize username for consistent lookup
2026-04-07 20:10:49 +02:00
Alexander 0fe6990df9 fix: remove keyed each on recipe tags to handle duplicate tag names
Duplicate tags (e.g. "Butter" at two indexes) caused a Svelte
each_key_duplicate error that broke rendering on /recipes.
Also use past tense for angelus streak button to match rosary.
2026-04-07 20:03:17 +02:00
Alexander 35721237b4 fix: use dynamic recipeLang in API calls instead of hardcoded /api/rezepte
Client-side navigation to /recipes hung because getUserFavorites and
other endpoints were hardcoded to /api/rezepte, causing fetch mismatches
during SvelteKit's client-side routing.
2026-04-07 19:50:35 +02:00
Alexander e59947dd97 fix: move clear filter button from muscle diagram to filter pills area 2026-04-06 21:30:24 +02:00
Alexander e80f84d152 feat: play double-beep sound when rest timer completes 2026-04-06 21:23:46 +02:00
Alexander e6ad619acd fix: extend Regina Caeli period through Saturday after Pentecost
The Regina Caeli replaces the Angelus from Easter Sunday through the
Saturday after Pentecost (Easter + 55 days), not just until Ascension.
2026-04-06 21:04:32 +02:00
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