Cloudflare Pages と Supabase の無料枠で運用可能な、大学委員会向けのイベント参加予約・電子チケット発券サイトです。
- 📱 スマホ優先・高コントラスト設計: 昼休みの混雑するイベント会場や屋外テントでも見やすい Indigo 暗色テーマ。
- ⚡ 先着順の厳密処理: Supabase 内のストアドプロシージャ (RPC) を利用し、同時アクセス時のオーバーブッキングを防ぐトランザクション処理。
- 🔒 強固なプライバシー保護:
reservationsテーブルに対する直接の SELECT は禁止。- 一般ユーザーはランダムな
public_tokenから RPC (get_ticket) 経由で自身のチケット情報のみ取得可能。 - 学籍番号や大学メールなどの個人情報は管理者アカウントのみ閲覧可能。
- 企画終了後にすべての予約者名簿と個人情報を管理画面から安全に完全消去可能。
- 🔄 手入力サポート & バリデーション: 学籍番号の自動半角大文字化、メールアドレス (
s[学籍番号]@ge.osaka-sandai.ac.jp) の自動補正生成。 - 📊 CSV出力: Excel で開いても文字化けしない UTF-8 BOM 付き CSV エクスポート。
- 📝 外部アンケート連携: 予約完了後およびチケット使用後に、Google フォーム等の外部アンケートへ誘導する動線機能。
- Supabase にサインインし、新しいプロジェクトを作成します。
- データベースのパスワードとリージョン(東京など)を選択して作成を待ちます。
- 作成した Supabase プロジェクトのダッシュボードに移動し、左側メニューの SQL Editor を開きます。
- New Query をクリックします。
- プロジェクト内の supabase/migrations/20260623_init.sql の中身をすべてコピーし、SQL Editor に貼り付けます。
- Run ボタンを押して実行します。すべてのテーブル、ユニークインデックス、RPC関数、RLSポリシーが構築されます。
- Supabase ダッシュボードの左側メニューの Authentication > Users を開きます。
- Add User > Create User をクリックし、管理者のメールアドレスとパスワードを入力して作成します。(確認メール送信の必要がない場合は、Auto Confirm を ON にするか、認証メール内の確認リンクを無効化してください)
- 作成されたユーザーの User ID (UUID) をコピーします。
- 再度 SQL Editor を開き、以下の SQL コマンドを実行して、作成したユーザーに管理者権限を付与します。
INSERT INTO admin_users (user_id) VALUES ('コピーしたUUID');
プロジェクトのルートディレクトリに .env.local ファイルを作成し、以下のように環境変数を入力します。(env.example も参照)
# Supabaseプロジェクトの接続情報 (API settings からコピー)
NEXT_PUBLIC_SUPABASE_URL=https://xxxxxxxxxxxxxxxxxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# サーバー側管理者用キー (API settings -> service_role key からコピー)
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# 許可する大学メールのドメイン設定 (カンマ区切りで複数指定可能)
NEXT_PUBLIC_ALLOWED_EMAIL_DOMAINS=ge.osaka-sandai.ac.jp,osaka-sandai.ac.jp
# 学籍番号からメールアドレスを自動生成する際のデフォルトドメイン
NEXT_PUBLIC_STUDENT_EMAIL_DOMAIN=ge.osaka-sandai.ac.jp以下のコマンドを実行してローカル開発サーバーを起動します。
# パッケージのインストール
npm install
# 開発サーバー起動
npm run devブラウザで http://localhost:3000 を開き、動作を確認します。
Cloudflare Pages は、Next.js アプリケーションの静的アセットおよび API Route (Workers ランタイム) を高速にデプロイできます。
Cloudflare ダッシュボードで Workers & Pages > Create application > Pages > Connect to Git を選択し、リポジトリを連携します。
ビルド設定は以下のように指定します。
- Framework preset:
Next.js - Build command:
npx @cloudflare/next-on-pages(または Pages 向けの適正コマンド) ※注: このアプリケーションはフロントエンド側で直接 Supabase RPC を呼び出してすべての処理を完結させているため、静的SPAとして出力することも可能です。その場合のビルドコマンドはnpm run build、出力ディレクトリはout(next.config.js でoutput: 'export'を設定した場合) またはdistになります。
Cloudflare Pages の設定画面の Environment Variables に、ローカルで設定した以下の変数を追加します。
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYNEXT_PUBLIC_ALLOWED_EMAIL_DOMAINSNEXT_PUBLIC_STUDENT_EMAIL_DOMAIN
- 一般公開サイトの右上にある「管理画面」リンクまたは
/adminにアクセスし、登録した管理者メールアドレスとパスワードでログインします。 - メニューから「新規企画作成」を開きます。
- 企画のタイトル、説明文、定員、開催日時などを入力します。
- 電子チケットが必要な場合は、「電子チケット機能を有効にする」をONにし、利用者が店員前で押すための「使用する」ボタンのON/OFFや利用可能時間帯を設定します。
- Googleフォーム等の外部アンケートリンクを表示させたい場合は、「外部アンケート連携」をONにしてURLと表示文面を設定します。
- 設定が完了したら「公開設定」の「企画を一般公開する」をONにし、「企画を作成する」を押すと予約ポータルに反映されます。
- 一般公開のトップページから作成した企画を選択し、「予約フォームへ進む」を押します。
- 氏名、学籍番号(半角小文字や全角で入力して、自動的に半角大文字に変換されることを確認)を入力します。
- メールアドレスが自動生成され、必要に応じて修正可能なことを確認します。
- 予約ボタンを押すと、即座にチケット画面(
/tickets/[publicToken])へ遷移することを確認します。 - チケット画面で「時計」が1秒ごとにリアルタイムに動作していること、および背景に微小なアニメーションがあることを確認します。
- スタッフの前で「使用する」ボタンを押し、二重確認ダイアログの承認後にステータスが「使用済み」になり、使用時刻が記録されることを確認します。
イベント当日の混乱を防ぐため、本番公開前に以下の項目を必ずチェックしてください。
- Supabase 接続確認: Supabase が一時停止または接続制限になっていないか。
- 公開フラグの確認: 企画が「一般公開する」になっているか(非公開の場合、予約できません)。
- 受付日時の確認: 予約受付の開始・終了日時が正しい日本時間に設定されているか(タイムゾーンのずれがないか)。
- 定員の確認: 設定された定員(上限数)が適切か。
- メールドメイン制限:
NEXT_PUBLIC_ALLOWED_EMAIL_DOMAINSの設定値と、実際の大学メールドメインが一致しているか。 - 学籍番号での重複予約防止: 同一の企画に対して、同じ学籍番号で2回目の予約を実行した際、エラー(「この学籍番号は既にこの企画を予約しています」)が返されるか。
- メールアドレスでの重複予約防止: 同一の企画に対して、同じメールアドレスで2回目の予約を実行した際、エラーが返されるか。
- 予約キャンセル後の再予約: 管理画面から該当する予約をキャンセル(取消)した後、同じ学籍番号・メールアドレスで再度予約が行えるようになっているか。
- 定員到達後のブロック: 予約数が定員に達した状態で予約しようとした際、エラーになり予約が作られないか。
- チケット使用ボタンの動作: チケットの「使用する」ボタンを押して使用済みに変更できるか。
- 使用後の再利用不可確認: 使用済みになったチケットに対して、ブラウザをリロードした際にも「使用済み」状態が維持され、再使用ができないようになっているか。
- 管理者画面のアクセス制限: ログアウトした状態、または一般ブラウザで
/admin/eventsなどに直接アクセスした際、自動的に/admin/loginにリダイレクトされ、予約者データが保護されているか。 - CSV出力の文字化け確認: エクスポートしたCSVファイルを Microsoft Excel やスプレッドシートで開き、日本語が文字化けせず、すべての予約データが正しい列に出力されているか。
- 個人情報のクレンジング: 企画が完全に終了した後、管理画面の「予約データの完全削除」ボタンが正常に動作し、予約者リストが空になるか。