- Constraint
- Two near-simultaneous final votes could otherwise reveal and broadcast the same round twice.
- Decision
- Make the voting-to-revealed transition atomic in the repository boundary.
- Why it mattered
- Every connected client receives one authoritative transition, even under concurrency.
- Trade-off
- The server owns more lifecycle logic instead of treating sockets as simple relays.
Scrum Poker
A real-time planning room with hidden voting, atomic reveals, live roles, round history, and a clean handoff after estimation.
Role & scope: Conceived the product, made the business decisions, and implemented it end to end as the sole engineer.

Read this first
The system at a glance.
- What the product does
- A collaborative estimation product for distributed engineering teams, usable with or without an account.
- Who it serves
- Distributed product and engineering teams estimating work together in live planning sessions.
- What makes it different
- The full estimation loop works without signup, while a flat facilitator plan adds the backlog handoff without per-seat friction.
- My contribution
- Conceived the product, made the business decisions, and implemented it end to end as the sole engineer.
- Proof point
- Every connected client receives one authoritative transition, even under concurrency.
Capability flow
How the system works.
Each step connects a user action to the system capability behind it.
-
Open a room
Authenticated teams or capped guest sessions create a persistent planning space.
-
Synchronize participants
Facilitator, voter, and spectator roles update as people join, leave, or transfer control.
-
Vote without anchoring
The server broadcasts who has voted but never exposes a value while the round is active.
-
Reveal atomically
The final eligible vote can reveal once, with average, median, range, and mode calculated for the room.
-
Carry the decision forward
Final estimates, revotes, and round history preserve the planning outcome for the next workflow.
Engineering judgment
Decisions that shaped the system.
- Constraint
- The first visible estimate can bias everyone who has not voted yet.
- Decision
- Broadcast participation state during voting, but withhold values until reveal.
- Why it mattered
- The interface supports independent estimates without hiding team progress.
- Trade-off
- Clients need separate active-round and revealed-round payloads.
Technical evidence
Skills backed by this system.
Open any skill to see the other products and professional work connected to it.
- React Renders the room, role controls, deck interactions, results, and history as one responsive workflow.
- TypeScript Defines shared room, participant, vote, reveal, and billing contracts across the real-time system.
- Vite Builds the fast single-page product surface and its route-based feature delivery.
- Astro Delivers the marketing surface with server-rendered pages and React islands.
- TanStack Router Organizes the web application with typed file-based routes for rooms, authentication, and dashboards.
- TanStack Query Manages server state and cache invalidation across room, account, and billing workflows.
- Zustand Maintains client-side room state and real-time interaction state alongside server data.
- WebSockets Keeps room membership, round state, votes, and facilitator changes synchronized live.
- Socket.IO Defines explicit client/server events for joining, voting, revealing, closing, and role changes.
- OpenAPI Publishes an OpenAPI 3.1 contract for the Hono API and its documented route schemas.
- REST APIs Exposes HTTP endpoints for rooms, authentication, analytics, billing, and content management.
- Zod Validates API inputs, environment configuration, and shared domain payloads at system boundaries.
- Testing Uses Vitest coverage across API routes, services, repositories, real-time flows, and shared UI.
- PostgreSQL Persists rooms, participants, rounds, votes, sessions, and the history behind revotes.
- Drizzle Keeps the relational schema and ordered migrations shared between API services and tests.
- Vercel Delivers the customer-facing planning room as a production web application.
- Railway Runs the backend services that coordinate persistent rooms and live collaboration.
- Docker Packages the service runtime into a consistent deployment unit for the backend environment.
- Nx Monorepo Coordinates the API, web, marketing, admin, and shared packages through Nx task orchestration.
- Better Auth Supports sessions, password flows, magic links, and optional Google sign-in around persistent rooms.
- Stripe Connects the optional Pro subscription to product capabilities after the core estimation loop.
Technology stack
- React
- TypeScript
- Vite
- Astro
- TanStack Router
- TanStack Query
- Zustand
- Socket.IO
- OpenAPI
- REST APIs
- Zod
- Testing
- PostgreSQL
- Drizzle
- Vercel
- Railway
- Docker
- Nx Monorepo
- Better Auth
- Stripe