Futbol Veritabanı
8대 리그 클럽·선수·통계—Transfermarkt 데이터
프리미어리그를 위한 다이너스티 판타지 풋볼, 세밀한 전술 포지션·실시간 이적 시장·실제 역할 기반 점수 엔진 제공
Dynasty fantasy football for the Premier League, with granular tactical positions, a live transfer market, and a scoring engine that judges every player against the role they actually played.
스포츠·피트니스TypeScript · CSSGitHub @dukerwang온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Gaffa is a dynasty-style fantasy football (soccer) app built for a single private league, live at gaffa.live. It exists because mainstream fantasy platforms — FPL, Sleeper, ESPN — score football with a spreadsheet's idea of the sport: a flat points table, three generic position buckets, and a season that resets to zero every summer. Gaffa scores it like a match-rating site instead, and runs the league like a real football club's boardroom.README 전문 보기 ↗Gaffa is a dynasty-style fantasy football (soccer) app built for a single private league, live at gaffa.live. It exists because mainstream fantasy platforms — FPL, Sleeper, ESPN — score football with a spreadsheet's idea of the sport: a flat points table, three generic position buckets, and a season that resets to zero every summer. Gaffa scores it like a match-rating site instead, and runs the league like a real football club's boardroom.
The rule that shapes everything else: a player is judged against what his specific role is expected to produce, not against a universal points table. There is no scoring quirk to farm — the way to win Gaffa is to be right about footballers.
The full player-facing rulebook — every mechanic paired with the reasoning behind it — lives in docs/USER_GUIDE.md. This document is the shorter version, plus the engineering underneath it.
| FPL | Sleeper (dynasty) | Gaffa | |
|---|---|---|---|
| Scoring | Flat points table, same for every player in a bucket | Flat points table, customizable but still context-free | Contextual sigmoid rating against position-specific statistical baselines — a clean sheet and a quiet 90 minutes are not scored the same way for a CB and a striker |
| Positions | 3–4 generic buckets (GK/DEF/MID/FWD) | Sport-generic slots, not football-tactical | 12 real tactical roles (CB, LB, RB, LWB, RWB, DM, CM, AM, LW, RW, ST, GK) — a wing-back is not a centre-back |
| Season model | Redraft every year, or classic "keep a few players" | True dynasty rosters | True dynasty — one draft, ever; every player after that is bought, sold, loaned, or traded like a real transfer |
| Economy | None — free waivers | FAAB waivers, typically blind and capped | An open, public auction economy: visible bidding, uncapped permanent budget, transfer fees that partly recirculate to the rest of the league (Scout's Fee + solidarity) instead of just vanishing |
| Depth of squad-building | Starting XI only | Bench + taxi squad | Starting XI, bench with strict positional cover, Injured Reserve, an Academy for U21 prospects, a loan market with recall clauses and performance bonuses, and a Retained List for players who leave the league but might come back |
| Season shape | League table only | League table (+ optional playoffs) | League table plus three parallel knockout cups running simultaneously, so a mid-table club still has something to play for in March |
| Squad transactions | Waivers only | Waivers + trades | Waivers/auctions + unrestricted manager-to-manager trades + loans (with real transfer terms: fees, recall clauses, buyback pricing) |
Nothing here is decorative. Every one of these systems solves a specific failure mode of the games it's compared against — see docs/USER_GUIDE.md for the reasoning behind each (why cups exist, why the transfer fee partly recirculates, why loans are capped 1-out/2-in, why retention pays 60% and not more).
Gaffa enforces 12 tactical positions — no generic DEF/MID/FWD buckets, no LM/RM (auto-mapped to LW/RW). Eligibility is exact: a bench centre-back never covers a left-back slot, because "defender" isn't a real football job. Starting XIs must fit one of 12 supported formations (4-3-3, 4-2-1-3, 4-2-2-2, 4-2-4, 4-3-1-2, 4-3-2-1, 3-4-1-2, 3-4-3, 3-4-2-1, 3-5-2, 5-3-2, 5-2-3), sourced from src/types/index.ts. Benches split into DEF/MID/ATT/FLEX groups, where FLEX accepts any starter-eligible player, including an emergency goalkeeper.
Two independent lock timings, not one: a manager's formation locks at the first kickoff involving any of their squad, but an individual player only locks when his own club kicks off — so a Saturday-morning lineup can still react to lunchtime results before the late kickoffs.
Instead of flat per-action points, every match performance is rated 1.0–10.0 against position-specific statistical baselines, then converted onto a separate, steeply convex fantasy-points scale.
0.0–1.0 component score per rating dimension via a logistic sigmoid against position-specific seasonal medians/stddevs:
$$score = \frac{1}{1 + e^{-Z}}, \quad Z = K \cdot \frac{value - median}{stddev}, \quad K = 1.0$$
Baselines are stored in rating_reference_stats and recomputed from live current-season data, so "average" is always relative to this season's actual Premier League, not a fixed historical constant.match_impact, influence, creativity, threat, defensive, goal_involvement, finishing, save_score. Goals score 6, assists 4, on a global cross-position scale. Clean-sheet bonuses are weighted by role (GK 16, DEF/DM 12, CM 4, AM/ATT 0) and require ≥60 minutes played. Goals conceded penalize keepers directly and outfielders against their team's expected goals conceded, not the raw scoreline.A team's weekly score is its starting XI's fantasy points, plus a Bench Depth Bonus: unused bench players who did play add 25% of their points to the total, so a deep squad is worth something beyond insurance. A 10-point draw band absorbs noise that isn't a real result — smaller gaps are draws, not coin-flip wins.
Auto-subs replace a zero-minute starter once his own fixture is confirmed finished, scanning the bench in a fixed DEF → MID → ATT → FLEX order and re-rating the substitute against the slot he filled, not his own position.
Three knockout cups — Champions Cup, League Cup, Consolation Cup — run in parallel with the league table, seeded by league position, so a club with no title chance still has a tie to play for. Cups never draw: level scores are broken by best individual performer, then by bracket seed.
Every player not currently on your roster — genuine free agents and other managers' listings alike — sits on one board, bid on the same way: a public, uncapped-duration open auction, paid from a Club Balance (the product name for the internal faab_budget — permanent, uncapped, never resets between seasons, and itself a tradeable asset).
Manager-to-manager trades need no commissioner approval and have no deadline — any combination of players, Club Balance, and Retained List rights against any combination of theirs. A trade involving a player already live in a gameweek is deferred until that gameweek resolves, so a mid-week trade can't be used to escape a bad lineup.
Loans move a player to another club for 4–16 gameweeks against an upfront fee and an optional per-point performance bonus, with a recall clause or a flat buyback fee to reclaim the roster slot. Hard capped at 1 player out, 2 players in at a time, so loans stay a specific deal about a specific player rather than a second roster.
The league drafts exactly once, ever. After that every new player is bought at auction. Rosters carry Active/Bench, IR (injured reserve — doesn't count against the roster cap, but blocks that manager from bidding while a healthy player sits on it), and an Academy for U21 prospects (age-cutoff, not games-played, so it can't be used to hide useful squad players off the books).
When a rostered player leaves the Premier League, the owning manager chooses, per departure: Release (60% of market value in compensation, and a bar from bidding on his eventual return) or Retain (forfeit the cash, keep tradeable rights that mature automatically if he ever comes back). The choice — and the exclusion that comes with Release — exists specifically to close an exploit the original all-cash-payout design had: a manager could be paid out and still win the player back later with a free option nobody else had. A player who leaves on loan skips the choice: he stays yours off the roster, uses no squad place or retained slot, and rejoins the squad automatically when he returns.
An arrival that finds the squad full (a loan ending, a retained player returning, an auction nobody with room bid on) is held rather than auto-dropped or pushed over the limit: he waits off the squad until the manager activates or drops him. While anyone is held the squad can't grow, and a hold that outlasts the next gameweek's first kickoff locks the lineup to the last one saved.
Once every fixture and cup tie is complete, the commissioner triggers the reset: rosters lock, the season is archived (standings, matchups, cup results, player stats), placement and cup prizes are paid (€40m→€20m by league position, €50m/€20m Champions Cup, €25m/€10m League and Consolation Cup), win/loss/draw records zero out, Club Balance carries over untouched, and a new schedule plus fresh cup brackets are generated. Departures are handled continuously through the season via Release/Retain, not dumped on the league in one lump at reset — so relegation arrives as a series of decisions across the summer, not a single event.
src/
├── app/ # Next.js route groups — (auth), (dashboard), and api/ (sync, cron, admin, transfers)
├── components/ # UI components by domain (players, teams, transfers, layout, ui)
├── context/ # React context (theme)
├── lib/ # Core business logic:
│ ├── scoring/ # sigmoid rating engine + matchup processor
│ ├── tournaments/ # cup bracket generation and advancement
│ ├── offseason/ # season reset, relegation compensation, prize distribution
│ ├── auction/, listings/ # bidding economy, sale listings, loan terms
│ ├── roster/, lineups/ # lineup validation and auto-subs
│ ├── economy/ # solidarity payments, merit (match revenue) payouts
│ ├── clubs/ # the durable club-identity registry (never keyed on FPL's seasonal team ids)
│ └── supabase/ # client/server/admin Supabase clients
├── scripts/ # Data-sync and scraper scripts colocated with app code
└── types/ # Authoritative global types — Formation, position taxonomy, bench bonuses
supabase/migrations/ # Sequential numbered SQL migrations — the source of truth for schema
docs/USER_GUIDE.md # The full player-facing rulebook this README summarizes
graph TD
A[FPL API Bootstrap] -->|Base metadata & injury status| B[Supabase players table]
C[SoFIFA Scraper] -->|Granular primary/secondary positions| B
D[Transfermarkt Scraper] -->|Fuzzy-matched market values, £50m+ auto-auction| B
E[FPL Live Event API] -->|Live match events| F["Scoring Engine (/api/sync/stats)"]
F -->|Sigmoid ratings & fantasy points| G[Supabase player_stats table]
G -->|update_player_fantasy_scores RPC| B
G -->|update_player_form_ratings RPC| B
G -->|resolveAllStalledGameweeks| H[Matchup Processor]
H -->|Auto-subs, Bench Depth Bonus, role-aware re-scoring| I[Supabase matchups table]
I -->|executeAdvanceTournament| J[Cup Brackets & Standings]
/api/sync/players) — pulls Premier League player metadata from FPL: names, clubs, injury status, preserving manual overrides./api/sync/sofifa-players) — matches players to their EA FC squad entries and updates primary/secondary tactical positions./api/sync/stats?mode=fpl_live) — during live gameweeks, fetches FPL live events, runs them through the scoring engine, and writes ratings and points to player_stats.