What's new

Recent updates, improvements and new features. Newest first.

7 Sep 2026

Latest

Water tracking in Nutrition trends, plus a PT workout-logging fix and a recipe privacy fix

✨

Water tracking in Nutrition trends

Water now has its own tab in the Log tab's trends chart, with a πŸ”₯ streak badge and personal best for hitting your daily water target.

πŸ›

PT workout-logging validation fix

A personal trainer logging a workout for a client now gets the same rep/weight range checks as every other workout entry point.

πŸ›

Recipe privacy fix

Saved meals and planned meals now check that a recipe you add actually belongs to you, closing a gap that could have exposed another user's private recipe.

6 Sep 2026

Pause habits while travelling, a weekly shopping list, and a food-item macro validation fix

✨

Pause a habit for travel or illness

Set a from/until date range on any habit (with 7 or 14-day shortcuts) and those days won't count against your streak or compliance percentage.

✨

Weekly shopping list

The Planner tab has a new "Shopping list for this week" button that combines everything you've planned - including recipe ingredients scaled to servings - into one copyable list.

πŸ›

Food-item macro validation fix

Saving a scanned barcode item to your library now enforces the same calorie/protein/carb/fat/fibre limits as every other way of adding food.

5 Sep 2026

Daily Inspiration now factors in your goals, a rare PR-milestone crash fixed, barcode data-validation fix

✨

Daily Inspiration knows your goals

Your check-in message now takes your calorie/protein targets and goal weight into account, instead of just reporting raw totals.

πŸ›

Rare crash saving a workout PR/milestone fixed

A double-submitted workout save could occasionally trigger a server error while checking for a new personal-record milestone. Fixed so it always saves cleanly.

πŸ›

Barcode data-validation fix

The barcode field on manually-added and scanned food items now goes through the same input cleanup as every other field.

4 Sep 2026

Fibre tracking, saved-meal ingredient editing, workouts/PRs data-validation fixes

✨

Fibre - a new optional macro

Fibre can now be tracked alongside protein, carbs and fat. Turn it on in Nutrition Settings and set a daily target - it's picked up automatically from barcode scans and Open Food Facts search, and shown in your daily totals.

✨

Saved meals - edit ingredients

Saved meals could only be renamed or deleted before. A new pencil icon lets you adjust quantities or remove items from a saved meal without recreating it.

πŸ›

Data-validation fixes

Two internal gaps closed from tonight's audit: the standalone PR-check endpoint now enforces the same date bounds as every other date field, and the exercise-merge "dismiss" action now sanitises its input.

3 Sep 2026

Add Food Entry now respects the day you're viewing, Daily Inspiration remembers past messages, medication reminders

πŸ›

Add Food Entry defaulted to today even when logging for a past day

Opening "+ Add Food Entry" while viewing yesterday (or any earlier day) now logs directly onto that day instead of silently defaulting back to today.

✨

Daily Inspiration - look back at past messages

A new clock icon on your Daily Inspiration card opens the last 14 days of generated recaps, so a message you liked doesn't disappear the next morning.

✨

Medications - daily dose reminders

Regular medications now get a bell icon in the quick-log panel to set a daily reminder time, matching the reminders habits already have.

13 Aug 2026

Daily Inspiration reads body composition, PR staleness badge, CSV import date bug fixed

✨

Daily Inspiration now knows about body fat % and waist trends

If you log body fat percentage or waist measurements, your Daily Inspiration recap will now mention how they're trending - alongside the weight trend it already tracked.

✨

Records now flag a lift that has gone quiet

On the Records tab, an exercise card shows a "days since last PR - needs a push" badge once it has been 60+ days since your last personal record on that lift.

πŸ›

CSV imports could accept garbage dates

Importing a workout, weight, or sleep CSV with a malformed date cell (a typo, or a date far in the past or future) could silently create a record with a nonsense date, throwing off streaks and trend charts. Rows with an invalid date are now skipped with a clear per-row error, matching the date validation used everywhere else in the app.

12 Aug 2026

Daily Inspiration reads your PRs, nutrition streak badge, more date crashes fixed

✨

Daily Inspiration now knows about your personal records

If you set a new PR today or yesterday, your Daily Inspiration recap will now mention it - it already read your workouts, habits, nutrition, journal, weight, medications and sleep, and now records too.

✨

On-target streak badge in Nutrition trends

If you've set a calorie target, the Nutrition trends chart now shows a πŸ”₯ streak badge for consecutive days within Β±15% of your goal, plus a personal-best badge for your longest run in the selected range.

πŸ›

Two more nutrition endpoints could fail on an unusual date

Viewing a food log or nutrition history with a malformed date could return a server error instead of a clear message. Fixed to match the validation already used everywhere else in the app.

10 Aug 2026

Excel report export, body measurements CSV, more report crashes fixed

✨

Export your report to Excel

The weekly/period report page now has a "πŸ“Š Excel (.xlsx)" export option alongside CSV - a full workbook with summary, workouts, habits, personal records and nutrition on separate sheets.

✨

Body measurements CSV export

Weight, body fat, lean mass and girth/limb measurements can now be exported to CSV from the weekly report page, alongside workouts, habits, nutrition, journal and personal records.

πŸ›

Two more report/PR endpoints could fail on an unusual date

The personal-record check endpoint and PT workout logging could return a server error if a date came through malformed, instead of a clear message. Fixed to match the validation already used everywhere else in the app.

9 Aug 2026

Records progression chart, reorder your habits, several report crashes fixed

✨

Personal record progression chart

Expand any exercise on the Records page to see your estimated 1RM plotted over your last 20 sessions, alongside its volume milestones.

✨

Reorder your habits

Hover over a habit in the Habits tab and use the new β–²/β–Ό arrows to move it up or down the list.

πŸ›

Several report and stats pages could fail to load with an unusual date range

A handful of endpoints behind Reports, Records exports and weekly stats could return a server error if a date filter came through malformed. Fixed to match the validation already used everywhere else in the app.

8 Aug 2026

Journal CSV export, a habit-logging crash fixed

✨

Journal CSV export

Your mood, energy, stress, tags and notes can now be exported to CSV from the weekly report page, alongside workouts, habits, nutrition and personal records.

πŸ›

Marking a habit done with a missing or unusual date could crash

Completing a habit without a valid date, or with a very large repeat count, could fail with a server error instead of a clear message. Fixed to validate and return a friendly error, matching every other date field in the app.

πŸ›

Habit emoji picker validation tightened

The emoji field on a habit now has to actually be an emoji, closing a gap that let arbitrary text slip through.

7 Aug 2026

Sleep now appears in the Feed, Daily Inspiration knows about your sleep and medications

✨

Sleep now appears in the Feed

If you have a sleep-tracking device connected, your total sleep duration for the night now shows up as its own card in the Feed alongside your workouts and nutrition.

✨

Daily Inspiration reads your sleep and medications

Your daily recap now takes last night's sleep and any medication doses you've logged into account, alongside workouts, habits, nutrition and journal entries.

πŸ›

A food-search caching gap closed

Product names and brands cached from food-database searches were missing the same length limit already applied when you add a food item yourself. Fixed for consistency.

6 Aug 2026

Goal weight tracking, a new "Fantasy Sage" tone, three validation gaps closed

✨

Goal weight tracking

Set a target weight in Nutrition Settings and the weight trend chart in Body Measurements now shows it as a dashed target line, plus how much you have left to lose or gain.

✨

"Fantasy Sage" Daily Inspiration tone

A new mystical wizard/sage voice for your daily recap - training framed as an epic quest, missed days framed as a quest merely delayed. Pick it from the tone settings on the inspiration card.

πŸ›

Three more text-sanitisation and validation gaps closed

A bug-report screenshot link, the personal-records recalculation endpoint, and a device-preference setting were missing the same input-cleaning treatment already applied elsewhere. Fixed for consistency.

5 Aug 2026

Weigh-ins and medication doses now show in the Feed, 30-day habit compliance, a workout-saving crash fixed

✨

Body weight and medication doses now appear in the Feed

Logging a weigh-in or a medication dose now surfaces a card in the Feed for that day, alongside your workouts, nutrition and journal entries, so it's all in one combined timeline.

✨

30-day habit compliance view

The compliance badge next to each habit (previously always a 7-day rolling percentage) can now be clicked to switch between 7-day and 30-day windows.

πŸ›

Saving a workout could crash with an invalid time

Manually logging a workout with a malformed start time could fail with a server error instead of a clear validation message. Fixed to return a friendly error.

πŸ›

Two more text-sanitisation gaps closed

An integration-suggestion email field and a bug-report resolution note were missing the same HTML-cleaning/length-limit treatment already applied elsewhere. Fixed for consistency.

4 Aug 2026

Journal entries now show in the Feed, medication dose-gap indicator, mood emoji rendering fixed

