FITNESS
VT FITNESS
Changelog
V20 Jul 2026 — current ● Current Latest: V21.26

The hardening & housekeeping release. V20 is a full-codebase audit: the API is locked down, the Config tab is retired with all Settings now living as a tile in the Profile tab, resuming a recovered walk or run no longer lands on a blank screen, Clear All Device Data works again, and thousands of lines of dead code, styling and legacy shims have been removed with no loss of functionality.

⏳ Health sync explains the “past data” rule (21.14)
  • Why a first sync can come back empty. Health Connect only lets an app read readings written after it was given access, so everything recorded before you granted permission stays hidden. The app now explains this and points you at the “access past data” setting, rather than leaving you wondering where your readings went.
🔎 Health sync now tells you exactly what's missing (21.13)
  • The sync result no longer disappears a second after you tap the button.
  • It now checks what Health Connect has actually granted before syncing. If no data types are permitted — the usual reason a sync returns nothing — it says so and tells you where to switch them on, instead of reporting a mystifying zero.
🔧 Health sync: manual trigger and clear diagnostics (21.12)
  • New “Sync health now” button in Data Sources (in the app), so you can pull readings on demand and see exactly what happened rather than waiting and guessing.
  • Health sync problems are now recorded. Permission refusals, a missing plugin or an empty health store previously failed silently; they now appear in the error log with the detail needed to fix them.
  • The panel now says plainly when you're in a browser, where health data cannot be read at all — only the installed app can.
🔍 Data Sources now shows your live readings (21.11)
  • The Data Sources table now fills in. Each field shows its latest reading, which app supplied it and when — so when two devices (say a watch and a band) both report steps or heart rate, you can see exactly which one you're looking at.
  • A reading shown dimmed with “(fallback)” means your chosen master app hasn't sent that field, so a value from another app is being used instead.
  • Added a Refresh readings button to pull the latest without waiting.
📊 Fix: weekly session count ignored ad-hoc sessions (21.10)
  • The header now counts this week's sessions properly. It reads “Week 6 · 2 sessions” and counts everything you've actually done since Monday — including ad-hoc / Quick Log entries and Strava imports. Only AI Coach reviews are excluded, since they aren't training.
  • The History tab still shows your lifetime total.
📱 Fix: header layout on narrow screens (21.9)
  • The header no longer collides with itself on narrow displays such as a folding phone's cover screen. The week/calorie readout is hidden when there isn't room for it beside your name — the same figures are on the dashboard — and the header now clears the phone's status bar properly.
📐 Fix: overlapping header text & sparse GPS points in the app (21.8)
  • Header text no longer overlaps. Android was inflating the app's text beyond the layout, causing your name, calories and water figures to print on top of each other. Text now renders at the intended size and the header shrinks gracefully instead of colliding.
  • Routes are recorded in far more detail. The first tracked walk logged only two GPS points across nearly a kilometre; the app now keeps every fix, so distance, pace and the route map are accurate.
🔧 Fix: live tracking wouldn't start in the app (21.7)
  • Start Live Track now works in the app. The background-location service returned its handle in a slightly different form than expected, which stopped tracking before it began. Fixed, and both forms are now handled.
  • If background tracking can't start (usually because location permission isn't granted), the app now tells you and falls back, instead of sitting silently on “Acquiring…”.
  • The body composition button label was still showing the old name — corrected.
🔓 Fix: existing key holders locked out of AI (21.4)
  • If you already had an AI key, your AI features are back. When the £4.99/£14.99 plans were introduced, AI started requiring a plan on your account as well as a key — which wrongly locked out members who had already paid under the earlier key-based model. Those accounts are now automatically upgraded to lifetime premium, permanently and at no cost. Nothing to do; it applies next time you open the app.
📷 Body Composition Scan — works with any scale, and your tape measure (21.3)
  • “Scan Renpho” is now “Body Composition Scan” and is no longer tied to one brand. Point it at a screenshot from any scale app — Hume, Renpho, Withings, Garmin, Fitbit, Samsung or Apple Health — a photo of a scale display, or a printed clinic/DEXA report.
  • It now reads tape measurements too, including a handwritten note. Measure yourself, jot the numbers on paper, photograph it, and neck, shoulders, chest, arms, forearms, waist, hips, thighs and calves fill in automatically.
  • Units are converted for you. Weights in stones or pounds become kg, and inches become cm. Wording differences (lean mass vs fat-free mass, hydration vs body water, body age vs metabolic age) are matched automatically.
⚖️ Body composition now defaults to Hume (21.2)
  • Weight and body fat now default to Hume in Data Sources, since the Hume scale writes both to your phone's health app automatically. Renpho stays available as an option so your existing history still resolves.
  • Lean mass, muscle mass and BMI default to manual entry — the Hume app keeps those to itself rather than sharing them with your phone's health store.
🏃 Couch-to-5K also records with the screen off (21.1)
  • C25K now uses background tracking too in the app — pocket the phone mid-run and your distance and pace keep recording, just like walk tracking. It also reconnects properly if a run is interrupted and recovered.
📱 V21 — VT Fitness becomes a real app (21.0)
  • Tracking no longer stops when your phone sleeps. In the new installable app, walks and runs keep recording with the screen off and the phone in your pocket — the single biggest limitation of the web version, gone.
  • Your wearable data flows in automatically. The app reads your phone's health store, so anything your band, watch or scale syncs there — steps, active calories, weight, body fat, sleep, heart rate, oxygen saturation, body temperature — lands in VT Fitness on its own.
  • Same account, same data. The app is the same VT Fitness you already use, so nothing to migrate and the website keeps working exactly as before.
  • The web version is unchanged and still fully supported — it just can't record GPS with the screen off, which is a limitation of browsers rather than of VT Fitness.
🎛️ Choose which app is in charge of each figure (20.023)
  • New Data Sources table in Profile → Settings. Fifteen fields — weight, body fat, lean and muscle mass, BMI, steps, active calories, distance, heart rate, resting HR, HRV, sleep, oxygen saturation, body temperature and blood pressure — each with a dropdown to pick which app is master.
  • Options per field include VT Fitness (manual), Hume, Renpho, Strava, Garmin, your phone's health app, or simply “most recent”.
  • Nothing is thrown away. Every reading from every source is still recorded — the master setting only decides which value the app shows and uses in your targets. If your chosen app hasn't sent anything yet, the most recent reading is used instead and shown greyed.
⌚ Groundwork for wearable sync (20.022)
  • VT Fitness can now receive health data from your phone. New server endpoints accept steps, heart rate, resting HR, HRV, sleep, SpO2, body composition and more — whatever you sync into Health Connect (Android) or Apple Health (iOS), from any device: Hume Band, Garmin, watch or scale.
  • Repeated syncs can't create duplicates, and each sync resumes from where the last one finished.
  • Nothing changes in the app yet — the companion mobile app that reads your phone's health store is the next piece.
✅ Real fix: profile, admin tab and premium status restored (20.021)
  • The database was missing new columns. Recent releases added premium and email-preference fields, but those were only created by a setup step the app never runs — so on a live database the user list query failed outright. That single failure caused every symptom: “User 1” instead of your name, no Admin tab, “free user, AI off”, and the GDPR prompt returning.
  • Upgrades are now self-healing. The app adds any missing columns automatically the first time it needs them, and still works even if that isn't possible — so a partial upgrade can never blank your profile again.
🔧 Fix: profile showing “User 1” and prompting for GDPR again (20.020)
  • Your own profile could come back empty. A fault in the 20.017 privacy change meant that if the server couldn't match your session to your account row, it returned no users at all — so the app showed “User 1”, lost your admin role (showing you as a free user with AI off) and re-asked for GDPR consent. It now always resolves your own account, so your profile, role and premium status load correctly.
🔁 Follow-up emails run on login, not on a cron (20.019)
  • No cron job needed. The weekly re-engagement email now runs as a queue job whenever someone logs in — the same pattern as the existing GDPR sweep. It's throttled to do real work at most once a day, so more logins never mean more emails.
