Skip to content

TrainGrid

A weekly training planner whose plan lives as files in the repository: edited locally, published by pushing to Git.

Role
Solo: product, design, engineering
Year
2026
Status
Live
Type
Product
train-grid.vercel.app
TrainGrid session template “Lower A”, listing back squat, pause squat and Romanian deadlift with sets, rest and target effort.

01Problem

Why it exists

I train for running and strength in the same week and wanted one straight answer to “what am I doing today?”. Fitness apps wanted accounts, feeds and streaks. A spreadsheet had no structure at all.

I needed a planner, not a logger. Other tools already record what happened; nothing I tried was good at deciding what should.

02Approach

How I went about it

The plan is data I own. Session templates are Markdown files with front matter, and the schedule is a single JSON file. Locally, Server Actions write those files directly. The hosted site is a read-only view of whatever is committed, so publishing a new week is a git push.

Before writing code I wrote the list of things the project would not use — a database, auth, a state library, a calendar kit, a date library — each with its reason. That list is still in the technical design, and it is why the project stayed small enough to finish.

03Architecture

Decisions that shaped it

WRITEDEPLOYREADLocal appServer Actions · fsdata/JSON + MarkdownGitcommit · pushHosted buildread-onlyResolverlink or snapshot
One set of files, two modes: writable locally, read-only when hosted.
  1. 01

    Files as the database

    The data folder is the runtime source of truth. Every write goes to a temporary file first and is then renamed into place, so an interrupted save cannot leave half-written JSON behind.

  2. 02

    One switch for read-only mode

    A single runtime check decides whether the app is published. When it is, every write path is disabled and visitors see a short notice instead of the editor. The same codebase serves both modes.

  3. 03

    Live link or snapshot

    A scheduled session points at its template until it is customised, at which point it keeps its own copy. Editing a template updates the sessions still linked to it and leaves customised ones alone. Deleting a template first copies its content into every session that depended on it.

  4. 04

    ISO weeks without a date library

    Weeks are addressed as 2026-W36. A small local utility handles the arithmetic and is tested across year boundaries, 53-week years and leap days.

04Build

What it does

  • Monday-to-Sunday planner with timed and untimed sessions
  • 18 seed templates across running, strength, plyometrics, warm-ups and cooldowns
  • Duplicate a week, then edit the copy without touching the original
  • JSON export and import with validation that rejects malformed backups
  • Equipment tags and video references on individual workout items
  • A single-day view on small screens, tested at 390px
Application
Next.js 16 (App Router) · React 19 · TypeScript · Tailwind CSS 4
Data
Markdown + front matter · JSON · Server Actions over Node fs
Quality
Vitest · Playwright · ESLint
TrainGrid template library with running, strength and plyometrics templates.
The template library: running, strength, plyometrics, warm-ups and cooldowns.
TrainGrid weekly planner in published read-only mode, showing a Monday to Sunday grid.
Published mode. The hosted site is read-only and ships with an empty week on purpose.

05Outcome

Where it stands

Live as a read-only published view; the writable planner runs locally.

The repository records 38 unit tests and 13 Playwright journeys passing, covering the week arithmetic, the template-versus-snapshot rules and the export/import round trip.

The lesson I took from it: constraints written down early are cheaper than features removed late.

Checked against the repository on 11 November 2026