✨

Journal entries now appear in the Feed

Logging your mood, energy, stress, tags or a note in the Journal now surfaces a card in the Feed alongside that day's workouts and nutrition, so your wellbeing history shows up in the same combined timeline as everything else.

✨

Medication dose-gap indicator

Regular medications now show "taken today" or "Nd since last dose" next to their adherence badge, so a gap in a routine medication is visible at a glance rather than only showing up in the 7/30-day percentage.

πŸ›

Mood emoji rendered as a broken character

The mood emoji shown in Daily Inspiration's "Today so far" section always rendered as a broken symbol instead of the correct face, for every mood value - a text-indexing bug on multi-byte emoji characters. Fixed.

3 Aug 2026

Daily Inspiration no longer assumes your gender, plus two behind-the-scenes fixes

πŸ›

Daily Inspiration assumed a gender

A user flagged that their check-in message used gendered language despite FitMesh never being told anyone's gender. Every tone now has an explicit instruction to address you directly and never guess.

πŸ›

Records leaderboard could show stale test data

A behind-the-scenes fix to how Personal Records are recalculated - a workout deleted outside the normal flow could leave a stray entry that resurfaced on the leaderboard. The recalculation now checks that the workout it's attributing a record to still exists.

πŸ›

Food search result sanitisation gap

Product names and brands pulled in from the barcode/search database weren't passed through the same text-cleaning step as manually entered foods. Fixed for consistency.

2 Aug 2026

Lean mass tracking, saved meal rename, three more validation bounds closed

✨

Lean mass tracking

The Body view now has a Lean Mass field alongside weight, height and body fat - log it in the measurement form and see a snapshot card with the change since your last entry, the same at-a-glance trend the other body composition stats already had.

✨

Saved meal rename

Saved meals could only be deleted, not renamed. Double-click a saved meal's name in the food log to rename it in place, the same pattern used for renaming habits.

πŸ›

Three more fields had no length limit

A routine audit found a custom food item's brand/serving unit, an imported PDF food entry's name, and a promo code/description had no maximum length, unlike their equivalent fields elsewhere in the app. All now capped consistently with their siblings.

1 Aug 2026

Appetite trend chart for medications, Sports Commentator inspiration tone, PT workout and signup validation gaps closed

✨

Appetite trend chart

Logging appetite effect with a dose now builds a trend chart on the Medications view, showing the last 14 logged doses at a glance - useful for tracking appetite changes over time on regular medications.

✨

Sports Commentator inspiration tone

A 15th Daily Inspiration tone - your day narrated as a live play-by-play broadcast, with roaring calls for big wins and thoughtful "let's look at the tape" analysis on quieter days.

πŸ›

Two fields had no length limit

A routine audit found a PT logging a workout on a client's behalf and a new account's display name at signup had no maximum length, unlike their equivalent fields elsewhere in the app. Both now capped consistently with their siblings.

31 Jul 2026

Limbs measurement trends, Noir Detective inspiration tone, two more validation bounds closed

✨

Limbs measurement trends

Bicep, thigh and calf measurements now get their own snapshot card on the Body view (left/right sides averaged when both are logged), matching the trend cards weight/height/body fat and waist/chest/hip already had.

✨

Noir Detective inspiration tone

A 14th Daily Inspiration tone - a hardboiled film-noir private eye narrating your fitness journey as a moody crime case, missed habits filed as "the ones that got away."

πŸ›

Two more fields had no length limit

A routine audit found saving a barcode-scanned food item and naming a recipe ingredient had no maximum length, unlike every other name field in the app. Both now capped consistently with their siblings.

30 Jul 2026

Girth measurement trends, Best Friend inspiration tone, two more validation bounds closed

✨

Girth measurement trends

Waist, chest and hip measurements now get their own snapshot card on the Body view, showing the latest value and the change since your last entry - the same at-a-glance trend the weight/height/body fat cards already had.

✨

Best Friend inspiration tone

A 13th Daily Inspiration tone - casual, warm, and a little chaotic, like a text from your actual best friend hyping you up (and gently calling out your excuses).

πŸ›

Two fields had no length limit

A routine audit found habit completion notes and food item names (when edited after creation) had no maximum length, unlike every other notes/name field in the app. Both now capped consistently with their siblings.

29 Jul 2026

Fixed stale activity-goal percentage on synced step/activity data, more HTML sanitisation gaps closed

πŸ›

Daily step/activity data could get stuck showing an old value

For Polar, Fitbit and Google Fit users, today's synced step count and activity-goal percentage could freeze at whatever the first sync of the day captured (e.g. first thing in the morning), even after re-syncing later - so the Daily Inspiration card kept showing an outdated, much-lower activity percentage than your device. Fixed: today's activity data now refreshes properly on every sync.

πŸ›

A couple more fields could store raw HTML

A routine sanitisation sweep found the resolved-bug note (admin) and promo codes (admin) weren't stripped of HTML the way other name/notes fields already are. Fixed for both.

28 Jul 2026

Closed more HTML sanitisation gaps, habit toughest-day badge, Grandma inspiration tone

πŸ›

A few more fields could store raw HTML

A routine sanitisation sweep found food item serving units, habit target units, and CSV-imported workout titles weren't stripped of HTML the way other name/notes fields already are. Fixed for all of them.

βœ…

Habit heatmap - toughest day

Alongside the existing "Best day" line on each habit's 12-week heatmap, a "Toughest day" line now shows which day of the week you're most likely to miss it.

✨

Grandma inspiration tone

A 12th Daily Inspiration tone - a doting grandmother, immensely proud but always ready with a loving guilt trip.

27 Jul 2026

Fixed a broken barcode-save endpoint and a cross-account data leak, more HTML sanitisation gaps closed

πŸ›

Scanned-barcode save endpoint always failed, and could leak another user's food item

Saving a scanned barcode item to your library always errored out due to a database query bug. While auditing it we also found the barcode lookup could, in rare cases, return another user's privately-saved item instead of the shared catalogue entry. Both fixed.

πŸ›

More free-text fields could store raw HTML

A routine sanitisation sweep found several more fields (PT-logged workouts, habit completion notes, meal plan labels, medication dosage units, and a few admin/report fields) that weren't stripped of HTML the way other name/notes fields already are. Fixed for all of them.

26 Jul 2026

Fixed more HTML sanitisation gaps and an unbounded habit field, body measurement trend deltas

πŸ›

Medication side effects, clothes sizes, and food item renames could store raw HTML

Medication side-effect tags, body measurement top/bottom clothes sizes, and renaming a food item weren't stripped of HTML the way other name/notes fields already are. Fixed for all three.

πŸ›

Habit emoji and colour had no length limit

The habit emoji and colour fields accepted an unbounded string with no validation, which could break the habit list layout. Both are now capped at 20 characters.

βš–οΈ

Body measurements - change vs your last entry

Weight, height, and body fat snapshot cards on the Body view now show a small up/down arrow with how much each has changed since your previous logged entry.

25 Jul 2026

Fixed profile name and PT/bug-report text sanitisation, Pirate Captain inspiration tone

πŸ›

Display name and PT/bug-report notes could store raw HTML

Your profile name (on sign-up and in Account settings), PT trainer notes, and bug/feature report titles and notes weren't stripped of HTML the way other name/notes fields already are. Fixed for all four.

πŸ΄β€β˜ οΈ

Daily Inspiration - Pirate Captain tone

A new swashbuckling tone joins the lineup - nautical slang, bold and adventurous, framing your training as a voyage.

24 Jul 2026

Fixed habit completion security gap and cardio duration display, records longest-duration leaderboard

πŸ›

Habit completions could be deleted or edited by any signed-in user

Ticking off or editing a habit completion by ID didn't check that the habit belonged to you. Fixed - both now require ownership, matching every other edit/delete endpoint.

πŸ›

Cardio "longest time" showed the wrong duration

The Records page and This Month's Cardio strip displayed longest-duration cardio sessions using the wrong time unit - a 45-minute run could show as "0m 45s". Fixed.

πŸƒ

Records - all-time top 5 for longest duration

Cardio Records now has an "All-Time Top 5 - Longest Duration" leaderboard, alongside the existing longest-distance and fastest-pace leaderboards.

23 Jul 2026

Fixed meal plan security gap and HTML sanitisation, saved meal deletion

πŸ›

Planned meals could be edited, skipped, confirmed or deleted by any signed-in user

Updating, skipping, confirming and deleting a planned meal by ID didn't check that it belonged to you. Fixed - all four now require ownership, matching every other edit/delete endpoint.

πŸ›

Saved meal, exercise-merge and key-lift names could store raw HTML

A few free-text name fields weren't stripped of HTML the way other name fields already are: saved meal names, exercise merge (canonical/alias) names, and key lift names. Fixed for all three.

