Commit Graph

755 Commits

Author SHA1 Message Date
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 a26fa5d005 feat: add seasonal badge to Regina Caeli link during Eastertide
Shows an "In season" / "Zur Zeit" / "Tempore" pill on the Regina
Caeli card in the faith links grid when it replaces the Angelus.
2026-04-07 20:25:18 +02:00
Alexander 474b4c3add feat: show exercise weights in template preview and quick start
Template detail modal now shows the initial weight per exercise.
Quick start hero shows the first exercise name and weight to help
with rack preparation before starting.
2026-04-07 20:19:32 +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 3562b4f106 feat: redesign nutrition goal editor with wizard flow, macro ring, and TDEE comparison
Replaces flat goal editor with a 3-step wizard (preset → calories → macros),
adds preset cards with diet descriptions, live macro donut ring preview,
overlaid TDEE vs target comparison bar, TDEE missing-data warning with
explanation, and surfaces latest weight used for TDEE calculation.
2026-04-06 15:38:19 +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 98c67070f6 perf: parallelize DB queries across routes, clean up fitness UI
Parallelize sequential DB queries in 11 API routes and page loaders
using Promise.all — measurements/latest, stats/overview, goal streak,
exercises, sessions, task stats, monthly expenses, icon page, offline-db.

Move calorie tracking out of /fitness/measure (now under /fitness/nutrition
only). Remove fade-in entrance animations from nutrition page.

Progressive streak computation: scan 3 months first, widen only if needed.

Bump versions to 1.1.1 / 0.2.1.
2026-04-06 13:12:29 +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 6f53fe3b7b fix: strengthen status bar drop shadow and clarify positioning
Increase shadow spread (4px offset, 10px blur, 0.4 opacity) for a
more visible boundary between Android status bar and page content.
2026-04-06 00:39:14 +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 fc44eb447a docs: add versioning guidelines to CLAUDE.md 2026-04-06 00:21:16 +02:00
Alexander a38f19cfcc feat: styled offline page with app install hint, bump versions
Replace bare offline fallback with styled page matching the app's
design (glass nav, dark/light mode, wifi-off icon, retry button).
Add hint to install Android APK or PWA for offline use.

Site: 1.0.0 → 1.1.0
Android/Tauri: 0.1.0 → 0.2.0
2026-04-06 00:21:03 +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 db1e33a92c fix: catechesis SVG fill color and enlarge DE badge
Remove fill="currentColor" from book SVG path so it inherits the
LinksGrid's nth-child fill colors. Increase DE badge size and offset.
2026-04-06 00:03:36 +02:00
Alexander d349658b33 feat: add Latin language notice and German link on catechesis pages
Show language-appropriate notice for non-German users with an
underlined link to the German version of the same page.
2026-04-06 00:01:57 +02:00
Alexander f3728a7c0a merge: integrate catechesis branch into master
Resolve merge conflicts keeping master's Latin/Eastertide support
while adding catechesis nav item, book SVG, DE badge, and disclaimers.
2026-04-05 23:54:54 +02:00
Alexander 520165a72b feat: improve catechesis page with expanded content, TOC, and i18n
- Add missing PDF content: Dt 4:12f, Mt 19:17, Sir 1:26 quotes in Ursprung/Warum sections
- Add äussere Seite section (Röm 12:1, 1 Kor 6:18-20, KKK 2702) and Gemeinschaftsgebet (Mt 18:20)
- Add pars potentialis concept to inner side section
- Add sticky section TOC nav for wide screens (1200px+)
- Align commandment highlight colors with tablet categories (God=orange, neighbor=blue)
- Use straight left borders instead of rounded on commandments
- Add German-only notice for English users on all catechesis pages
- Add disclaimer attributing errors to site author, not P. Ramm/FSSP
- Replace Inkscape katechese SVG with cleaner book icon on faith landing page
- Fix 10 commandments tablet SVG to show 5+5 lines
2026-04-05 23:49:43 +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 0a3796fe90 fitness: use server-computed PRs on workout summary screen
The summary screen was comparing against only the last session
(limit=1), showing false PRs when you beat last time but not your
all-time best. Now uses the server-computed PRs and kcal from the
save response, which compare against the best from 50 sessions.
2026-04-03 08:31:45 +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 181b9cc23f fitness: improve weight SMA with lookback and partial-window scaling
Fetch up to 6 extra measurements beyond the display limit so the SMA
window is fully populated from the first displayed point. For users
with fewer total measurements, use a reduced window with Bessel's
correction and sqrt(w/k) sigma scaling to reflect increased uncertainty.
2026-04-02 22:24:28 +02:00
Alexander 77da0a5c33 chore: remove dead migration and one-off scripts 2026-04-02 21:11:36 +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 fe17af66fc nutrition: pre-download HuggingFace models at build time
The deployment server couldn't fetch transformer models at runtime due to
restricted network access and permission errors writing to node_modules.
Add a prebuild script to download models during build and document
TRANSFORMERS_CACHE env var for configuring a shared writable cache path.
2026-04-02 20:47:10 +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