Skip to content

Slashgear/poker-planning

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

243 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Poker Planning

CI/CD Production

Collaborative poker planning web application for agile team estimation using the Fibonacci sequence.

Screenshots

Click to view screenshots

Homepage

Create a new room to start a planning session.

Homepage

Join Room

Share the room code with your team members.

Join Room

Voting Session

Team members vote anonymously using Fibonacci values.

Voting Session

Results

View vote distribution and average when revealed.

Results

Consensus

Celebrate when everyone agrees!

Consensus

Features

Core Functionality

  • Dynamic rooms with shareable 6-character codes
  • Real-time synchronization with SSE (Server-Sent Events)
  • Anonymous votes until collective reveal
  • Fibonacci sequence for estimation (1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ?, ☕)
  • Keyboard shortcuts for quick voting (1-9 keys for first 9 values)
  • Automatic statistics (average, vote distribution)
  • Confetti celebration when all votes match
  • Session persistence via httpOnly cookies (2 hours)
  • Auto-cleanup of inactive members (5 minutes)
  • Member management - any member can remove others

Progressive Web App (PWA)

  • Installable on mobile and desktop devices
  • App-like experience with standalone display mode

Accessibility & Quality

  • WCAG compliant with proper ARIA attributes and semantic HTML
  • Keyboard navigation throughout the entire application
  • Screen reader support with live regions and announcements
  • axe-core automated accessibility testing in development

Tech Stack

Frontend

  • Preact 10 with TypeScript
  • Vite 7 for build and dev server
  • Tailwind CSS 4 for styling
  • preact-iso for client-side routing

Backend

  • Hono - Lightweight web framework
  • Server-Sent Events for real-time synchronization
  • Node.js with TypeScript
  • Redis/Valkey - Distributed storage for horizontal scaling
  • ioredis - Redis/Valkey client with connection pooling

Tests

  • Playwright for end-to-end tests
  • Vitest for unit tests
  • k6 for load and performance testing

Linting & Formatting

  • oxlint for fast JavaScript/TypeScript linting
  • oxfmt for code formatting

Quick Start

Prerequisites

  • Node.js 24+
  • pnpm 10+
  • Redis or Valkey (local or remote instance)

Installation

# Clone the repository
git clone <url>
cd poker-planning

# Install dependencies
pnpm install

# Install Playwright browsers (for tests)
pnpm exec playwright install chromium

# Configure environment variables
cp .env.example .env
# Edit .env and set your REDIS_URL

Running with Docker Compose

Full stack (Redis/Valkey + Application) - Production-like environment:

# Build and start everything
docker-compose up -d

# View logs
docker-compose logs -f

# Stop everything
docker-compose down

# Application available at http://localhost:3001

Redis/Valkey only (for local development with hot-reload):

# Start only Redis
docker-compose up -d redis

# Stop Redis
docker-compose down

# Set in .env:
REDIS_URL=redis://localhost:6379

# Then run the dev servers manually:
# Terminal 1: pnpm run dev:server
# Terminal 2: pnpm run dev

Storage Backend Setup

The application is compatible with both Redis and Valkey (a fully open-source fork of Redis maintained by the Linux Foundation).

Valkey with Docker (recommended for open-source stack):

docker run -d --name poker-valkey -p 6379:6379 valkey/valkey:alpine

Redis with Docker:

docker run -d --name poker-redis -p 6379:6379 redis:alpine

Local Valkey installation:

# macOS
brew install valkey
brew services start valkey

# Linux (Ubuntu/Debian)
# Add Valkey repository
curl -fsSL https://packages.valkey.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/valkey-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/valkey-archive-keyring.gpg] https://packages.valkey.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/valkey.list
sudo apt-get update
sudo apt-get install valkey
sudo systemctl start valkey

Local Redis installation:

# macOS
brew install redis
brew services start redis

# Linux (Ubuntu/Debian)
sudo apt-get install redis-server
sudo systemctl start redis

