少人数が1つの共有ワークスペースを編集するマーケットウォッチリストです。価格取得をサーバー側へ集約し、全利用者が同じキャッシュ済み価格とチャート履歴を参照します。
npm ci
npm run devNode.js 22.16以降とnpm 10以降を使用します。lockfileどおりに環境を作るときは npm ci を使ってください。Windows PowerShellでは実行ポリシーによる npm.ps1 の失敗を避けるため、エージェントと手動検証のどちらも npm.cmd を使います。
npm.cmd ci
npm.cmd run dev
npm.cmd run check
npm.cmd run verifycheck: Node標準テストランナーの単体テストとTypeScript型検査verify:checkに加えてNext.js本番ビルド- 依存追加・更新は明示的な作業として行い、通常の実装では
package.jsonとpackage-lock.jsonを変更しません。
Codexはリポジトリをtrustedとして開くと .codex/config.toml を読み込み、AGENTS.md の短いプロジェクト指示に従います。既定はGPT-5.6のmedium reasoning、Standard相当の実行、最大3エージェントです。小さな変更は単一エージェントで処理し、独立した調査や検証だけを並列化します。
Copy .env.example to .env.local and fill Supabase values when enabling auth.
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=
SUPABASE_SECRET_KEY=
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
MARKET_DATA_PROVIDER=mock
FINNHUB_API_KEY=
EODHD_API_KEY=
MASSIVE_API_KEY=- Create a Supabase project.
NEXT_PUBLIC_SUPABASE_URLにはhttps://<project-ref>.supabase.coだけを設定し、/rest/v1などのパスは付けません。NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYには Project Settings > API Keys の Publishable key(sb_publishable_...)を設定します。SUPABASE_SECRET_KEYには Secret key(sb_secret_...)を設定します。このキーはDiscord所属確認後のメンバー登録にだけサーバー側で使い、NEXT_PUBLIC_を付けないでください。 - Supabase Dashboardの Authentication > Sign In / Providers でDiscordを有効化し、DiscordのClient ID / Client Secretを保存します。同じ値をサーバー専用の
DISCORD_CLIENT_ID/DISCORD_CLIENT_SECRETにも設定します。アプリは期限切れのDiscordアクセストークンをこの資格情報で更新するため、NEXT_PUBLIC_を付けないでください。 - Discord Developer PortalのOAuth2 Redirectsには、Supabase画面に表示される
https://<project-ref>.supabase.co/auth/v1/callbackを登録します。アプリの/auth/callbackではありません。 data/supabase-schema.sql、data/shared-workspace-migration.sql、data/spaces-migration.sqlの順にSupabase SQL Editorで実行します。- SupabaseのURL ConfigurationでSite URLを設定し、Redirect URLsへ
http://127.0.0.1:3000/auth/callbackと本番のhttps://<host>/auth/callbackを追加します。 - 利用者をDiscordだけに限定する場合は、SupabaseのほかのSign In Providerを無効にします。
Discord認証では identify email guilds スコープを要求します。既存のログインセッションは一度ログアウトし、再ログインして所属サーバー一覧へのアクセスと自動更新用トークンを保存してください。以後はSupabaseセッションとDiscordアクセストークンを自動更新します。サーバー配下には複数の共有スペースを、個人には複数のプライベートスペースを作成できます。
MARKET_DATA_PROVIDER=finnhubとFINNHUB_API_KEYをサーバー環境変数へ設定すると、/api/market/snapshotが価格を取得します。APIキーはブラウザへ公開しません。- 価格は60秒、チャート履歴は15分キャッシュされます。同じ銘柄構成の同時リクエストは1回の外部API呼び出しへまとめられます。
- ブラウザは60秒ごとに共有キャッシュを確認します。各利用者からFinnhub WebSocketへ直接接続しません。
- 履歴の取得時刻は15分境界へ揃えているため、全利用者へ同じチャート系列を返します。
- US stocks use symbols like
AAPL; FX uses OANDA-style symbols likeOANDA:USD_JPY; Japan equities try.Tsymbols like7203.Tand fall back to demo data if realtime is not available. - The API routes do not return dummy data when a provider is missing or a symbol has no data; the card stays in loading/no-data state.
/api/market/snapshotnormalizes Finnhub REST snapshots whenMARKET_DATA_PROVIDER=finnhub, and EODHD snapshots whenMARKET_DATA_PROVIDER=eodhd.- サーバーが複数インスタンスに分かれる環境でもNext.jsのfetch/CDNキャッシュを利用します。インスタンス内ではさらに同時リクエストをsingle-flightします。
- Discordログイン済み利用者は全員
Shared Market Deskの同じレイアウトを編集し、Supabase Realtimeで反映されます。 - 未ログイン時や同期障害時はローカル保存を継続します。
- Discord認証の開始・コールバック交換・共有DB接続のエラーは画面上に表示されます。
- Original indexes are equal-weighted from selected visible instruments with a 1000 base value.
- Deployment probe: 2026-07-09.