エンジニアが新婦のために結婚式にITで全力で貢献しようとした話【連載第12回】2026年4月5日、すべてが動いた日
前日23:58の最終コミット。当日コミット0件。3ヶ月・170コミットの全てを賭けた2時間半。披露宴から二次会、表彰式、フィナーレまで──結婚式カジノ本番の全記録。
最終更新:
2026年4月5日、すべてが動いた日
commit b1eba0f 2026-04-04 23:59:15 NFC書き込みツール・QRコード印刷用画像
commit 4054c6d 2026-04-04 23:59:01 いいね・返信・写真いいね・チップ手動紐付け
commit 13547ff 2026-04-04 23:58:41 ランキング画面改修・表彰式修正・UI統一
前日の23:58。最終コミットが3つ、34秒の間に飛んだ。
3ヶ月間、170コミット。93本のDBマイグレーション。40枚の物理NFCチップと予備8枚。
そして翌日──2026年4月5日、すべてが動いた。
想定通りに動いたものもあれば、本番で初めて露呈したバグもあった。これは、その日の全記録です。
🎯 この記事で得られること
- ✅ 3ヶ月間のシステム開発が本番2時間半でどう動いたかの完全記録
- ✅ 披露宴NFC席次カード→二次会NFCチップの実際の受付フロー
- ✅ 「みんなで大予想」3問の設計と会場の反応
- ✅ 表彰式10賞の発表と景品選定の裏話
- ✅ 前日深夜に追加した「最後の3コミット」の中身
🌙 前日:23:58の最終コミット
最後の34秒
4月4日の深夜。明日は結婚式。普通なら寝ているべき時間に、3つのコミットを積んだ。
23:58:41 ── ランキング画面改修・表彰式修正・UI統一
表彰式のリハーサルをして気づいた。THE GAMBLER賞が「誰よりもチップを乗せた人」だが、参加者が少ないと盛り上がらない。削除。チーム賞も2つは冗長。1つに統合。
そして「コロシアム」→「みんなで大予想」への名称変更。結婚式の場で「コロシアム」は物騒すぎる。この判断は正しかった。
23:59:01 ── いいね・返信・写真いいね・チップ手動紐付け
新婦から2日前に「メッセージに返信できたら嬉しい」と言われて急遽実装した返信機能。管理画面からの写真いいね。そして予備チップ8枚(SPARE-001〜008)の緊急発行と手動紐付けRPC。
「NFCが読めなかったら?」「チップを紛失したら?」──最悪のケースに備えた最後の保険。
23:59:15 ── NFC書き込みツール・QRコード印刷用画像
RC-S300(ソニーのNFCリーダー)でNTAG215に書き込むPythonスクリプト。予備チップ用のQRコード画像。バー端末用のQR。
これでコードフリーズ──のはずだった。
「コードフリーズ」は幻想だった
正直に言います。当日もコードを触りました。
「前日にフリーズして当日は触らない」と決めていたのですが、本番が始まると想定外の問題が出てくる。コミットこそしていないものの、ホットフィックスをデプロイする場面が複数あった。
詳しくは後述しますが、大予想のポップアップがスマホでスクロールできない致命的バグ、スライドショーの写真表示ロジックの偏り──これらは当日の現場で修正してデプロイしています。
「コードフリーズ」は理想であり、現実のイベント運用では「最小限のホットフィックスを許容する覚悟」が必要だった。 これが最大の学びの1つです。
💒 披露宴フェーズ:NFC席次カードの受付
14:00 受付開始
ゲストが受付に到着し、席次カードを受け取る。カードにはNFCタグが仕込んであり、スマホにかざすと /m/[token] が開く。
受付係「おめでとうございます。席次カードをスマホにかざしてみてください」
↓
ゲストがかざす → 自分の名前 + 新郎新婦からの個別メッセージが表示
↓
「写真を投稿する」→ 顔写真撮影 → プロフィール完成
第7回で解説したフローが、初めてリアルに動いた瞬間。
ゲストの反応は「え、すごい!」が大半。 席次カードからメッセージが出てくるのは予想外だったようで、受付周辺で「これ見た?」と見せ合う光景が生まれた。
14:30〜17:00 披露宴
披露宴中、ゲストは写真を撮ってアップロードする。顔認識でタグ付けされ、自分が写った写真が「My Album」に集まる。
この時間帯のシステムは安定稼働。フリーWi-Fiではなく会場の有線LAN + ルーター構成にしたのが効いた。
17:00 ── サプライズ演出の解放
披露宴の終盤、スクリーンに特別な演出が流れる。新郎から新婦への想いを込めたメッセージ。
この連載の記事タイトルが1つずつ表示され、それぞれに「きみへのメッセージ」がタイプライターエフェクトで表示される。
「#1 なぜ結婚式にITで貢献しようと思ったのか」 ── きみに最高の1日をプレゼントしたかった
「#2 1回限りのシステムを設計する」 ── たった1日のために3ヶ月。でも、きみのためならそれでいい
最後のメッセージ:
「言葉にできなかった想いは全部このシステムに込めました」 「50年後、またこの動画を一緒に見て笑いながら話せたらいいなと思います」 「これからもよろしくね」
──エンジニアが新婦のために3ヶ月かけて作ったシステムの、本当の意味がここにある。
🎰 二次会フェーズ:カジノオープン
18:00 受付 ── NFCチップ配布
二次会の受付で、ゲストにNFCチップを手渡す。披露宴からの参加者は既にセッションが残っているため、チップをタッチするだけでカジノに入れる。
披露宴組: チップタッチ → 即カジノ(セッション引き継ぎ)
二次会組: チップタッチ → オンボーディング → カジノ
第7回で設計した「2つの入口、1つの出口」が機能した瞬間。
18:15 Interactive Party 開始
新郎新婦が会場前方でルール説明。事前に作っておいたルールスライドをスクリーンに投影する。
【チップの稼ぎ方】
📸 写真を撮ってアップロード → +500 chips
💌 メッセージを送る → +500 chips
🍺 バーでドリンクを受け取る → +100 chips
🎫 知らない人にチップを贈る → スタンプ報酬 +500 chips
🔮 みんなで大予想 → 当たればオッズに応じて配当!
18:30〜19:30 自由交流+ゲーム
チップ経済圏が回り始める。バーNFCにタッチしてドリンクを受け取り、チップを稼ぎ、対戦し、スタンプラリーを進める。
スタンプラリーが想定以上に機能した。 「新婦同僚のスタンプがまだない」→「あの人に話しかけよう」という行動が自然に発生。新郎側と新婦側の垣根を超えた交流が生まれた。
19:00〜19:45 みんなで大予想(3問)
二次会のメインイベント。全員のスマホにベットモーダルが自動で浮上する。
第1問:プロポーズ再現
「新郎にプロポーズを再現してもらいます。新婦の再現度判定は?」 選択肢:100% / 75% / 50% / 25% / 0%
新郎が照れながらプロポーズを再現し、新婦が判定。オッズがリアルタイムで動くスクリーンに歓声が上がる。
第2問:握手で新郎を当てろ
「目隠しした新婦が5人と握手。何回目で新郎を当てる?」 選択肢:1回目 / 2回目 / 3回目 / 4回目 / 5回目 / 当てられない
会場が一体となって「がんばれ!」と声をかける。locked状態(締切〜結果発表の間)の数十秒間が、狙い通りの緊張感を生んだ。
第3問:シンクロクイズ
「新郎新婦に5問質問します。何回答えが一致する?」 選択肢:0回 / 1回 / 2回 / 3回 / 4回 / 5回
19:45 色対抗バトル
4チーム(RED/BLUE/GREEN/YELLOW)対抗戦。
- 前半:共通点写真ミッション ── お題に合う写真をチームで協力してアップロード
- 後半:格付けバトル ── 各チーム代表者が「ウイスキー3種を安い順に並べろ」「日本茶3種を安い順に並べろ」に挑戦
19:50 クライマックスルール発動
ラスト30分。同じ所属間のチップ送付が禁止される。
「ここからクライマックスルール発動!同チーム内のチップ送付はできません!自力で稼ぐしかありません!」
技術的な制限を「ゲームのルール」として伝えることで、盛り上がりのピークを作る。
🏆 表彰式:10の賞と景品
発表順(盛り上がりの設計)
特別賞から始め、個人ランキング3位→2位→1位でクライマックス。管理画面の「次の賞を発表」ボタンを押すだけで、受賞者の名前・記録・景品がスクリーンに表示される。
| 順 | 称号 | 基準 | 景品 |
|---|---|---|---|
| 1 | 🏆 色対抗バトル チーム優勝 | チームポイント1位 | Amazonギフト券 2,000円(全員) |
| 2 | 🎯 属性賞 | チーム内最優秀 | スタバギフトカード 1,500円 |
| 3 | 🍺 バーの主 | バー来店回数1位 | 日本酒 |
| 4 | 📸 伝説のカメラマン | 写真投稿数1位 | スマホ用拡大レンズ |
| 5 | ✨ みんなのアイドル | タグ付け回数1位 | 高級フェイスマスクセット |
| 6 | 🗺️ スタンプマスター | スタンプ収集数1位 | 名湯巡り入浴剤セット |
| 7 | 💸 名誉スポンサー | チップ損失額1位 | 豚の貯金箱 |
| 8 | 🥉 個人ランキング3位 | チップ3位 | 新婦の職場製品詰め合わせ |
| 9 | 🥈 個人ランキング2位 | チップ2位 | お菓子の詰め合わせセット |
| 10 | 👑 KING OF CASINO | チップ1位 | バルミューダ 電気ケトル |
景品選定の設計意図
「名誉スポンサー」の景品が豚の貯金箱──これは意図的な笑いの設計です。最もチップを失った人に「これで貯金してください」と渡す。会場が沸いた瞬間。
KING OF CASINOの景品がバルミューダの電気ケトル──実用性が高く、見た目にもインパクトがある。1位の景品は「その場で見せて盛り上がるもの」を選びました。
受賞者は user_stats_view から自動計算。新郎新婦は結果を事前に知る必要がなく、表彰式の瞬間に「1位は……○○さん!」とサプライズになる。
🔧 予備チップが救った場面
SPARE-001〜008:最後の保険
前日23:59に追加した予備チップ8枚。これが実際に役立った。
NFCチップが読み取れないゲストが数名。原因はスマホケースの厚さとNFCアンテナの位置。QRコードのフォールバックで対応できたケースもあったが、一部のゲストには管理画面から予備チップを手動紐付けした。
-- 管理者がゲストにチップを手動紐付けするRPC
CREATE OR REPLACE FUNCTION admin_assign_chip(
p_chip_code TEXT,
p_profile_id UUID
) RETURNS JSONB AS $$
この緊急対応RPCも前日深夜に追加したもの。「使わないに越したことはないが、あれば助かる」──保険を用意しておいて正解だった。
🔥 当日のホットフィックス
「コードフリーズ」と言いつつ、当日に修正してデプロイした変更がいくつかある。正直に記録します。
インシデント1:大予想ポップアップがスクロールできない
発生タイミング: 大予想の第1問が始まった直後
ゲストのスマホにベットモーダルが自動表示されたが、選択肢が多い問題で画面からはみ出し、スクロールできない。プリセットボタンや「ベットする」ボタンに辿り着けないゲストが続出。
原因: モーダルの div に max-height と overflow-y: auto が設定されていなかった。
修正:
- className="bg-gradient-to-b from-purple-900 to-indigo-900 rounded-2xl max-w-md w-full p-6 space-y-6"
+ className="bg-gradient-to-b from-purple-900 to-indigo-900 rounded-2xl max-w-md w-full max-h-[90vh] overflow-y-auto p-6 space-y-6"
1行の修正。即デプロイ。所要時間:約3分。 しかしこの3分間、ベットできないゲストがいた。第2問以降は問題なく動作。
教訓: 選択肢が2択のテストしかしていなかった。5択の問題でモーダルの高さをテストすべきだった。
インシデント2:スライドショーの写真表示が偏る
発生タイミング: 披露宴中のスライドショー投影
写真が順番に表示されるロジックだったが、新しい写真がアップロードされるたびにインデックスがリセットされ、同じ写真ばかり表示される問題が発生。
修正: 順番表示→表示回数の少ない写真を優先し、同率ならランダム選択するアルゴリズムに変更。
// Before: 順番に表示(偏る)
const photoData = photoQueue[photoIndexRef.current % photoQueue.length];
// After: 表示回数が少ない写真からランダム選択
const minCount = Math.min(...photoQueue.map((_, i) => counts.get(i) || 0));
const candidates = photoQueue.filter((_, i) => (counts.get(i) || 0) === minCount);
const chosen = candidates[Math.floor(Math.random() * candidates.length)];
インシデント3(翌日修正):メッセージ返信が1件しかできない
発生タイミング: 二次会後、新婦がメッセージに返信しようとしたとき
1つのメッセージに1つしか返信できない制限に気づいた。これは当日中には修正せず、翌日にDBテーブルを新設して対応。
-- 20260406100000_blessing_replies_table.sql
CREATE TABLE blessing_replies (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
blessing_id UUID NOT NULL REFERENCES blessings(id) ON DELETE CASCADE,
reply_text TEXT NOT NULL,
replied_by UUID NOT NULL REFERENCES profiles(id),
created_at TIMESTAMPTZ DEFAULT now()
);
判断: イベント中にDBスキーマを変えるリスクは取らない。翌日に落ち着いて修正する。
💭 2時間半で見えたこと
うまくいったこと
1. NFC席次カードの受付体験 「席次カードをかざしたらメッセージが出てきた!」という驚きが、最初の会話のネタになった。テクノロジーを意識させない導入として設計通りに機能した。
2. スタンプラリーによる交流促進 新郎側と新婦側のゲストが自然に話しかける理由を作れた。「スタンプが欲しいから」という口実が、初対面のハードルを下げた。
3. みんなで大予想のlocked演出 締切から結果発表までの「間」が、会場全体の一体感を生んだ。全員が同じ方向を向いて結果を待つ数十秒間。
4. 予備チップの事前準備 NFCが読めないケースは実際に発生した。予備チップ+手動紐付けRPC+QRフォールバックの三重保険が安心感を与えた。
課題として残ったこと
1. メッセージ返信の制限 1メッセージ1返信の制限は当日に発覚。事前のテストプレイで気づくべきだった。
2. バー端末のクールダウン設定
5分のクールダウンが短すぎて、バーに長居するゲストがチップを稼ぎすぎる場面があった。当日は system_config で10分に変更して対応。
3. ルール説明の時間 口頭でのルール説明に想定以上の時間がかかった。ルールスライドを用意していたが、それでも「で、何をすればいいの?」という質問は出た。
📐 「1回限り」の運用で学んだこと
教訓1:コードフリーズは理想、ホットフィックスの覚悟は必須
「前日にフリーズして当日は触らない」と決めていたが、大予想のスクロール不可バグは当日に直すしかなかった。完全なコードフリーズは現実には難しい。 重要なのは「触らない覚悟」ではなく「最小限の修正を最速でデプロイできる体制」を整えておくこと。
教訓2:system_config が救世主
バーのクールダウンを5分→10分に変更、報酬額の微調整──これらは全て管理画面から即座に変更できた。リデプロイなしで設定変更できる仕組みは、ライブイベント運営の生命線。
教訓3:予備は「使わないつもり」で用意する
予備チップ8枚、手動紐付けRPC、QRフォールバック──全て「使わないに越したことはない」ものだが、実際に使った。「もしも」の対策に使った時間は、本番で必ず報われる。
教訓4:演出の「間」はシステムが作る
大予想のlocked状態、表彰式の1賞ずつの発表──盛り上がりの「間」をシステムの状態遷移で制御できたことが、イベント全体のリズムを作った。
リアルタイムイベントシステムの運用Tips
1. ホットフィックスの即時デプロイ体制
完全なコードフリーズは理想だが、本番で初めて露呈するバグは必ずある。重要なのは「最小限の修正を最速でデプロイできる体制」。Vercel CLIでの直接デプロイ(npx vercel --prod)をリハーサルしておく。
2. system_configによるランタイム設定変更
報酬額、クールダウン、ルール設定をDBテーブルで管理し、管理画面から即時変更可能にする。リデプロイ不要で本番中に調整できる仕組みが、ライブイベントでは必須。
3. 物理デバイスのフォールバック設計
NFC + QRのデュアルインターフェース + 予備デバイス + 管理者手動紐付けRPCの三重保険。物理デバイスは「読めない」可能性を前提に設計する。
4. 予備データの事前準備
本番チップ40枚に対して予備8枚(20%)を用意。予備はコードとして事前にDBに登録しておき、管理画面からワンクリックで紐付けできるようにする。
5. マイグレーションの本番適用ルール
イベント中のDBスキーマ変更は禁止。機能が不完全でも、動いているものを壊すリスクは取らない。翌日以降に落ち着いて修正する。
🔜 次回予告
2時間半の熱狂が終わった。次はデータの世界に入ります。
全トランザクションを分析し、チップ経済の動き、大予想のオッズ分布、スタンプラリーの達成率をデータで振り返ります。
次回:【連載第13回】データで振り返る結婚式カジノ
この記事が面白いと思ったら、ぜひシェアをお願いします!
あなたのシェアが、同じような「面白いことやりたいエンジニア」に届くかもしれません。
tinou
情報処理安全確保支援士とPMの資格を使ってITコンサルタントとして働く傍ら、自宅で自動化とセキュリティを研究しているエンジニア