📧 Clearer sharing, anonymised examples, re-engagement emails (20.018)
  • Link requests spell out what's shared. The email now says plainly that accepting lets you and the other person each see the other's food log and workout history — nothing else — and that either side can remove the link anytime.
  • Anonymised sign-up examples. The profile form no longer uses a real person's details as the example placeholders.
  • Weekly re-engagement emails for people who started but never finished setting up — a friendly nudge covering the free features and optional Premium, capped so it never nags.
  • Every email is compliant: one-click unsubscribe, plus a self-service page to unsubscribe, erase your data, or delete your account outright.
🛡️ Privacy fix: users can no longer see the full member roster (20.017)
  • Directory scoped. Previously any signed-in account could see every member's name, email and photo. Regular users now see only themselves and members they have an accepted link with; admins still see everyone.
  • Profile photos locked down the same way — you can only fetch a photo for yourself or a linked member.
  • Viewing a linked member's food log / history was already restricted to accepted links and audited — unchanged. Remove a link any time via Profile → Active links → Remove.
🔒 AI key is admin-managed · per-device pricing (20.016)
  • The AI key is now hidden from users. It's no longer bring-your-own-key — the key is provisioned by an admin per device and can't be viewed or edited by regular users. The Profile → Licences screen shows users only their premium status; the key entry is admin-only.
  • Pricing shown per device. Annual £4.99/yr and Lifetime £14.99 are now clearly labelled per device across the app and About page.
  • Admins provision the key from Profile → Licences (or the key prompt) on each device; it's masked and never exposed to the user.
🔐 Premium = the AI features · annual or lifetime (20.015)
  • Free vs Premium is now simply the AI features. Everything else — logging, tracking, plans, manual food — stays free for life. AI food logging, macro lookup, the AI Coach, photo body-composition and the daily AI report are Premium.
  • Two ways to pay via PayPal: Annual £4.99/yr or Lifetime £14.99. Shown in the licence prompt, Profile and the About page.
  • Lapsed premium drops to free cleanly. If an annual plan expires you return to the free tier and AI locks — but your AI key is kept, so renewing re-enables everything instantly.
  • About page rewritten to explain the pricing and make the free/premium (AI-only) difference clear.
💳 Premium plan + sleep-proofed live tracking (20.014)
  • New premium pricing: £4.99/year or £14.99 lifetime. The free version stays free for life.
  • Expiry warning + Renew. Annual members get a heads-up banner as their plan nears its end (and if it lapses), with a one-tap Renew request. Lifetime and free never expire.
  • Admin accounts control. Admins can grant, extend, override the date, or revoke premium per user, and see who's requested a renewal.
  • Live tracking survives a screen-lock better. When your phone sleeps mid-walk/run, tracking now re-acquires GPS cleanly on wake and clearly flags any stretch it couldn't record (“X min untracked”) instead of silently under-counting. A browser still can't record GPS with the screen fully off — the upcoming native app fixes that properly with background location.
🏋️ Gym session fixes: skipping, planks, cardio & earned calories (20.013)
  • Skip now works as often as you need. Choosing “Do later” sends an exercise to the back of the queue, and if it comes round again with the machine still busy you can skip it again — previously it froze as “SKIPPED” and left you stuck on it. Deferring several exercises no longer ends the session early either.
  • Planks are timed, not counted. A plank (or any timed hold) now shows its target in seconds instead of asking for reps.
  • Cardio is a record, not a set of sets. Treadmill, bike, rower and swim now show a single entry for time, distance, speed and incline — no multiple sets and no easy/tough/failed rating. It's marked done once you've logged some time or distance.
  • Your earned calories now reliably reach food & dashboard. The end-of-session review was hardened so a stray value can't crash it — that crash was stopping sessions saving, which is why the calories you'd burned sometimes never showed. The Save button is always reachable now.
🤖 Send your Body Constitution to the AI Coach (20.012)
  • New 🤖 Submit to AI Coach button at the bottom of Body Constitution. It hands over your latest readings for a review of your progress, and your coach will adjust your training programme and nutrition targets if the numbers justify it — or tell you plainly that nothing needs changing.
  • Scanning a Renpho screenshot now does this automatically — scan, and the review starts on its own. No second tap.
  • Your coach now sees the full picture: not just weight and body fat, but skeletal muscle, body water, bone mass, protein, BMR, metabolic age and your tape measurements — none of which it could see before.
  • Readings are now kept as a dated trail, so each review reports what has changed since your last reading rather than commenting on a single snapshot in isolation. Reviews are saved to your History alongside your sessions.
🔗 See a linked member's food log and history (20.011)
  • Once a link is accepted, each of you can view the other's food log and training history from Profile → Linked Profiles — tap Food log or History on any active link. Either side can look; it doesn't matter who sent the invitation.
  • It's strictly read-only and covers only food and history. Your profile, health readings, medications and body photos stay private, and a linked member can never change anything of yours. Remove the link and access stops immediately.
🔒 Security: linked profiles are now properly protected (20.011)
  • The link features — listing your links, sending an invitation, cancelling and removing — were not checking that the request came from you. Listing in particular gave out the names and email addresses of the people you're linked to. All four now require you to be signed in as yourself. This mattered doubly now that a link grants sight of your food and training.
  • Every time a linked member views your data it is recorded in the audit log.
🐛 Fix: errors on the photo and water pages vanished (20.010)
  • Body Photo Analysis reported its problems only as a pop-up on your screen. If an analysis failed, a photo wouldn't save or a delete didn't work, the message appeared, faded, and left no trace — so we never knew it happened. Every error on that page now reaches the error log, along with the device, the page and what you were doing at the time.
  • Same for the water quick-add page: "Could not save" and "Connection error" were dead ends. They're now reported too, so water that silently fails to log can actually be chased.
  • Both pages now also catch unexpected crashes and failed background requests, which previously went nowhere at all.
📊 Analytics: cleaner referrer reporting (20.010)
  • Link tags (?utm_source=, ?fbclid= and similar) made one referrer look like dozens, splitting the report into fragments. Referrers and paths are now tidied to the underlying address before being recorded, so one source counts as one source — and existing history is grouped the same way, so past figures make sense too.
🐛 Fix: finishing a C25K run didn't move you to the next one (20.009)
  • After completing Week 1 Run 1, the tile still offered Week 1 Run 1. Since the timer stopped auto-finishing in 20.007, the plan only advanced if you held Finish after the very last second of the cool-down walk — in Week 1 that left a 6.5 minute window where you'd done every run interval, stopped like a normal person, and the run was filed as "ended early". Completing all the running now completes the session and moves you on; the cool-down is a walk home, not a gate.
🍽️ Food tab tiles (20.009)
  • The Food tab now uses the same tiles as the rest of the app — Day & Totals, Water, Food Logger, Photo Food Log, Quick Add, Dietary Suggestion and Food Log all collapse and drag to reorder, and your layout is remembered.
  • Collapse the parts you don't use and put your favourite at the top — if you log by photo, drag it above the typing box and fold the rest away.
🌅 Morning Check-in (20.008)
  • A new Morning Check-in card on your Dashboard for the readings your watch can't send us automatically — HRV, resting heart rate and sleep, plus Body Battery and stress if you use Garmin, and your weight. It's pre-filled with your last figures, so you only change what moved overnight, then tap once to save and see your readiness score.
  • It jumps to the top of the Dashboard while it's outstanding and disappears for the day once you've saved or skipped it.
  • No watch? You'll never be nagged. Tap Not today to skip once, or Don't ask again to switch it off entirely — and turn it back on any time under Profile → Settings → Integrations.
  • The card only shows fields that make sense for you: Body Battery and stress appear only if Garmin is one of your health sources, and the sleep box asks for a score or hours depending on which app you use.
