Skip to main content
Back to case studies

Spike Series

One platform to run an entire circuit.

Regional VALORANT circuits for a European organiser: public website, management portal and Discord bot, built from scratch by VentuLabs with the same stack and the same guarantees as our own products.

4,839
automated tests
8
languages
197
architecture decisions
67
database tables
1,200
concurrent viewers, measured

In production at spikeserieseu.es (Opens in a new tab)

Spike Series public home page with live matches, regions and upcoming tournaments

One platform to run an entire circuit

A public website for players and viewers, a management portal for the organiser and a Discord bot that connects everything in real time.

  • Complete competition engine

    Single and double elimination, groups, Swiss, league and GSL. It generates brackets and standings and recalculates them on its own after every result.

  • Live map vetoes

    Both captains ban and pick maps in turns against a countdown, in real time and without reloading, with the series history in view.

  • Check-in and match flow

    Check-in before playing, rescheduling with time slots proposed and accepted between captains, and per-map result reporting.

  • Chat connected to Discord

    Team and match chat inside the website, with automatic retention, synced with the circuit's Discord channels.

  • Integrated Discord bot

    Creates team roles and channels automatically and sends direct messages about matches, results and deadlines, in the user's language.

  • Team and player marketplace

    A board where players and teams post and find a spot before registrations close.

  • Sign in with Discord

    Sign-up and login with the player's Discord account, plus email and password with an encrypted session.

  • Eight languages

    Website, portal and content translated into ES, EN, FR, PT, IT, DE, NL and TR, with each language loading only its own strings.

  • Live scoreboard

    Score reading from the broadcast to update live matches without manual intervention.

  • Maintenance without downtime

    Switched on from the portal and delivered instantly to anyone browsing, without reloading the page.

  • Audited support

    The support team can log in as a user to help them, with a visible notice and a full log of the session.

  • Designed mobile first

    Every screen is designed and tested first at 390 px wide, from the bracket to the chat, before adapting it to desktop.

Technical architecture

The same stack and the same guarantees as our own products: tests, automatic deployment and several organisers per instance from day one.

Frontend

  • Next.js 16 with App Router
  • React 19
  • TypeScript in strict mode
  • Tailwind CSS 4
  • 8 languages, each in its own bundle
  • Mobile first, tested at 390 px

Backend

  • Server components and API routes
  • Encrypted sessions and bcrypt
  • Zod validation on everything that mutates data
  • Live updates with server-sent events
  • CSRF protection and rate limits
  • Sign in with Discord

Data

  • PostgreSQL 16 with Drizzle ORM
  • 67 tables and 99 migrations
  • Isolation per organiser and per circuit
  • Foreign keys with controlled deletes
  • Updated-at triggers
  • Versioned SQL migrations

Competition engine

  • A pure library, with no framework or database
  • Single and double elimination, Swiss, league and GSL
  • Deterministic: the same tournament generates the same bracket
  • 100% line coverage
  • Configurable standings and tiebreakers
  • Consumed only by the interface and the portal

Infrastructure

  • Ubuntu 24.04 server with Node 22
  • Nginx and PM2 with several instances
  • Let's Encrypt certificates with HSTS
  • Deployment from VentuHub with a backup beforehand
  • Health check and automatic rollback
  • 1,200 concurrent viewers measured

Quality

  • 4,141 tests with Vitest across 405 files
  • 698 end-to-end tests with Playwright
  • Three projects: mobile Chrome, mobile Safari and desktop
  • Real Postgres in tests
  • ESLint with quality rules and a ratchet
  • Lighthouse 91, 100, 100 and 100 on mobile

Distinct roles

A captain can't touch another team. A referee only verifies the matches assigned to them.

  • Admin

    Full access: users, audit log, organiser settings and maintenance.

  • Organisation

    Operational management of circuits, tournaments, registrations and teams.

  • Referee

    Verifies the results of the matches assigned to them.

  • Captain

    Their team: roster, registrations, check-in, vetoes and result reporting.

  • Player

    Sees their team and their matches and edits their own profile.

Not just a results website

Engineering decisions you don't usually see, but that keep a live competition stable.

  • Competition engine as a pure library

    No dependencies on the framework, the database or the system clock: time is injected and the draw uses a seed, so the same tournament always generates the same bracket in tests.

  • Only the active language travels to the browser

    Each of the eight languages is its own bundle: the server already knows the language before rendering the page and the client downloads only that one.

  • Live matches without reloading

    A single event stream per tab announces results, vetoes and standings changes as they happen, with automatic reconnection.

  • Maintenance without leaving anyone stranded

    Switched on from the portal and delivered instantly to anyone browsing, with no need to refresh to find out.

  • Support with full traceability

    The support team can log in as a user to resolve an issue, with a permanent on-screen notice and a record of what they did.

  • Several organisers from day one

    Each organiser and each circuit is isolated in the database: that's what turns the prototype into a replicable product.

  • Capacity measured, not estimated

    Load tests with live matches: 1,200 concurrent viewers with responses under 350 ms at the 95th percentile.

  • Deployment with automatic rollback

    The build is prepared separately and goes into the server in one go; if startup fails, the system reverts to the previous version on its own.

Thousands of automated tests

Coverage from the competition engine to the complete captain and organiser flows. Every deployment is blocked if anything fails.

4,141
tests with Vitest
405
test files
698
end-to-end tests
3
projects: two mobile and one desktop
  • Competition engine

    Single and double elimination, Swiss, league and GSL brackets: correct byes, stable standings and impossible results rejected.

  • Authentication and session

    Login with email and with Discord, encrypted session, CSRF, attempt limits and audit logging.

  • Isolation per organiser

    Separation per organiser and per circuit verified at query and database level.

  • Matches and live play

    Check-in, rescheduling, map vetoes, result reporting and verification, and the live event stream.

  • Languages and content

    The eight languages load what they should and nothing more: tests check that no client downloads a language it isn't using.

  • End to end, mobile first

    Complete captain and organiser flows on real Chrome, in two mobile projects and one desktop project, with accessibility checks.

Full stack

The same criteria as our own products: only modern, maintained tools with an active community.

  • Next.js 16
  • React 19
  • TypeScript 5
  • Tailwind CSS 4
  • Node.js 22
  • PostgreSQL 16
  • Drizzle ORM
  • PGlite in tests
  • Encrypted sessions
  • Zod
  • discord.js
  • Vitest
  • Playwright
  • ESLint 9
  • SQL
  • Bash
  • Nginx
  • PM2
  • Ubuntu 24.04
  • VentuHub
  • Let's Encrypt

Need something like this?

Spike Series is our own code, custom-built for a VALORANT circuit organiser: no templates, no third-party services and the same technical rigour we put into our products.

Back to case studies