🍽️

Delete a saved meal

The saved meals list in the food log's Favourites tab now has a delete (βœ•) button, so you can remove a saved meal you no longer want without contacting support.

22 Jul 2026

Fixed recipes security gap and HTML sanitisation, recipe editing

πŸ›

Recipes could be edited or deleted by any signed-in user

Editing and deleting a recipe by ID didn't check that it belonged to you. Fixed - both now require ownership, matching every other edit/delete endpoint.

πŸ›

Recipe and ingredient names could store raw HTML

Recipe names and AI/manually-named ingredients weren't stripped of HTML the way other name fields already are. Fixed for both creating and editing a recipe.

πŸ“

Edit saved recipes

Library β†’ Recipes now has an ✎ edit button on each recipe - reopens the same builder used to create it, pre-filled with the current name, servings, and ingredients.

21 Jul 2026

Fixed exercise names not sanitising HTML, records fastest-pace leaderboard

πŸ›

Exercise names in workout sets could store raw HTML

Exercise names weren't stripped of HTML the way food, habit and medication names already are, so a name containing markup was saved and displayed verbatim. Fixed for both logging and editing a workout.

πŸƒ

Records - all-time top 5 for fastest pace

Cardio Records now has an "All-Time Top 5 - Fastest Pace" leaderboard, ranking sports by quickest pace per km, alongside the existing longest-distance leaderboard.

20 Jul 2026

Fixed a profile-settings crash, medication side effects this week

πŸ›

Saving profile settings could fail with a server error

Updating account settings with a malformed request could fail with a raw server error instead of a clear message. Fixed - now returns a proper error response.

πŸ’Š

Medications - side effects this week

The Medications history now shows a "This week" summary of any side effects logged in the last 7 days, so recurring symptoms are easy to spot at a glance.

17 Jul 2026

Journal tag sanitisation, records best-set leaderboard, Cheerleader tone

πŸ›

Journal tags could store raw HTML

Journal entry tags weren't stripped of HTML the way notes and other name fields already are, so a tag containing markup was saved and displayed verbatim instead of as plain text. Fixed for both creating and editing entries.

πŸ†

Records - all-time top 5 for best set

Personal Records now has an "All-Time Top 5 - Best Set" leaderboard, ranking exercises by highest single-set volume (weight Γ— reps), completing the set alongside the existing 1RM, max-reps, session-volume, and cardio-distance leaderboards.

πŸ“£

New Daily Inspiration tone - Cheerleader

A tenth check-in tone: peppy, spirited, pom-pom energy. Pick it from the Daily Inspiration settings alongside Kick Ass, Gentle, Boot Camp, Zen, Sports Coach, Stoic, Science Nerd, and Comedian.

16 Jul 2026

Fixed two account/data-deletion crashes, records max-reps leaderboard

πŸ›

Deleting a food item still used in a recipe could throw a server error

Removing a food from your library while it was still an ingredient in a saved recipe could fail with a raw server error. It now shows a clear message asking you to remove it from the recipe first.

πŸ›

Account deletion could fail for anyone who had redeemed a promo code

Deleting your account (or the scheduled auto-delete after a cancellation) could fail with a server error if you had ever redeemed a promo code, because that record wasn't cleaned up before the rest of your account. Fixed - deletion now clears promo redemptions first.

πŸ†

Records - all-time top 5 for max reps

Personal Records now has an "All-Time Top 5 - Max Reps" leaderboard, ranking exercises by the most reps completed in a single set, alongside the existing 1RM, session-volume, and cardio-distance leaderboards.

15 Jul 2026

Records session-volume leaderboard, saved recipes in Quick Log, journal personal-best streak

πŸ†

Records - all-time top 5 for session volume

Personal Records now has an "All-Time Top 5 - Session Volume" leaderboard, ranking exercises by the most weight moved in a single session, alongside the existing 1RM and cardio-distance leaderboards.

πŸ₯—

Saved recipes in Quick Log

Recipes saved under Library β†’ Recipes now appear in the ⭐ Favourites tab when logging food, alongside favourite foods and saved meals - pick a recipe, adjust servings, and log it in one tap.

πŸ““

Journal - personal-best streak

The Journal history now shows a "PB:N" badge alongside your current logging streak once your longest-ever run beats it, matching the personal-best badge habits already show.

14 Jul 2026

Fixed a water-log date bug causing "Invalid Date" feed entries, cardio all-time leaderboard

πŸ›

A malformed water log date could show up as "Invalid Date" in your feed

Logging water with a non-standard date value (rather than the usual YYYY-MM-DD) was accepted but not normalized before saving, so it could create a second, hidden entry for the same day - corrupting that day's total and showing up as an "Invalid Date" row in your activity feed. Water logs now always normalize to the calendar day before saving.

πŸ†

Records - all-time top 5 for cardio

Personal Records now has an "All-Time Top 5 - Longest Distance" leaderboard for running, cycling, walking and swimming, mirroring the existing strength 1RM leaderboard.

13 Jul 2026

Fixed deleted workouts resurfacing after sync, hardened admin endpoints, medication 30-day adherence

πŸ›

Some deleted workouts could still resurface after a sync

The 12 Jul fix stopped newly-deleted workouts from leaving orphaned data behind, but didn't retroactively clean up older orphans from before the fix - those could still get silently regrouped into a brand new workout entry the next time sync ran. Sync no longer resurrects manually-logged workouts this way, and the leftover orphaned records have been cleaned up. Also removed an unused internal debug endpoint that had the same underlying issue.

πŸ›

Malformed requests could crash a few admin-only endpoints

A handful of admin and promo-code endpoints returned a blank server error instead of a clean message if a request body was malformed - not reachable through normal use of the app, but a robustness gap. Fixed, matching the same hardening applied elsewhere on 8 Jul.

πŸ’Š

Medications - 30-day adherence

The adherence badge on Regular medications now also shows a 30-day percentage alongside the 7-day count, e.g. "Vitamin D: 6/7 days Β· 84% (30d)" - matching the rolling 7/30-day compliance habits already show.

12 Jul 2026

Dashboard cache fix, deleted-workout data leak fix, cardio + medication records

πŸ›

Dashboard nutrition/habit summary could go stale

The "Today so far" summary on the dashboard recap card was cached in your browser for the whole day, so editing or deleting a food log, workout or habit after your first visit didn't update the numbers shown until the cache reset. It now quietly reconciles with the latest data in the background, at no extra AI cost.

πŸ›

Deleting a manual workout could leave data behind - and let it resurface later

Deleting a manual workout didn't clean up its underlying source data, which could later get silently regrouped into a brand new workout entry by the sync process - including data you'd already deleted. Deleting a workout now fully removes it. Also fixed: this endpoint was missing an ownership check present on similar endpoints elsewhere in the app.

πŸ…

Records - This Month's Cardio

The Records page now highlights any cardio personal best set this calendar month (longest distance, best pace, longest time, race bests) the same way strength records already do.

πŸ’Š

Medications - 7-day adherence

Regular medications now show how many of the last 7 days you've logged a dose, right above your medication history.

11 Jul 2026

Food logging and habit trigger crash fixes, AI usage admin panel

πŸ›

Food log crash on missing quantity

Logging a food item without a quantity crashed the request instead of showing a friendly error. Quantity is now always required, with a clear message if it's missing.

πŸ›

Food macros could get "stuck" on a reused name

The per-100g nutrition rate saved the first time you logged a food by name was being reused for every later log under that same name, ignoring whatever macros you entered afterwards. Logging a food now refreshes its stored macros from what you actually enter each time.

πŸ›

Habit auto-complete trigger crash on malformed input

Creating or editing a habit's auto-complete trigger with an unrecognised value crashed instead of returning a clear error - not reachable through normal use of the app, but a robustness gap. Fixed.

8 Jul 2026

API hardening, habit best-day insight, journal mood correlation

πŸ›

Malformed requests could crash the server

A number of API endpoints returned a blank server error instead of a clean message if a request body was malformed - not reachable through normal use of the app, but a robustness gap. Fixed across all affected endpoints.

πŸ“…

Habits - best day of the week

Open the edit (✏️) sheet on any habit and the 12-week heatmap now also shows which day of the week you're most likely to complete it, e.g. "Best day: Wed (86%)".

πŸ““

Journal - tag and mood correlation

The Month summary in Journal History now shows how your mood compares on days you used your most common tag versus days you didn't, once there's enough data in a month to make it meaningful.

7 Jul 2026

Journal streak, food log sanitisation fix

πŸ”₯

Journal streak

The Journal History header now shows a "πŸ”₯ N day streak" badge once you've logged two or more consecutive days, alongside your 7-day mood/energy/stress average.

πŸ›

Food log item names not sanitised

