defineEnv — zod 検証つき env リゾルバ
3リポのどこにも無かった欠落機能である。DATABASE_URL / CRON_SECRET / FOURS_* の欠落を boot 時に fail-fast で検出し、本番で undefined のまま静かに走らせない。
// src/env.ts
import { z } from "zod";
import { defineEnv } from "@event/core";
export const env = defineEnv({
FOURS_EVENT_SLUG: z.string().min(1),
ADMIN_PASSWORD: z.string().min(8),
SESSION_SECRET: z.string().min(16),
DATABASE_URL: z.string().url().optional(),
});
検証失敗は EnvValidationError を throw し、キーごとの理由を列挙する。同じ shape から envExample(shape, comments) で .env.example の内容を生成できる(optional キーには # optional 注記が付く)。生成物は commit して運用する。
4S 接続(@event/fours-sdk — createFoursConfig が解決)
| 変数 | 用途 | 既定 / 備考 |
|---|
FOURS_API_BASE | event API base | https://api.4s.link。legacy FOURS_API / FOUR_S_API fallback あり |
FOURS_EVENT_SLUG | 対象イベント slug | fetchEvent の既定 slug |
FOURS_PUBLIC_READ | 1/true で public-read mode | 認証なし読み取り |
FOURS_API_KEY | write 系 Bearer。設定で authenticated mode | legacy FOUR_S_API_KEY / FOUR_S_SERVICE_TOKEN fallback |
USE_MOCK_DATA | 1 で mock-locked(4S に一切出ない) | mode 判定の最優先 |
FOURS_WEBHOOK_SECRET | inbound webhook HMAC-SHA256 鍵 | verifyWebhookSignature |
FOURS_V2_API_BASE / NEXT_PUBLIC_4S_V2_API_BASE | auth 系(login / users/me / handoff)base | 未指定なら apiBase と同一ホスト |
NEXT_PUBLIC_4S_V2_WEB_BASE | 4S Web base(プロフィール URL 組み立て) | https://4s.link |
NEXT_PUBLIC_4S_LOGIN_URL | ログインレス handoff の起点 URL | https://4s.link/ja/handoff/launch |
セッション / 認証
| 変数 | 用途 | 備考 |
|---|
SESSION_SECRET | jose HS256 cookie セッションの署名鍵 | 本番未設定は createSessionCodec が throw(fail-closed)。dev は警告つき固定鍵 |
ADMIN_PASSWORD | 共有パスワード admin の期待値 | 未設定は fail-closed(ログイン不可)。realm ごとに passwordEnv で別変数も指定可 |
4S service / admin API(opt-in)
| 変数 | 用途 |
|---|
FOURS_REFRESH_TOKEN | Cognito refresh token(優先。Google ログインのアカウント可) |
FOURS_LOGIN_EMAIL / FOURS_LOGIN_PASSWORD | POST /auth/login fallback |
FOURS_EVENT_ID | admin API(/manage/events/{id}/entries 等)の対象イベント ID |
コンテンツストア(@event/core createContentStore — 本番のみ)
| 変数 | 用途 | 既定 |
|---|
GITHUB_TOKEN | Octokit commit 用 PAT | 必須(本番書き込み) |
GITHUB_REPO_OWNER / GITHUB_REPO_NAME | commit 先リポジトリ | 必須 |
GITHUB_BRANCH | commit 先ブランチ | main |
ストレージ / KV / cron
| 変数 | 用途 | 備考 |
|---|
BLOB_READ_WRITE_TOKEN | Vercel Blob(@event/asset-kit createAssetStore) | 未設定時 put は throw |
KV_REST_API_URL / KV_REST_API_TOKEN | Upstash Redis REST(Vercel KV) | 未設定なら dev in-memory shim に自動フォールバック |
UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN | 同上の別名 | kv() が両方を解決 |
CRON_SECRET | Authorization: Bearer 厳格一致(withCronAuth) | 未設定は 503 fail-closed。比較は trim 硬化 |
ビルド制御
| 変数 | 用途 |
|---|
NEXT_DIST_DIR | distDir の明示指定(createNextConfig) |
BUILD_LOCAL | 1 で distDir を .next-local に分離(dev 中の yarn build 事故防止) |
既知のトラップ
- 前後空白 / 末尾スラッシュ: env に紛れ込んだ空白は Authorization ヘッダを壊して 401 になる。
createFoursConfig は全値を trim() し、base URL は normalizeBase() で末尾スラッシュも除去する。CRON_SECRET の比較も trim 済み。ただし SDK を通らない自前コードは自衛が必要 *2 付きホスト(api-staging2.4s.link / api-develop2.4s.link)は staging / develop 専用。本番は api.4s.link / 4s.link- legacy
FOUR_S_ 系は fallback として読まれるが、新規イベントでは FOURS_ に統一する