Skip to content

agustinusnathaniel/spoker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

spoker

A real-time planning poker (scrum poker) application for agile teams to estimate story points collaboratively.

Quality Gate Status Bugs Code Smells Duplicated Lines (%) Technical Debt Maintainability Rating Reliability Rating Security Rating Vulnerabilities

Commitizen friendly

Ask DeepWiki

Overview

Spoker enables distributed teams to conduct planning poker sessions in real-time. Team members join rooms, vote on story points, and see results synchronized across all participants. The application uses Firebase Realtime Database for instant updates and supports multiple user roles with different permissions.

What It Does

  • Real-time collaboration: Multiple users can join rooms and vote simultaneously with live updates
  • Role-based access: Three roles (owner, participant, observant) with different capabilities
  • Task management: Queue-based workflow with completed task history
  • Vote hiding: Configurable emoji-based labels to hide votes until all participants vote
  • Room privacy: Support for public and password-protected private rooms
  • Email verification: Required authentication with email verification

What It Does Not Do

  • Persistent user profiles or voting history across sessions
  • Integration with project management tools (Jira, Trello, etc.)
  • Analytics or reporting beyond basic vote averages
  • Mobile native applications (web-only)
  • Offline mode or local-first synchronization

Architecture

High-Level System Architecture

graph TB
    subgraph "Client (Next.js)"
        UI[React Components]
        Store[Zustand Stores]
        Services[Firebase Services]
    end
    
    subgraph "Firebase Services"
        Auth[Firebase Auth]
        DB[(Realtime Database)]
        AppCheck[App Check]
    end
    
    subgraph "External"
        Sentry[Error Tracking]
        Analytics[Umami Analytics]
    end
    
    UI --> Store
    UI --> Services
    Services --> Auth
    Services --> DB
    Services --> AppCheck
    UI --> Sentry
    UI --> Analytics
    
    style DB fill:#4CAF50
    style Auth fill:#FFA726
    style Store fill:#7B68EE
Loading

Core Data Flow

sequenceDiagram
    participant User
    participant UI
    participant Store
    participant Service
    participant Firebase
    
    User->>UI: Join Room / Vote
    UI->>Service: Call Firebase Service
    Service->>Firebase: Write to Realtime DB
    Firebase-->>Service: Update Confirmed
    Firebase-->>Store: Real-time Listener Update
    Store-->>UI: State Change
    UI-->>User: UI Update
Loading

Repository Structure

spoker/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ lib/                    # Core application logic
β”‚   β”‚   β”œβ”€β”€ components/         # Reusable UI components
β”‚   β”‚   β”œβ”€β”€ constants/          # Configuration constants
β”‚   β”‚   β”‚   β”œβ”€β”€ routes/         # Route definitions (public/private/restricted)
β”‚   β”‚   β”‚   └── hide-label.ts   # Vote hiding emoji options
β”‚   β”‚   β”œβ”€β”€ hooks/              # Custom React hooks
β”‚   β”‚   β”œβ”€β”€ layout/             # Layout components (header, footer, auth)
β”‚   β”‚   β”œβ”€β”€ models/             # Form validation schemas (Zod)
β”‚   β”‚   β”œβ”€β”€ pages/              # Page-level components
β”‚   β”‚   β”‚   β”œβ”€β”€ hall/           # Room creation/joining interface
β”‚   β”‚   β”‚   β”œβ”€β”€ room/           # Main voting interface
β”‚   β”‚   β”‚   └── home/           # Landing page
β”‚   β”‚   β”œβ”€β”€ services/           # Firebase service layer
β”‚   β”‚   β”‚   └── firebase/
β”‚   β”‚   β”‚       β”œβ”€β”€ auth/       # Authentication operations
β”‚   β”‚   β”‚       β”œβ”€β”€ room/       # Room CRUD and updates
β”‚   β”‚   β”‚       └── rules.ts    # Security rules generator
β”‚   β”‚   β”œβ”€β”€ stores/             # Zustand state management
β”‚   β”‚   β”œβ”€β”€ styles/             # Theme configuration (Chakra UI)
β”‚   β”‚   β”œβ”€β”€ types/              # TypeScript type definitions
β”‚   β”‚   └── utils/              # Utility functions
β”‚   └── pages/                  # Next.js pages (routing)
β”œβ”€β”€ public/                     # Static assets
β”œβ”€β”€ tools/                      # Build-time scripts
└── config files               # Next.js, TypeScript, Biome, etc.

Tech Stack

Core Dependencies

