障害概要
| 項目 |
内容 |
| 発生日時 |
2026-03-22 20:44 JST (デプロイ完了後) |
| 検知日時 |
2026-03-22 21:07 JST (最初のログインエラー) |
| 影響 |
POST /api/v1/auth/login が500を返し全ユーザーがログイン不能 |
| 影響範囲 |
/api/v1/auth/referral も同時に500 |
| 環境 |
Railway (backend-production-db434.up.railway.app) |
| 復旧 |
修正コミット 1fa0d4f デプロイ後に復旧 |
原因
直接原因
コミット d094bdd (招待コード機能) で User モデルに以下のカラムを追加:
referralCode (TEXT, UNIQUE)
referralCount (INTEGER)
referralCredits (INTEGER)
referredBy (TEXT)
デプロイ時に prisma db push が失敗し、DBにカラムが追加されなかった。
Prisma Clientはビルド時に新スキーマで生成済みのため、findUnique() が存在しないカラムを参照して500エラー。
根本原因: DockerfileのCMD演算子優先度バグ
# 問題のCMD
CMD ["sh", "-c", "npx prisma db push ... && npx prisma db seed || true && node dist/main"]
シェルの評価順: (db push && db seed) || (true && node dist/main)
→ db push が失敗しても || true && node dist/main でサーバーが起動してしまう。
prisma db push が失敗した理由
ログに db push の出力が一切なく、エラー内容は不明。
エラーログ
[Nest] 1 - 03/22/2026, 12:07:06 PM ERROR [ExceptionFilter] POST /api/v1/auth/login 500: Internal server error
PrismaClientKnownRequestError:
Invalid `prisma.user.findUnique()` invocation:
The column `User.referralCode` does not exist in the current database.
修正内容
1. prisma/ensure-schema.js (新規) — ba6cdeb, 1fa0d4f
起動時に ALTER TABLE IF NOT EXISTS で招待カラムを確実にDB適用するスクリプト。
prisma db push が失敗しても、このスクリプトが先に実行されカラムを追加する。
# 修正後
CMD ["sh", "-c", "node prisma/ensure-schema.js && (npx prisma db push ... || echo 'WARNING') && (npx prisma db seed || true) && node dist/main"]
findUnique() / findFirst() で全カラム取得を避け、必要なカラムのみ取得する防御的クエリに統一。
対象ファイル:
auth.service.ts (9箇所)
admin.service.ts (2箇所)
billing.service.ts (2箇所)
follows.service.ts (1箇所)
users.service.ts (1箇所)
関連コミット
| コミット |
内容 |
d094bdd |
原因: 招待コード機能追加 (referralCodeカラム) |
4573c4e |
修正1: loginにselect追加 |
ba6cdeb |
修正2: Dockerfile CMD修正 (db push失敗時もサーバー起動) |
1fa0d4f |
修正3: ensure-schema.js + 全Userクエリにselect追加 |
教訓・再発防止
- Docker CMDのコマンドチェーンでは
() で明示的にグルーピングする — && || は左結合で意図しない評価順になりやすい
prisma db push のようなDB変更は失敗を検知できるようにする — ログ出力必須、失敗時のフォールバック機構
- Prismaの
findUnique() で select を省略すると全カラム取得になる — 新カラム追加時にDB未適用だと既存の全クエリが壊れる
- スキーマにカラムを追加するPRでは、既存クエリへの影響を確認する — selectなしのクエリが壊れないか
🤖 Generated with Claude Code
障害概要
POST /api/v1/auth/loginが500を返し全ユーザーがログイン不能/api/v1/auth/referralも同時に5001fa0d4fデプロイ後に復旧原因
直接原因
コミット
d094bdd(招待コード機能) でUserモデルに以下のカラムを追加:referralCode(TEXT, UNIQUE)referralCount(INTEGER)referralCredits(INTEGER)referredBy(TEXT)デプロイ時に
prisma db pushが失敗し、DBにカラムが追加されなかった。Prisma Clientはビルド時に新スキーマで生成済みのため、
findUnique()が存在しないカラムを参照して500エラー。根本原因: DockerfileのCMD演算子優先度バグ
シェルの評価順:
(db push && db seed) || (true && node dist/main)→
db pushが失敗しても|| true && node dist/mainでサーバーが起動してしまう。prisma db push が失敗した理由
ログに
db pushの出力が一切なく、エラー内容は不明。エラーログ
修正内容
1.
prisma/ensure-schema.js(新規) — ba6cdeb, 1fa0d4f起動時に
ALTER TABLE IF NOT EXISTSで招待カラムを確実にDB適用するスクリプト。prisma db pushが失敗しても、このスクリプトが先に実行されカラムを追加する。2. Dockerfile CMD修正 — ba6cdeb, 1fa0d4f
3. 全Userクエリに
select追加 — 4573c4e, 1fa0d4ffindUnique()/findFirst()で全カラム取得を避け、必要なカラムのみ取得する防御的クエリに統一。対象ファイル:
auth.service.ts(9箇所)admin.service.ts(2箇所)billing.service.ts(2箇所)follows.service.ts(1箇所)users.service.ts(1箇所)関連コミット
d094bdd4573c4eba6cdeb1fa0d4f教訓・再発防止
()で明示的にグルーピングする —&&||は左結合で意図しない評価順になりやすいprisma db pushのようなDB変更は失敗を検知できるようにする — ログ出力必須、失敗時のフォールバック機構findUnique()でselectを省略すると全カラム取得になる — 新カラム追加時にDB未適用だと既存の全クエリが壊れる🤖 Generated with Claude Code