🐛 Fix: C25K and Walk were losing most of your distance (20.007)
  • GPS distance was being under-counted badly — a Week 1 C25K session recorded about 40% of the real distance. The tracker ignored any movement under 2 metres between fixes as GPS jitter. At the once-a-second rate phones report position, 2 metres is 7.2 km/h — so every walking step was thrown away and only running counted. Since C25K is around 60% walking in the early weeks, most of the distance vanished. The jitter threshold now scales with the time between fixes, and the phone's own speed reading is used to tell "standing still" from "walking slowly". Walk tracking had the same fault and is fixed too.
  • Discarded fixes are now counted and reported at the end of a session, so this class of problem shows up in diagnostics instead of silently eating distance.
🗣️ C25K coaching: proper countdowns (20.007)
  • Voice prompts said the wrong duration. A 90-second walk was announced as "2 minutes" and a 30-second run as "1 minute" — the voice contradicted the countdown on screen. Prompts now say minutes and seconds: "Walk for 1 minute and 30 seconds".
  • Every change now gets a full countdown, for walks as well as runs: "Prepare to run/walk" at 10 seconds, a "5 seconds" warning, then 3-2-1 beeps, then the new instruction on the change itself. Previously only runs got a cue, and only 3 seconds ahead.
  • The end of the session gets the same countdown instead of just stopping.
⏱️ C25K keeps timing until you finish (20.007)
  • The session used to save and close itself the instant the plan's last segment elapsed. It now announces "workout complete", shows a green COMPLETE banner, and keeps timing and tracking until you hold Finish — so your walk back still counts. Finishing after the plan has run its course still counts as completed and still advances you through the programme.
🐛 Fix: merging history entries discarded activity detail (20.007)
  • Merging two entries rebuilt the result from a fixed list of fields (duration, distance, heart rate, calories, notes and exercise sets) and silently dropped everything else — for a tracked run or walk that meant the GPS route, average speed, elevation gain and C25K week/day were destroyed. The merge now keeps the whole entry and only overrides the fields you actually chose.
👁️ Emulation now works across the app — except body photos (20.006)
  • When an administrator views a member's account, Body Photo Analysis and Gallery now opens as that member rather than switching back to the administrator's own account. Emulation is honoured consistently across the app.
  • Body photos stay private to the account holder. An administrator viewing your account can see your profile and measurements, but your body photos cannot be viewed, added or deleted by anyone but you — the server refuses those requests outright, whoever is asking. The page says so plainly rather than appearing broken.
  • Every action an administrator takes while viewing another account is now recorded in the audit log.
🐛 Fix: Body Photo Analysis opened as the wrong account while emulating (20.005)
  • Opening Body Photo Analysis while emulating another member silently signed you in as yourself, while the app still showed you as emulating. The page authenticates from a sign-in token in the link, and an emulated member has no token on your device — so the page fell back to your own saved session. It now refuses to open rather than switch identity behind your back, and tells you to end emulation first.
⚖️ Plan Settings now first (20.005)
  • In My Goals & Training Setup, the Plan Settings section (start/target weight and dates) has moved to the top of the tile, above your goals and training setup.
💬 Footer tidied (20.005)
  • Added Raise a Support / Feature Request next to Contact us — it opens the VT Fitness WhatsApp group so you can report a problem or suggest a feature.
  • Removed the settings gear from the footer — settings live in the Profile tab.
⚡ Quick Start moved to the Train tab (20.004)
  • Quick Start has moved from the Dashboard to the top of the Train tab — today's scheduled session, the quick-log activity buttons and the Recovery link are now where you go to start training.
  • Walk (beta) and Couch to 5K (beta) now live inside the Quick Start tile as sub-sections, rather than as two separate tiles. Everything you can start — a gym session, a quick log, a tracked walk or a guided run — is in one place at the top of the tab.
  • If a recovered walk or run is resumed while Quick Start happens to be collapsed, the tile now opens itself so the session is actually visible.
🗂️ History grouped by period (20.003)
  • Session history is now grouped into collapsible periods — Last 7 days, Last month, Last year and Older — each showing its session count, with Last 7 days open by default. Empty periods are hidden. Drag any period to reorder; your layout is remembered.
📊 Plan tab tidied into five draggable tiles (20.003)
  • Current Plan Progress now sits inside the This Week's Target tile, and Plan Settings inside My Goals & Training Setup — seven cards down to five tiles.
  • Every Plan tile is now collapsible and drag-to-reorder, with both the order and what's open remembered per user — matching how the Dashboard and Train tabs already work.
🏠 Things moved to where you actually use them (20.002)
  • Water quick-add on the Dashboard. Today's Nutrition now has +250ml / +500ml / +750ml buttons, so logging a drink no longer means a trip to the Food tab. Both views stay in step whichever one you use.
  • Walk (beta) has moved from the Dashboard to the Train tab, next to Couch to 5K — both live GPS activities now sit together where you go to start training.
  • Dietary Suggestion has moved from the Dashboard to the Food tab, alongside the food logger and water tracker.
  • Profile header rearranged. Your member number and photo now sit to the left, with your Fitness Age alongside them on the right instead of buried further down the tile.
  • Today's Readiness appeared on both the Dashboard and the Profile tab. The Dashboard tile is now the single source — the Profile copy is gone, and the sync stamps (Strava / Garmin / Apple Health) stay where they were.
  • Body Composition photo analyser is now called Body Photo Analysis and Gallery, on the page itself and everywhere that links to it.
🐛 Fix: tape measurement fields opened the photo analyser (20.002)
  • In Body Composition, the whole Tape Measurements block had ended up nested inside the "Open photo analyser" link. Tapping any measurement field opened the analyser in a new tab instead of letting you type. The link now sits below the fields where it belongs.
📊 Plan tab: training setup and nutrition targets brought together (20.001)
  • Training days per week and available equipment have moved out of Profile and into the Plan tab, merged into the goals card — now 🎯 My Goals & Training Setup. Everything that shapes your programme (what you are training for, how often, and with what kit) sits in one place, with 🤖 Update my Program right beneath it.
  • Nutrition targets are no longer entered in two places. The Plan tab's Nutrition Targets card now has an ✎ Edit targets button that opens the calorie, protein, carb and fat fields inline — the duplicate set in Profile has been removed.
🔒 Security: API lockdown (20.000)
  • Data export is now protected — a backup can only be requested by the signed-in owner of that account. Previously the export endpoint (and several other unused endpoints) could be called without signing in; all have been secured or removed.
  • Four legacy API endpoints that the app no longer uses have been removed entirely, shrinking the attack surface.
⚙️ Settings moved into the Profile tab (20.000)
  • Licence & AI Keys, Integrations and Data & App Info now live in a single collapsible ⚙️ Settings tile in the Profile tab — drag it to reorder like any other tile.
  • The old Config tab and its separate layout system have been retired, along with the legacy-key compatibility shim that had caused several duplicate-tile bugs in the 18.x line.
🐛 Fixes (20.000)
  • Resuming a recovered Live Walk or C25K run (after the phone had closed the app mid-session) showed a blank screen — it now returns you to the Train tab with your session intact.
  • Clear All Device Data in Data & App Info was showing as a dead label with no button — the button is restored and works again (it asks for confirmation first).
🧹 Housekeeping (20.000)
  • Removed 27 dead functions, 39 unused style rules and two redundant files (strava_oauth_start.php, redirect.html) identified by a full-code audit — smaller download, faster load, no functional change.
V17–18 Jul 2026 Previous Latest: V18.017

The scale & accessibility release. V17 opens VT Fitness to everyone: free accounts with manual food logging, a self-correcting shared food library, and per-user AI keys. Self-service registration supports hundreds of users. A complete layout rewrite fixes scrolling and responsiveness across all devices, and a queued daily nutrition report emails each user a personalised end-of-day summary with AI-generated food swaps — no server cron required.

ℹ Exercise guides: admin control + build on request (18.017)
  • "Build missing exercise guides" has moved to the Admin tab, with a live count above it showing how many of your exercises are missing a guide. The button greys out once everything's covered.
  • Tapping ℹ on an exercise with no guide now offers to build one, rather than starting to build it automatically. You choose — a tap you only meant as a look no longer spends anything, and the guide is saved to your account so it's only ever built once.
  • If a build fails, the real reason is shown right there with a Try again button, rather than a dead end.
🐛 Fix: guide building failed silently (18.016)
  • "Build missing guides" reported failures but wrote nothing to the error log, leaving nothing to diagnose. Failures are now logged properly and the actual error message is shown on screen, so a failure can be acted on instead of guessed at.
  • Guide building now uses the same connection handling as the AI Coach — a 30-second timeout and one automatic retry — instead of a bare request that could hang or fail without explanation.
  • If three guides fail in a row it now stops and reports why, rather than working through dozens more doomed attempts.
  • Building 41 guides previously re-saved your entire profile 41 times over (including your profile photo). It now saves once at the end, and paces requests to stay within API limits.
  • Replies that wrap the guide in extra text are now read correctly rather than discarded.
ℹ Exercise guides for every exercise (18.015)
  • Why the ℹ said "no guide available". Guides only existed for the 66 built-in exercises. Anything the AI creates — a session built from a description, an optimised session, an exercise the Coach adds — invents its own internal name, which was never going to match the built-in list. A fixed list of guides could never keep up.
  • Adding an exercise mid-session also renamed it behind the scenes when it clashed with one already in the session, which lost the guide for exercises we plainly did have one for. Now handled.
  • Guides are now built automatically whenever an exercise is added — from the library, the AI session builder, the AI optimiser, the Coach, or mid-session. They're saved to your account, so they're written once and available everywhere, on every device.
  • Tapping ℹ on an exercise that somehow still has no guide now builds one on the spot instead of dead-ending. Generated guides use the same format as the built-in ones: goal, step-by-step method, movement and muscle diagrams, and a key coaching tip.
  • New "Build missing exercise guides" button in the Train tab fills every gap across your whole programme in one go, with progress as it works.
🎯 Your goals now drive the app (18.014)
  • The Goals tab has a new My Goals card. Pick everything that applies — weight loss, muscle build, physique change, strength, fitness/stamina, fight ageing, general wellbeing, mobility. Each one explains what it means for how you train, and they're displayed back to you rather than buried.
  • Suggested weights now match your goals. A fitness/stamina goal suggests lighter loads for higher reps; a strength goal suggests heavier. Where your goals imply different loads, the lighter one is used — you can always add weight after your first set, but you can't undo an injury. The card tells you exactly how much your goals have shifted the suggestions.
  • Your goals are now passed to the AI Coach and to Body Composition analysis, so advice is aimed at what you're actually training for.
  • When the AI Coach reviews a body composition analysis or photo comparison, it now saves a summary to your History tab — previously that advice only lived in the chat, which scrolls away and expires after 7 days. Reviews are correctly excluded from session counts, calorie totals and fitness-age calculations, since they aren't workouts.
  • Fixed a bug that silently wiped your goals text every time you saved your height or weight — it was clearing the field from an input that no longer exists.
🏋️ Sets are now prefilled — and suggested weights actually work (18.013)
  • Suggested weights never worked at all. The built-in baseline table had a weight of zero for every single exercise, and the code only displayed a suggestion when that number was above zero — so the "start at X kg" hint could never appear, for anyone, ever. That's why Session A showed no weights.
  • Every set is now prefilled when you start a session. Where you've done the exercise before, it carries over exactly what you lifted last time. The old "Last Session" tile is gone — it was just repeating numbers that now sit in the fields themselves.
  • With no history, the app estimates a starting weight from your bodyweight, age and sex, adjusted for the rep target. These are deliberately conservative — starting too light costs one easy session, starting too heavy costs weeks. Estimated fields are marked in amber with an "est" tag so a guess is never mistaken for something you actually lifted, and they're replaced by your real numbers from the next session onward.
  • Exercises added mid-session get the same treatment, rather than being the one place left blank.
✨ AI Progress Review — compare photos over time (18.012)
  • Select 2–4 gallery photos and press Compare to get an AI review of what has actually changed between them. It reads your profile, your weight goal and target date, and your previous analyses — so the verdict is measured against your goal, not generic advice.
  • The review separates Improvements (what has visibly progressed) from Focus Areas (what needs work, and why it matters for reaching your goal), plus an honest read on progress toward your target. It's told to say so plainly when change is minimal rather than inventing progress, and to acknowledge that lighting, pose and angle affect appearance.
  • A Send to AI Coach button hands the review straight to your coach, which will adjust your training programme and nutrition targets to concentrate on the areas identified.
  • Admin functions now appear on the Body Composition page — the Admin tab in the header, and Reports / Error Log / Beta / Hits in the footer. The page previously had no way to know your account role, so they could never show.
🐛 Fix: Body Composition profile, gallery & comparison (18.011)
  • Regression fixed (introduced in 18.010, apologies). A single line added last release referenced a value that wasn't available where it was used, causing an error that stopped the Body Composition page from loading your profile at all. That one failure explains three separate symptoms: your profile details weren't being sent to the analysis, the AI didn't have your full context, and your profile picture was missing from the gallery. The page's startup steps are now isolated, so no single failure can silently take out the rest.
  • The photo comparison strip no longer appears on its own showing every photo. It now only ever shows what you've actually selected — which is also why the Compare button seemed dead: the strip was already on screen before you pressed it, so pressing it changed nothing. Compare is now the explicit trigger, with a Clear button alongside it.
  • Analysis history was never actually saving to your account — the request was missing its login credentials and was being rejected silently, so your history only ever existed on the device that created it. It now saves properly and is restored on any device, giving the AI genuine previous-analysis context to compare against.
  • Body Composition's header and footer now match the rest of the app — same app icon, and the footer's social links, About link and version stamp are all present and consistent.
  • Profile loading failures are now reported instead of silently ignored.
