All work
Production SaaS 2026

Kas Badminton

Real-time badminton club cash & match manager — 2-pair matchup calculations, dynamic QRIS generation, offline-first PWA, and single Go binary delivery via go:embed.

Visit live
GoSvelteKitPostgreSQLSSEPWACaddy
Kas Badminton preview
Problem

Tracking badminton shuttlecock usage per pair and splitting court fees manually across club members is chaotic, prone to missed debts, and creates ledger friction during sessions.

My role

Solo Architect & Fullstack Engineer: end-to-end rewrite from v2 (Next.js/Prisma) to v4 (Go + SvelteKit static embedded), data migration, and live operations.

Technical decisions

Single binary delivery with go:embed

Compiled SvelteKit static SPA directly into the Go binary using go:embed. Zero Node.js runtime on the VPS, instant sub-millisecond cold start, and idle RAM footprint below 16MB.

Realtime session sync via Server-Sent Events (SSE)

Chose unidirectional SSE over WebSockets for live match, debt, and balance updates across active courts — eliminating ping/pong connection overhead and saving mobile battery.

Dynamic QRIS & offline court-ready PWA

Generated exact-amount dynamic QRIS images on the client side with text-sharing fallbacks, paired with service worker caching for reliable operation in indoor courts with weak cellular signal.

Domain-driven idempotent debt reconciliation

Structured transactional balance state machines (player_balances) with goose migrations, ensuring debt recalculations remain 100% idempotent across repeated runs.

Results
  • Live and actively used in weekly production at kasbadminton.com
  • Native arm64 automated CI/CD deployment with /healthz verification
  • 99+ domain logic tests guaranteeing zero accounting discrepancies
  • Zero runtime memory leaks and instant responsiveness on low-end devices