Skip to main content
Back to projects

StandUp Tracker

Reduce cognitive load. Your commits already know what you did.

A full-stack developer tool that solves a specific friction: reconstructing yesterday's work across GitHub, Jira, and Slack from memory every morning. Groups commits by day and branch, links tasks automatically, and formats updates for every tool that needs it.

StandUp Tracker screenshot

The Problem

Engineers context-switch constantly: a bug for one team, a feature branch, a pairing session. Then 9am comes and you have to reconstruct your yesterday from memory while someone is already talking, then manually update GitHub, Jira, Slack, and smart goals. That cognitive load adds up.

The Solution

Standup Tracker reduces that tax. Your commits already know what you did, grouped by day and branch, with your tasks already linked. What you complete gets formatted for every tool that needs it, so the update takes seconds instead of minutes. Tasks don't go stale because the work you're already doing becomes the communication.

Key Features

  • Dual OAuth (GitHub + Jira) with token refresh and secure storage
  • Optimistic UI with race-safe rollback using TanStack Query
  • WCAG-compliant keyboard navigation (skip links, focus management on route transitions)
  • Commit grouping by day and branch with smart selection
  • Automatic task linking from commit messages
  • Export formats for Slack, Markdown, Jira, and plain text
  • PostgreSQL with Drizzle ORM for type-safe queries
  • Playwright E2E suite against real Vercel preview deployments

Challenges & Solutions

Optimistic UI with race-safe rollback

When a user creates a standup, the UI updates immediately. If the request fails, it rolls back. The subtlety is that a naive rollback restores the current cache state, which may have changed if another request landed in the meantime.

How I solved it:

Snapshot the cache before the mutation and cancel any in-flight background refetches. The `cancelQueries` call makes it race safe: without it, a background refetch could overwrite the snapshot before the optimistic update lands.

OAuth cookie bridge across serverless functions

Jira OAuth requires two serverless functions that share no memory. The redirect handler knows the user's ID and generates a CSRF state. The callback handler needs both, but has no way to get them.

How I solved it:

A short-lived HttpOnly cookie. The redirect encodes state + userId into the cookie. The callback reads it, validates the CSRF state, and clears the cookie. SameSite=Lax (not Strict) is required for the OAuth redirect to work.

The sr-only ghost that broke 13 tests

Adding a screen reader live region to toasts caused 13 Playwright tests to fail. The live region was working perfectly. The tests were wrong.

How I solved it:

Scoped toast assertions to Sonner's `[data-title]` attribute, which exists only on the visible toast element. The sr-only div became invisible to the test, and the accessibility feature stayed.

What I Learned

  • Cognitive load is a tax. Reducing it for developers should be a primary design goal.
  • OAuth across serverless functions requires thinking about stateless bridges, not just copying patterns.
  • Accessibility is not a checklist. A working feature can break your tests, forcing you to write better, more resilient assertions.
  • The right place to handle null is at the boundary where data enters the component tree, not inside every leaf that uses it.
  • Types should describe reality, not paper over it. `?? undefined` in adapter code is a code smell.

Tech Stack

  • React
  • TypeScript
  • Radix UI
  • Tailwind CSS
  • Zustand
  • React Query
  • PostgreSQL
  • Drizzle ORM
  • Playwright
  • Vercel
  • GitHub OAuth
  • Jira OAuth