Logging food via Quick Log (search, photo, describe or PDF import) didn't strip HTML from item names the way editing an existing item already did, so raw markup could end up saved in your personal food library. Fixed - item names are now sanitised consistently everywhere.

6 Jul 2026

Habit history heatmap, hydration warning fix

πŸ“Š

Habit history heatmap

Open the edit (✏️) sheet on any habit to see a 12-week history heatmap - a quick visual of which days you hit it, missed it, or it wasn't scheduled.

πŸ›

Console warning on every page load

A harmless but noisy React hydration warning fired on every single page load, caused by the dark-mode/text-size script that runs before the page finishes loading. Silenced correctly rather than suppressed by hiding the underlying script.

5 Jul 2026

Records reorganised, rehab pain trend chart, integration data drawer

πŸ†

Records - this month + all-time top 5

The Records page now leads with a "This Month's Records" strip showing any PR set in the current calendar month, and an "All-Time Top 5" leaderboard ranked by estimated 1RM. The full searchable, sortable exercise list remains below under "All Records".

πŸ“ˆ

Rehab pain trend chart

When you have two or more Rehab sessions logged with pain levels, the Training tab now shows a line chart of pre- and post-session pain over the selected period, so you can see whether things are trending in the right direction.

πŸ”Œ

Integrations - see exactly what's been synced

Click the β–Ό on any connected integration to expand a drawer showing counts of what FitMesh has pulled from that source - workouts, step days, sleep nights, heart rate samples, weight logs - with quick links to jump to each view.

πŸ›

Manual workout logging didn't refresh the UI

Saving a new manual workout closed the modal but didn't refresh the Feed or Training list, so the new entry was invisible until a full page reload. Fixed.

πŸ›

Distance and steps wiped on manual workout edit

Editing a manually logged run or walk reset its distance and step count to blank, the same bug class previously fixed for rehab pain levels. Both fields now load and save correctly.

3 Jul 2026

Rehab split into Appointment and Training, pain level edit fix

✨

Rehab is now two activity types

Rehab Appointment logs a treatment session (physio, chiro, massage) with pain levels and notes but no exercise sets. Rehab Training logs a structured rehab exercise session with the full block/set editor, matching how strength training is logged. Existing Rehab entries are unaffected.

πŸ›

Editing a rehab workout no longer wipes its pain levels

Pre- and post-session pain levels were never included when a workout was loaded for editing, so saving any change to a rehab session - even just fixing the date - silently reset its pain levels to blank. Fixed: pain levels now load correctly into the edit form and are preserved on save.

2 Jul 2026

Android PWA feel, Strava compliance update, waitlist page

πŸ“±

Android PWA native feel hardening

Removed the blue tap flash on tappable elements (-webkit-tap-highlight-color), suppressed rubber-band overscroll so the app feels native in standalone mode, clamped input font sizes to 16 px to prevent iOS auto-zoom on focus, and added active press feedback to the bottom navigation bar.

πŸ”’

Strava view-only - excluded from AI and PT reports

Strava's June 2026 API terms prohibit using their data in AI or machine learning features. Your Strava activities are still visible in the feed and timeline, but Daily Inspiration, AI coaching context, and PT check-in reports are now built exclusively from your other connected sources. The Data Sources page has been updated with the current policy and recommends Polar as the primary integration. A bug where Strava workouts could leak into the Monday morning AI context has also been fixed.

✨

Beta waitlist page (/try)

A public sign-up page at /try lets anyone join the early access waitlist. Logged-in users see a one-click 'Add me to the list' button pre-filled with their account email. Duplicate sign-ups return a friendly message rather than an error.

1 Jul 2026

Rehab pain tracking, exercise set validation, tighter habit auto-complete

✨

Pain levels for rehab sessions

When logging a Rehab / Physio session, you can now record a pre-session and post-session pain level (1 = none β†’ 10 = severe). The picker uses colour coding: green for low pain, amber for moderate, red for high. Data is saved per session and will feed into pain trend charts in a future update.

πŸ›

Editing a rehab session no longer fails silently

The workout edit API was missing REHAB from its list of valid activity types, so saving edits to a rehab session returned a 400 error without explanation. Fixed.

πŸ›‘οΈ

Timed and distance exercise sets now validated server-side

Set duration is now capped at 86,400 seconds and distance at 200,000 m. Previously these were stored without bounds checks.

✨

Habits auto-tick on full history import

When you trigger a historical sync (Strava, Polar, Fitbit, Garmin), habits with matching activity triggers are now auto-completed retroactively across the full imported window - not just the last 7 days.

30 Jun 2026

Delete Now fix, sleep custom date range, workout list cleanup

πŸ›

Admin "Delete Now" fixed for promo users

Immediately deleting a user who had redeemed a promo code silently failed due to a missing foreign-key delete step. The deletion transaction now clears promo redemptions first, and an error message is shown if anything else goes wrong.

✨

Sleep view: custom date range

The Sleep tab now has a Custom option alongside the period presets. Select it to enter any from/to date range and hit Apply to load that window of sleep history.

πŸ›

Steps, water & sleep no longer appear in workout history

Passive tracking entries synced from devices (daily step counts, water logs, sleep sessions) were occasionally appearing in the workout list. These are now filtered out at the API level - only actual workout sessions appear.

πŸ›

Feed now shows actual workout titles

Workout cards in the activity feed were showing "Workout" instead of their actual title (e.g. "Upper Body Strength"). Fixed a type mismatch between the API response and UI component.

✨

Notes & location in expanded workout cards

When you expand a workout card in the feed, any notes you logged and the location label now appear below the stats. Previously these were invisible despite being saved.

πŸ›‘οΈ

HTML stripped from workout titles and locations

Workout titles and location labels now strip HTML tags before saving, closing the last XSS sanitisation gaps. Previously only notes were sanitised.

29 Jun 2026

New inspiration tones, sleep date picker, HTML sanitisation for names

✨

3 new Daily Inspiration tones

Pick from Stoic (wisdom & discipline), Science Nerd (data-driven analysis), or Comedian (funny & light-hearted) in the inspiration settings. Total: 6 β†’ 9 tones.

✨

Sleep view: date range picker

The Sleep tab now has period presets - 7 days, 2 weeks, 30 days, 3 months, or All time - so you can focus on recent trends or browse your full history.

πŸ›‘οΈ

HTML stripped from all name fields

Food item names, habit names, and medication names now strip HTML tags before saving - closing the last XSS gaps. Notes fields were already sanitised.

27 Jun 2026

Validation hardening: required mood, food item names, HTML sanitisation

πŸ›

Journal entries now require mood

Previously, journal entries could be created without a mood rating. Mood (1–5) is now required. Energy and stress remain optional.

πŸ›

Food log items require a name

Food log items without a foodItemId or recipeId must now include a name. Previously, missing names were silently defaulted to "Unknown".

πŸ›‘οΈ

HTML tags stripped from text inputs

All notes fields (journal, workouts, body measurements, medications) now strip HTML tags before saving, preventing stored XSS.

26 Jun 2026

Onboarding: journal, medications & promo codes; workout date validation

✨

Journal & Medications in onboarding

The onboarding flow now includes Journal and Medications as tracking preferences alongside Training, Habits, Sleep, Nutrition, and Steps. Selecting Journal or Medications also surfaces relevant habit suggestions.

✨

Promo code entry during onboarding

New users can now redeem a promo code during onboarding. A "Have a promo code?" link on the first screen expands an input field. Invalid codes show a clear error; valid codes unlock PRO immediately.

πŸ›

Workout date validation tightened

Manually logged workouts previously accepted dates up to 2 years in the future. Now consistent with all other endpoints - dates cannot be more than 1 day in the future.

25 Jun 2026

Water intake in feed & weekly stats, invalid JSON error handling

✨

Water intake in activity feed

The daily nutrition card in your activity feed now shows water intake alongside calories, protein, carbs, and fat. Days with water logged display the total in litres with a cyan highlight.

✨

Average daily water in weekly stats

The Training tab weekly stats bar now includes an "avg water/day" card showing your average daily water intake for the selected period.

✨

Water context in Daily Inspiration

The AI daily inspiration now sees your water intake for today and yesterday, so coaching recaps can comment on hydration alongside nutrition and training.

πŸ›

Invalid JSON no longer causes 500 errors

Sending a malformed request body to the workout, food log, or water endpoints previously returned a 500 server error. These routes now return a clear 400 "Invalid JSON" message.

24 Jun 2026

Journal search, weekly stats dashboard cards, medication validation

✨

Journal search

Search your journal entries by notes text or tags. A search bar below the calendar filters entries as you type, making it easy to find past entries about specific topics or tagged moods.

✨

Weekly stats: nutrition & wellbeing cards

The weekly stats bar on the Training tab now shows average daily calories, average daily protein, and average mood/energy/stress scores for the selected period. A quick snapshot of how training, nutrition, and wellbeing align.

