概要
利用している技術
pnpm のモノレポ(shared / api / web / e2e)、全部 TypeScript です。
フロントは Expo Router + React Native を react-native-web でビルドした Web アプリ。バックエンドは Fastify を Cloud Run、データは Firestore、認証は Firebase Auth + App Check。配信は Firebase Hosting、/api/** を Cloud Run へ rewrite して同一オリジンです。
効いているのが packages/shared です。順位計算・達成率・日付の境界をここに1つだけ置き、サーバーと画面が同じ関数から値を導出します。両側で別々に計算しないので表示のズレが構造的に起きません。
定刻処理は Cloud Scheduler から毎分 activate-due / finalize-due、毎時 ensure-public-room。検証は Zod、テストは vitest(ドメイン245件+統合156件)と Playwright です。
サービスのPR点
■ 匿名が演出ではない
「結果発表まで名前を伏せる」を選ぶと、実行中はサーバーが実名を送りません。画面で隠しているのではなく、そもそもクライアントに届いていない。結果が確定した瞬間、同じトランザクションで全員に開きます。
■ 同じ数字が二度と食い違わない
順位も達成率も shared の1実装から導出。サーバーと画面で別々に計算していません。
■ 二重に数えない
記録は operation_id による冪等。通信が重なっても、同時に押しても1回しか入りません。
■ 主催者の操作が全部見える
失格・復帰・記録枠の付与・招待の失効は、理由つきで参加者全員に公開されます。
■ 途中参加
開始後も入れる部屋を作れます。あとから入ると積み上げで不利になるので、順位の式は変えずに「4日目から参加」と並べ、負けている理由が読めるようにしました。
今後の追加機能など
■ 通知
いま、開始・終了・順位が動いたことをアプリの外から知る手段がありません。ここが最優先です。
■ App Check の強制
サイトキーは入れてありますが、まだサーバー側で必須にしていません。
■ 再戦の自動再招待
終わったチャレンジから同じルールで再戦は作れますが、参加者は改めて招待し直す必要があります。
■ チャレンジ個別のOGP
いまはサイト共通のカードしか出ません。「◯◯チャレンジ、あと2日」が出るようにしたいです。
■ 入口の作り直し
参加者が増えたら、紹介ページではなく「いま参加できるチャレンジの一覧」を先に見せる形へ戻す予定です。
その他メッセージ
ベータ版です。動作確認のため、チャレンジや記録を予告なく削除・初期化することがあります。ご利用は16歳以上の方に限らせていただいています。
記録は自己申告です。水増しを技術的に防ぐことはできないので、友人同士で盛り上げるための道具として作っています。「終盤の非表示」も見せ方の演出であって秘匿の保証ではないため、賭けなど見えたら不公平になる用途には使わないでください。
個人開発です。触ってみての感想や「ここが分かりにくい」は大歓迎です。
フィードバック募集
開発報告
開発者からのリリース報告などのコメントです
過去7日間のツイートを表示します
コメント
サービスの利用者などからのフィードバックコメントです