• #eurekapu
  • #nuxt4
  • #better-auth
  • #cloudflare-d1
  • #ssr
  • #e2e-test
  • #devops
開発eurekapu-nuxt4メモ

導入

朝からeurekapu-nuxt4の認証・DB・デプロイ周りに手を入れ続けて、気づいたらターミナルのログが画面から溢れていた。SSRでのクッキー転送、D1マイグレーション、画像配信ルート上限、Google OAuth、E2Eテスト -- 一つ直すと次の問題が顔を出す連鎖を一日がかりで潰していった。

SSRでのクッキー転送問題

SSR環境でサーバーサイドからAPIを叩くと、ブラウザのクッキーが転送されず認証が通らなかった。fetchAccessInfoheadersを明示的に渡すように修正。SSRではブラウザ→Nuxtサーバー→APIの2段階になるので、最初のリクエストのヘッダーを手動で引き回す必要がある。

// useRequestHeaders()でブラウザのCookieを取得し、fetch時に渡す
const headers = useRequestHeaders(['cookie'])
const data = await fetchAccessInfo({ headers })

Better Auth: メール+パスワード認証の追加

開発環境でのテスト用に、メール+パスワード認証を追加した。import.meta.devで分岐させて、本番環境ではGoogle OAuthのみに絞っている。

管理者メール(ADMIN_EMAILS)も本番と開発で分離。開発環境では[email protected]系のアドレスを管理者として扱う。

D1マイグレーション管理

0003から0005まで3本のマイグレーションを作成し、ローカルとリモートの両方に適用した。

外部キーのON DELETE CASCADE統一(0005)

SQLiteではALTER TABLEで外部キー制約を変更できないため、テーブルを作り直す必要がある。0005マイグレーションでは以下の手順を踏んだ:

  1. 新テーブルを作成(CASCADE付き)
  2. データをコピー
  3. 旧テーブルを削除
  4. リネーム

リモートD1からは本番で不要なpasswordカラムも削除。スキーマスナップショットをドキュメントとして残し、ローカルとリモートの差分を比較できるようにした。

quiz_answerのquestion_idフォーマット不一致

quiz_answerテーブルのquestion_idが、あるパスではハイフン区切り、別のパスではスラッシュ区切りで保存されていた。テストを書いて不一致を再現させてから、フォーマットを統一するように修正した。

画像配信: _routes.jsonの100ルール上限

Cloudflare Pagesの_routes.jsonにはルールが100件までという上限がある。画像パスを個別に列挙していたら上限に引っかかった。ワイルドカード化して対処。

Google OAuthのredirect_uri_mismatch

デプロイ後にGoogle OAuthでredirect_uri_mismatchエラーが発生。BETTER_AUTH_URL環境変数が正しく設定されていなかった。合わせてTRUSTED_ORIGINSの正規化処理をURL.originを使う形に修正し、末尾スラッシュの有無で弾かれる問題を潰した。

UIの微調整

  • ヘッダーをstickyレイアウトに修正。スクロールしてもナビゲーションが追従するようにした
  • ヒーローテキストのフォントサイズ調整

E2Eテスト強化

CIのE2Eテストが不安定だったので、Chromiumのみ実行に変更。--project引数の渡し方も修正した。

テストカバレッジは55件から78件に増加。新しく追加した認証フローやクイズ回答のテストが大半を占める。

その他の修正

  • ログアウト後のリダイレクト先を/loginから/に変更
  • .env.exampleからVPS IPを削除(公開リポジトリに残すべきでない情報)

振り返り

D1マイグレーションでは、SQLiteの「外部キーを後から変更できない」制約に3回テーブル再作成を繰り返した。RDBMSごとのALTER TABLEの差異を体で覚えた一日だった。

_routes.jsonの100件上限は、ドキュメントを読み飛ばしていて踏んだ地雷。Cloudflare Pagesの制約はビルドが通ってからデプロイ後に判明するパターンが多いので、制約一覧を手元にまとめておく価値がある。

テスト数が78件まで積み上がったことで、認証フロー周りの変更を入れるときの安心感が変わった。壊れたらCIが教えてくれるという状態を一日で作れたのは収穫。