Stride

One workspace where a task, the time you plan for it and the session you spend on it are the same record.

Context
Independent product, Feb to Jun 2026
My part
Everything: product, design, frontend, schema and deployment
Stack
Next.js, React 19, TypeScript, Supabase, Clerk, OpenAI Responses API, Vitest
Year
2026
Stride Today view

The problem

Students keep tasks in one app, their week in a calendar and their focus sessions in a timer. None of them know about each other, so a deadline never learns how much time was planned for it, and a finished session never counts toward the task it was for.

Stride is built around one loop: capture a task, decide what matters now, plan real time for it, work in focused sessions, and adjust tomorrow from what actually happened. The loop only works if every step writes to the same data.

How it works

  • CaptureQuick Add reads projects, deadlines, priority, estimates, reminders, recurrence and labels straight from the line you type.
  • PlanCalendar blocks are stored rows linked to a task, so planned minutes add up against its estimate.
  • FocusTimer sessions are saved against the task or block they were started from.
  • ProjectsList and board views, sections, members, assignees and comments on the same task model.
  • TodayAn optional AI overview summarises the day from what is actually on it.

Capture

Stride Quick Add dialog
Quick Add turns one typed line into a structured task.

Plan

Stride calendar with task-linked focus blocks
Planned blocks sit beside the tasks they belong to.

Focus

Stride focus timer
Sessions are recorded against the planned work.

Projects

Stride project workspace
Sections, board and list views over the same tasks.

Decisions

  • Planned time is a row, not a calendar event

    Each block is stored with the task it serves. That lets the app compare planned minutes with the estimate and mark a task unplanned, partly planned, fully planned or overplanned, which is the signal a student actually needs on a Sunday night.

  • Clerk for identity, row-level security for access

    Clerk signs people in; its token is passed to Supabase on both the browser and server clients, and 64 Postgres policies decide what each person can read or write, separating their own data from projects shared with them. The database, not the UI, is the boundary.

  • Optimistic writes that ignore their own echo

    Edits show instantly, then Realtime brings the same change back from the database. Writes that the client made itself are marked so their echo is skipped, which keeps quick edits from flickering or undoing each other while changes from other tabs and members still arrive.

  • The AI summary gets a strict, small input

    The Day Overview route is authenticated, rejects payloads over a size limit, validates every field with a strict schema (task titles, timing, estimates and planned blocks, all capped), calls the model server-side, sanitises the reply and never caches it. The app works fully without it.

  • Test the logic people will notice when it’s wrong

    Deadlines, recurrence, reminders, estimates, ordering, filters and the Quick Add parser each have their own tests. Those are the parts where a quiet off-by-one day costs a student a deadline.

Results

  • 16

    Tables in the final schema, from tasks and steps to planned blocks and focus sessions

  • 64

    Row-level security policies separating personal data from shared projects

  • 62

    Tests across 14 files on dates, recurrence, reminders, planning and parsing

Stride is an archived MVP built alone over five months and 68 commits. It had no public user base, so there are no adoption or impact numbers to report; the source, screenshots, tests and final schema are the evidence.

Limits

  • A portfolio MVP, not a production service; the live deployment has been retired.
  • Tests cover business logic; browser-level and end-to-end coverage are thin.
  • Collaboration exists as foundations (members, assignees, comments, realtime) but was never tested with real teams.
  • The schema grew through many migrations and was archived as one baseline, not a clean one-command rebuild.