Managed services (for production):

Both Valkey and Redis are protocol-compatible, so you can use managed services:

  • Scaleway Managed Database for Redis
  • AWS ElastiCache (supports both Redis and Valkey)
  • DigitalOcean Managed Redis
  • Any Redis-compatible service

Example configuration:

REDIS_URL=redis://username:password@your-instance.cloud:6379

Development

The application requires 2 servers running in parallel:

# Terminal 1 - API server
pnpm run dev:server

# Terminal 2 - Vite frontend
pnpm run dev

Then open:

Usage

  1. Create a room: Click "Create a Room" on the homepage
  2. Share the link: Copy the room URL to invite team members
  3. Join: Each member enters their name to join
  4. Vote: Click a Fibonacci card to vote
  5. Reveal: Any member can reveal all votes
  6. Celebrate: Confetti appears when everyone agrees!
  7. Reset: Start a new estimation round

Tests

End-to-End Tests (Playwright)

# Run all E2E tests
pnpm test

# Interactive mode with UI
pnpm test:ui

# With visible browser
pnpm test:headed

# View HTML report
pnpm test:report

Unit Tests (Vitest)

# Run unit tests
pnpm test:unit

Load Tests (k6)

Load testing ensures the application can handle expected traffic and identifies performance bottlenecks.

Prerequisites: Install k6

Standard Tests (runs in CI)

# Quick validation (1 user, 1 minute)
pnpm run test:load:smoke

# Basic workflow (20 concurrent users, 3.5min)
pnpm run test:load:basic

# Spike test (sudden surge to 100 users)
pnpm run test:load:spike

Heavy Tests (manual/nightly/releases)

These production-ready tests run in a dedicated GitHub Actions workflow to avoid impacting CI performance:

# Stress test (up to 1000 concurrent users, 17min)
pnpm run test:load:stress

# Realistic sessions (500 users across 50-100 rooms, 18min)
pnpm run test:load:realistic

# SSE endurance (1000 concurrent connections for 10+ minutes, 20min)
pnpm run test:load:sse

# Run all heavy tests (~55min total)
pnpm run test:load:all

Performance Thresholds:

  • Basic/Spike: <1% error rate, p95 < 500ms
  • Stress: <5% error rate at 1000 users, p95 < 2s, p99 < 5s
  • Realistic: <2% error rate, >30% consensus rate, p95 < 1s
  • SSE: <5% error rate, >800 active connections maintained

GitHub Actions Workflows:

  • Standard tests run on all PRs and pushes
  • Heavy tests run nightly at 2 AM UTC, manually, or on releases

See tests/load/README.md for detailed documentation.

Progressive Web App (PWA)

The application is installable as a Progressive Web App on both mobile and desktop.

Installation

Desktop (Chrome/Edge):

  1. Visit the app URL
  2. Look for the install icon in the address bar
  3. Click "Install"

Mobile (iOS/Android):

  1. Visit the app URL in Safari/Chrome
  2. Tap the share button
  3. Select "Add to Home Screen"

Accessibility

The application follows WCAG 2.1 Level AA guidelines.

Development Tools

axe-core runs automatically in development mode:

pnpm run dev
# Open browser console to see accessibility violations

Accessibility Features

  • Keyboard navigation: Full keyboard support with arrow keys, Tab, Enter
  • Screen readers: ARIA labels, live regions, and semantic HTML
  • Skip links: Jump to main content and voting section
  • Form labels: All inputs have associated labels (some visually hidden)
  • Focus management: Clear focus indicators and logical tab order
  • Color contrast: All text meets WCAG AA contrast ratios

Linting & Formatting

# Run linter
pnpm lint

# Format code
pnpm format

Project Structure

