My Gym My Way
Free home-gym workouts built from the equipment you own. No paywall, no account, no tracking.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Full-stack fantasy sports web app (multi-sport: NFL, NBA). Go backend + React/Vite/TypeScript frontend + PostgreSQL. Users authenticate via Yahoo OAuth, sync their Yahoo fantasy leagues, and view live rosters, scoreboards, standings, and matchup details.README 전문 보기 ↗
Fantasy Sports
Full-stack fantasy sports web app (multi-sport: NFL, NBA). Go backend + React/Vite/TypeScript frontend + PostgreSQL. Users authenticate via Yahoo OAuth, sync their Yahoo fantasy leagues, and view live rosters, scoreboards, standings, and matchup details.
backend/ Go API server (Chi router, pgx/pgxpool, golang-migrate, gorilla/sessions, Yahoo OAuth2)
frontend/ React 18 + Vite 5 + TypeScript + Tailwind CSS + shadcn/ui + TanStack Query v5
Backend layout:
cmd/api/main.go — entry point; wires router, DB pool, sessions, oauth config, handlerscmd/import/main.go — CLI tool to download nflverse CSV data and upsert into nfl_players / nfl_player_statsinternal/handlers/ — one file per resource; all handlers are methods on Handler{db, sessions, oauthConfig, config}
handlers.go — Handler struct definition + constructorrespond.go — JSON response helpersauth.go — Login, Callback, Me, Logoutleagues.go — ListLeagues, CreateLeague, GetLeagueteams.go — ListLeagueTeams, GetTeam, GetTeamRoster (with stat period support); includes gsis_id batch lookup for player detail linksplayers.go — ListPlayers, CreatePlayer, GetPlayerscoring.go — GetLeagueScoreboard, GetLeagueStandingsyahoo_helpers.go — leagueYahooKey(), userTokens(), newYahooClient() shared helpers used by multiple handlerssync.go — Sync (Yahoo league+team upsert)league_players.go — SearchLeaguePlayers, GetAvailablePlayerskeepers.go — GetKeeperRules, UpdateKeeperRules, GetLeagueDraftResults, GetLeagueKeepers, GetKeeperSummary, ListTeamKeeperWishlist, AddKeeperWishlist, RemoveKeeperWishlist, SubmitKeepers, UnsubmitKeepersanalysis.go — GetLeagueRankings: weighted z-score rankings; category weights = CV × FA-scarcity (normalised); adds position_score (z-score within position group); includes gsis_id lookup for player detail linksprojections.go — ListProjections, GetProjectionDetail; serves pre-computed comp-based NFL player projections from nfl_projections tablenfl_players.go — GetNFLPlayer (full player detail: metadata + YoY stats + projection); GetNFLPlayerByYahooID (resolves Yahoo key → gsis_id and redirects)draft_values.go — GetDraftValues: league-specific auction values (VOR + $ value based on actual roster settings)grades.go — ListGrades, GetPlayerGrades: real-life player grades (0-100 percentile) from nfl_player_grades table; supports comma-separated position filter (e.g. ?position=RB,WR,TE)internal/models/models.go — shared domain types (User, League, Team, Player, RosterEntry)internal/middleware/auth.go — RequireAuth: reads session, attaches *models.User to ctxinternal/yahoo/ — Yahoo Fantasy API client, OAuth config, XML types
client.go — all API methods + dbTokenSource (auto-refreshes + persists tokens)oauth.go — Yahoo OAuth2 endpoint + NewOAuthConfigtypes.go — all XML response structsinternal/db/db.go — pgxpool connect helpermigrations/ — numbered SQL migration filesFrontend layout:
src/api/client.ts — all typed API functions + TypeScript interfacessrc/api/queryKeys.ts — all TanStack Query cache keyssrc/lib/queryClient.ts — QueryClient config (staleTime: 30s, retry: 1)src/lib/utils.ts — cn() utility (clsx + tailwind-merge), zScoreIndicator, zScoreColorsrc/lib/grades.ts — shared grade display utilities: gradeColorClass, trendIndicator, phaseLabel, phaseColorsrc/lib/constants.ts — CURRENT_SEASON (2025), PROJECTION_SEASON (2026)src/pages/ — pages by route; complex pages split into subdirectories:
Home.tsx, Leagues.tsx — simple single-file pagesleague-detail/ — index.tsx + tab components (StandingsTab, ScoreboardTab, PlayersTab, KeepersTab, RankingsTab, DraftTab [NFL only]) + hooksteam-detail/ — index.tsx + components/ (RosterTable, MatchupCard) + hooks/useTeamDetail.tsmatchup-detail/ — index.tsx + components/ (CategoryTotalsTable, TeamRosterTable) + hookplayer-detail/ — index.tsx + components/GradeCard.tsx — unified NFL player detail page (metadata, grade card, YoY stats table, projection with PPR/Half/Standard toggle + comps)projection-detail/ — index.tsx + components/ (CompCard, TrajectoryChart) + hook — legacy detail page (redirects to player-detail)rankings/ — index.tsx + hooks/useRankings.ts — standalone real-life player grades page (top-level /rankings) with Flex/Superflex position filtersprojections/ — index.tsx + hooks/useProjections.ts + components/ (ProjectionTable, ConfidenceBadge, UniquenessBadge) — comp-based projection rankings with PPR/Half/Standard togglesrc/components/ui/ — shadcn/ui components (badge, button, input, table, tabs, provider) + table-helpers (SortableHead, PlayerCell, ClickableRow, ZScoreCell, HeaderRow)src/App.tsx — router + nav (with active page highlighting) + auth checksrc/main.tsx — React root, QueryClientProvider, BrowserRouter/api and /auth → http://localhost:8080 in devPublic:
GET /auth/login, /auth/callback, /auth/logout
GET /api/health
GET/POST /api/leagues, GET /api/leagues/{id}
GET /api/leagues/{id}/teams
GET /api/teams/{id}
GET/POST /api/players, GET /api/players/{id}
GET /api/projections?season=&position=&sort=&limit=&offset=
GET /api/projections/{gsisId}?season=
GET /api/nfl/players/{gsisId} — full player detail (metadata + YoY stats + projection)
GET /api/nfl/players/by-yahoo/{yahooKey} — resolves Yahoo key → HTTP redirect to /api/nfl/players/{gsisId}
GET /api/grades?season=&position=&limit=&offset= — real-life player grades; position supports comma-separated (e.g. RB,WR,TE)
GET /api/grades/{gsisId} — all seasons of grades for a player
Protected (RequireAuth):
GET /api/auth/me
POST /api/sync
GET /api/leagues/{id}/scoreboard?week=N
GET /api/leagues/{id}/standings
GET /api/leagues/{id}/players?search=q
GET /api/leagues/{id}/players/available?position=&start=&status=
GET /api/leagues/{id}/draftresults
GET /api/leagues/{id}/keepers
GET /api/leagues/{id}/keeper-rules
PUT /api/leagues/{id}/keeper-rules
GET /api/leagues/{id}/keeper-summary
GET /api/leagues/{id}/rankings?stat_type=season
GET /api/leagues/{id}/draft-values?season=&format=ppr|half|standard&budget=200
GET /api/teams/{id}/roster?stat_type=lastweek|season|today (or ?week=N)
GET /api/teams/{id}/keepers
POST /api/teams/{id}/keepers/{playerKey}
DELETE /api/teams/{id}/keepers/{playerKey}
POST /api/teams/{id}/keepers/submit
DELETE /api/teams/{id}/keepers/submit
cd backend)make run # go run ./cmd/api
make build # go build -o bin/api ./cmd/api
make test # go test ./...
make migrate-up # run migrations up (requires DATABASE_URL env)
make migrate-down # roll back one migration
make generate # sqlc generate (regenerates internal/db/queries/)
make import-nfl # import nflverse data (default: 2020-2024)
make import-nfl ARGS="-from 2015 -to 2024" # custom year range
make import-nfl ARGS="-rosters-only" # just player metadata
make import-nfl ARGS="-stats-only" # just weekly stats
make project-nfl ARGS="-profiles" # build player season profiles (run after import)
make project-nfl ARGS="-project -season 2025" # compute comp-based projections
make project-nfl ARGS="-grades" # compute real-life player grades (0-100)
make project-nfl ARGS="-all -season 2025" # profiles + grades + projections
make backtest-nfl ARGS="-from 2015 -to 2024" # backtest projections across historical seasons
make autotune-nfl ARGS="-from 2015 -to 2024 -train-to 2021" # auto-tune weights, saves projection_config.json
Run a single test:
go test ./internal/handlers/... -run TestHealthHandler
cd frontend)yarn dev # Vite dev server on :5173 (proxies /api and /auth to :8080)
yarn build # tsc + vite build → dist/
yarn lint # eslint
cp .env.example .env
docker compose up # starts db + backend + frontend
docker compose up db # just PostgreSQL on :5432
Copy .env.example → .env. Required:
DATABASE_URL — e.g. postgres://fantasy:fantasy@localhost:5432/fantasy_sportsPORT — defaults to 8080YAHOO_CLIENT_ID, YAHOO_CLIENT_SECRET, YAHOO_REDIRECT_URLSESSION_SECRET — random 32+ char string*Handler; use r.Context().Value(models.UserContextKey) for current user in protected routesyahoo.NewClient(ctx, db, oauthConfig, userID, accessToken, refreshToken, expiry); tokens auto-refresh and persist to DBtype=week, type=lastweek, type=date;date=YYYY-MM-DD, etc.)roster[].stats[].label — no hardcoded stat IDssort_order field ("1" = higher is better, "0" = lower is better) is passed through to the frontend for correct winner determination in MatchupDetailanalysis.go concurrently fetches rosters, scoring categories, and top-25 FA stats. Category weights = CV × scarcity (normalised): CV = stdev/|mean|; scarcity = 1/(1 + max(0, avgFAz)). overall_score = weighted z-sum. position_score = z-score within position group (independent). RankedPlayer response includes position_score + position_rank. Frontend: TeamDetail RosterTable shows Value column (+8.3 #4 overall, PG #2 position) + color-coded stat cells. See docs/ranking-algorithm.mdcmd/import/ downloads roster + player_stats CSVs from nflverse GitHub releases, upserts into nfl_players and nfl_player_stats. Idempotent (ON CONFLICT upserts). Data available from 1999–present; default imports 2020–2024. nfl_players.yahoo_id links to Yahoo fantasy player keys for cross-referencing.cmd/projections/main.go is a batch CLI tool. Step 1 (-profiles) aggregates nfl_player_stats into per-player, per-season profiles with pre-computed z-scores stored as JSONB. Step 2 (-project) finds similar historical players (similarity threshold ≥ 0.60, not a fixed count) using weighted Euclidean distance on z-scored dimensions, then applies their post-match development trajectories (weighted by ) to project the target player. Comp count is itself a signal: many comps = common archetype (higher confidence), few/zero = unique profile. Draft capital only used as a similarity dimension for players with < 3 years experience. See .vite-plugin-basic-ssl (required for Yahoo OAuth)similarity²docs/projection-algorithm.mdcmd/projections/backtest.go defines projConfig (similarity threshold, age window, per-position dimension weights). Reads projection_config.json if it exists; otherwise uses hardcoded defaults. Auto-tuner (-autotune) does coordinate descent over these parameters across training seasons and saves the best config. -backtest runs temporal-integrity backtesting (only prior-season data used) and stores RMSE/MAE/correlation metrics in nfl_backtest_results.GET /api/nfl/players/{gsisId} returns metadata + year-over-year season stats + projection (if exists). Player rows in all tables (rosters, rankings, matchup, players tab, draft tab) are clickable and navigate to /players/:gsisId. Yahoo→GSIS lookup via nfl_players.yahoo_id; batch ANY() query for rosters, per-request map for rankings.league.sport === 'nfl'). Uses GET /api/leagues/{id}/draft-values to fetch league-specific VOR + auction values based on actual roster settings (superflex-aware). Position filter + PPR/Half/Standard format toggle. /projections/:gsisId routes redirect to /players/:gsisId.cmd/projections/grades.go; (2) Stat Projections — comp-based; (3) Fantasy League Value — VORP/z-scores. Grades use position-specific sub-score weights (production, efficiency, usage, durability). Computed via make project-nfl ARGS="-grades". nfl_player_grades table stores results. Grade z-score (overall_grade_z) is injected into season profiles and used as a similarity dimension for comp matching (weight 1.25). Grade YoY trend applies a bounded ±5% adjustment to projected stats. Frontend: GradeCard on player detail, Grade column on projections/draft/players tabs, standalone /rankings page. Former Rankings tab absorbed into Players tab.sqlc.yaml exists but is unused; raw queries are preferred for their directness and flexibility with pgx features (e.g. ANY($1) with slices). Keep queries in handler methods, not in a separate query layer.