開発環境セットアップ(開発者向け)
このページはツールを自分のマシンで動かす開発者向けです。リポジトリの clone から最初の Bundle が出力されるまでを 30 分で通します。BQ 鍵・docker compose・smoke export までを順に説明します。アプリの「使い方」を知りたい方は左メニューの「使い方ガイド」へ。
📘 これは開発者向けのページです。 アプリを「使う」だけなら、このセットアップは不要です。ブラウザでツールを開いて操作する手順は はじめての解析(30分) を見てください。
5 ステップで動かす
環境前提: WSL2 / Linux / macOS。pnpm 9、uv 0.4+、docker compose v2、bq CLI、gcloud CLI が入っていること。
git clone 後 pnpm install && uv sync で Node/Python 依存をまとめて入れる。 /home/k1ito/suntory-nedo2/.keys/suntory-analytics-bq.json に 600 権限で置く。git 管理外。 .env.example をコピーして BQ_PROJECT_ID / BQ_LOCATION / BQ_SA_KEY_FILE の 3 つだけ書く。 scripts/smoke-export.py で「被験者 1 件 → Bundle 完成」までを 1 コマンドで確認する。 1. リポジトリを準備する
モノレポは pnpm workspace (Node 側) と uv workspace (Python 側) の二段構成です。それぞれのロックファイルが既に同梱されています。
# clone git clone <repo-url> ~/suntory-nedo2 cd ~/suntory-nedo2 # Node 側: pnpm 9 を有効化 (corepack 経由が確実) corepack enable corepack prepare pnpm@9 --activate pnpm install # Python 側: uv (Astral) で全 package + apps をインストール uv sync # ビルド一括確認 (turbo タスクグラフ) pnpm build
なぜ pnpm + uv? pnpm はモノレポでのリンク高速化、uv は Python 依存解決 / ロック / Docker レイヤキャッシュが圧倒的に速いため。Yarn berry や Poetry より導入摩擦が低い。
2. BigQuery サービスアカウント鍵を配置する
本リポジトリは `.keys/` 配下にローカル限定で鍵を置く 規約です (旧 suntory-nedo リポは外部パスに置いていましたが、v2 ではリポ配下に閉じ込めます)。.gitignore で *-bq.json と suntory-analytics-bq.json の二重除外があります。
# 旧リポからコピー (持っていなければ GCP 管理者から取得)
sudo cp /home/k1ito/MizutaniLab3/.keys/suntory-analytics-bq.json \
/home/k1ito/suntory-nedo2/.keys/suntory-analytics-bq.json
sudo chown k1ito:k1ito /home/k1ito/suntory-nedo2/.keys/suntory-analytics-bq.json
chmod 600 /home/k1ito/suntory-nedo2/.keys/suntory-analytics-bq.json 絶対にコミットしない: 鍵 JSON は .gitignore で除外されていますが、誤って git add -A で巻き込まないよう git status を毎回確認してください。漏えい時は GCP IAM コンソールで該当鍵を delete し、新鍵に差し替えます。
3. .env を最小構成で作る
本プロジェクトは "Frontend-Configurable First" 方針で、OS 環境変数は DB に到達するまでの最小値 だけに限定します。それ以外は Settings 画面から編集します (settings カタログ 参照)。
# .env (リポルートに作成。.gitignore 済み) BQ_PROJECT_ID=sic-poc1-verify BQ_LOCATION=US BQ_SA_KEY_FILE=/home/k1ito/suntory-nedo2/.keys/suntory-analytics-bq.json # docker compose 用 (DB/Redis 接続) SN_DB_URL=postgresql+asyncpg://sn:sn@localhost:5432/sn SN_REDIS_URL=redis://localhost:6379/0 # ローカル開発用 KMS フォールバック (本番は SN_KMS_KEY_URI=gcp-kms://...) SN_KMS_LOCAL_PASSPHRASE=devsecret
LLM キーや S3 認証情報は .env に書かない: Settings 画面 (llm.api_key / storage.access_key 等) から KMS 暗号化付きで登録します。.env.example にコメントとして残しているのは「ここには置かないでね」という意図的なリマインダです。
4. docker compose で依存を立ち上げる
Postgres / Redis / MinIO が依存サービスです。各 app は pnpm dev でホスト側で起動するのが速い (Web の HMR・API の reload が即時)。本番イメージのテストをしたいときは docker compose --profile full up で API/Worker もコンテナ起動できます。
# 依存サービスだけ立てる (default profile) docker compose -f docker-compose.dev.yml up -d postgres redis minio # Alembic マイグレーション uv run alembic -c apps/studio-api/alembic.ini upgrade head # DefaultRegistry → settings 初期投入 uv run python scripts/seed-defaults.py # allowlist 初期投入 (xhro_NN.* + xhro_view.* + xhro_04_modeling_v2.*) uv run python scripts/seed-allowlist.py # 3 プロセスをそれぞれ起動 (別ターミナル推奨) pnpm --filter @suntory-nedo/studio-api dev pnpm --filter @suntory-nedo/studio-worker dev pnpm --filter @suntory-nedo/studio-web dev
立ち上がるプロセスと役割
| プロセス / サービス | ポート | 役割 |
|---|---|---|
| studio-web | 3000 | Next.js 15 dev server (App Router)。Quick Export 単一ページが既定着地。 |
| studio-api | 8080 | FastAPI + uvicorn。/v1/healthz / /v1/catalog/sources などを提供。 |
| studio-worker | — | Arq ワーカー。Redis の bundle_build キューを監視して Bundle ジョブを実行。 |
| postgres | 5432 | bundles / jobs / settings / subject_id_map / audit_log テーブルが入る。 |
| redis | 6379 | Arq キュー + settings:changed pubsub + SSE broker のメッセージバス。 |
| minio | 9000 | S3 互換 (本番は GCS)。bundles/{id}/... と _staging/{job_id}/... を保持。 |
| docs | 4321 | 本仕様書 (Astro 5 静的サイト)。pnpm --filter @suntory-nedo/docs dev で起動。 |
5. Smoke Export を回す
scripts/smoke-export.py は「被験者 1 件 → 5 分 Window × 2 → ECG Bundle 生成 → manifest 検証」までを 1 コマンドで実行します。新環境で最初に通すべき E2E スモークです。
uv run python scripts/smoke-export.py \ --source xhro_04.eeg \ --hid XH015 \ --window 2023-11-10T20:00:00+09:00..2023-11-10T20:05:00+09:00 \ --window 2023-11-11T20:00:00+09:00..2023-11-11T20:05:00+09:00 \ --attached acc \ --preset xhro-multiday
期待される出力
[1/8] catalog mirror OK (xhro_04.eeg)
[2/8] subject resolve OK (sub_01HZMX9...XH015, expt_id=XHRO-04)
[3/8] dry_run OK (bytes=12.4MB, rows=1.5M, cost=USD 0.0023, cap_ok=True)
[4/8] enqueue job_01J... canonical_hash=0123abcd...
[5/8] worker phase=extract ✓ (3.1s)
worker phase=clean ✓ (1.2s)
worker phase=rpeak ✓ (0.8s)
worker phase=hrv ✓ (0.4s)
worker phase=pyramid ✓ (1.6s)
worker phase=attach ✓ (0.6s)
worker phase=manifest ✓ (0.1s)
worker phase=register ✓ (0.3s)
[6/8] _READY committed → bdl_01HZMX...
[7/8] manifest_sha256 verified
[8/8] file integrity (9 files) verified
DONE: bdl_01HZMX9P2QR3S4T5U6V7W8X9Y (12.4 MB, 9 files, USD 0.0023) 失敗時のチェック順: ① bq --location=US ls sic-poc1-verify: が通るか (鍵と権限)、② Postgres マイグレーションが head か (alembic current)、③ Redis に届くか (redis-cli ping)、④ MinIO バケット sn-bundles が作成済みか (scripts/reset-dev.sh が作る)。
ブラウザで Quick Export を触る
http://localhost:3000 で Quick Export ページが開きます。OIDC を未設定の場合は dev session で自動ログインされます (auth.oidc_* 設定が空のとき)。
- 被験者ピッカーで
(XHRO-04, XH015)を検索 → 選択。raw UID は表示されません。 - 時間帯セクションで「Recording をそのまま全部」 / 「Recipe」 / 「ドラッグで選ぶ」のいずれか。概観波形は pyramid L3 から描画。
- 含める信号は ECG と ACC が既定 ON。PPG / BioZ / 派生 SpO2 は必要時のみ追加。
- 見積もりカードに「約 30 秒」「予算内」のように人間語で出ます (詳細を開くと dry-run の bytes/USD)。
- [エクスポート] → Job ページに遷移して SSE で進捗バーが流れます。完了で Bundle ID と Workspace deep link が表示されます。
cost cap や Window 上限に当たると: [エクスポート] ボタンが押せなくなり、上に黄帯で「Window が bq.windows_per_bundle_max=12 を超えています」のような警告が出ます。エラーは Build 押下後ではなく 押す前 に出る設計です (FR-X14)。
開発でよく使うコマンド
頻出のタスクをまとめます。turbo タスクグラフで一括化されているので、リポルートから pnpm <task> で全アプリ横断に走ります。
Node 側
pnpm dev # 全 app の dev サーバを並列起動 pnpm build # 全 app のビルド pnpm lint # biome lint (eslint+prettier 置換) pnpm typecheck # tsc --noEmit pnpm test # vitest (UI + lib) pnpm e2e # Playwright (Quick Export + Wizard)
Python 側
uv sync # 依存同期 uv run ruff check . # lint uv run ruff format . # format uv run pytest -q # 全テスト (unit + integration) uv run pytest -m "not bq" # BQ 必須テストを除外 uv run alembic upgrade head # マイグレーション
本仕様書 (この Astro サイト) を編集する
このページ自体は apps/docs/ 配下に Astro 5 で書かれています。ホットリロード付きで触れます。
pnpm --filter @suntory-nedo/docs dev # http://localhost:4321 pnpm --filter @suntory-nedo/docs build # apps/docs/dist/ に静的サイト出力 pnpm --filter @suntory-nedo/docs preview # build 後のローカル確認
- レイアウト:
apps/docs/src/layouts/Doc.astro(左ナビとヘッダー) - 各ページ:
apps/docs/src/pages/<name>.astro - 共通スタイル:
apps/docs/src/styles/global.css(Coinbase Blue + Inter) - 新規ページを追加する場合は
Doc.astroのnavGroups配列に項目を追加してください。
つまずいた時の参照先
BQ で空結果やエラーが出る
生 xhro.* を読んでいませんか? data § xhro テーブルの罠 を確認してください。Studio は xhro_NN.* (clone) を読むように allowlist が設定されています。
Settings が反映されない
変更が反映されないキーは「再起動が必要 (restart-required)」かもしれません。settings § Hot reload を参照。
Bundle build が失敗する
失敗は jobs テーブルの error_code / error_message に残ります。中間 Parquet は gs://<bucket>/_staging/{job_id}/ に 7 日間保持され、再開可能です (operations § Job 状態機械)。
permission denied / 403 が返る
RBAC マトリクスは rbac.matrix_json 設定で定義されています。デフォルトでは新規ユーザは viewer ロールで、Bundle build は scientist 以上が必要です (operations § RBAC マトリクス)。