poker-planning/
├── server/              # Hono API server
│   ├── index.ts        # API endpoints and SSE handling
│   ├── storage.ts      # Redis/Valkey storage layer for rooms
│   └── redis.ts        # Redis/Valkey client wrapper
├── src/
│   ├── pages/          # Page components
│   │   ├── Home.tsx    # Homepage with room creation
│   │   └── Room.tsx    # Room with voting interface
│   ├── hooks/          # Custom hooks
│   │   ├── useRoom.ts  # Room state and actions
│   │   └── useConfetti.ts
│   ├── router.tsx      # preact-iso router configuration
│   ├── main.tsx
│   └── index.css
├── tests/
│   ├── e2e/            # Playwright E2E tests
│   └── load/           # k6 load tests
│       ├── scenarios/  # Test scenarios
│       └── README.md   # Load testing documentation
└── playwright.config.ts

API Documentation

The API is fully documented using OpenAPI 3.0 specification.

Quick Reference

  • POST /api/rooms - Create a new room
  • POST /api/rooms/:code/join - Join a room
  • GET /api/rooms/:code - Get room info
  • GET /api/rooms/:code/events - SSE connection for updates
  • POST /api/rooms/:code/vote - Submit a vote
  • POST /api/rooms/:code/reveal - Reveal all votes
  • POST /api/rooms/:code/reset - Reset the session
  • DELETE /api/rooms/:code/members/:id - Remove a member

For detailed request/response schemas, authentication, and examples, see the interactive API documentation.

Infrastructure

graph TB
    subgraph "Scaleway fr-par"
        subgraph "GitHub Container Registry"
            GHCR["ghcr.io/slashgear/poker-planning<br/>Docker Images"]
        end

        subgraph "Private Network VPC"
            Redis[("Redis Managed Database<br/>rediss://10.x.x.x:6379<br/>TLS Enabled")]

            subgraph "Serverless Containers"
                Prod["Production Container<br/>Image: v2.x.x<br/>Deploy on git tags"]
            end
        end

        subgraph "CI/CD"
            GHA["GitHub Actions<br/>Build • Test • Deploy"]
        end
    end

    GHA -->|1. Build & Push| GHCR
    GHA -->|2. Deploy| Prod

    GHCR -.->|Pull Image| Prod

    Prod -->|rediss://| Redis

    style Redis fill:#dc3545
    style Prod fill:#28a745
    style GHCR fill:#6c757d
    style GHA fill:#ffc107
Loading

Storage & Scalability

  • Redis/Valkey for distributed session storage
    • Rooms stored with 2-hour TTL (auto-expiry)
    • Supports horizontal scaling across multiple container instances
    • Atomic operations for consistency
    • Protocol-compatible: works with both Redis and Valkey
  • Session data persists across container restarts
  • Inactive member cleanup runs every minute

Room System

  • Rooms are identified by 6-character codes (e.g., ABC123)
  • Members are tracked via session cookies (httpOnly, 2h expiry)
  • Inactive members are automatically removed after 5 minutes
  • Empty rooms are automatically cleaned up by Redis/Valkey TTL

Real-time Updates

  • Server-Sent Events broadcast room state to all connected clients
  • Automatic reconnection on connection loss
  • Keep-alive pings every 30 seconds
  • SSE clients tracked per container (roomClients Map)
  • Room state fetched from Redis/Valkey on each broadcast

Available Scripts

pnpm run dev          # Start Vite dev server
pnpm run dev:server   # Start API server
pnpm run build        # Production build
pnpm run preview      # Preview build
pnpm lint             # Run linter
pnpm format           # Format code
pnpm test             # Run Playwright tests
pnpm test:ui          # Tests in interactive UI mode
pnpm test:headed      # Tests with visible browser
pnpm test:report      # Show test report
pnpm screenshots      # Generate example screenshots

Contributing

See CONTRIBUTING.md for contribution guidelines.

License

MIT License

Copyright (c) 2026 Antoine Caron (@Slashgear)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

About

Real-time poker planning app for agile team estimation using Fibonacci sequence

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors