文化祭スタンプラリー

https://github.com/minmmmmin/progate-hackathon-202605

Next.js

TypeScript

PostgreSQL

TailwindCSS

リアルタイム混雑状況がわかる!文化祭特化型デジタルスタンプラリー

さくぱん

min

もみじゅ

kazari4

推しアイデア

スタンプラリーで楽しい みんなが楽しむことでみんなが助かる!

作った背景

従来の紙のスタンプラリーは「台紙をなくす」「集計が大変」という課題がありました。また、文化祭特有の「人気のお化け屋敷や飲食ブースに人が集中しすぎて大行列になる」という課題を、デジタル技術で解決しつつ、参加者全員がもっとワクワクできるお祭り空間を作りたいと思い開発しました。

推し技術

1.自動ポスター印刷:隠しiframeとCSS印刷設定を駆使し、管理画面からデザイン済みQRポスターを直接A4出力する機能を構築。2.リアルタイム同期:SWRのポーリングにより、運営側の混雑状況の変更を即座に参加者画面へ反映し、テーマパークのようなUXを実現しました。

プロジェクト詳細

アプリ概要

文化祭の来場者が QR コードを読み取ってスタンプを集めながら、会場内の回遊を楽しめるスタンプラリーアプリです。 来場者向けには、QR スキャン、スタンプ帳、混雑状況、おすすめスポットの表示をまとめ、運営向けにはスポット登録、QR コード発行、混雑確認を行える管理画面を用意しています。

ターゲット

  • 文化祭に来る生徒、保護者、外部来場者
  • 文化祭を運営する学生スタッフ
  • 出店しているクラスや団体

ストーリー

なぜこのプロダクトを作ろうと思ったか

文化祭では「どのブースに行けばいいかわからない」「気になる場所が混んでいて回りにくい」という課題が起きやすいです。 一方で、出店者側は自分たちのブースにもっと来てもらいたい、運営側は会場全体の回遊を偏らせずに楽しんでもらいたい、という思いがあります。

そこで、QR コードを使ったスタンプラリーと、混雑状況の見える化を組み合わせることで、回遊のきっかけを作りつつ、会場内をより快適に楽しめる体験を目指しました。

誰のどんな課題を解決したいか・どんな楽しさを届けたいか

来場者には、「次はどこへ行こう」という迷いを減らしながら、スタンプを集める達成感と、空いているスポットを見つける楽しさを届けたいです。 運営や出店者には、来場者の流れを把握しやすくして、ブース間の偏りを減らし、会場全体の満足度を上げることを狙っています。

また、ログインなしでも使えるようにして、初見の来場者でもすぐ参加できることを重視しました。

技術構成・アーキテクチャ図など

技術構成

  • Next.js 16 / React 19 / TypeScript
  • Tailwind CSS 4 / daisyUI
  • Supabase(Auth, Database, Storage)
  • Hono + OpenAPI + Scalar による API 実装とドキュメント
  • html5-qrcode による QR スキャン
  • SWR による一覧取得と再取得
  • sonner による通知
  • lucide-react によるアイコン

アーキテクチャの考え方

  • 画面は来場者向けと運営向けで分け、役割ごとに迷わない構成にしています。
  • フロントエンドは Next.js の App Router で画面を組み、QR スキャンや一覧の再取得はクライアントコンポーネントで制御しています。
  • API は /api 配下にまとめ、usersboothsscans の責務を分割しています。
  • データは Supabase に集約し、boothsusersscan_logs を中心に扱っています。
  • スタンプ画像は Supabase Storage に保存し、管理画面から新規スポット追加時にアップロードします。
flowchart LR A[来場者ブラウザ] --> B[Next.js 画面] B --> C[/api/users] B --> D[/api/booths] B --> E[/api/scans] E --> F[Hono API] C --> F D --> F F --> G[Supabase Database] F --> H[Supabase Storage] B --> I[QR スキャナ] I --> E J[運営ブラウザ] --> K[管理画面] K --> D K --> F

実装上のポイント

  • 初回アクセス時に匿名ユーザー ID を発行し、localStorage に保持してログインなしで使えるようにしています。
  • QR 読み取り後はスキャン登録 API を呼び出し、スタンプ獲得ダイアログと通知を表示します。
  • 混雑状況は直近 120 分のスキャン数から算出し、会場の動きをざっくり把握できるようにしています。
  • 同じブースは 5 分以内の再スキャンを弾き、意図しない重複取得を防いでいます。

遊びごころポイント

ターゲットに刺さる機能

  • QR を読み取るだけでスタンプが増えていく、直感的なスタンプラリー体験
  • スタンプ帳で「集めた実感」がすぐ見える設計
  • 空いているおすすめスポットを出して、次に行く場所を自然に誘導する仕組み
  • 管理画面からスポットを増やしやすく、文化祭当日の運用にも載せやすい構成

技術的遊び

  • カメラ起動から QR 読み取りまでをブラウザ上で完結させている点
  • スキャン履歴をそのまま混雑推定に転用している点
  • スキーマ定義を共有して、フロントと API のデータ形を揃えている点
  • API ドキュメントを同じルートで公開して、実装と確認を行き来しやすくしている点

アプリ画面(スクショや動画など)

  • ホーム画面: QR スキャン、スタンプ帳の進捗、混雑状況、おすすめスポットをまとめて表示
  • 使い方画面: 4 ステップの案内と QR スキャンのコツ、FAQ を掲載
  • スタンプ帳画面: 獲得済みスタンプを一覧表示し、スタンプをタップすると詳細を確認可能
  • 管理画面: 混雑マップ、スポット一覧、一括操作、お知らせ管理を表示
  • スポット追加画面: スタンプ画像をアップロードして新規スポットを登録

※ ここには必要に応じて、各画面のスクリーンショットや画面録画を貼ると完成度が上がります。

挑戦・成長したところ

  • QR スキャン、匿名ユーザー管理、スタンプ付与までを一連の体験としてつなげたこと
  • 来場者向け UI と運営向け UI を分けて、目的の違う画面を整理したこと
  • 混雑状況を別システムに頼らず、スキャンログから推定する実装にしたこと
  • API ルート、型定義、画面を分けて、変更に強い構成を意識したこと
  • モバイル前提の導線を作りつつ、管理画面では一覧性を優先したこと

チームワーク・チーム開発で工夫したところ

  • バックエンドとバックエンド型定義を爆速で作ることで、AI駆動開発で齟齬が起こりにくいようにした。
  • 来場者向け画面、管理画面、API、型定義を分けて、担当を切り分けやすくしました。
  • 画面の文言やデータ名を統一し、UI と API の認識ズレが起きにくいようにしています。
  • スタンプ取得、スポット追加、混雑表示のように、機能ごとに独立した流れを作ることで、並行して実装しやすい構成にしています。
  • API ドキュメントを同じリポジトリ内で見られるようにして、確認と実装の往復を短くしています。

さくぱん

@saku_pan