Invalid Date
バイト先情報交換掲示板の開発日誌:Indeed APIから独自機能、そして多言語化・翻訳機能まで
はじめに
このプロジェクトは当初、Indeed APIを活用した求人情報サイトとして構想されました。しかし、Indeed APIの利用が却下されたことを受け、私たちは方向転換を決断しました。ユーザーが自身のアルバイト先に関する情報交換を行える「バイト先情報交換掲示板」という、よりコミュニティに根ざしたサービスへと趣旨を変更し、開発を進めることになりました。
本記事では、このプロジェクトの変遷と、その中で実装された主要な機能、そして直面した技術的な課題とその解決策について、開発日誌としてまとめます。
掲示板機能の導入
新しいコンセプトに基づき、ユーザーが自由に情報を投稿できる掲示板機能の核となる部分を構築しました。
- Prismaモデルの定義: 掲示板の投稿を管理するため、
prisma/schema.prismaにForumPostモデルを新規追加しました。これにより、投稿のタイトル、内容、投稿者などの情報をデータベースで管理できるようになりました。 - APIエンドポイントの実装: 投稿の作成(
POST /api/forum/posts)と一覧取得(GET /api/forum/posts)を行うためのAPIルートをsrc/app/api/forum/posts/route.tsに実装しました。 - 基本的なUIの構築: 投稿の一覧表示ページ(
src/app/[locale]/forum/page.tsx)と、新規投稿を作成するためのフォームページ(src/app/[locale]/forum/new/page.tsx)を実装し、ユーザーが基本的な掲示板操作を行えるようにしました。
投稿機能の改善と詳細化
掲示板の利便性を高めるため、投稿内容にさらなる情報を追加できるよう拡張しました。
- 連絡先フィールドの追加: 投稿者が任意で連絡先情報を共有できるよう、
ForumPostモデルにcontactフィールドを追加し、新規投稿フォームにも対応する入力欄を設けました。これにより、ユーザー間のコミュニケーションを促進します。- 表示時には、メールアドレスであれば
mailto:リンク、httpで始まるURLであれば外部リンクとして自動的に変換し、それ以外はテキストとして表示するように改善しました。
- 表示時には、メールアドレスであれば
- 地域情報の追加: 投稿内容に地域性を持たせるため、「都道府県」と「市区町村」フィールドを追加しました。
ForumPostモデルにprefectureとcityフィールドを追加し、新規投稿フォームにも入力欄を設けました。- 掲示板一覧では、これらの地域情報が表示されるようになりました。
- 絞り込み機能: 投稿された掲示板を「都道府県」と「市区町村」で絞り込んで表示できるフィルター機能を実装しました。これにより、ユーザーは関心のある地域の情報に素早くアクセスできるようになりました。
投稿削除機能
掲示板の健全な運用のため、投稿の削除機能を実装しました。
- 管理者ロールの導入: ユーザーモデル(
User)にRoleというenum型(USERとADMIN)を導入し、管理者権限を持つユーザーを識別できるようにしました。 - 削除APIの実装: 特定の投稿を削除するための
DELETE /api/forum/posts/[id]エンドポイントをsrc/app/api/forum/posts/[id]/route.tsに実装しました。このAPIは、投稿者本人または管理者のみが削除を実行できるように権限チェックを行います。 - フロントエンドの対応: 掲示板一覧ページに削除ボタンを設置し、現在のユーザーが投稿者であるか管理者であるかである場合にのみ表示されるようにしました。
多言語化対応の強化とユーザー生成コンテンツの翻訳
グローバルなユーザーベースを想定し、アプリケーション全体の多言語化を推進しました。特に、ユーザーが投稿した内容そのものを翻訳する機能は、大きな挑戦でした。
- UI要素の多言語化: 掲示板のタイトル、ボタン、フォームのラベルなど、すべてのUI要素を
react-i18nextとcommon.jsonファイルを通じて多言語化しました。 - 都道府県名の多言語化: 投稿に表示される都道府県名も、
prefectureKeyMapを用いて現在の表示言語に合わせて翻訳されるようにしました。 - ユーザー生成コンテンツの翻訳機能:
- バックエンドAPI (
/api/translate): Google Cloud Translation APIを利用して、投稿のタイトル、内容、連絡先、市区町村といったユーザーが入力したテキストを翻訳するAPIエンドポイントを実装しました。このAPIは、GOOGLE_TRANSLATE_API_KEY環境変数を必要とします。 - フロントエンドの統合: 掲示板一覧の各投稿に「翻訳」ボタンを追加しました。このボタンをクリックすると、投稿内容が現在のUI言語に翻訳されて表示されます。「元の表示」ボタンで元の言語に戻すことも可能です。
- バックエンドAPI (
直面した技術的な課題と解決
開発過程ではいくつかの技術的な課題に直面しましたが、一つずつ解決していきました。
- Next.jsのハイドレーションエラー:
Date.toLocaleString()の使用やブラウザ拡張機能が原因で発生するハイドレーションエラーに対し、クライアント側でのレンダリングタイミングを調整するなどの修正を行いました。 - ルートパスの404エラー: 国際化されたルーティングにおいて、ルートパス(
/)へのアクセスが404となる問題を解決するため、デフォルトのロケール(ja)へリダイレクトするミドルウェア(src/middleware.ts)を導入しました。 - 非同期クライアントコンポーネントのエラー:
LoginPage内でRegisterLinkが非同期クライアントコンポーネントとして扱われエラーとなる問題を、paramsの解決方法を見直すことで修正しました。 - APIでのセッション処理の不備: 掲示板投稿時に「Unauthorized」エラーが発生する問題を、
getSession関数へのcookieHeaderの渡し方とセッションチェックのロジックを修正することで解決しました。 - Google Cloud Translation APIキーの認証: APIキーが有効でないというエラーに対し、APIキーとサービスアカウント認証の違いを明確にし、正しいAPIキーの取得と環境変数への設定方法を案内しました。
おわりに
本プロジェクトは、Indeed APIの制約から始まり、ユーザー中心の掲示板機能へと進化しました。多言語対応やユーザー生成コンテンツの翻訳といった複雑な機能の実装を通じて、多くの技術的課題を乗り越え、より堅牢で使いやすいアプリケーションへと成長しました。
今後の展望としては、翻訳機能のパフォーマンス最適化や、ユーザーからのフィードバックに基づいたさらなる機能改善が考えられます。