# DFRAG Fantasy

> I designed and built the fantasy system behind DFRAG's Logitech G Play Days campaign. Players collect account-bound player cards, build a five from the cards they own and score from real OCE Counter-Strike matches.

- **Role:** Fantasy System Engineer
- **Category:** Personal project
- **Status:** Live
- **Human-readable case study:** https://lutherminshull.com/projects/dfrag-fantasy

## Context

DFRAG is an Oceania and Asia Counter-Strike hub covering news, matches and events. DFRAG Fantasy turns its tournaments into a persistent card-collecting fantasy game: every match day, players pick five owned cards before the lock, and real match performance decides the standings. I built the Fantasy system with the DFRAG team, who also run the wider site, launch operations and campaign integrations.

## Luther's role

- Designed and built the original Fantasy system, from versioned rulesets and database contracts to the scheduled jobs and first player and staff screens.
- Built the scheduled publication, pricing, period-lock and scoring jobs in DFRAG's companion API.
- Delivered the second-generation player experience, then continued into staff pick controls, score explanations, standings and starter-pack setup for the live event.
- Contributed to the in-repo Card Studio and built the Card desk used to review and compile the player card sets that Fantasy lineups depend on.

## What Luther built

- Event-driven competitions whose match days, prices and eligible player pools come from DFRAG's own tournament, roster and match data.
- Owned-card lineups with revisions, optional scoring roles, rarity bonuses, same-team factors and database-authored match-day locks.
- Deterministic scoring with private per-card score detail, reviewed corrections and finalized global standings with rank movement.
- Starter-pack claims, owned-card eligibility and trade-up selection integrated with DFRAG's card collector.
- Audited staff tools for price exceptions, match-day pick windows, score review and starter recovery.
- Public rules presented from each competition's frozen ruleset.

## How it works

- Nuxt and Vue application backed by Supabase PostgreSQL, with a separate Nitro API running scheduled Fantasy jobs.
- Rulesets are frozen and hashed so a competition's scoring formula cannot change after publication; behaviour changes ship as new versions.
- PostgreSQL remains authoritative for card ownership, eligibility, revisions and locks, while TypeScript validates every request and RPC envelope at the boundary.
- Score runs read immutable, content-hashed match snapshots and integer millipoints, so a rerun produces the same result and corrections stay auditable.
- Staff actions resolve the actor from a verified token, require an audit reason and use idempotency keys, so retries never duplicate an operation.
- SQL suites cover concurrent publication and period locks, pick controls and owned-card rules alongside TypeScript unit tests.

## Outcomes

- Launched DFRAG Fantasy for the DFRAG Logitech G Pro Series 2026, where it runs live match days, lineups and global standings.
- Gave the Play Days campaign a durable product to build on, not a disposable sponsor microsite.
- Made scoring explainable, with every card's performance, role, rarity and team adjustments visible to the player.

## Technologies

TypeScript, Vue, Nuxt, Supabase, PostgreSQL, Nitro, Cloudflare Pages

## External link

- [Visit DFRAG Fantasy](https://dfrag.gg/counterstrike/fantasy/)

## Contact

- [Discuss an opportunity](https://cal.com/lutherminshull)
- [Email Luther](mailto:luther@lutherminshull.com)
- [Return to the portfolio overview](https://lutherminshull.com/index.md)

## Scope note

This case study covers Luther's own contribution and omits private repository data, credentials and private user information.
