OpenAthlete
AGPLv3 endurance training platform: EU-oriented hosting, transparent CTL/ATL/TSB logic in code, self-hosting, and full export. Built in Grenoble.
翻译准备中
制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗競馬の観戦メモを残し、レース単位/馬単位でふりかえるための Web アプリ。 Cloudflare Workers + D1 の上で動く SvelteKit アプリケーション。URL は https://uma-memo.com (workers.dev から移している途中。手順は docs/operations.md「独自ドメインへ移す」)。
旧名は k-note。リポジトリ(keiba-note)・Worker・D1・Google Cloud のプロジェクトは旧名のまま (→ docs/operations.md「名前について」)。
文書の目次は AGENTS.md にある。何を作るかは docs/product.md、 どう動くかは docs/architecture.md から読むとよい。
現在のフェーズ: 予想・ふりかえり・共有が動く。
メモは既定で非公開。 見せたいメモだけ1件ずつ共有リンクを発行して渡す。
共有ページ /notes/[id] はログイン不要で開けるが、検索にも一覧にも出ない。
他人のメモはどの画面にも出てこない(→ product.md 第2章 2-2)。
出走馬の登録は画面からではなく data/ の YAML を PR で更新して行う。
| レイヤ | 採用 |
|---|---|
| フレームワーク | SvelteKit 2 / Svelte 5 (runes) |
| アダプタ | @sveltejs/adapter-cloudflare |
| 実行環境 | Cloudflare Workers |
| DB | Cloudflare D1 (SQLite) — プライマリは apac |
| ORM | Drizzle ORM + drizzle-kit |
| 検証 | Valibot |
| スタイル | Tailwind CSS v4 |
| テスト | Vitest / Playwright |
| パッケージ管理 | pnpm |
Node.js は 24 系(CI の node-version)、pnpm は 10.16.1
(package.json の packageManager)を使う。
Dev Container: Docker と Dev Container 対応ツールで clone 済みのリポジトリを開き、Reopen in Container を選ぶ。
.devcontainer/devcontainer.json が Node 24、git、GitHub CLI を用意し、
作成後に Corepack を有効化して以下の install と setup を実行する。Wrangler はローカル依存関係から使う。
VS Code の設定や拡張機能は検証の前提ではない。
Windows で Docker Desktop を使う場合は、WSL2 側の Linux ファイルシステムに clone して開くことを推奨する。
CLI のみ・Dev Container を使えない場合: Node 24、Corepack、git、GitHub CLI を用意する。
Corepack を有効化して packageManager 指定の pnpm を使い、リポジトリのルートで実行する。
Linux では setup が Chromium の OS 依存パッケージを入れるため、apt と sudo が使える環境が必要。
Windows では Chromium の取得を行う。
corepack enable
node --version # v24.x
pnpm --version # 10.16.1
pnpm install --frozen-lockfile
pnpm run setup
pnpm run verify
verify は型 → lint → 単体テスト → E2E の順に動く。vite.config.ts の単体テストの client プロジェクトも
実 Chromium を使うため、test:unit より前に setup を実行する。test:e2e 内の導入だけでは初回の単体テストに間に合わない。
Linux で OS パッケージの導入権限がない場合は、管理者が Playwright の依存パッケージを用意してから setup を再実行する。
権限やネットワークの制約で準備できなければ
検証を完了できないとき に従う。
検証に本番の認証情報は不要。 .dev.vars の作成や Google OAuth の設定も、上の検証の前提ではない。
E2E は専用のローカル D1 と seed のセッションを使い、マイグレーションとデータ準備も自動で行う
(testing.md 第3章)。本番の D1・シークレット・デプロイには触れない。
上の依存関係の導入後、画面を手元で操作するときだけ次を行う。
cp .dev.vars.example .dev.vars # 下記の開発用モック認証、または開発用 Google OAuth を設定
pnpm run db:migrate:local # ローカル D1 にマイグレーションを適用
pnpm run dev
vite dev は platformProxy 経由で .wrangler/state のローカル D1 に接続する。
E2E は別の .wrangler/e2e を毎回空にして使うので、ここに入れたデータは E2E に混ざらない。
Google Cloud Console でのクライアントの作り方と、承認済みのリダイレクト URI
(http://localhost:5173/auth/google/callback を含む)は operations.md 5 にある。
開発用の値を .dev.vars(ローカル)に入れる。本番のシークレット設定は
operations.md に従って人が行う。エージェントは wrangler secret を実行しない。
| 変数 | 用途 |
|---|---|
GOOGLE_CLIENT_ID | OAuth クライアント ID |
GOOGLE_CLIENT_SECRET | OAuth クライアントシークレット |
ADMIN_EMAIL | サイト管理者(admin)になるアドレス |
メモの書き味を見るあいだは、Google OAuth を通さずに入れる。
.dev.vars に MOCK_AUTH="1" を置くと、ログイン画面を飛ばして
モックユーザー(admin / user の2人)として入る。画面上部に警告帯が出て、
そこで2人を切り替えられる。「他人のメモが1件も出てこない」ことの確認に使う。
この経路は dev ガードの中にあり、本番ビルドには存在しない。
$app/environment の dev はサーバー側では静的に false になるため、
分岐ごとバンドルから消える。本番で MOCK_AUTH を設定しても無視される。
招待コードは無い。 Google アカウントがあれば誰でもログインでき、 入ってきた人には自分のメモしか見えない。グループやメンバーの概念は持たない。
ログインした email が ADMIN_EMAIL と一致したときだけ role='admin' になる。
admin ができるのは馬・レース・出走馬(全員共通のマスタ)の修正と、
ユーザーの凍結だけ。admin でも他人のメモは読めない
(→ product.md 第3章)。
| コマンド | 内容 |
|---|---|
pnpm run dev | 開発サーバー |
pnpm run check | wrangler types --check + svelte-check |
pnpm run lint / pnpm run format | Prettier + ESLint |
pnpm test | 単体テストと E2E を順に実行 |
pnpm run test:unit | Vitest を1回実行 |
pnpm run test:watch | Vitest の監視モード |
pnpm run test:e2e | Playwright(本番ビルド + E2E 専用 D1) |
pnpm run verify | check / lint / 単体テスト / E2E を順に(文書だけの変更なら E2E は飛ぶ) |
pnpm run screens <機能名> <before/after> | PR 用の画面キャプチャ(docs/testing.md) |
pnpm run db:generate | schema.ts から drizzle/*.sql を生成 |
pnpm run db:migrate:local | ローカル D1 に適用 |
pnpm run db:migrate:remote | 本番 D1 に適用 |
pnpm run deploy | ビルドして wrangler deploy |
画面からではなく data/races/ の YAML を PR で更新して投入する。 予想に使うには開催前に出馬表が入っている必要があり、毎週16頭を手で打つのは現実的でないため。 人でも AI でも同じ経路で入れられる。書式と投入の性質は data/README.md。
枠が決まる前に名前だけで登録し、確定後に同じファイルを更新してよい。 馬が二重に作られることも、馬番の訂正で落ちることもない。
投入するのは内容が変わったファイルだけ(適用済みのハッシュを D1 の data_import
に覚えている)。投入スクリプトは冪等で、メモ(note)を消さない。 メモに触れるのは
出走しなかった候補を取り下げる(withdrawn)ときだけで、それも近況メモに移すだけ。
YAML は pnpm run data:fetch で netkeiba から書ける(候補・枠順・過去走・馬の基本情報・結果)。
Claude Code からは /race-data スキルで同じ手順を踏める。
スキーマの正は src/lib/server/db/schema.ts。生成は drizzle-kit、適用は wrangler が行う。
pnpm run db:generate # drizzle/NNNN_*.sql と drizzle/meta/ を更新
pnpm run db:migrate:local
pnpm run db:migrate:remote
drizzle/meta/_journal.json は drizzle-kit が採番に使うので、SQL を手書きせず
必ず db:generate を通すこと。
PR までの手順と、コードを変えるときの約束の目次は AGENTS.md にある。 人も AI エージェントも同じものに従う。
main の CI 成功後に ステージング環境 へ反映する。
アプリはリリースの publish で、出走馬データは main へのマージで本番に出る(別系統)。
Cloudflare の構築手順・API トークンの権限・ワークフローの一覧・バックアップは
docs/operations.md。
どこに何を書いてよいか(層と機能の依存の向き)は docs/architecture.md 第2章にある。
src/
├── app.d.ts # App.Platform['env'] の型(Env は wrangler types が生成)
├── hooks.server.ts # 認証。ここだけが認証方式を知っている
├── worker.js # Worker の入口。adapter の Worker を包む(docs/architecture.md 3-5)
├── lib/
│ ├── server/
│ │ ├── db/ # Drizzle スキーマとクライアント生成
│ │ ├── auth/ # セッション / OAuth
│ │ └── services/ # 業務ロジック。SvelteKit を import しない
│ ├── schemas/ # Valibot スキーマ
│ ├── components/
│ └── utils/
└── routes/
drizzle/ # 生成されたマイグレーション SQL