πŸ›

Medication type validation

The medication API now rejects invalid medication types with a clear error instead of silently defaulting to ONE_OFF. Consistent with all other API validation.

22 Jun 2026

COMPLIANCE habit frequency, exercise name validation hardening, AI inspiration sync awareness

πŸ›

COMPLIANCE frequency now accepted for habits

The habit API validation was missing the COMPLIANCE frequency type, even though the database schema supported it. Habits with floor/target/stretch compliance tiers can now be created and edited as intended. Fixed in both POST and PATCH routes. (BUG-167)

πŸ›

Null exercise names no longer bypass workout validation

Sending an exercise with a null name in workout sets skipped the name validation entirely and saved to the database. The validator now treats null and undefined exercise names as empty strings, correctly rejecting them with "Exercise name cannot be empty". (BUG-168)

πŸ›

Daily Inspiration now waits for sync before generating

The AI recap was firing immediately on dashboard load, before the auto-sync had a chance to pull the latest data from connected apps. The inspiration card now waits for the dashboard sync to complete, so the AI sees your most recent workouts and habits before writing the recap.

21 Jun 2026

AI recipe generator, owner rate-limit bypass, AM/PM inspiration limits

✨

AI recipe generator

Describe a dish (e.g. "chicken stir fry for 2") and AI generates the full recipe - name, ingredients with macros, and step-by-step cooking method. Find it under Library β†’ Recipes β†’ + Create recipe β†’ ✨ Generate recipe. Uses the RECIPE_GENERATE quota (free: 3/day, PRO: 20/day).

πŸ”„

Daily Inspiration now uses AM/PM refresh limits

Instead of a flat daily limit, Daily Inspiration now allows 2 refreshes in the morning (midnight–noon UTC) and 3 in the afternoon/evening (noon–midnight UTC). The transparency page and How-To guide have been updated to reflect this.

⚑

Owner accounts bypass AI rate limits

The app owner's account is no longer subject to daily AI usage caps - all AI features are unlimited for accounts in the owner list.

15 Jun 2026

Fixed nutrition log showing yesterday's meals, tightened Walk habit auto-completion

πŸ›

"Today" in Nutrition no longer shows yesterday's logged meals

The nutrition log's date range was computed using the server's local time, which could shift the day boundary and pull the previous day's entries into "today" (and vice versa) depending on when in the day you checked. Date ranges for both the daily log and the history/reports view are now computed in UTC, matching how dates are stored - "today" now reliably shows only today's entries. (BUG-158)

πŸ›

Walking habits no longer auto-complete from passive step counts alone

Habits with a "Walking" trigger could be auto-marked complete just from a synced "Daily Steps" total, even on days with no actual walk logged. Daily step aggregates are now excluded from workout-based habit triggers - Walking (and other workout-type) habits only auto-complete from a real recorded activity. Step-count goals continue to work via dedicated "Steps" habit triggers. (BUG-159)

13 Jun 2026

Duplicate detection for repeated manual entries, PR recalculation fix, copy meals from any day

πŸ”

Duplicate warning now also catches two manual entries for the same session

The duplicate-warning check introduced on 12 Jun only compared a new manual workout against sessions synced from Strava, Hevy, Polar or similar. Logging the same session manually a second time slipped through. It now also flags when a new manual entry overlaps in time, duration and activity type with another manual entry you logged earlier, with the same "This looks like a duplicate - save it anyway?" prompt.

πŸ›

Recalculating personal records no longer leaves stale entries behind

"⚑ Recalculate from history" on the Achievements page previously only added new PRs and volume milestones - it never removed ones whose underlying workout had since been deleted or edited, so outdated records could linger indefinitely. Recalculating now clears your existing PRs and volume milestones first, then rebuilds them from your current workout history. (BUG-157)

✨

Copy meals from any past day

Nutrition logging now has a "πŸ“… Copy meals from another day…" option alongside "Copy yesterday's meals" - pick any past date from a calendar and copy that day's logged meals into today. Handy for repeating a meal plan from earlier in the week.

12 Jun 2026

Manual workout duplicate warning, clearer macro calculator errors

πŸ”

Manual workout logging now warns about likely duplicates

When you manually log a workout that overlaps in time, duration and activity type with a session already synced from Strava, Hevy, Polar or another source, FitMesh now shows a warning - "This looks like a duplicate of … - save it anyway?" - before saving. Confirm to log it anyway, or cancel to avoid double-counting.

πŸ›

Macro calculator now shows the real reason a save failed

Saving the macro calculator results previously showed a generic "2 of 2 writes failed" message if a value was out of range. It now shows the specific validation error for each part that failed (e.g. body measurements vs. nutrition targets), so you know exactly what to fix.

11 Jun 2026

Daily Inspiration formatting fix

πŸ›

Daily Inspiration recap no longer shows raw "#" heading characters

The AI-generated check-in message is displayed as plain text, but the model occasionally opened with a "# Heading" or wrapped phrases in **bold** markdown despite being told not to. That formatting now shows up literally as "#" or "**" in the recap. The API now strips markdown heading and emphasis syntax from the generated message before it's saved and displayed.

8 Jun 2026

Habit weekly compliance fix, Daily Inspiration persistence, security fix

βœ…

Weekly habit compliance percentage now correct

Habits set to Weekly or Times per week frequency were showing the wrong compliance percentage in the 7-day and 30-day badges - for example, ticking a weekly habit once in a week showed 14% instead of 100%. The calculation now correctly measures sessions completed vs. sessions required for the period, not days ticked vs. total days.

✨

Daily Inspiration setting now persists across devices and after clearing storage

If you enabled Daily Inspiration and then opened the app on a different device - or your browser cleared its local storage - the setting would reset to Off. The server-synced preference was being written to the wrong local storage key. It now correctly seeds the user-specific key that the component reads from, so your enabled/tone preference is restored from the server on any device.

πŸ”’

Food log delete security fix

The food log deletion endpoint now verifies that the log belongs to the authenticated user before deleting it. Previously an authenticated user who knew or guessed another log's ID could delete it. (BUG-155)

7 Jun 2026

Daily Steps habit trigger, exercise merge validation

πŸ‘£

New habit trigger: Daily Steps

Habits can now use a "Daily Steps" trigger type. When your synced daily step count (from Polar, Fitbit, or Google Fit) meets or exceeds the step target set on the habit (via Target Value - defaults to 10,000), the habit is automatically marked complete for that day. Set up a "hit 10k steps" habit and connect a step-tracking integration to take advantage. (REQ-154)

πŸ”’

Exercise merge validation hardening

The exercise name merge endpoint (used in the Training tab to consolidate duplicate exercise names) now validates that canonical and alias names cannot exceed 200 characters, each alias must be a string, and no more than 50 aliases can be submitted at once. Previously, arbitrary-length strings were accepted and non-string values caused a 500 error. (BUG-151, BUG-152)

πŸ›

Recovery endpoint invalid-date crash fixed

Passing a non-date string as the "from" or "to" parameter to the Recovery data endpoint now returns a clear 400 error instead of a 500 crash. (BUG-153)

6 Jun 2026

Daily steps in feed, password & email validation hardening

πŸ‘£

Daily steps now appear in the activity feed

If you have Fitbit, Polar, or Google Fit connected, your daily step counts now appear as compact πŸ‘£ step cards in the feed timeline - one per day, showing the total steps pulled from your device's daily aggregate. Step cards sit just below workout cards in the daily stack, giving you a historical view of your activity alongside workouts and habits. (REQ-150)

πŸ”’

Password change, PT email, and profile source length limits

Three additional validation gaps closed. The change-password form now caps the new password at 1,000 characters (consistent with signup) - previously an arbitrarily long password could trigger a slow bcrypt computation. The PT connection request form now rejects email addresses longer than 254 characters (RFC 5321 limit). The steps source preference field on the profile endpoint is now capped at 100 characters. (BUG-147, BUG-148, BUG-149)

5 Jun 2026

Copy day includes logged food, signup validation, bug report limits

πŸ“‹

"Copy entire day" now includes logged food, not just planned meals

The "⧉ Copy day" button in the Nutrition Planner tab now copies both meal plan entries and any food that was actually logged on the source day. Previously it only copied planned meals (MealPlan records) and silently dropped food log entries. The modal summary now shows the combined count (e.g. "2 plans + 1 logged meal") and the empty-state message is updated when a day has neither plans nor logged food. (REQ-145)

πŸ”’

Sign-up email format validation added

Creating a FitMesh account now validates that the email address contains an "@" and a domain (e.g. user@example.com). Previously any string was accepted - including strings with no "@" symbol. Emails longer than 254 characters (RFC 5321 limit) are also rejected. (BUG-142)

πŸ›

Bug report and PT notes length limits

