- 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
- 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
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.
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.
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.
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
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
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.
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.
- 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
- 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
Volume PRs were calculated client-side in the workout summary but never
saved to the database, so they didn't appear in history detail pages.
Add bestSetVolume PR detection to both session save and recalculate
endpoints, and render the new type in the history detail view.
restExerciseIdx and restSetIdx were sent by the client but never
persisted server-side, so other sessions couldn't display which
exercise/set the rest timer belonged to.
Estimate strength workout energy expenditure using the Lytle et al. multiple
linear regression model. Maps all 77 exercises to 7 studied categories with
confidence levels. Shows kcal on stats page (cumulative), session cards,
workout detail, and workout completion screen. Supports sex/height demographics
via profile section on measure page. Includes info tooltip with DOI reference.
Store a per-user weekly workout target (1-14) in a new FitnessGoal model.
Compute consecutive-week streak from WorkoutSession history via a new
/api/fitness/goal endpoint. Display streak as a 4th lifetime card on the
stats page with an inline goal editor modal.
Users can define a custom order of templates (e.g., Push → Pull → Legs).
Based on the last completed session, the next workout in rotation is
recommended via a prominent banner and the floating action button.
- New WorkoutSchedule MongoDB model (per-user template order)
- GET/PUT /api/fitness/schedule API endpoints
- Schedule editor modal with reorder and add/remove
- Action button starts next scheduled workout when schedule exists
- Validate exerciseId instead of name (templates use exerciseId, not name)
- Remove mandatory reps minimum from template sets
- Allow exercises with empty sets in schema and API validation
- SessionCard SVG: cosine-corrected coordinates with proper aspect ratio (xMidYMid meet)
- SessionCard: use --color-primary for track/distance/pace, add Gauge icon for pace
- History detail: theme-reactive pace chart colors via MutationObserver + matchMedia
- History detail: add Gauge icon, accent color for distance/pace stats, remove "avg" label
- Move GPS remove button from info view to edit screen
- Add Leaflet map preview to edit screen
- Remove data points count from GPS indicators
Add GPX file upload for cardio exercises in workout history. Parses
GPX track points and stores them in the session. Shows route map
(Leaflet), pace-over-distance chart (Chart.js), and per-km splits
table with color-coded fast/slow pacing. Auto-fills distance and
duration on single-set exercises. Disables Chart.js animations.
- Add metrics system (weight/reps/rpe/distance/duration) per exercise type
so cardio exercises show distance+duration instead of weight+reps
- Add 8 new cardio exercises: swimming, hiking, rowing outdoor, cycling
outdoor, elliptical, stair climber, jump rope, walking
- Add bilateral flag to dumbbell exercises for accurate tonnage calculation
- Make SetTable, SessionCard, history detail, template editor, and exercise
stats API all render/compute dynamically based on exercise metrics
- Rename Profile to Stats with lifetime cards: workouts, tonnage, cardio km
- Move route /fitness/profile -> /fitness/stats, API /stats/profile -> /stats/overview
Enables real-time workout synchronization across devices using
Server-Sent Events and an ephemeral MongoDB document (24h TTL).
Rest timers now use absolute timestamps instead of interval-based
countdown for accurate cross-device sync. Adds +/-30s rest timer
adjust buttons.
- Add exerciseId to WorkoutSession model (interface + schema)
- Fix button-in-button hydration warning in TemplateCard (use div)
- Expand FitnessChart dataset type to include all Chart.js properties
- Fix getTime type error in session update with proper cast
- Fix weight nullable type in profile stats with non-null assertion
- Fix $or query typing in templates list endpoint
- Re-add gym link on homepage pointing to /fitness
Add all 5 PPL+Upper/Lower templates matching the target split,
with Day 3 (Legs) adjusted to include Bulgarian split squats and
standing calf raises, and Day 5 (Lower) reworked with front squats,
hip thrusts, and goblet squats — all equipment-free of machines.
Also adds incline row, decline crunch, flat leg raise, and nordic
hamstring curl to the exercise list, and updates the WorkoutTemplate
model to use exerciseId instead of name for exercise references.
- 5-tab layout (Profile, History, Workout, Exercises, Measure) with shared header nav
- Workout system: template CRUD, active workout on /fitness/workout/active with localStorage persistence, pause/resume timer, rest timer, RPE input
- Shared workout singleton (getWorkout) so active workout state is accessible across all fitness routes
- Floating workout FAB indicator on all /fitness routes when workout is active
- AddActionButton component for button-based FABs (measure + template creation)
- Profile page with workouts-per-week bar chart and weight line chart with SMA trend line + ±1σ confidence band
- Exercise detail with history, charts, and records tabs using static exercise data
- Session history with grouped-by-month list, session detail with stats/PRs
- Body measurements with latest values, body part display, add form
- Card styling matching rosary/prayer route patterns (accent-dark, nord5 light, box-shadow, hover lift)
- FitnessChart: fix SSR hang by moving Chart.register to client-side, remove redundant $effect
- Exercise API: use static in-repo data instead of empty MongoDB collection
- Workout finish: include exercise name for WorkoutSession model validation
Replace ~100 `any` usages with proper types: use existing interfaces
(RecipeModelType, BriefRecipeType, IPayment, etc.), Record<string, unknown>
for dynamic objects, unknown for catch clauses with proper narrowing,
and inline types for callbacks. Remaining `any` types are in Svelte
components and cases where mongoose document mutation requires casts.
Add type annotations, JSDoc types, null checks, and proper generics
to eliminate all svelte-check errors. Key changes include:
- Type $state(null) variables to avoid 'never' inference
- Add JSDoc typedefs for plain <script> components
- Fix mongoose model typing with Model<any> to avoid union complexity
- Add App.Error/App.PageState interfaces in app.d.ts
- Fix tuple types to array types in types.ts
- Type catch block errors and API handler params
- Add null safety for DOM queries and optional chaining
- Add standard line-clamp property alongside -webkit- prefix
Allow recipes to specify a default pan shape (round, rectangular, gugelhupf)
with dimensions. On the recipe page, users can enter their own pan size to
auto-calculate an ingredient multiplier based on the 2D area ratio.
Household-shared list of external recipes to try, with name, multiple
links, and optional notes. Includes add/edit/delete with confirmation.
Linked from the favorites page via a styled pill button.
Instead of generating/serving 20px placeholder images with blur CSS, extract
a perceptually accurate dominant color (Gaussian-weighted OKLAB average) and
use it as a solid background-color while the full image loads. Removes
placeholder image generation, blur CSS/JS, and placeholder directory references
across upload flows, API routes, service worker, and all card/hero components.
Adds admin bulk tool to backfill colors for existing recipes.
- Add RosaryStreak MongoDB model for logged-in users
- Add /api/glaube/rosary-streak GET/POST endpoints
- Sync streak to server when logged in, merge local/server data
- Auto-sync when coming back online (PWA offline support)
- Falls back to localStorage for guests
Add optional baseMultiplier field to ingredient and instruction references, allowing base recipes to be included at scaled amounts (e.g., 0.5 for half the recipe).
- Add baseMultiplier field to Recipe schema with default value of 1
- Update TypeScript types to include baseMultiplier
- Add multiplier input field to BaseRecipeSelector modal
- Apply baseMultiplier to ingredient amounts during flattening
- Combine baseMultiplier with recipe multiplier in links
- Display and allow editing baseMultiplier in recipe editor
The multiplier cascades through nested references and works alongside the standard recipe multiplier for compound scaling.
Add comprehensive base recipe system allowing recipes to reference other recipes dynamically. References can include custom items before/after the base recipe content and render as unified lists.
Features:
- Mark recipes as base recipes with isBaseRecipe flag
- Insert base recipe references at any position in ingredients/instructions
- Add custom items before/after referenced content (itemsBefore/itemsAfter, stepsBefore/stepsAfter)
- Combined rendering displays all items in single unified lists
- Full edit/remove functionality for additional items with modal reuse
- Empty item validation prevents accidental blank entries
- HTML rendering in section titles for proper <wbr> and ­ support
- Reference links in section headings with multiplier preservation
- Subtle hover effects (2% scale) on add buttons
- Translation support for all reference fields
- Deletion handling expands references before removing base recipes
Add new page at /rezepte/untranslated for recipe admins to view and manage recipes without approved English translations. Includes translation status tracking, statistics dashboard, and visual badges.
Changes:
- Add API endpoint to fetch recipes without approved translations
- Create untranslated recipes page with auth checks for rezepte_users group
- Add translation status badges to Card component (pending, needs_update, none)
- Add database index on translations.en.translationStatus for performance
- Create layout for /rezepte route with header navigation
- Add "Unübersetzt" link to navigation for authorized users
Add content-based hashing to recipe images for proper cache invalidation
while maintaining graceful degradation through dual file storage.
Changes:
- Add imageHash utility with SHA-256 content hashing (8-char)
- Update Recipe model to store hashed filenames in images[0].mediapath
- Modify image upload endpoint to save both hashed and unhashed versions
- Update frontend components to use images[0].mediapath with fallback
- Add migration endpoint to hash existing images (production-only)
- Update image delete/rename endpoints to handle both file versions
Images are now stored as:
- recipe.a1b2c3d4.webp (hashed, cached forever)
- recipe.webp (unhashed, graceful degradation fallback)
Database stores hashed filename for cache busting, while unhashed
version remains on disk for backward compatibility and manual uploads.
Add comprehensive translation support for previously untranslatable fields:
- Portions (serving sizes)
- Time fields (preparation, cooking, total_time)
- Baking properties (temperature, length, mode)
- Fermentation times (bulk, final)
- Ingredient units (EL→tbsp, TL→tsp, etc.)
Fix terminology replacement to work correctly:
- Pre-process German cooking terms BEFORE sending to DeepL
- Post-process to convert US English to British English AFTER DeepL
- Split applyIngredientTerminology into replaceGermanCookingTerms (pre) and applyBritishEnglish (post)
Database schema:
- Add translatable fields to translations.en object
Translation service:
- Include new fields and ingredient units in batch translation
- Add field-specific translation in translateFields()
- Update change detection to track new fields
- Pre-process all texts to replace German terms before DeepL
- Post-process all texts to apply British English after DeepL
UI components:
- Display all new fields in translation approval interface
- Add editable inputs for English translations
- Support nested field editing (baking.temperature, fermentation.bulk, etc.)
Fix changed fields detection:
- Only show changed fields when editing existing translations
- Don't show false warnings for first-time translations
- Add embedded translations schema to Recipe model with English support
- Create DeepL translation service with batch translation and change detection
- Build translation approval UI with side-by-side editing for all recipe fields
- Integrate translation workflow into add/edit pages with field comparison
- Create complete English recipe routes at /recipes/* mirroring German structure
- Add language switcher component with hreflang SEO tags
- Support image loading from German short_name for English recipes
- Add English API endpoints for all recipe filters (category, tag, icon, season)
- Include layout with English navigation header for all recipe subroutes
- Replace 8 duplicate formatCurrency functions with shared utility
- Add comprehensive formatter utilities (currency, date, number, etc.)
- Set up Vitest for unit testing with 38 passing tests
- Set up Playwright for E2E testing
- Consolidate database connection to single source (src/utils/db.ts)
- Add auth middleware helpers to reduce code duplication
- Fix display bug: remove spurious minus sign in recent activity amounts
- Add path aliases for cleaner imports ($utils, $models)
- Add project documentation (CODEMAP.md, REFACTORING_PLAN.md)
Test coverage: 38 unit tests passing
Build: successful with no breaking changes
- Add ExchangeRate model for currency conversion tracking
- Implement currency utility functions for formatting and conversion
- Add exchange rates API endpoint with caching and fallback rates
- Update Payment and RecurringPayment models to support multiple currencies
- Enhanced payment forms with currency selection and conversion display
- Update split method selector with better currency handling
- Add currency-aware payment display and balance calculations
- Support for EUR, USD, GBP, and CHF with automatic exchange rate fetching
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add RecurringPayment model with flexible scheduling options
- Implement node-cron based scheduler for payment processing
- Create API endpoints for CRUD operations on recurring payments
- Add recurring payments management UI with create/edit forms
- Integrate scheduler initialization in hooks.server.ts
- Enhance payments/add form with progressive enhancement
- Add recurring payments button to main dashboard
- Improve server-side rendering for better performance
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add settlement category with handshake emoji (🤝)
- Create settlement page for recording debt payments with user → user flow
- Implement settlement detection and visual styling across all views
- Add conditional "Settle Debts" button (hidden when balance is 0)
- Style settlement payments distinctly in recent activity with large profile pictures
- Add settlement flow styling in payments overview with green theme
- Update backend validation and Mongoose schema for settlement category
- Fix settlement receiver detection with proper user flow logic
🤝 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add EnhancedBalance component with integrated single-user debt display
- Create DebtBreakdown component for multi-user debt overview
- Add predefined users configuration (alexander, anna)
- Implement personal + equal split payment method
- Add profile pictures throughout payment interfaces
- Integrate debt information with profile pictures in balance view
- Auto-hide debt breakdown when single user (shows in balance instead)
- Support both manual and predefined user management modes
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add comprehensive category system: Groceries 🛒, Shopping 🛍️, Travel 🚆, Restaurant 🍽️, Utilities ⚡, Fun 🎉
- Create category utility functions with emoji and display name helpers
- Update Payment model and API validation to support categories
- Add category selectors to payment creation and edit forms
- Display category emojis prominently across all UI components:
- Dashboard recent activities with category icons and names
- Payment cards showing category in metadata
- Payment modals and view pages with category information
- Add image upload/removal functionality to payment edit form
- Maintain responsive design and consistent styling across all components
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add MongoDB models for Payment and PaymentSplit with proper splitting logic
- Implement API routes for CRUD operations and balance calculations
- Create dashboard with balance overview and recent activity
- Add payment creation form with file upload (using $IMAGE_DIR)
- Implement shallow routing with modal side panel for payment details
- Support multiple split methods: equal, full payment, custom proportions
- Add responsive design for desktop and mobile
- Integrate with existing Authentik authentication
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add UserFavorites MongoDB model with ObjectId references
- Create authenticated API endpoints for favorites management
- Add Heart icon and FavoriteButton components with toggle functionality
- Display favorite button below recipe tags for logged-in users
- Add Favoriten navigation link (visible only when authenticated)
- Create favorites page with grid layout and search functionality
- Store favorites by MongoDB ObjectId for data integrity
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>