🐛 Fix: gallery showing duplicate photos, slow to open (18.010)
  • One root cause, four symptoms. Loading the gallery reset a shared list and then added photos to it one at a time while waiting on the network. Opening the gallery directly (which is exactly what the Profile tab's Gallery button does) started that process twice at once, so both runs added to the same list — every photo appeared several times over.
  • Because each duplicate was the same underlying photo, tapping one in compare mode highlighted all of its copies while only counting as a single selection — so the Compare button stayed greyed out and looked like it did nothing.
  • Photos are now fetched all at once instead of strictly one-after-another, and the gallery no longer loads twice on open — both of which made it much slower than it needed to be.
  • Videos can no longer be picked for a comparison (they can't appear in a side-by-side of stills, so selecting two of them was another way to enable Compare and get nothing).
  • The Profile tab's Gallery button is now an actual button. The previous change was applied to a fallback version of the profile panel that only renders if the normal one fails — so in practice it never appeared.
🐛 Fix: session history was silently read backwards (18.009)
  • The big one: the server returns session history newest-first, but every feature that reads it (the "Last Session" weight suggestion, the AI Coach's recent-sessions context, and the automatic schedule-adjustment feature) assumed it was oldest-first. After a normal login/reload, all three were silently working from the OLDEST matching entries instead of the most recent ones — which is why "suggested weights were blank" whenever the oldest matching session didn't happen to include that exercise. Fixed at the source so history is always in one consistent order everywhere it's used.
  • Exercise drag-and-drop reordering: a proper touch-compatible reorder handler already existed in the code but was never actually called from anywhere — only the desktop-only (mouse) drag API was wired up, which doesn't fire on phones/tablets. Dragging the ☰ handle now works on touch devices. Also fixed a listener pile-up bug in that handler that would have made repeated drags increasingly unreliable within one editing session.
  • Exercise technique guide (the ℹ button): 27 of the app's 66 exercises/segments had no entry at all, so the button either didn't appear or opened nothing. All 66 now have a goal, step-by-step method, muscle diagram and key coaching tip. The button is also now available when editing a session in the Train tab, where it was previously missing entirely.
🖼️ Body Composition: gallery comparison, consistent navigation (18.009)
  • Gallery photos can now be selected for comparison — tap "Select to Compare", choose any photos (not just the 6 most recent), then Compare to see them side by side in date order.
  • Body Composition now has the same top-level tab bar as the rest of the app, so you're never stuck with only a small back-link to get anywhere else.
  • The Profile tab now has a proper, prominent "Body Composition Gallery" button, replacing a tiny inline link that was easy to miss.
  • Version number in the footer was missing the "V" prefix used everywhere else in the app.
🐛 Fix: Medications & Supplements duplicated on Profile (18.008)
  • Same root cause as the Admin tab fix in 18.007: when Medications & Supplements moved into the Profile tab's own tile system, the legacy Config-section layout was never told to stop rendering it too — so it showed up twice on the Profile page, both copies sharing the same element IDs
  • Add/Remove also silently refreshed the wrong (legacy) copy in the background, so on a page with just the one visible tile the list could appear to not update after adding or removing an item — both now refresh correctly
🐛 Fix: Admin tab not working, hit-counter date filters broken (18.007)
  • Admin now works correctly from its own top-level tab. A leftover config-layout bug meant the Profile tab was still quietly rendering a duplicate Admin panel with the same element IDs as the real Admin tab — since element lookups always resolve to whichever copy appears first in the page, every search/edit typed into the Admin tab was silently updating the hidden Profile-tab copy instead. The duplicate is now gone; Admin lives only in the Admin tab
  • hits.php: switching between Today/24h/7 days/30 days/All time was building a malformed link with two "?" in it, which broke both the filter and, in some cases, the page's own access token. Date-range switching now works correctly
🐛 Fix: Live Track sessions logging 500+ "sets" (18.006)
  • Live Walk and Couch to 5K store a GPS route trail alongside the session summary. The History editor's "find the sets" logic treated any array on the entry as a list of sets to edit — so a 30-minute walk's ~500-600 GPS fixes (recorded every ~3 seconds) showed up as 500+ editable "sets"
  • The GPS route is now excluded from that detection, and route points are recorded roughly once per km travelled instead of once every 3 seconds (plus the very first and last fix), so a typical walk now has a handful of route points instead of hundreds
  • Cardio-type entries (Live Walk, C25K, quick-logged runs/swims/rides) now get a proper Summary edit section in History — Duration, Distance, Elevation and Avg speed — instead of no editable fields at all
  • Manually entering a distance (Log Activity, and the new History summary editor) now has a km/mi toggle. Whatever unit you pick, it's converted and stored as km, same as everywhere else in the app
🐛 Fix: Add Session opened the wrong modal (18.005)
  • Two functions were both named showAddSessionModal — the second silently overrode the first, so tapping "Add Session" always opened an old Swim/Run/Cycle type picker instead of the custom-name dialog. That picker also had a bug where selecting a type didn't close the picker, so it stayed open and made it easy to add several session types in one go without meaning to
  • Add Session now works as one dialog: name it, optionally start from a Swim/Run/Cycle template, or optionally describe what you want and let AI build the exercise list for you
  • A direct Rename button now sits next to Duplicate/Share on every session card, so renaming — including a just-duplicated session — no longer requires entering full edit mode
  • History entries can now have a custom title and a free-text description, editable from the same "Edit" action used for correcting sets — available on every entry, including ad-hoc logs with no sets
🐛 Fix: Live Walk & Couch to 5K under-reporting distance (18.004)
  • GPS distance could come out far short of the real route (e.g. a walk logging a small fraction of its true distance). The filter that rejects implausible GPS jumps used a fixed 80m cap regardless of how long it had been since the last fix — so any stretch where fixes arrived more than ~25 seconds apart (weak signal, background throttling) had its real distance silently discarded rather than counted
  • The jump filter now scales with the actual elapsed time since the last fix, so normal gaps in GPS delivery no longer lose distance. Gaps over 90 seconds (a likely screen-lock/background suspend) are skipped rather than guessed at, so a genuine loss of signal still doesn't get counted as fabricated distance
  • Version numbers are now consistently zero-padded to 3 digits and shown with a V prefix everywhere the app displays them (footer, Data & App Info, About page, changelog)
💾 Crash-proof sessions — auto-resume (18.2)
  • Your active workout, walk or run is now snapshotted continuously — if the app is killed, force-locked or reloaded mid-session, you'll be offered to resume exactly where you left off when you reopen it
  • Time-based activities restore a frozen elapsed time so the dead period isn't counted, and walks/runs come back paused so you can re-engage before continuing
🔒 Keep-awake & lock screen for tracking (18.1)
  • Live Walk and Couch to 5K now hold a screen wake-lock so your phone won't sleep and suspend GPS mid-session — the cause of walks "stopping on their own". It's released the moment you pause or finish, to save battery
  • New Lock screen button during tracking shows a near-black minimal display (battery-friendly on OLED) that blocks accidental Pause/Finish taps — unlock with a deliberate hold
  • Strength sessions get a Keep screen awake checkbox so the screen doesn't blank between sets
  • Footer social links now point to the VT Fitness Facebook page, Community group and WhatsApp chat
🚀 Version 18 — major release (18.0)
  • New branding throughout — refreshed logo, app icons and a crisp circular favicon
  • Couch to 5K — voice-guided, GPS-tracked running plan with a session preview and collapsible breakdown
  • Smarter AI Coach — logs your exercise to History with correct net-of-BMR earned calories, understands device active vs total calories, and scrolls to your latest message
  • Accurate calories — standardised net-of-BMR earned calories across every source, with the full burn shown in History and a device-calorie logger for Garmin/Apple/Samsung
  • Better History — collapsible entries, correct cardio metrics (duration/distance/incline), total weight lifted, and full set editing after the fact
  • Admin analytics — a page-hit counter with visitor journeys and date filters, plus a beta-feature usage tracker
  • Cross-device fixes — medication sync, session stability, and a rewritten multi-line footer with social links
🎨 New logo & icons (17.163)
  • Refreshed the app logo, home-screen icons and favicons with the new VT Fitness branding
🐛 Fix: anonymous hits mis-tagged as a member (17.162)
  • Page hits from logged-out visitors were being attributed to the default account (VT0001). Hits are now only tagged with a member when someone is actually signed in; anonymous visits show no member
📈 Analytics: fixed logging + date filters (17.161)
  • Page hits are now recorded reliably — the initial page load (which shows the dashboard without a tab change) is now logged, and the beacon uses a request path the service worker doesn't intercept
  • The Hits page now has date filters: Today, 24h, 7 days, 30 days, All time, and a custom from/to range
📈 Page hit counter / analytics (17.160)
  • New hits.php analytics page (admin, linked in the footer) — shows pages hit with counts, the host/IP, OS, browser and referrer of each visit, plus top referrers and totals
  • Click any host/IP to see that visitor's full journey through the site — the ordered sequence of pages they viewed, with timing between each
🏃 Cardio shows correctly in History (17.159)
  • Cardio exercises (run, walk, swim, treadmill, cycle, row) now display their real metrics in History — duration, distance, speed/pace and incline/resistance — instead of being mislabelled as kg × reps
  • Cardio sessions now show a total duration/distance summary (in place of the weight total), on both the session-done screen and the History card
  • Editing a logged set now shows the correct fields for cardio (time/distance/speed/incline) vs strength (kg/reps)
✎ Edit logged sets in History (17.158)
  • Expand a session in History and tap Edit sets to correct the weight, reps and rating of any logged set — changes save to your account and update your totals
🏋 Weight lifted, smarter rest & session calories (17.157)
  • The session summary and History now show total weight lifted (kg) again — a 🏋 badge on each strength session plus a big total on the "Session Done" screen
  • Rest timer now only runs between sets, not after the last set of an exercise
  • Session calories now use the actual time you spent training (tracked from start to finish) instead of assuming 60 minutes, and are netted against your BMR like other activities — so earned calories should read more accurately
🐛 Fix: session crash + set logging (17.156)
  • Fixed a crash that broke the workout session screen the moment you typed in a set (weight/reps/cardio) — the set-update handler was missing. Sessions now log and edit sets correctly again
  • History now shows the full logged sets for every exercise, even if your programme changed since (weights, reps/secs, cardio splits and ratings)
  • Skipping an exercise now offers two choices: Do later this session (moves it later in today's queue) or Skip for this session (skips it today, keeps it in your programme)
🧪 Beta feature usage tracker (17.155)
  • New beta.php tracker (admin, linked in the footer) records every start/pause/resume/stop, voice prompt and GPS event for the Walk and C25K beta features — with version, member, device/OS and how each was triggered (user tap, timer, GPS loss, backgrounding, OS suspend)
  • Captures the events that reveal a session "stopping on its own" — background, page-hide, freeze and timer-gap (OS suspend) — to debug the beta tools
🐛 Fix: AI Coach crash on image messages (17.154)
  • Fixed the AI Coach tab failing to open when the chat history contained an image message — image entries now show a placeholder instead of crashing the tab
☰ Collapsible & reorderable Train tiles (17.153)
  • The Couch to 5K and Log device calories cards on the Train tab are now collapsible, drag-to-reorder tiles that remember their order and open/closed state — matching the Dashboard
📟 Log device calories on the Train tab (17.152)
  • New "Log device calories" card on the Train tab — enter a figure from your Garmin/Strava/Apple/Samsung and pick Active calories (logged as-is) or Daily total (the app strips out your estimated resting burn), with optional steps, distance and duration
  • Choosing "Daily total" shows a clear warning that the conversion is approximate and Active Calories is more accurate
⌚ Coach understands device active vs total calories (17.151)
  • The AI Coach now knows the difference between a fitness tracker's daily total calories (which include resting metabolism) and active calories. It won't log a daily total as a workout — it asks for your Active Calories instead
  • Device active calories (Garmin, Strava, Apple/Samsung) are logged as-is with no BMR deduction (they're already net); the app's own MET estimates still have BMR deducted
🔥 Net & total burn shown on Dashboard and Food (17.150)
  • The calorie strip now shows the net "Earned" figure with the full burn beneath it (e.g. "330" · "of 368 burned"), so the BMR difference is visible at a glance on both the Dashboard and the Food tab
🔥 Standardised net earned calories (17.149)
  • Every logged exercise now credits the same way — Walk, C25K, manual quick-logs, programme sessions and AI-Coach logs all count only the net calories above your BMR toward Food and the Dashboard, while History always shows the full burn
💊 Medication sync, net calories & coach scroll (17.148)
  • Your daily medication "taken" checkboxes now sync across devices (they were stored only on the device before; the medication list already synced)
  • When the AI Coach logs an exercise, it now works out the net calories above your BMR: the full burn is recorded in History, while Food and the Dashboard count only the net "earned" calories (burn above resting)
  • The AI Coach now scrolls to the newest message on open and after every new message or reply
🤖 AI Coach can log exercise to History (17.147)
  • Tell the AI Coach you did a workout and it now logs it to your History — earned calories are auto-calculated (activity type × duration × body weight), and it notes the impact on your plan and goals
  • The logged entry appears in History as an expandable card with the exercise summary and its calculated impacts
  • Opening the AI Coach now scrolls straight to the latest message
🔽 Collapsible detail: C25K breakdown & History (17.146)
  • The C25K session breakdown is now an accordion — collapsed it shows a one-line summary (e.g. "Warm-up 5:00 · 8 × (Run 1:00 / Walk 1:30) · Cool-down 5:00"); tap to expand the full interval timeline
  • History entries are now collapsible too — each shows its summary (duration, distance, calories) by default, and expands to reveal the full exercise/set breakdown or GPS detail (elevation, pace, route, C25K week)
🏃 C25K: session preview before you start (17.145 · beta)
  • The Couch to 5K tile now opens into the tracking view first — showing the full session breakdown (every warm-up/run/walk/cool-down interval) and the tracking fields with a single Start button
  • Once you tap Start, the Start button is replaced by Pause and Finish, and the breakdown highlights your current interval as you progress
🛡️ AI Coach: unrestricted mode for admins (17.144)
  • For admin accounts, the AI Coach's app-level guardrails are relaxed: it can proactively update profile, measurements, goals, nutrition and programme without waiting to be asked, discuss any topic (not just fitness), and analyse any image. Standard users keep the conservative fitness-only behaviour.
🏃 Couch to 5K — voice-guided runs (17.143 · beta)
  • New Couch to 5K tile on the Train tab (beta): the full 9-week C25K plan with live GPS tracking
  • Spoken coaching guides every interval — it tells you when to run, when to walk, gives a "get ready to run" heads-up and a halfway cue, and announces completion
  • Tracks distance, pace and route, saves each run to History, and automatically advances to your next session (Week/Run). Previous/Skip controls and a voice on/off toggle included
🟠 Strava token refresh actually works now (17.142)
  • The Strava token refresh was failing with a 401 because the request wasn't sending your session — so once the token expired it got stuck on "token refreshing" forever. It now authenticates correctly and renews as expected. (17.141 added the proactive triggers; this makes the refresh itself succeed.)
🟠 Strava token no longer expires overnight (17.141)
  • The Strava access token is now proactively refreshed when the app opens, when it returns to the foreground, and whenever the "token refreshing" status is shown — so it no longer sits expired after being closed overnight (the old 1am auto-refresh only ran if the app happened to be open at 1am).
🔑 AI key syncs to your account · login/name fixes (17.140)
  • Your AI/licence key is now saved to your account per device, so it's automatically restored when you sign in on a device that cleared its cache — no more re-entering it
  • Fixed the header showing "User 1" after signing in — real display names now load on login
  • Further hardened the login flow to prevent the sign-in loop
🔄 Reliable cache refresh for installed apps (17.139)
  • "Refresh Cache" now forces a genuinely fresh download of the app, so the installed/pinned app can't get stuck on an old version (the previous reload could still be served from the browser's disk cache).
🔍 Android search — event-independent fix (17.138)
  • Admin user search now updates from a background value-watcher, so it filters correctly on Android/Edge keyboards that don't send typing events to the page (text was appearing but results stayed blank). Verified the filter renders from a value change alone.
🔓 Login loop, emulation reset & search fixes (17.137)
  • Fixed a login loop: signing into an account different from the current one now hides the sign-in banner and completes properly
  • Leaving emulation now resets the header/display name back to your own account
  • Hardened user-switching so an empty profile can't revert to a broken state
  • Admin search wiring moved earlier and made more robust (events + value-poll) for Android/Edge keyboards
🔍 Android admin search & beta visibility (17.136)
  • Admin user search now uses a value-poll fallback while the box is focused, so it filters reliably on Android keyboards that don't fire standard input events
  • Beta features now appear for beta users again (this was blocked by the start-up crash fixed in 17.135)
🐛✅ Critical fix: app crash on some accounts (17.135)
  • Fixed a startup crash that stopped the app initialising on newer accounts (whose registry entry hadn't loaded yet). Because start-up aborted, data never loaded or saved on those accounts — this was the underlying cause of the "profile not persisting" issue on some devices.
🛡️ Admin: member numbers, inactive filter & delete (17.134)
  • Error Log and Reports now show the member number (VT0000) instead of the internal user key
  • Admin search has an "Include inactive accounts" checkbox (active-only by default); inactive accounts are badged
  • Admins can now permanently delete an account and all its data from the record editor (with confirmation)
  • Admin user search now handles Android predictive/gesture keyboards (compositionend) so typing filters correctly
🐛✅ Critical fix: empty profiles now save (17.133)
  • Fixed a serious bug where edits to a profile that was empty in the database were silently lost. An empty profile was loaded as a list rather than a record, so saved changes serialised to nothing — this affected new/empty accounts both on-device and when an admin edited them via emulation. Profiles are now always handled as proper records.
👁️ Emulation fixes (17.132)
  • Emulation now loads the emulated user's History (previously it showed the admin's own history)
  • The Profile, Food and Settings tabs no longer show a "sign in" prompt while emulating — the admin is already authenticated
🔧 Walk tuning, cloud sync button & fixes (17.131)
  • Walk: Pause/Finish hold reduced to 1 second; distance now shown to 3 decimal places
  • New “Sync this device to cloud” button in your Profile — uploads this device's data to your account (must be signed in), with a success/error message
  • Fixed an error that could break the AI Coach intro on some devices (empty/partial programme data)
  • Admin user search is more reliable (retries if the directory hasn't loaded, and handles Android keyboards better)
🚶 Walk tracking tweaks (17.130 · beta)
  • Pause and Finish now require a 2-second press-and-hold (with a fill indicator) to avoid stopping a walk by accident
  • Live stats now update without redrawing the buttons, so a hold is never interrupted
  • Distance is truncated to 2 decimal places
  • Screen wake-lock removed for now, to test whether GPS keeps tracking with the screen locked
🚶 Walk live GPS tracking (17.129 · beta)
  • New Walk — beta tile on the Dashboard (visible to beta users only) with a Start Live Track button
  • Live tracking records duration, GPS route, distance, elevation gain, speed and estimated calories, with Pause/Resume and Finish controls
  • Finishing the walk saves it to your History; the screen is kept awake while tracking where supported
🔍 Emulation save diagnostics (17.128)
  • While emulating, the banner now shows a live save status for every change (“Saving…”, “Saved to their record”, or the exact error) so cloud-save problems are visible instead of silent
🔄 Sync fixes: sign-in upload & full emulation saves (17.127)
  • Signing in on a device that was used in local mode now uploads that device's local-only data to the cloud (previously this only happened when switching accounts, not when signing into the account you were already using)
  • While emulating, name/email/display-name edits now save too (previously only the main profile blob saved; the name fields silently failed)
🎚️ Moderator permissions & colour pickers (17.126)
  • Moderators can now edit free and premium users in the admin panel, but can't change anyone's role (free/premium/moderator/admin status)
  • The accent colour and RGB fields in the admin record editor now have a colour picker, with the text values kept in sync
☁️ Cloud sync fixes (emulation & local data) (17.125)
  • Edits made while emulating a user now save to that user's record in the database (previously they only updated the local cache and appeared to vanish)
  • When an account signs in, any data it had only stored locally is now uploaded to the cloud — so a profile is no longer stranded on one device
✉️ Invite new users, admin search & emulation rules (17.124)
  • New "Invite a new user" field under Linked Profiles — enter an email to send a one-time magic link that opens their new, empty profile (no password needed to start)
  • Admin accounts can no longer be emulated
  • The admin user directory now shows results only once you start typing a search
🆔 Member numbers & admin record editor (17.123)
  • Every profile now shows a read-only member number (VT + zero-padded account id, e.g. VT0007) to the left of the profile photo
  • The Admin tab user list is now a searchable directory — search by member number, email, display name, first name or surname
  • Selecting a user shows their full database record; admins can edit any field (identity keys aside) and submit changes, including setting a new password
  • Password management is now disabled for demo accounts
🚫 Demo account data protections (17.122)
  • Demo accounts can no longer remove their data or delete their account — the controls are hidden and the actions are blocked on the server too
⚙️ Settings in Profile, tab rename & logged-out fixes (17.121)
  • Everything from the separate Settings page (Licence, Integrations, Data & Device) now lives as tiles in the Profile tab — settings.php redirects there
  • The Health tab is now called Profile
  • When signed out, the app now opens on the Profile tab (with sign-in); signed-in users still land on the Dashboard
  • The Admin tab and the "Admin" status badge no longer appear when no one is signed in
🔐 Profile list privacy (17.120)
  • The Linked Profiles tile and the user switcher now only show accounts present on your own device (you, plus anyone signed in here) — they no longer list every registered user. Accounts you've actually linked with still appear in the Profile Link Requests section
🔒 Demo profile locking, copy privacy & emulation tweaks (17.119)
  • Copy-to-profile now only lists linked accounts — previously it exposed every profile on the system
  • Demo profile fields are read-only for the public; an admin can still edit them while emulating the account
  • Removed the "EMULATING" overlay on the avatar (the banner remains as the emulation indicator)
  • Demo account details refreshed (display names, dates of birth and gender)
🎭 Demo avatars & always-on demo login (17.118)
  • The demo accounts now have gender-appropriate avatars and their gender is set correctly, so the right avatar and accent colour show throughout the app
  • Demo accounts are always treated as logged in: the About-page links sign you in with one tap (passwordless), and a demo session is re-established automatically on return visits — no sign-in prompts or GDPR gate
  • New passwordless demo_login endpoint, restricted server-side to accounts whose type is Demo
👥 User types & demo accounts (17.117)
  • The per-user beta flag is now a three-way user type: Beta (admins), Demo (public demo accounts), and Standard (everyone else), set from the Admin tab
  • Two public demo accounts (John Doe — muscle gain; Jane Doe — fat loss) are now featured on the About page with one-tap sign-in links
  • Demo accounts bypass the GDPR consent gate and are excluded from the data-retention sweep
🐛 Error log viewer now loads from the database (17.116)
  • Fixed the paginated query in the error log viewer that failed under emulated prepared statements (bound LIMIT/OFFSET were sent as quoted strings, causing a SQL syntax error and forcing the flat-file fallback). The DB view — with search, filters and per-entry User/Device/OS/Last-action — now works
🔧 Startup error & log viewer fixes (17.115)
  • Fixed a ReferenceError in the user-registry loader that threw an unhandled promise rejection on every app load (a response variable was out of scope in the profile-image prefetch)
  • Error log viewer now explains why it has fallen back to the flat errors.log file (e.g. no DB connection, or the vt_errors table missing) instead of silently showing raw text
🐞 Error log diagnostics (17.114)
  • Flat-file error log now records the user, device, OS and last action alongside each error — previously these were saved to the database but omitted from the errors.log file
  • Unhandled promise rejections and JS errors now capture the top stack frames (function & line), making the source of an error far easier to locate
🛡️ Admin tab & beta access (17.113)
  • New top-level Admin tab, visible only to admins and moderators — user management moved here from the Profile page for a cleaner, dedicated workspace
  • Per-user beta access flag, toggleable by admins from the Admin tab to gate early-access features
  • Beta is enabled for admin accounts on rollout; moderators see each user’s beta status read-only
🆓 Free & Premium accounts
  • Free accounts log food manually — known foods fill in automatically from the shared library; new foods you enter yourself
  • Self-correcting food library: manually-entered foods are flagged unverified and automatically corrected the next time an AI lookup encounters them
  • Premium features unlock with your own AI Functions Key: AI food logging, photo analysis, AI Coach, and the daily nutrition report
  • Every AI-gated control shows a clear “Premium Feature” badge until a key is added
  • About page rebuilt with a full Free vs Premium comparison
👥 Multi-user & accounts
  • Self-service registration — anyone can create an account (email + password), scaling to hundreds of users
  • AI Functions Keys stored per-user in the database, never in shared config files
  • Two account links under the avatar: Log in / Register when signed out, Profile / Log out when signed in
  • Profile Settings password-locked per user
📧 Daily nutrition report
  • Personalised end-of-day email: how you did against every target, your biggest gap, and 2–3 specific AI-generated food swaps for tomorrow
  • Queued delivery with an 11pm floor — no server cron needed; sends on next app open after 11pm, or first login next day
  • Each report uses that user’s own AI key; users without one get a rule-based summary
📐 Layout & responsiveness
  • Complete CSS Grid layout rewrite: header and footer frozen, content scrolls cleanly between them on every device
  • Android width and scroll issues resolved (viewport-fit, dynamic viewport height, explicit grid columns)
  • All Plan tab tiles collapsible, with per-user persisted state
🍽 Food logging
  • Named recipes and meal kits (Gousto, HelloFresh) split into individual ingredients rather than one combined entry
  • Multi-select food copy to another profile
  • Shared “All Foods” library with per-user quick-add personalisation and reliable emoji icons on Android
  • Food quantities normalised so “strawberries” and “2 strawberries” group as one item
🐛 Diagnostics & fixes
  • Error log now captures logged-in user, device, operating system and last action for faster debugging
  • Progress tile correctly anchors Week 0 to the programme start weight and date (timezone-safe)
  • This-week figure shows last measured weight against plan target
Revisions: 17.000 Major layout 17.012 Shared library 17.013 Meal splitting 17.015 Error diagnostics 17.100 Multi-user + queue 17.101 Free accounts
V14–16 Jul 2026 ● Stable Latest: V16.000

The intelligence and usability release. V14 adds AI-driven calorie estimation from exercise, a fully featured history management system (long-press multi-select, merge with field comparison, persistent edit and delete), food shortcut personalisation, and a complete settings architecture. The food and dashboard nutrition tiles now share identical layout and data. Public-facing pages (About, Changelog, Reports) complete the app's web presence.

🔥 Calorie intelligence
  • MET-based calorie estimation for all exercise — walk (3.5), run (8.0), swim (6.0), row (7.0), cycle (7.5), gym sessions (5.0) — uses your logged body weight. Estimated kcal shown on history cards and in the session save toast
  • Earned calories flow from exercise log into the food tab and dashboard: Base + Earned = Total breakdown with manual override input, matching on both tiles
  • Adhoc activities auto-estimate kcal from MET when calories field is left blank
📋 History management
  • Long-press any history card (500ms) to enter multi-select mode with vibration feedback; 12px displacement threshold prevents false triggers from finger tremor
  • Merge comparison table: each selected entry shown as a column, recommended source marked ✦, tap any cell to pick the winner per field. Session Data field shows per-exercise set summary so you never lose gym data during a merge
  • Inline edit modal for any entry — duration, distance, HR, calories, notes
  • Single and multi-select delete with confirmation
  • All history operations (merge, edit, delete) now write to vt_history table via proper API — changes survive page reload
🍽 Food tab
  • Today tile layout and data identical to dashboard nutrition tile: large kcal figure, earned-adjusted progress bar, 3-column protein/carbs/fat grid
  • Medications, supplements and alcohol reminders shown on both food tab and dashboard, kept in sync
  • Food shortcuts long-press: Edit macros (saved as per-user override) or Remove from shortcuts (per-user hidden list) — works in grid and View All modal
🏋 Training sessions
  • Session tiles collapsible in Train tab — state persisted to DB, survives across browsers
  • Edit mode: ↑ / ↓ arrow buttons for reliable mobile reorder (replaced broken touch-drag)
  • Skip exercise queues it one place later — if all remaining are skipped the session completes
⚙️ Architecture & pages
  • Settings moved to standalone /settings.php — licence, integrations, data export
  • About page (/about.html) — friendly description and £4.99 one-off licence CTA
  • Reports page (/reports.php) — admin-only live dashboard: user accounts, profile completeness, food days, exercise sessions per user, DB size
  • Water shortcut (/water.php) — home-screen-friendly standalone page for one-tap +750ml logging with animated drop progress and persistent cookie auth
  • Consistent VT monogram logo (VT letterforms + red ECG + teal FITNESS) across all pages
  • Footer standardised: version number → changelog, ⚙ → settings, About link; Reports link visible only for admin
🐛 Key fixes
  • Food tab today tile blank on load — earnedF declared after the block that used it (temporal dead zone ReferenceError). Fixed by moving declaration before first use
  • Footer was fixed to viewport bottom — moved inside scroll container
  • Adhoc exercise logged twice — redundant hist.push() removed from saveAdhocSession
  • Multi-select second tick not showing — label was double-firing toggle; stopPropagation added
Revisions: V16.000 Major V16.000 V16.000 Timestamps V16.000 New-user data isolation V16.000 Cal estimation + history UX V16.000 Long-press fix V16.000 Footer + double-log V16.000 Shortcut delete V16.000 Food tile + merge modal V16.000 Session data in merge V16.000 Earned cal breakdown V16.000 Train edit + skip queue V16.000 Food tab blank fix V16.000 History persistence V16.000 Logo + About page V16.000 Reports page V16.000 Water shortcut
V13 Jul 2026 Stable

The security and hardening release. V13 locked down the API, introduced proper session-based authentication across all data endpoints, and stripped all hardcoded personal data from the codebase. The error logging system and client-side JS diagnostic pipeline were also added in this version.

  • All API actions converted from GET to POST — prevents .htaccess interception that was serving the setup response for every request
  • Session token authentication on every data endpoint (load, save, food, water, history, Strava). Unauthenticated visitors see only a sign-in prompt — no data is read or written without a valid token
  • list_users requires authentication — prevented unauthenticated access to names and emails
  • All hardcoded personal data removed: seeded sessions, milestone weights, food entries, Allopurinol references, Google Sheets ID, Strava athlete name
  • New users no longer inherit another user's DB record on first registration
  • Client-side JS error logging to vt_errors DB table; errorlog.php viewer for admin
  • safeRender() wrapper on all tab renders — catches errors and shows diagnostic rather than blank screen
  • Renpho screenshot scanner in Body Constitution tile — AI vision extracts all 13 body metrics from a screenshot
  • 8 new Renpho fields: Fat-Free Mass, Skeletal Muscle %, Subcutaneous Fat %, Body Water %, Bone Mass, Protein %, BMR, Metabolic Age
  • AI Coach can now update Goals tab (start weight, target weight, target date) and Nutrition targets
  • Photo gallery: profile picture section separated from body composition photos (excluded from AI analysis)
  • Duplicate div#pg-history caused History, Coach, Profile and Config tabs to nest inside it and all be hidden
  • localStorage quota-safe lsSet() helper — evicts oversized history cache on QuotaExceededError
Revisions: V13.000 Major V13.016 Critical tab fix V13.017 UX polish V13.018 API auth V13.019 Gallery + auth V13.020 Renpho AI scanner V13.021 list_users auth V13.022 Hardcoded data removed
V12 Jun–Jul 2026 Legacy

The integrations and social release. V12 connected VT Fitness to Strava, added body composition photo analysis with AI, built the linked users system, and delivered a fully featured active session experience with cardio tracking, rest timers and set ratings.

  • Strava OAuth 2.0 — paginated sync of all activities with deduplication, HR, distance and calorie import
  • Body composition AI: multi-angle photos, face and genital blurring before save, private gallery with EXIF date extraction
  • Active session UX: RATS ratings per set (Too Easy / Achieved / Tough / Failed), skip with reason, rest timer with audio beeps, dual-phase plank timer
  • Cardio fields for treadmill, bike, static row and swim sessions within programme sessions
  • Adhoc activity capture (Walk, Treadmill, Swim, Row) via bottom-sheet quick-log
  • Linked Users: email-based link requests, accept/reject/cancel, invite unknown emails via magic link
  • Food quick-add grid: top 25 scored from history, 24 shown with View All overflow
  • Exercise calorie priority chain: manual override → adhoc cals → Strava → Apple Health → MET estimate
  • 90-day session tokens, magic link registration and password reset, email verification codes
  • Service worker: no-cache on POST requests, hostname guard for dev environments
V8–V11 2026 — Foundations Legacy

The foundations releases. Built the entire single-page PWA architecture from scratch: PHP/MySQL backend, vanilla JS frontend, full auth system, all core tracking tiles, the AI Coach, and the licence model.

  • Single-page PWA — installable, service worker, manifest, icon pipeline
  • PHP/MySQL REST API — all state DB-persisted with localStorage offline fallback
  • Multi-user system: dynamic registry, accent colours, gender-specific avatars, 90-day session tokens
  • Email + password auth with magic link support and login modal
  • Dashboard: collapsible/draggable tiles, per-user layout saved to DB
  • Training programme A (Push+Core), B (Pull+Legs), C (Cardio/Core) with set-by-set tracking
  • Food logging: manual entry, AI photo recognition, macro tracking, water tracker (2,500ml/day)
  • Recovery tab: HRV, RHR, sleep, stress, VO2, steps, unified health fields with source priority
  • Goals tab: 10-week progressive plan, dynamic milestones, weekly weight targets
  • AI Coach: conversational fitness coach with cross-tab data updates and programme management
  • Medication daily checklist — auto-elevated to dashboard top when doses outstanding
  • Fitness Age calculator from VO2 max, HRV, RHR, sleep quality, BMI and session frequency
  • Licence system (sk-ant- key) unlocks AI features, display name editing, avatar colouring