Skip to content

障害記録: POST /api/v1/auth/login 500 — prisma db push失敗によるログイン不能 (2026-03-22) #3

@Workwrite-Niidome

Description

@Workwrite-Niidome

障害概要

項目 内容
発生日時 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 が失敗しても、このスクリプトが先に実行されカラムを追加する。

2. Dockerfile CMD修正 — ba6cdeb, 1fa0d4f

# 修正後
CMD ["sh", "-c", "node prisma/ensure-schema.js && (npx prisma db push ... || echo 'WARNING') && (npx prisma db seed || true) && node dist/main"]

3. 全Userクエリに select 追加 — 4573c4e, 1fa0d4f

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追加

教訓・再発防止

  1. Docker CMDのコマンドチェーンでは () で明示的にグルーピングする&& || は左結合で意図しない評価順になりやすい
  2. prisma db push のようなDB変更は失敗を検知できるようにする — ログ出力必須、失敗時のフォールバック機構
  3. Prismaの findUnique()select を省略すると全カラム取得になる — 新カラム追加時にDB未適用だと既存の全クエリが壊れる
  4. スキーマにカラムを追加するPRでは、既存クエリへの影響を確認する — selectなしのクエリが壊れないか

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions