A real-time Planning Poker server for agile estimation. Teams join a shared room, vote on story points simultaneously, and reveal all votes at once to surface disagreement and reach consensus. https://pp.serk-b.de
  • Go 63.3%
  • HTML 34.1%
  • Makefile 1.9%
  • Dockerfile 0.7%
Datei suchen
rev 7ab143cbf8
Alle Prüfungen waren erfolgreich
build / go-build (push) Successful in 3m58s
added podman compose persist start after reboot
2026-07-13 22:00:17 +02:00
.config/systemd/user added podman compose persist start after reboot 2026-07-13 22:00:17 +02:00
.devcontainer update devcontainer 2026-06-13 01:11:47 +02:00
.forgejo/workflows added podman compose persist start after reboot 2026-07-13 22:00:17 +02:00
api inital commit 2026-06-11 21:42:38 +02:00
hub update tests, pipeline, caching 2026-06-13 11:44:34 +02:00
models added dark mode 2026-06-12 10:41:52 +02:00
web [upd] Responsive Design 2026-06-15 17:34:02 +02:00
.editorconfig added default files 2026-06-13 22:34:54 +02:00
.gitignore added rasperypi builds 2026-06-11 22:02:56 +02:00
.golangci.yml added default files 2026-06-13 22:34:54 +02:00
CLAUDE.md added default files 2026-06-13 22:34:54 +02:00
config.json added repoURL 2026-06-11 21:51:33 +02:00
docker-compose.yml inital commit 2026-06-11 21:42:38 +02:00
Dockerfile added repoURL 2026-06-11 21:51:33 +02:00
Dockerfile.apline inital commit 2026-06-11 21:42:38 +02:00
go.mod inital commit 2026-06-11 21:42:38 +02:00
go.sum inital commit 2026-06-11 21:42:38 +02:00
LICENSE inital commit 2026-06-11 21:42:38 +02:00
main.go update tests, pipeline, caching 2026-06-13 11:44:34 +02:00
main_test.go update tests, pipeline, caching 2026-06-13 11:44:34 +02:00
Makefile added Version 2026-06-11 22:44:48 +02:00
README.md added podman compose persist start after reboot 2026-07-13 22:00:17 +02:00

Story Points Finder

A real-time Planning Poker server for agile estimation. Teams join a shared room, vote simultaneously, and reveal all votes at once to surface disagreement and reach consensus.

Getting started

Run locally

go run .

Run with Docker

make docker-build   # build binary + Docker image
docker compose up   # start the container

Open http://localhost:8080 in your browser.

Autostart with Podman Compose (systemd user service)

To keep the app running across reboots when started via podman compose, a systemd user unit template is included at .config/systemd/user/podman-compose@.service. It is also bundled into every Linux release archive under the same path.

# Copy it into place (if not already there via the release archive)
mkdir -p ~/.config/systemd/user
cp .config/systemd/user/podman-compose@.service ~/.config/systemd/user/

# Allow user services to start on boot without an active login session
loginctl enable-linger "$(whoami)"

# Enable and start it — the instance name is the project path relative to
# $HOME, with "/" escaped as "-". E.g. if docker-compose.yml lives in
# ~/apps/storypointsfinder:
systemctl --user daemon-reload
systemctl --user enable --now podman-compose@apps-storypointsfinder.service

The service runs podman compose up -d in ~/apps/storypointsfinder on boot and podman compose down on stop.

Makefile targets

Target Description
make build Compile Linux amd64 binary
make build-windows Compile Windows amd64 binary
make test Run all tests
make run Run locally without Docker
make docker-build Build binary and Docker image
make up Start via Docker Compose
make clean Remove compiled binaries

How it works

  1. Enter a username and a room ID — the room is created automatically on first join.
  2. Share the room ID with your team.
  3. Everyone selects a card and submits their vote.
  4. Any participant reveals the votes once everyone has voted.
  5. After discussion, anyone can reset the round to start over.

Viewer mode — join with ?viewer=true in the WebSocket URL to observe without voting. Viewers can still reveal votes and reset rounds.

Planning cards

1 2 3 5 8 13 21 ? Coffee Joker

WebSocket API

Connect to ws://localhost:8080/ws?username=<name>&room=<id>[&viewer=true].

Client → Server

type Fields Description
BET_SUBMIT card Submit a vote
WITHDRAW_VOTE Retract your vote (not allowed after reveal)
REVEAL_VOTES Reveal all votes
RESET_ROUND Clear votes and start a new round
KICK_PLAYER targetUsername Remove a player from the room

Server → Client

type Description
CONNECTED Sent on successful join; includes allowedCards
STATE_UPDATE Full room snapshot after any state change
ERROR Operation failed; reason in roomState
KICKED You have been removed from the room

Project structure

├── main.go                       # Entry point
├── hub/hub.go                    # WebSocket hub and game logic
├── hub/hub_integration_test.go   # Integration tests
├── models/types.go               # Shared data structures
├── api/poker.go                  # Auxiliary game logic
├── web/index.html                # Browser client
├── Dockerfile                    # Runtime image (uses pre-built binary)
├── Makefile                      # Build, test, and Docker targets
├── docker-compose.yml
└── .config/systemd/user/podman-compose@.service  # Autostart on boot (Podman Compose)

Running tests

go test ./...

Versioning & releases

The version is baked into the binary at build time via -ldflags. Without a tag the version defaults to dev. It is visible in the browser footer, the startup log, and the /api/config endpoint.

Create a release:

git tag v1.0.0
git push origin v1.0.0

The CI pipeline picks up the tag automatically and stamps all four binaries (amd64, exe, arm64, armv7) with it before packaging the artifact.

Version format:

Situation Example
Exactly on a tag v1.0.0
Commits after a tag v1.0.0-3-gabcdef
Uncommitted local changes v1.0.0-dirty
No tags at all dev

License

Apache 2.0 — see LICENSE.