Invalid Date
開発日誌:Konnichiworkプロジェクトの課題解決の旅
この開発日誌では、Konnichiworkプロジェクトで直面した様々な技術的課題と、それらをどのように解決していったかを記録します。Next.jsの特性、特にApp RouterとEdge Runtimeの挙動を深く理解する良い機会となりました。
1. 初期ビルドエラーの解決
プロジェクト開始直後、useEffectがServer Componentで使われているというビルドエラーに遭遇しました。これはNext.jsのServer ComponentとClient Componentの混在によるものでした。
- 問題点:
src/app/[locale]/page.tsxがasync関数でありながら'use client'ディレクティブを持ち、useEffectを使用していた。 - 解決策:
asyncコンポーネントはServer Componentであるため、useEffectの使用は不適切でした。useEffectの呼び出しと関連するインポートを削除することで、このエラーは解消されました。
2. ミドルウェアとルーティングの問題
次に、APIルートや画像アセットへのアクセス時に、言語ロケールが不適切に付加される問題が発生しました。
- 問題点:
src/middleware.tsのmatcher設定が不十分で、APIルートや静的ファイル(例:lang_icon.png)にも国際化ルーティングが適用され、404 Not Foundエラーを引き起こしていた。 - 解決策:
middleware.tsのconfig.matcherを修正し、apiルート、_next関連パス、favicon.ico、そしてlang_icon.pngのような静的アセットを明示的に除外するようにしました。
3. 認証システムの大規模なリファクタリング
プロジェクトの最も根深い問題は、認証システムにありました。next-authとカスタム認証ロジックが混在しており、これが多くの問題の根本原因となっていました。
- 問題点:
- ログイン後もヘッダーの表示が更新されない。
- 「Not authenticated」エラーが頻発する。
[auth][error] MissingSecretやJWTSessionErrorといったnext-auth関連のエラーが発生する。- お気に入り機能が動作しない。
- 根本原因: プロジェクトが
next-authのセッション管理と、独自のカスタムセッション管理(getSession関数とsessionクッキー)の二重構造になっていたこと。next-authは独自のクッキーとJWTを使用するため、カスタムセッションでは認証状態を認識できなかった。 - 解決策:
src/auth.tsにCredentialsProviderを追加し、既存のパスワード検証ロジックを統合。- ログインページ(
src/app/[locale]/login/page.tsx)を修正し、カスタムAPI呼び出しの代わりにnext-authのsignIn関数を使用するように変更。 - 不要になったカスタムログインAPIルート(
src/app/api/login/route.ts)を削除。 next-authのシークレットキー(AUTH_SECRET)が環境変数に正しく設定されていない問題を修正し、.env.localに追記。JobCardのお気に入りボタンの動作を修正するため、window.location.reload()を削除し、親コンポーネントからのコールバック(onFavoriteToggleSuccess)で状態を更新するように変更。- メインページ(
src/app/[locale]/page.tsx)、求人投稿ページ(src/app/[locale]/post-job/page.tsx)、マイページ(src/app/[locale]/my-page/page.tsx)、求人詳細ページ(src/app/[locale]/jobs/[id]/page.tsx)、お気に入りAPI(src/app/api/favorites/add/route.ts,src/app/api/favorites/remove/route.ts)、求人API(src/app/api/jobs/route.ts,src/app/api/jobs/[id]/route.ts)など、認証が必要なすべての箇所で、カスタムセッションロジックをnext-authのauth()関数に置き換え、セッション管理を一元化。
4. フォーラム機能の改善
フォーラム機能にも複数の問題が見つかりました。
- 問題点:
PrismaClient is unable to run in this browser environmentエラーが発生し、フォーラムの投稿が表示されない。- 都道府県名が翻訳されず、市区町村名が消える。
- 中国語版で多くのUIテキストが翻訳されていない。
- コメント機能が動作しない。
- 解決策:
src/app/api/forum/posts/route.tsで、new PrismaClient()の代わりに@/lib/prismaからEdge Runtime互換のPrisma Clientをインポートするように修正。また、$queryRawの使用を避け、findManyなどの標準的なクエリに置き換え。prisma/migrationsディレクトリの不整合を解消するため、マイグレーション履歴をリセットし、再生成。src/app/[locale]/forum/page.tsxおよびsrc/app/[locale]/forum/new/page.tsxで、都道府県名の表示ロジックを修正し、prefectureKeyMapとt()関数を適切に利用するように変更。public/locales/zh/common.jsonに不足していた中国語の翻訳キーを大量に追加。src/app/api/forum/posts/route.tsで、市区町村のローマ字変換ロジックを復活させ、city_romajiフィールドをデータベースに保存・取得するように変更。src/app/[locale]/forum/page.tsxで、翻訳ボタンの動作を修正し、県名を翻訳対象から除外。- コメントAPI(
src/app/api/forum/posts/[id]/comments/route.ts)も、next-authのauth()を使用するように修正し、PrismaClientのインスタンス化も修正。 - コメントフォームに連絡先フィールドを追加し、表示ロジックも更新。
5. 求人詳細ページと画像アップロード
- 問題点:
- 求人詳細ページでJobCardが翻訳されない。
- 削除ボタンとお気に入りボタンが重なる。
- 画像アップロードが
501 Not Implementedエラーで失敗する。
- 解決策:
- 求人詳細ページ(
src/app/[locale]/jobs/[id]/page.tsx)のtranslateJobContentから、英語翻訳をスキップする条件を削除。 JobDetailClient.tsxで、ボタンの重なりを修正するため、FavoriteButtonとJobActionsの配置を調整。- 画像アップロードAPI(
src/app/api/upload/route.ts)を、ローカルの/public/uploadsディレクトリにファイルを保存するように実装。ただし、これは開発環境専用であり、本番環境ではクラウドストレージサービスが必要であることを明記。
- 求人詳細ページ(