Skip to main content

RDEV STUDIO / DRAFT ANALYSER

DRAFT

GAMEWEEK 5Deadline in …Data as of 16 hr ago
Deadline check: your XI currently has an amber starter. Change it in the FPL app - this site is read-only.

Under the hood

How it's built

Both FPL APIs block browsers, so nothing in the page ever calls them. A daily cron writes into Supabase; the pages read Postgres. The live gameweek page is the exception - Vercel Hobby cannot run every five minutes, so that route hits the live endpoint server-side, stores the snapshot, and pushes it over Pusher when credentials exist. The tab also polls once a minute.

Availability, 0-100

base = { a:100, d:55, i:5, s:0, u:0, n:15 }[status]
cop  = chance_next ?? chance_this ?? null
score = cop != null ? 0.55 * base + 0.45 * cop : base
score -= newsPenalty(news, age)          // official FPL text only
score += minutesTrend(last4)             // 0 until per-match minutes exist
score += reportedAbsence(signal)         // RSS/Claude, labelled reported
score  = clamp(0, 100)
if status == i: score = min(score, 40)   // unofficial reports cannot green an injury
green >= 75   amber 40-74   red < 40

Projected points

pStart = 0.55 * availability/100 + 0.45 * starts_per_90
xP = pStart * (appearance + xG * goalPts + xA * 3
     + CS_prob * csPts + defconProb * 2 + bonus)
fixMult = {1:1.25, 2:1.12, 3:1.00, 4:0.88, 5:0.75}[FDR]
Scoring values come from bootstrap settings, not hardcoded 10s.

News layer

Daily cron pulls BBC/Guardian RSS (feeds and summaries only), keeps items from the last 48 hours, and asks Claude for a structured availability signal per club. Matches are scoped to that club. Stored rows never overwrite official FPL status, news, or chance fields. The UI labels every extract reported, not confirmed.

What is not here yet

  • Per-match minutes history, so the availability minutes-trend term stays at zero.
  • True five-minute in-play cron. Hobby is daily; on Pro set /api/cron/live to */5 * * * *. Until then the live page refreshes itself, with Pusher when configured.