Package Purpose Version
next React framework with SSR/SSG ^16.1.1
react UI library ^19.2.3
firebase Backend (Auth + Realtime Database) ^12.7.0
@chakra-ui/react Component library ^2.10.9
zustand State management ^5.0.9
zod Runtime type validation ^4.2.1
react-hook-form Form handling ^7.69.0

Development Tools

  • Biome: Linting and formatting (replaces ESLint/Prettier)
  • TypeScript: Type safety
  • Commitlint: Conventional commits
  • Husky: Git hooks
  • Knip: Unused code detection
  • Sentry: Error tracking and monitoring

Getting Started

Prerequisites

  • Node.js v24.11.x (specified in engines)
  • pnpm v10.24.0 (specified in packageManager)
  • Firebase project with Realtime Database enabled
  • ReCAPTCHA v3 site key (optional, for App Check)

Environment Variables

Create a .env.local file with the following variables:

# Firebase Configuration
NEXT_PUBLIC_FIREBASE_API_KEY=
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
NEXT_PUBLIC_FIREBASE_DATABASE_URL=
NEXT_PUBLIC_FIREBASE_PROJECT_ID=
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
NEXT_PUBLIC_FIREBASE_APP_ID=
NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=

# Optional: ReCAPTCHA for App Check
NEXT_PUBLIC_RECAPTCHA_SITE_KEY=

# Optional: Sentry
SENTRY_DSN=
NEXT_PUBLIC_SENTRY_DSN=
APP_ENV=

Installation

# Install dependencies
pnpm install

# Run development server
pnpm dev

Open http://localhost:3000 to view the application.

Building

# Type check
pnpm type:check

# Lint and format
pnpm biome:check
pnpm biome:fix

# Build for production
pnpm build

# Start production server
pnpm start

Firebase Setup

  1. Create a Firebase project in the Firebase Console
  2. Enable Realtime Database (not Firestore)
  3. Configure Authentication (Email/Password and Google providers)
  4. Deploy security rules using pnpm generate-rules (generates rules from src/lib/services/firebase/rules.ts)
  5. Optionally enable App Check with ReCAPTCHA v3

Development Workflows

Code Quality

# Run all checks (linting, type checking)
pnpm check:turbo

# Check for unused code
pnpm check:unused

Commits

This project uses Conventional Commits. Use pnpm commit (via Commitizen) or follow the format:

type(scope): subject

body (optional)

footer (optional)

Release Process

# Create release (updates version, CHANGELOG.md)
pnpm release

# Push release tags
pnpm push-release

Key Concepts

User Roles

  • Owner: Can create rooms, finish votes, configure room settings, manage tasks
  • Participant: Can vote on tasks, view results when revealed
  • Observant: Can view votes and results but cannot vote

Room Lifecycle

  1. Creation: Owner creates room with name, privacy, and optional password
  2. Joining: Users join with a role (owner/participant/observant)
  3. Voting: Participants vote on current task; votes hidden until all vote
  4. Reveal: When all participants vote, results are shown to all
  5. Completion: Owner selects final estimate and moves to next task in queue

Vote Hiding

Votes can be hidden using emoji labels (monkey, chicken, cow, fish, money, cloud, shrimp, think) until all participants have voted. This prevents bias in estimation.

Task Queue

  • Current Task: Active task being estimated (room.task)
  • Queue: Upcoming tasks (room.queue[])
  • Completed: Finished tasks with estimates (room.completed[])

Common Development Tasks

Adding a New Page

  1. Create component in src/lib/pages/[page-name]/index.tsx
  2. Create route in src/pages/[page-name].ts (or [page-name]/[id].ts for dynamic routes)
  3. Add route to appropriate constant in src/lib/constants/routes/

Adding a New Firebase Service

  1. Create service function in src/lib/services/firebase/[domain]/[operation]/index.ts
  2. Export from service module
  3. Update Firebase rules in src/lib/services/firebase/rules.ts if needed
  4. Run pnpm generate-rules to regenerate rules JSON

Modifying State Management

  • Room state: src/lib/stores/room.ts
  • Auth state: src/lib/stores/auth.ts
  • Use useShallow from Zustand to prevent unnecessary re-renders

Testing

Currently, the project does not include automated tests. Manual testing should cover:

  • Room creation and joining
  • Real-time vote synchronization
  • Role-based permissions
  • Task queue management
  • Email verification flow
  • Private room password protection

Deployment

The project is configured for Vercel deployment (vercel.json). Ensure environment variables are set in the deployment platform.

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Agustinus Nathaniel
Agustinus Nathaniel

πŸ’» πŸ› 🎨 πŸ€” πŸš‡ 🚧

This project follows the all-contributors specification. Contributions of any kind welcome!

Related Documentation