The bug/feature report form now caps URL and notes at 2,000 characters, page title at 200 characters, and screenshot URL at 2,000 characters. PT trainer notes are capped at 10,000 characters. Previously all these fields were unbounded. (BUG-141, BUG-143)

4 Jun 2026

Strava API compliance, meal-plan validation hardening

πŸ”’

Strava data excluded from PT reports and AI features

FitMesh now complies fully with Strava's updated API terms (effective 1 Jun 2026). Workouts synced via Strava are no longer included in PT coaching reports or fed into AI-powered features (Daily Inspiration). These workouts remain visible to you in the Training tab and Feed as normal - only third-party sharing and AI use is restricted. Polar is recommended as the primary integration for full data access with no restrictions. (REQ-125)

πŸ—“οΈ

Meal plan validation: date bounds, mealType enum, label length, item quantity

The meal planning API (POST /api/food/plan) now fully validates input. Date must be 1970 or later and no more than 1 day in the future. mealType must be one of BREAKFAST, LUNCH, DINNER, SNACK, DRINK - invalid values now return a 400 with a plain-English message instead of a 500 crash. Plan labels are capped at 200 characters. Item quantities must be greater than 0 and no more than 10,000g. All the same rules apply when editing a plan (PUT /api/food/plan/[id]), with status validated against PLANNED, CONFIRMED, SKIPPED. (BUG-130, BUG-131, BUG-132, BUG-133)

3 Jun 2026

Regular vs one-off medications, habit history % display, validation hardening

πŸ’Š

Medications - Regular vs One-off type

Each medication log now carries a type: Regular (an ongoing medication taken routinely, e.g. blood pressure pills, vitamins) or One-off (taken as needed, e.g. Paracetamol for a headache). The log form has a clear ⚑ One-off / πŸ”„ Regular toggle with descriptive helper text. Your history is split into two sections - Regular medications at the top, One-off doses below - so you can see at a glance which are routine and which were situational. Each card shows a colour-coded badge. (REQ-126)

βœ…

Habits - completion % shown in activity feed

Habit cards in the activity feed now show a colour-coded completion percentage for partial days (e.g. "3 of 5 habits (60%)"). Amber for β‰₯75%, orange for β‰₯50%, grey below. All-done days still show "All habits done". (BUG-118)

πŸ”’

Validation hardening - compliance, label consistency

Habit complianceTarget (0–1) and complianceWindow (1–365 days) now reject negative and out-of-range values. Error message labels are now consistently capitalised across all endpoints: Steps, Distance (workouts), Calories, Protein, Carbs, Fat (food), Top size, Bottom size (body measurements), Date of birth (profile). (BUG-127, BUG-128)

2 Jun 2026

Generic medication tracking, saved-meals validation & recipe validation

πŸ’Š

Medications - now works for any drug, not just GLP-1s

The medication log now supports any medication - Paracetamol, Ibuprofen, Aspirin, vitamins, supplements, and prescription drugs, alongside the existing GLP-1 options. The autocomplete list has grown from 7 to 30+ common medications. Dosage units expanded from 4 to 9 (mg, ml, mcg, g, IU, tablets, capsules, drops, units). Side effects expanded from 11 to 16 quick-tags. A new "Your medications" panel at the top shows your recently logged medications as one-tap chips - click any to pre-fill the form instantly for a repeat dose. (REQ-117)

🍽️

Saved meals: name length capped, item quantity validated

Saved meal names are now capped at 200 characters (previously unlimited). Item quantities on saved meals must be greater than 0 and no more than 10,000g - negative and zero quantities are now rejected with a clear error. (BUG-119, BUG-120)

πŸ“–

Recipes: name length capped, servings must be β‰₯ 1

Recipe names are now capped at 200 characters. Servings must be a number of 1 or more - zero, negative, and non-numeric values are rejected. Applies to both recipe creation (POST) and editing (PUT). (BUG-121, BUG-122)

πŸ‹οΈ

Key lift names now capped at 200 characters

The key lifts configuration (used on the weekly report) now validates each entry: names must be non-empty strings and cannot exceed 200 characters - matching the cap already in place for exercise names on workout logs. (BUG-123)

πŸ”—

Integration suggestion form: length limits added

The "Suggest an integration" form now caps appName at 200 characters, reason at 1,000 characters, and email at 200 characters. Previously all fields were unbounded. (BUG-124)

1 Jun 2026

Consistent validation error messages across edit forms

πŸ’¬

Workout and habit edit forms now show plain-English errors

Editing a workout or habit via the PATCH endpoint was still surfacing raw API field names in validation errors ("durationMinutes must be a valid number", "avgHeartRate cannot exceed 250", "timesTarget must be a valid number"). These have been updated to match the human-readable labels already used by the creation forms: "Duration must be a valid number", "Average heart rate cannot exceed 250 bpm", "Times target must be a valid number", etc. (BUG-114, BUG-115)

πŸ₯—

Nutrition settings validation errors now name the field in plain English

When a nutrition target was invalid, the error said "calorieTarget must be a non-negative number" and "calorieTarget value is unrealistically high". These now read "Calorie target must be a non-negative number" and "Calorie target cannot exceed 100,000" - matching the style used across the rest of the app. Applies to Calorie, Protein, Carb, Fat and Water targets. (REQ-116)

31 May 2026

Validation hardening & new edit endpoints

🍽️

Food item names can no longer be saved as blank

Both the food log POST and the food item edit (PATCH) endpoints now reject empty or whitespace-only names with a clear "Food item name cannot be empty" error. Previously, submitting an empty name would silently write a blank entry to the database.

πŸ’Š

Medication edit: future dates now rejected

Editing a medication entry via the PATCH endpoint previously allowed setting the taken-at date far into the future (e.g. 2028). The PATCH handler now enforces the same tomorrow cap as the POST endpoint - takenAt cannot be more than 1 day in the future.

πŸ“

Correct a body measurement without deleting it

A new PATCH /api/body/measurements/{id} endpoint lets you update individual fields on an existing measurement entry (weight, height, body fat %, girth measurements, clothing sizes, notes). Previously, fixing a typo meant deleting and re-creating the row, which broke the chart trend line. The timestamp (recordedAt) stays locked - only field values can be changed.

πŸƒ

Edit distance and steps on saved cardio workouts

The workout edit endpoint now accepts distance (metres, 0–1,000,000) and steps (0–100,000). Previously these could only be set at creation time; editing a run after saving to correct the distance was not possible.

30 May 2026

Accent colours, notification dismiss, copy meals & friendlier errors

🎨

Choose your accent colour

Account β†’ Appearance now shows six colour swatches - Red (default), Violet, Blue, Teal, Amber, Pink. Picking one immediately recolours every button, ring, badge, and progress indicator across the whole app via a CSS variable swap. Your preference is saved locally so it persists between sessions.

πŸ””

Dismiss individual notifications and clear all

The notification bell now shows a βœ• on each notification so you can remove it with a single click, plus a "Clear all" button in the dropdown header to wipe the entire list at once. Both call a new DELETE /api/notifications endpoint and update the UI instantly.

πŸ“‹

Copy yesterday's meals

When today's food log is empty, a "πŸ“‹ Copy yesterday's meals" button now appears below the Add Food Entry button. Clicking it fetches all of yesterday's logged meals and recreates them for today - breakfast, lunch, dinner, snacks, and drinks - in one tap. Items copy with their full macros and library links intact.

πŸ’¬

Validation error messages are now human-readable

Form validation errors were showing raw camelCase API field names (e.g. "durationMinutes cannot exceed 1440", "avgHeartRate cannot exceed 250", "weightKg out of range (20–400)"). These are now replaced with plain English: "Duration cannot exceed 1,440 minutes", "Average heart rate cannot exceed 250 bpm", "Weight must be between 20 and 400 kg". Applies to workout logging, body measurements, and habit creation forms.

29 May 2026

Daily Inspiration upgrade - journal, weight trend & mood UI

πŸ““

Daily Inspiration now reads your journal

The AI recap was missing your journal data entirely. The daily inspiration prompt now includes yesterday's and today's mood, energy, stress scores, tags (e.g. Sick, Tired, Rest day), and free-text journal notes when present. If you logged that you were injured or feeling low, the AI will acknowledge it rather than cheerfully ignoring it.

βš–οΈ

Body weight trend in Daily Inspiration context

The AI recap now includes your most recent body weight and, if a previous measurement exists, whether you're trending up or down. The AI can weave fitness progress - "you're down 1.5 kg from your last check-in" - into the motivational message.

😊

Mood and energy chips in "Today so far"

When you've logged a journal entry today, the "Today so far" section on the Daily Inspiration card now shows your mood (πŸ˜” to πŸ˜„) and energy level alongside workouts, habits, and nutrition - giving a fuller wellbeing snapshot at a glance.

πŸ“Š

Wellbeing summary stats endpoint

A new GET /api/wellbeing/journal/summary endpoint returns 7-day and 30-day averages for mood, energy, and stress, plus the top 5 most-used tags in each window. Powers trend displays and can be used by future dashboard widgets.

May 2026

Input validation & stability fixes

πŸ’Š

Medication tracking

A new Medications tab is now live under Wellbeing. Log GLP-1 injections or any other medication with name, dosage, unit (mg / ml / units / mcg), and date. Rate appetite suppression on a 1–5 scale and tag common side effects (Nausea, Fatigue, Headache, Diarrhoea, Injection site reaction, and more). Free-text notes up to 500 characters. Autocomplete suggests Ozempic, Wegovy, Mounjaro, Saxenda, and other common medications. Full edit and delete from history. Data is stored per-user via a dedicated MedicationLog table.

πŸ›

Journal entries now save correctly

A schema migration had added the WellbeingEntry model but not regenerated the Prisma client, causing every journal POST to return HTTP 500 with "Cannot read properties of undefined (reading 'create')". The client is now up to date and journal entries save correctly.

πŸ““

Journal - daily wellbeing log

A new Journal tab is now live under Wellbeing. Log mood, energy and stress each day (rated 1–5), add quick tags (Sick, Tired, Stressed, Rest day, Travel, Period, Injury, Low energy), and write a free-text note up to 500 characters. Entries are dated so you can backfill past days. The history list lets you edit or delete any entry. All data is stored per-user and only visible to you. The API supports full CRUD - GET, POST, PATCH and DELETE - with the same input validation applied across FitMesh.

🚫

Blank exercise names now rejected

Manually logged workouts with an empty or whitespace-only exercise name (e.g. setting exercise to "" or " ") previously saved silently - the name was stored as a blank string. The validation in validateExerciseSets() now trims the name and rejects it if the result is empty, returning a clear 400 error: "Exercise name cannot be empty". Applies to both v1 (flat array) and v2 (blocks) workout formats.

🎯

Polar activity goal shown in Daily Inspiration

Daily Inspiration now includes your Polar activity goal completion percentage alongside workouts and habits. Non-workout movement - DIY, errands, walking between meetings - is now reflected in the AI recap, not just gym sessions. The activity percentage also appears as a chip in the "Today so far" card on the Habits tab.

⌨️

Food quantity and macro fields no longer block editing on mobile

Number inputs in the Edit Food Item modal were using type="number" with a minimum of 0, which caused Chrome and Safari to block deletion of the last digit - making it impossible to clear a field and type a new value. The fields now use text mode with a decimal keyboard, matching standard form UX.

πŸ”’

Food library: custom item macros now validated

Creating a custom food item in the food library previously accepted negative macro values, unrealistically large numbers (e.g. 999,999 calories), and non-numeric text that silently converted to 0. Macros are now validated on save: calories capped at 9,999 kcal, protein/carbs/fat each capped at 999g. Non-numeric values and negatives return a clear error.

πŸ‹οΈ

Exercise name and notes length limits added

Manually logged workout exercise names are now capped at 200 characters and workout notes at 1,000 characters. Previously both fields had no upper bound, which could cause DB bloat and rendering issues. Submitting values over the limit now returns a clear 400 error.

πŸ“…

Body measurement dates now validated

The recordedAt field for body measurements now rejects dates before 1970 and dates in the future. Previously any date was accepted, which allowed nonsensical entries (e.g. year 1900 or 2099) to pollute weight charts and progress graphs.

🚫

Food quantity of 0 is now rejected

Logging a food item with a quantity of 0g now returns a clear error - "quantity must be greater than 0" - instead of silently saving a zero-quantity entry. Zero-quantity entries had no nutritional value and only cluttered meal logs.

πŸ›‘οΈ

Body measurements rate-limited

The body measurements endpoint now enforces a rate limit of 20 entries per minute per user. Previously there was no limit, which allowed accidental or malicious bulk submissions to bloat the database and slow the body weight chart.

πŸ“·

Photo food log no longer shows a network error on bad images

When the AI could not process a photo (corrupt file, unsupported encoding, or a transient API error), the endpoint was returning an empty HTTP 500 with no body - which the app displayed as a generic "network error". The error is now caught and returns a clear message: "Photo could not be read. Please use a clear JPEG or PNG." Matches the error-handling pattern already used by the workout photo scan.

🏷️

Workout title capped at 500 characters

Manually logged workout titles are now limited to 500 characters on both creation (POST) and edit (PATCH). Previously, any length was accepted, which was inconsistent with the 200-character cap on habit names. Submitting a title over 500 characters now returns a clear 400 error.

βš–οΈ

Body measurements reject non-numeric text

Entering a text value (e.g. "eighty") in a body measurement field now returns a clear error - "weightKg must be a valid number" - instead of silently saving a blank entry. Previously the text was coerced to null and the entry was rejected only with the misleading "at least one measurement required" message.

🀝

PT invite code confirmation step

Generating a PT invite code on the Account page now requires a confirmation step. An amber warning box explains that the code is for your client to enter - not for entering your trainer's code. This prevents users from accidentally claiming the PT role when they meant to join as a client.

πŸ“‰

Negative calorie values no longer shown in Training tab

A pre-existing workout entry with a negative calorie value (βˆ’999 kcal) was being displayed as "βˆ’999 kcal" in the workout timeline and activity feed due to a truthiness check that passed for negative numbers. The display now only shows calorie values that are greater than zero.

πŸ›‘οΈ

API enum validation

Three endpoints (manual workout logging, food log, and habit creation) now return a clear 400 error instead of crashing when an unrecognised activity type, meal type, or habit frequency is submitted. The valid values are listed in the error message.

πŸ“‰

Nutrition target validation

Calorie, protein, carb, fat, and water targets in Nutrition Settings now reject negative values and unrealistically high numbers (above 100,000) rather than silently storing them.

πŸ”

Dashboard tab navigation fix

Opening the dashboard with a ?tab= URL (e.g. from a notification link) no longer causes a brief page freeze. The tab was being read during server-side rendering and causing a React hydration mismatch. It is now read after the page loads.

⏱️

Workout duration cannot be negative

Manually logged workouts now reject a negative duration (e.g. βˆ’30 minutes). The field previously accepted any number including negative values. It now returns a clear error if duration is below zero.

πŸ“

Workout field upper bounds

Manual workout entries now enforce sensible upper limits: duration cannot exceed 1,440 minutes (24 hours), calories cannot exceed 10,000 kcal, and heart rate fields cannot exceed 250 bpm. Values above these limits return a clear error.

🎯

Habit target values cannot be negative

Habit numeric targets (floor value, target value, stretch value, and times target) now reject negative numbers with a clear error. Previously, a negative target could be saved silently.

πŸ₯—

Food quantity cannot be negative

Food log entries now reject a negative quantity (e.g. βˆ’50g) with a clear 400 error. The how-to guide stated that negative values were rejected, but the server-side check was missing - this has been corrected.

πŸ‹οΈ

Exercise set reps and weight bounds

Manually logged strength workouts now validate individual set data. Reps cannot exceed 9,999 and weight cannot exceed 2,000 kg per set. Non-numeric or negative values in either field now return a clear error rather than being stored silently.

🍽️

Food item name length limit

Food item names are now capped at 500 characters. Previously, names of any length were accepted, which could cause layout issues in the food library and meal cards. Names over 500 characters now return a clear error.

βš–οΈ

Food quantity upper limit

Food log entries now reject quantities above 10,000g per item with a clear error. This prevents unrealistically large entries (e.g. 9,999g of oats) from inflating daily macro totals and cluttering the food library.

✏️

Editing a food item now validates quantity and macros

The edit-item flow (tapping ✏️ on a logged food row) now applies the same validation as logging new food. Non-numeric quantity returns a clear error instead of a server crash. Negative or over-limit quantities (above 10,000g), names over 500 characters, and negative macro values are all rejected with a descriptive message.

✏️

Editing a habit now validates name and target values

Editing a habit via the pencil icon now validates the same fields as habit creation. Name cannot be empty or exceed 200 characters. Floor, target, and stretch values must be valid numbers and cannot be negative. Frequency must be one of the accepted options. Previously, invalid edits could cause a server error or silently store corrupt data.

πŸ”’

Habit target values now have upper limits

Times-per-day/week targets (e.g. "drink water 8Γ— daily") are now capped at 100 completions. Floor, target, and stretch values are capped at 100,000 - covering step-count goals up to 100k. Values above these limits return a clear error.

πŸ₯—

Food item macro values now have upper limits

Per-item calorie values are now capped at 9,999 kcal and protein, carbs, and fat are each capped at 999g. These limits prevent obviously erroneous entries (e.g. 999,999 calories for a single item) from skewing daily totals. Non-numeric macro values also now return a clear error instead of being silently ignored.

πŸ“

Workout location label capped at 200 characters

The location label on a manually logged workout is now limited to 200 characters. Previously the field had no upper bound, which could cause layout overflow in workout cards and export files. Submitting a value over 200 characters now returns a clear 400 error.

πŸ“

Body measurement notes and clothing sizes now have length limits

The notes field on a body measurement is now capped at 500 characters and clothing size fields (top size, bottom size) are capped at 50 characters each. Previously all three had no upper bound. Values over the limit now return a clear 400 error.

πŸ“…

Food log dates are now validated

Food log entries now reject dates before 1970 and dates more than 1 day in the future. This brings the food log in line with the existing date validation on workouts and body measurements, preventing nonsensical back-dated or future-dated entries from appearing in the nutrition calendar.

πŸ“

Workout distance and steps now validated

Manually logged workouts now reject negative distance values and cap distance at 1,000,000 metres and steps at 100,000. Previously both fields had no bounds, which allowed nonsensical entries like a negative 5-metre run.

✏️

Editing food items: zero quantity now consistently rejected

Editing a logged food item to have a quantity of 0g now returns the same "quantity must be greater than 0" error as logging new food. Previously the edit path accepted zero, creating a silent inconsistency.

✏️

Editing food items: macro upper limits now enforced

Editing a logged food item now enforces the same per-item macro caps as logging new food: calories cannot exceed 9,999 kcal and protein, carbs, and fat each cannot exceed 999g. The edit path previously had no upper bounds on these fields.

😴

Sleep target on habits now validated

The sleep target field on a habit is now capped at 24 hours. Previously, any value was accepted including nonsensical values like 999 hours. Values above 24 now return a clear error on both habit creation and editing.

✏️

Editing habits now enforces the same upper limits as creation

Habit edits now enforce the same maximum values as creating a new habit: times-per-day/week targets cannot exceed 100 and numeric goal values cannot exceed 100,000. Previously these caps only applied when creating a habit, not when editing one.

πŸ’§

Water intake logging now validated

The water log endpoint now validates that ml is a finite number (non-numeric text previously caused a server error), caps intake at 10,000ml per day, and rejects dates before 1970 or more than 1 day in the future.

πŸ‹οΈ

Editing workouts now validates all fields

The workout edit path now enforces the same validation as creating a workout: location label cannot exceed 200 characters, date year must be between 1970 and the current year +2, and set data validates reps (≀ 9,999) and weight (≀ 2,000 kg).

🍽️

Calorie balance shown below the ring

The nutrition summary now shows a colour-coded balance pill below the calorie ring when you have a calorie target set - green when under, red when over. At a glance you can see "+200 kcal" or "βˆ’350 kcal" without doing the maths yourself.

πŸ‹οΈ

Exercise validation now covers block-format workouts

Reps (≀ 9,999), weight (≀ 2,000 kg), and exercise name (≀ 200 characters) limits were already documented but were silently skipped when exercises were sent in the block format used by the manual-entry modal (supersets, circuits). The validator now handles both the legacy flat format and the current block format. Boundary values are still accepted; over-limit values now return a clear 400 error.

✏️

Edit metadata on synced workouts

The Edit button is now shown for all workouts - not just manually logged ones. For workouts imported from Strava, Hevy, Polar, or other sources you can rename the workout, change the activity type, correct the date, add a location, or attach notes. Exercise sets remain read-only for synced workouts (those can only be edited at the source). Delete is still restricted to manual entries only.

May 2026

Fitbit integration & sync improvements

πŸ”΅

Fitbit connected

Fitbit is now a live integration. Connect from the Integrations tab and sync your workouts, daily steps, sleep stages, and weight log entries. Fitbit uses OAuth - you will be redirected to approve access.

⚑

Per-source sync

The sync button next to each integration now syncs only that source rather than triggering a full re-sync of everything. Faster, uses less API quota, and feels more responsive.

πŸ”„

Smarter deduplication

The dedup engine now re-processes recent unconfirmed workouts on each sync. If a Strava run and a Hevy session for the same workout arrived at different times, they will now correctly merge into one entry rather than staying as separate events.

May 2026

How-to page fixes

πŸ–±οΈ

Consistent click language

The how-to guide previously used "tap" in a few steps (barcode scanning, favourites) while the rest of the page used "click". All instructions now consistently use "click" throughout.

πŸ–ΌοΈ

Logo filename fix

The FitMesh logo files had a typo in their filename (FtiMesh instead of FitMesh) across all pages. The files and all references have been corrected sitewide.

April 2026

Food library, favourites & recipe builder

⭐

Personal food library

Every food you log via AI (Describe, Photo, or PDF import) is automatically saved to your personal library with the correct macros per 100g. Go to Library β†’ Foods to see everything, organised into Favourites, Recent, and All.

β˜…

Favourite foods & meals

Tap the β˜… star on any logged food row to save it as a favourite. Or use the "β˜… Save as meal" button at the bottom of any meal edit sheet to save an entire meal in one tap. Favourites appear at the top of the Favourites tab whenever you add food.

🍽️

Quick-log from favourites

The ⭐ Favourites tab in the add food modal now shows both your starred individual foods and saved meals. Starred foods show the default serving - tap to adjust quantity, then log in one tap. Saved meals log all items at once.

πŸ“–

Recipe builder

Go to Library β†’ Recipes β†’ + Create recipe. Describe the dish in plain text and AI parses it into a full ingredient list with macros. Adjust quantities per ingredient - macros rescale automatically. Set the number of servings and see per-serving totals before saving.

✏️

Edit logged food entries

Tap any logged meal card to open it, then tap ✏️ on an individual item to edit it inline. Change the name, quantity or any macro. Changing the quantity automatically rescales protein, carbs, fat and calories using the original per-gram ratio.

April 2026

Photo food logging & describe improvements

πŸ“·

Photo food logging

Tap πŸ“· Photo in the add food modal to take or upload a photo of your meal. AI identifies every item on the plate and estimates portions and macros. Tick what to keep and log in one tap. Uses 1 AI credit per photo (free: 3/day, PRO: 15/day).

⌨️

Keyboard mic & Wispr support

The Describe tab now works seamlessly with your phone keyboard's built-in microphone and dictation tools like Wispr. Just tap the mic icon on your keyboard and speak - no in-app microphone permission needed.

⚠️

Photo accuracy warning

When using photo logging, a note reminds you that visual estimates can vary and suggests switching to the Describe tab for more precise logging when accuracy matters.

March–April 2026

Polar integration & recovery tracking

πŸ”΅

Polar integration

Connect your Polar device or Flow account to sync workouts automatically. Go to the Integrations tab and connect Polar to get started.

😴

Recovery tab

A new Recovery section in the Training tab shows sleep, HRV, and readiness data from supported devices. Helps you track how well you are recovering between sessions.

March 2026

Account controls & data safety

πŸ”’

14-day deletion grace period

When you request account deletion, your account is scheduled for deletion in 14 days rather than deleted immediately. You can cancel from Account β†’ Delete account at any point during that window. A notification is sent with a link to download your data first.

πŸ“₯

Data export before deletion

The deletion notification includes a direct link to export your data so you can keep a copy before anything is removed.

πŸ’³

Billing portal fix

The Manage Billing button in Account now correctly detects whether you have a Stripe subscription. Gifted PRO accounts (no card on file) no longer see a broken button.

March 2026

Habits & compliance

🎯

Tiered compliance targets

Habits now support three tiers: a minimum floor (non-negotiable), a target (the actual goal) and a stretch goal. The weekly view shows which tier you hit each week rather than a simple pass/fail streak.

πŸ”’

Multiple completions per day

Habits like "take medication 3Γ— daily" or "drink water 8Γ— daily" now track count per day rather than a binary yes/no. Set a daily target and log each completion separately.

πŸ“Š

Compliance percentage view

Each habit now shows a rolling 7-day and 30-day compliance percentage alongside the streak. Useful for seeing whether you are consistently hitting a target, not just whether you're on a current run.

February 2026

Nutrition foundations

πŸ₯—

Describe food with AI

Type what you ate in plain English and AI breaks it into items with estimated macros. Works for complex meals, cooking from memory, or anything that isn't in a database.

πŸ“₯

Import from MyFitnessPal

Upload a PDF export from MyFitnessPal (or similar) and FitMesh reads every entry and previews it before import. Brings your history across without needing CSV access.

πŸ’§

Water tracking

Track daily water intake with a tap counter (250ml per tap). Syncs with water-based habits - hitting your daily target auto-completes any water habit you have set up.

πŸ“ˆ

Nutrition trends & charts

The Log tab shows daily calorie bars for the last 30 days, 7-day rolling macro averages, and a weekly summary card.