Tierline: a native iOS fantasy football draft board on a serverless Rust backend

Tierline is a native iOS fantasy football draft-board app: tiered rankings, auction values and keepers, on a serverless Rust and GraphQL backend on AWS.

The problem

Building draft boards for fantasy football means juggling positional rankings, overall boards, tiers, average draft position (ADP) and auction values across leagues with different formats: snake or auction, 12-team or superflex, keepers. Imported values and personal opinions get mixed together destructively, and draft-day tools assume you have a connection.

What Tierline does

  • Draft boards per position, hand-reorderable, with tiers, plus an overall board ordered by format-aware ADP. The player catalog and ADP come from public Sleeper data.
  • Board groups, one per league, so auction values and rankings are always read in the right format. A group can be built by hand. Importing league settings from Yahoo is built and tested, and is waiting on Yahoo to approve the developer app before it runs against a real league.
  • Baseline vs. override for auction values: imported numbers never change, and your edits sit on top of them.
  • Keepers removed from the pool, with the auction budget netted for their salaries.
  • Draft day runs on the device: tap a player as drafted and the board re-sorts locally, offline.

How it’s built

RequestNightly refreshIcon-Architecture-Group/32/AWS-Cloud-logo_32AWSGraphQLnightlyAppleiPhone appSwiftUIBuild tiered draft boards.Cross off picks on draftday, even offline.SwiftSwiftSQLiteSQLiteIcon-Architecture/48/Arch_AWS-Lambda_48APILambda · Rust · GraphQLIcon-Architecture/48/Arch_Amazon-DynamoDB_48DatabaseDynamoDBIcon-Architecture/48/Arch_Amazon-EventBridge_48Data refreshScheduled LambdaLeague dataSleeperYahoo Fantasy
GraphQLIcon-Architecture-Group/32/AWS-Cloud-logo_32AWSnightlyAppleiPhone appSwiftUIBuild tiered draft boards.Cross off picks on draft day, even offline.SwiftSwiftSQLiteSQLiteIcon-Architecture/48/Arch_AWS-Lambda_48APILambda · Rust · GraphQLIcon-Architecture/48/Arch_Amazon-DynamoDB_48DatabaseDynamoDBIcon-Architecture/48/Arch_Amazon-EventBridge_48Data refreshScheduled LambdaLeague dataSleeperYahoo FantasyRequestNightly refresh
Your board lives on your phone. The cloud keeps rankings, ADP and league settings fresh.
  • iOS app in Swift, with Sign in with Apple, Swift Charts for player value history, and an Xcode Cloud pipeline that builds, tests and signs to TestFlight.
  • Backend in Rust on serverless AWS. Data sources plug in through a ports-and-adapters layer, and the app reads through a single GraphQL endpoint. A sport dimension runs through the whole model so other sports can be added without a rewrite.
  • Admin panel in Vue for the operator review queue.
  • Infrastructure in Terraform, with dev and prod environments defined from one shared module. Dev is running; prod is not created yet. The backend and admin panel deploy from GitHub Actions through OIDC, with no stored AWS keys.
  • Analytics are self-owned: a typed event taxonomy behind a consent gate, with no third-party SDK. Sending events to the backend isn’t wired up yet.

Under the hood

  • Pro subscription through StoreKit 2: paywall, purchase and restore. The server enforces which features each tier gets, and handles App Store notifications for refunds and revocations.
  • Boards belong to the phone. Each board lives in a local SQLite store and syncs to the server as an opaque document the server never reads, with merging, conflict handling and a recovery path if a board is lost.
  • Sign-in sessions use self-issued tokens with rotating refresh tokens, kept in the Keychain.
  • Failure testing: fault-injection suites cover cases such as forged tokens, authorization bypass and lost boards.
  • Deploy checks and tracing: smoke tests run after each deploy, and the Lambdas are traced with OpenTelemetry.

Where it stands

  • Testing multi-source data ingestion for fantasy player data.
  • Developing the UX design of the views and improving the statistic formulas.

Get in touch

Text me:

Open in new tab

Loading…