0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

再受験の悔しさから、AI活用でIPA資格試験の過去問アプリを個人開発した話(Cloudflare Pages + D1 + Clerk)

0
Posted at

なぜ作ったか

自分のITに関する技術を強化するために、これまで資格試験を通した学習を続けてきました。ただ仕事をしながらだとまとまった学習時間が取れず、試験には何度か挑戦しても合格に至らないことがありました。

それでもやはり合格したいという気持ちは消えず、ちょうどAIが実務でも当たり前に使われるようになってきたタイミングだったので、「AIを活用した学習体験そのものを自分で作ってみよう」というのが今回の個人開発のきっかけです。

対象はIPA(情報処理推進機構)が実施する高度情報処理技術者試験のうち、プロジェクトマネージャ試験(PM)とITストラテジスト試験(ST)です。どちらも午前II試験は過去問の再出題が多く、「過去問を繰り返し解いて弱点を潰す」学習が有効な一方、市販の過去問道場的なサービスは選択肢が限られていたため、自分が欲しい機能(苦手分野だけを抽出した特訓モード、計算問題専用トレーニング、午後試験への橋渡し分析など)をアプリを作ることにしました。

技術構成

個人開発なので、まずは「ほぼ無料で本番運用できる構成」を最優先で選定しました。

レイヤー 技術 理由
フロントエンド Next.js(App Router)+ React + TypeScript Cloudflare Pagesとの相性が良く、静的書き出しとEdge SSRを両立できる
ホスティング Cloudflare Pages 商用利用でもリクエスト数無制限の無料枠があり、個人開発の初期費用をゼロにできる
API Cloudflare Workers(Hono) Pagesと同じCloudflareネットワーク上でEdge実行でき、レイテンシが低い
データベース Cloudflare D1(SQLite) 無料枠で5GB・月25億行読み取りまで使え、問題データベース程度の規模なら十分すぎる
画像ストレージ Cloudflare R2 過去問の図表画像を格納。エグレス料金がかからないのが決め手
認証 Clerk(Google / Facebook / LINE / メール) SSO一式を自前実装せずに済み、無料枠(月間アクティブユーザー10,000人)も個人開発には十分
CI/CD GitHub Actions プッシュ時にlint・テスト・デプロイを自動化

実際に金銭的コストが発生したのは、お名前.comで独自ドメインを購入した費用だけです。それ以外はすべて各サービスの無料枠内に収まっています。

ハマった点:Clerk認証のCORSエラー

一番苦労したのが、Clerk認証まわりのCORSエラーでした。

Cloudflare Pagesの独自ドメイン(本記事執筆時点の it-test.manari-it.net)を使い始めた途端、ブラウザのコンソールに大量のCORSエラーが出て、ログイン処理がまったく動かなくなりました。Clerkは内部的にFAPI(Frontend API)と呼ばれる専用エンドポイントと通信するのですが、これがCloudflare Pagesの *.pages.dev ドメインとは異なるオリジンとして扱われ、ブラウザに素通しでブロックされてしまう構造でした。

解決までにやったことをざっと振り返ると、次のような紆余曲折がありました。

  1. まずClerk JSの読み込み元をCDN切り替え(公式CDN→jsdelivr)で試すも改善せず
  2. Cloudflare Pages Functionを使ってClerk FAPIへのリクエストをプロキシする方式を実装
  3. プロキシ時に origin / referer ヘッダーが悪さをしていることが判明し、ヘッダーを除去
  4. 疎通確認用の診断エンドポイントを追加してどこで詰まっているかを可視化
  5. window.fetch をパッチしてClerkの通信をすべてプロキシ経由にリルート
  6. 最終的に、Clerkダッシュボード側で発行される clerk.{独自ドメイン} というサブドメインを正しいFAPIエンドポイントとして使う方式にたどり着き、ようやく安定

つまり、Clerkの proxyUrl やCDN読み込み元をいじる小手先の対応ではなく、「独自ドメインごとに専用のClerk FAPIサブドメインが発行されている」という前提を正しく理解して、ホスト名から動的にFAPI URLを組み立てる実装に切り替えたことで根本解決しました。数日にわたって一進一退を繰り返した箇所だったので、同じようにCloudflare PagesとClerkを組み合わせている方の参考になれば幸いです。

おわりに

「合格したい」という個人的なモチベーションから始まった開発でしたが、AIと一緒に手を動かしながら作っていく過程自体もかなり学びが多いものでした。

今年で最後にはなりますが、PM試験・ITストラテジスト試験の再受験者の方はもちろん、これから受験する方にもよかったら使ってみてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?