| 項目 | 内容 |
|---|---|
| ドキュメントバージョン | v1.3 |
| 対象システム | tec-nova Nagasaki 統合管理プラットフォーム |
| 運用状況 | Phase 1(MVP)を本番デプロイ・稼働中 |
| 関連ドキュメント | 下表参照 |
| ドキュメント | 役割 |
|---|---|
本書 requirements.md |
なぜこう設計したか(構想・スコープ・データモデルの判断・非機能要件・リスク・判断ログ) |
mvp.md |
実装ガイド(API契約・画面仕様・実装の how) |
architecture.md |
全体システム構成図(Current/Future)・拡張ロードマップ |
handoff.md |
進捗・既知の罠・残作業(最新状況) |
このドキュメントは「①人間がプロジェクトを理解する入口」かつ「②Spec-Driven 開発の仕様書」を兼ねる。実装の細かな手順は
mvp.mdに委ね、本書は設計判断の根拠を残すことに集中する。
tec-nova Nagasaki(テクノバながさき)は、長崎市と長崎大学による共同事業として開催される子ども向けファブリケーション活動である。週3日の開催日に小学1年生から高校3年生までを中心とした利用者が自由来場し、3Dプリンタ、プログラミング、マイクラ、ロボット、3Dモデリングなど多様な技術活動に取り組む。
本活動は研究対象でもあり、参加者属性のクラスター分析等の研究データ収集も並行して行われている。
本プロジェクトは、tec-nova Nagasaki の運営を支える統合管理プラットフォームを内製で開発するものである。コアな目的は以下の4点。
- 来場・退出のチェックインシステムとしての基本機能の安定化
- メンターによる活動ログ記入のDX化(従来スプシ運用のボトルネック解消)
- 研究用データの構造化収集(自然言語ログの分類負荷軽減)
- API-firstな基幹システムとして将来の機能拡張に耐える設計
昨年度はNext.jsフルスタックでオンプレ運用していたが、以下の課題が顕在化した。
| 課題 | 詳細 |
|---|---|
| モノリス肥大化 | 機能拡張で内部結合が強くなり、保守困難に |
| API設計欠如 | 他システム連携・公開API提供が後付けで実現困難 |
| ログ記入のDX未達成 | 30分グリッドの自然言語ログが結局スプシ手動運用のまま |
| 二重登録問題 | Googleフォーム事前登録と現場再登録の混乱 |
| ID-人物の照合困難 | メンターが「この子何してたっけ」「どの子がIDの子か」混乱頻発 |
| 振り返りシート転記の負荷 | 紙→スプシの手転記がメンターの隠れタスクに |
これらを構造的に解決することが本プロジェクトの設計指針である。
| 役割 | システムへの関わり方 |
|---|---|
| 利用者(小1〜高3中心・その他含む) | チェックイン/アウト、紙ネームカード(QR付き)を使用 |
| 保護者 | 付き添いのみ。MVP範囲ではシステム未関与(Phase 2で検討) |
| メンター(学生スタッフ) | スマホPWAでログ記入、QRスキャンで子ども特定 |
| エリアマネージャー | ネームカード作成、初回登録対応支援、教員側スプシから学生側スプシへの転記 |
| 教員陣 | 事前登録情報の管理(学生側システムには非開示) |
| 研究者(研究室メンバー) | 蓄積データの分析・エクスポートCSV利用 |
| 開発・保守担当 | プロジェクトメンテナ |
各フェーズの判定基準は「これがないと運用が回らないか」。Phase 1 は本番稼働中、Phase 1.5 / Phase 2 は今後の拡張スコープ。最新の進捗・残作業は handoff.md を参照。
運用開始に絶対必要な最小構成として実装し、本番デプロイ済み。実装の詳細は mvp.md 参照。
- バックエンドAPI基盤(Hono on Cloudflare Workers)
- 参加者マスタ(Google Sheets連携でアクティベート管理)
- チェックイン画面(iPad PWA・QR/バーコードスキャン対応)
- 「初めての方」フロー(スプシ参照→ニックネーム選択→ID採番→アクティベート)
- 当日来場状況閲覧の管理画面(ダッシュボード・参加者一覧・メンター管理・事前登録管理)
- Google OAuth認証(Better Auth・許可リスト方式)
- 参加回数の集計・表示(ターム制/30分ルール。参加者ごと+会場全体の集計ビュー。詳細は §5.4)
Phase 1(MVP)の3アプリ(api / checkin / admin)には含まれないが、運用開始後に追加・出荷したアプリを含む。
運用と並行して実装・追加していく機能群。
- 会場サイネージ(
apps/signage): 大型モニター・キオスク向けの配信風表示。活動サイクル(50分活動/10分休憩)のチャイムと進行、来場・にぎわい・前回開催の集計を提示。メンター認証・PII 非表示。詳細は §9.4 と付録B、docs/superpowers/specs/2026-05-29-signage-chime-design.mdを参照(2026-05-30 出荷) - メンターアプリ(スマホPWA)
- 活動ログ記入(30分グリッド・未記入ハイライト・QR遷移)
- 活動カテゴリ・機材マスタ
- 共同活動者の記録
- ログCSVエクスポート
- 管理画面の機能拡張(参加者検索・編集・マスタ管理)
- ターム境界の自動チェックアウト(Cron Trigger)・会場スケジュール/休講カレンダー設定(現状はタームを来場時刻から自動判定し、締めは手動の「滞在中全員をチェックアウト」で運用する)
- 振り返りシートのOCR取り込み(Vision LLM経由)
- 教員側スプシとの自動同期(GAS Webhook)
- 公開API(混雑状況配信・APIキー認証)
- 高度な分析ダッシュボード(クラスター分析支援)
- リアルタイム編集状況表示(誰が今編集中か)
- 保護者向け機能(混雑状況・活動サマリ閲覧)
- iPadオフライン対応(PWAキャッシュ+復帰時同期)
- スロット切り替えのプッシュ通知
- 紙の振り返りシートのデジタル代替(教育方針として紙運用を維持)
- 紙の目標設定シートのデジタル代替(同上)
- 子ども向けのタブレット入力UI
- ネームカードPDFの自動生成・印刷(手動運用で十分)
- 教員側Googleフォーム置き換え
- 子どもが来場
- iPadのチェックイン画面で「初めての方」をタップ
- 事前登録済みかつ未アクティベートの参加者一覧(ニックネーム+学年)が表示される
- 自分のニックネームをタップ
- その瞬間に内製IDが採番される(来場順・年度2桁+連番)
- システムが学生側スプシに「アクティベート済」フラグと内製IDを書き戻す
- 同時に最初のチェックインセッションが作成される
- 画面に内製IDが表示される
- エリアマネージャーがその情報を元にネームカード(QR付き)を作成し、子どもに渡す
- 紙の目標設定シート記入後、活動開始
- 子どもがiPadのチェックイン画面の前に来る
- ネームカードのQR/バーコードをiPadのカメラにかざす
- 「○○さん、こんにちは!」と表示、自動でチェックイン記録
- 自分の場所に戻り活動開始
- メンターはスマホPWAを常時携帯
- トップ画面で現スロット(例: 10:00-10:30)の未記入の子が赤くハイライト、記入済みは緑
- メンターが対象の子の元へ行き、ネームカードのQRをスキャン
- 該当の子のログ記入画面が即座に開く
- 入力フロー(3秒で完了する動線):カテゴリ選択→機材選択→自由記述→メンターサポート→共同活動者選択→保存
- 5秒ポーリングで複数メンター間の記入状況をリアルタイム共有
- 子どもが帰る前に紙の振り返りシートを記入
- 自分のネームカードをiPadでQRスキャン → チェックアウト
- 「お疲れさま!今日の滞在時間: ○時間○分」と表示
- ネームカードを所定の保管場所へ片付ける
- 閉場後、メンターが紙の振り返りシートをスプシ等へ手転記(Phase 2でOCR化予定)
土日は午前(9:00–12:00)と午後(13:00–16:00)でタームが分かれ、またがらない。12:00 に受付端末の「滞在中全員をチェックアウト」を押して午前タームを締め、午後も活動する子は 13:00 に再チェックインする(その日2回の参加としてカウント)。各回の終了時も同様に締める。詳細は §5.4。
- 当日中、管理画面でリアルタイムに来場状況を確認
- 閉場後、当日のログをCSVエクスポート(Phase 1.5以降)
内製DBに持つのは運用に必要な最小限(氏名・ニックネーム・学年と来場記録)。機微情報は教員側に寄せる。実際のスキーマは packages/db/src/schema.ts が正。
| カラム | 型 | 説明 |
|---|---|---|
| id | varchar(8) PK | 内製発行ID(例: 26001、年度2桁+連番、来場順採番) |
| pre_registration_id | varchar UNIQUE | 学生側スプシの事前登録キー(例: PRE-2026-0001) |
| full_name | varchar(80) | 氏名(本名)。識別補助に使用 |
| nickname | varchar(50) | ニックネーム(メイン識別子) |
| grade | varchar(10) | 学年(小1, 小4, 中2, 高1, その他 等) |
| activated_at | timestamp | 初回来場・タップ時にアクティベートされた日時 |
| active | boolean | 有効/無効 |
設計上の重要事項:
- 内製DBに保持するのは 氏名・ニックネーム・学年 のみ。住所・年齢・保護者連絡先・学校名は保持しない(これらは教員管理側で完結)
- 氏名はメンターによる呼びかけや救急時の本人確認のために必要なので学生側にも持つが、メイン識別子はニックネーム(QR・検索・一覧の主表示はニックネーム)
| カラム | 型 | 説明 |
|---|---|---|
| id | uuid PK | |
| date | date UNIQUE | 開催日(チェックイン時に自動生成) |
| note | text NULL | 後から書ける任意メモ(雨だった、特別企画あり等) |
| created_at | timestamp |
運用上は意識しない設計。チェックイン時にその日のレコードがなければ INSERT ... ON CONFLICT DO NOTHING で自動生成される。
| カラム | 型 | 説明 |
|---|---|---|
| id | uuid PK | |
| participant_id | varchar(8) FK | |
| event_id | uuid FK | |
| checked_in_at | timestamp | |
| checked_out_at | timestamp NULL |
1日に参加者あたり複数の
sessionsが生まれうる(朝/昼/夕方のタームごと)。ターム区分はchecked_in_atから都度導出し、列としては保存しない。数え方は §5.4 を参照。
| カラム | 型 | 説明 |
|---|---|---|
| id | uuid PK | |
| varchar UNIQUE | 個人Gmail可(OAuth許可リスト判定キー) | |
| name | varchar | |
| role | enum | admin / mentor |
| active | boolean | |
| created_at | timestamp | |
| last_login_at | timestamp NULL |
activity_logs(活動ログ・30分スロット単位)activity_categories(活動カテゴリマスタ)equipment(機材マスタ)
participants 1 ─── n sessions
events 1 ─── n sessions
mentors 1 ─── n activity_logs (Phase 1.5)
sessions 1 ─── n activity_logs (Phase 1.5)
会場は時間帯(ターム)ごとに運用する。
| ターム | 時間帯(JST) | 主な開催日 |
|---|---|---|
| 朝 | 9:00–12:00 | 土日 |
| 昼 | 13:00–16:00 | 土日 |
| 夕方 | 16:00–19:00 | 平日(主に木) |
- 参加日数ではなく「参加回数」で数える。土日に朝と昼の両方に来れば、その日は 2回。利用者は来場ごとに物理スキルカードへチェックを付けており、システム上の集計もこの参加回数に揃える。
- 午前・午後はまたがない。12:00 に一旦全員チェックアウトし、午後継続者は 13:00 に再チェックインする(
sessionsが2件作られる)。 - 30分ルール: そのタームの終了まで残り30分未満に来場した場合、チェックイン/チェックアウトは通常どおり行うが、参加回数にはカウントしない。
- ターム区分とカウント可否は
checked_in_at(来場時刻)から都度導出し、sessionsには保存しない。判定ロジックはpackages/shared/src/venue-schedule.ts(classifyTerm/countsTowardParticipation)に集約し、API・フロント双方が同じ実装を使う。 - 同一タームに事故的な再チェックインが複数あっても、参加回数は
(開催日, ターム)単位で重複排除して1回として数える。 - 締めの「全員チェックアウト」は手動運用(受付端末の既存ボタン)。Cronによる自動化や会場スケジュール設定は Phase 1.5 以降の候補(§3.2)。
┌─────────────────────────────┐
│ 教員管理スプシ │ ← 事前登録フォームから受信
│ (本名・住所等の機微情報を含む)
└──────────┬──────────────────┘
│ 必要列のみ手作業で転記
│ (MVP期間中はこの作業を継続)
▼
┌─────────────────────────────┐
│ 学生側スプシ │ ← バックエンド参照用
│ ・事前登録ID (PRE-2026-XXXX) │
│ ・氏名 │
│ ・ニックネーム │
│ ・学年 │
│ ・事前登録日 │
│ ・内製ID(バックエンドが書込)│
│ ・アクティベート日時(同上) │
│ ・アクティベート済(同上) │
└──────────┬──────────────────┘
│ Google Sheets API
│ ・「初めての方」一覧取得時に読み取り
│ ・アクティベート時に書き戻し
▼
┌─────────────────────────────┐
│ 内製DB (Cloudflare D1) │ ← アクティベート以降の主データソース
└─────────────────────────────┘
学生側と教員側の完全な分離は、教員陣のプライバシー管理体制への配慮および学生側システムの責任範囲を限定する目的で必須要件とする。
- Google OAuth のみ(Better Auth経由)
- 許可リスト方式:
mentorsテーブルにメアドが登録されかつactive=trueのアカウントのみログイン可能 - 個人Gmailを許容(大学発行アカウント限定にしない)
| ロール | 権限 |
|---|---|
| admin | イベント編集・マスタ編集・参加者編集・CSVエクスポート・全機能 |
| mentor | 閲覧・ログ記入(Phase 1.5以降) |
- 関係者用Googleグループへの追加と並行して、管理画面から
mentorsレコードを追加 - 退会時は
active=falseに変更(レコード自体は残す)
API-first を貫き、3種のフロントが同じ API 基盤を共有する。型整合は共通 Zod スキーマで担保する。
- API-firstを徹底。フロントエンド3種(チェックインiPad / メンタースマホ / 管理PC)が同じAPI基盤を経由
- REST API、JSON Body
- Hono on Cloudflare Workersで実装
- 共通の Zod スキーマ(
packages/shared/src/schemas/)をフロント/バック両方から参照することで型整合を担保(Hono Clienthcは使わず、フロントはapiFetch+ 共通スキーマで型アサート) - Phase 2の公開APIは別エンドポイント群(
/public/v1/...)で素直に拡張可能
| エンドポイント群 | 認証方式 |
|---|---|
/api/*(メンター・管理用) |
Better Auth Google OAuth |
/checkin/*(iPad受付端末用) |
Better Auth Google OAuth。受付メンターの端末で運用するため、Cookie ベースの mentor 認証必須に変更した |
/public/v1/*(Phase 2) |
APIキー認証 |
Phase 1 で以下の範囲を実装・稼働中。リクエスト/レスポンス形式の詳細は mvp.md 参照。
- 認証系(
/api/auth/*・Better Auth ハンドラ) - 受付端末系(
/checkin/*): 「初めての方」フロー(pre-registered / activate)、チェックイン・アウト(sessions/check-in・check-out)、QRスキャン(scan)、当日履歴・一括チェックアウト(history/today・history/check-out-bulk)、参加者検索・詳細・来場履歴(participants/search・:id・:id/attendance) - 管理系(
/api/*): 自分の情報(me)、当日来場状況(sessions/today)、セッション・イベント・参加者一覧、メンター管理(mentors GET/POST/PATCH)、事前登録管理(pre-registrations GET/POST/DELETE。未活性+活性化済みの両リストを返す)
Phase 1.5以降で活動ログ・マスタ管理エンドポイントを追加予定。
- iPadのSafariからPWA化、ホーム画面追加
- iOSのアクセスガイド機能でアプリ固定運用
- 受付メンターが操作する想定で、Better Auth セッション必須
- 主要画面: トップ(QRスキャナ+ショートカット)/受付プロフィール(参加者詳細+実行ボタン)/初めての方一覧/受付履歴&一括チェックアウト/マニュアル入力(ID/名前検索)/ログイン/設定/ガイドライン
- Phase 1: ダッシュボード(当日来場状況)/参加者一覧(閲覧のみ)/メンター管理/ログイン
- Phase 1.5: 参加者編集/イベント管理/マスタ管理/CSVエクスポート
- 現スロットダッシュボード/ログ記入画面/子ども詳細画面/過去履歴
大型モニター・キオスク向けの配信(ブロードキャスト)風画面。会場の活動進行と雰囲気を来場者・ 保護者に見せる公開面だが、個人を特定できる情報は出さない(人数・にぎわい等の集計表現のみ)。
- 稼働判定・在館数: 認証付き
GET /api/sessions/todayを再利用し、ターム別チェックイン数から算出 - 動画: YouTube IFrame Player API の自前キュー(
GET /api/signage/playlist)。関連動画・終了画面を抑止 - チャイム・サイクル:
@tecnova/shared/activity-cycle(50分活動/10分休憩)。次チャイムまでのカウントダウンと進行を表示 - 巡回インフォ: 動画タイトル・来場・にぎわい・前回開催の集計(
GET /api/signage/previous-summary)・稼働状況(GET /api/signage/health)を巡回 - 認証: checkin/admin と同じメンター・ホワイトリスト。共有の管理用 Google アカウントで運用
- 詳細仕様:
docs/superpowers/specs/2026-05-29-signage-chime-design.md
| レイヤー | 採用技術 |
|---|---|
| バックエンドAPI | Hono on Cloudflare Workers |
| データベース | Cloudflare D1(SQLiteベース、Workersネイティブ) |
| ORM | Drizzle ORM |
| 認証 | Better Auth(Google OAuth) |
| フロントエンド | Next.js (App Router)。checkin / admin / signage の 3 アプリ(加えて Phase 1.5 予定の mentor) |
| フロントホスティング | Vercel |
| ストレージ | Cloudflare R2(必要時のみ・Phase 2で本格使用) |
| モノレポ管理 | pnpm workspaces + Turborepo + Biome |
| ドメイン管理 | Cloudflare |
| CI/CD | GitHub Actions + Vercel自動デプロイ + Wrangler自動デプロイ |
| 外部API | Google Sheets API(学生側スプシの読み書き) |
tecnova-platform/
├── README.md
├── CLAUDE.md
├── LICENSE
├── docs/
│ ├── requirements.md ← このファイル
│ └── mvp.md
├── apps/
│ ├── api/ # Hono on Cloudflare Workers
│ ├── checkin/ # Next.js (iPad PWA・受付端末)
│ ├── admin/ # Next.js (PC)
│ └── signage/ # Next.js (会場サイネージ・大型モニター/キオスク)
│ # apps/mentor (スマホPWA) は Phase 1.5 で着手予定。現時点では未作成。
├── packages/
│ ├── db/ # Drizzle schema・migrations
│ ├── ui/ # 共通UIコンポーネント (shadcn/ui)、APIクライアント、JSTフォーマッタ、MeProvider
│ └── shared/ # 共通型・Zodスキーマ・Sheets連携・activity-cycle
│ # Better Auth 設定は apps/api/src/lib/auth.ts に集約(リクエスト毎に
│ # auth instance を作る都合上、Workers の Env を直接受け取る場所に置く)
├── .env.example
├── .gitignore
├── biome.json
├── pnpm-workspace.yaml
└── turbo.json
- Hono: エッジ実行最適化、型安全、Cloudflare Workersとの親和性
- Cloudflare Workers: 既にCloudflareでドメイン管理を行っている、エッジ実行・無料枠
- Cloudflare D1: WorkersネイティブなSQLite。接続プーリング不要、レイテンシゼロ、無料枠で本プロジェクトの規模を十分カバー(参加者数百人・同時数十接続)
- Drizzle ORM: TypeScriptネイティブ、D1対応(
drizzle-orm/d1)、Honoコミュニティの主流 - Better Auth: フレームワーク非依存、セッション管理を自分で制御できる学習価値、マルチクライアント対応
- モノレポ: Honoの型推論、3フロントの共通化、実務(メガベンチャー)標準
| 項目 | 目標 |
|---|---|
| API応答時間(中央値) | 200ms以下 |
| API応答時間(95%ile) | 500ms以下 |
| メンターアプリのポーリング間隔(Phase 1.5) | 5秒 |
| 同時接続デバイス数(ピーク時) | 20デバイス想定 |
- 本システムは100%オンライン前提で設計する
- 会場のWi-Fi切断時は、チェックイン業務を一時停止し、紙運用に切り替える
- 復帰後、メンターが手動でログを追加可能
- Phase 2でiPadチェックインのオフライン対応を検討
- HTTPS必須(Cloudflare自動)
- Better AuthによるセッションCookie(HttpOnly, Secure, SameSite=Lax)
- 許可リスト方式によるOAuthアクセス制御
- iPad受付端末用エンドポイント(
/checkin/*)も Cookie ベースの mentor 認証必須(5月改修)。受付メンターがログインした状態で運用する前提 - iPadはiOSアクセスガイド機能でアプリ固定、子どもの誤操作を防ぐ
- Google Sheets APIアクセスはサービスアカウント経由、必要最小限のスコープに限定
| データ種別 | 内製DBに保持 | 保持先 |
|---|---|---|
| 氏名(本名) | ✅ | 内製DB+学生側スプシ |
| ニックネーム | ✅ | 内製DB+学生側スプシ |
| 学年 | ✅ | 内製DB+学生側スプシ |
| 活動ログ(Phase 1.5) | ✅ | 内製DB |
| 年齢・生年月日 | ❌ | 教員管理スプシ |
| 住所 | ❌ | 教員管理スプシ |
| 保護者連絡先 | ❌ | 教員管理スプシ |
| 学校名 | ❌ | 教員管理スプシ |
氏名は呼びかけ・救急時の本人確認に必要なので学生側でも持つが、メイン識別子はニックネーム(QR・検索・一覧の主表示はニックネーム)。
設計時に想定した主要リスクと、それぞれに対して講じた(または講じる)対策の一覧。
| # | リスク | 影響度 | 発生確率 | 対策 |
|---|---|---|---|---|
| R1 | 会場のWi-Fi不安定によりチェックイン業務停止 | 高 | 中 | 紙運用に切り替えるフォールバック手順を運用マニュアルに明記。Phase 2でオフライン対応 |
| R2 | Better Auth on Workers のライフサイクル問題(waitUntil未使用で503/30秒ハング) |
中 | 中 | リクエスト毎にauth instanceを生成し、遅延処理を足す場合はc.executionCtx.waitUntilを必ず通す方針(現行は DB 書き込みを await 完結のため未配線) |
| R3 | Google Sheets API書き戻し失敗時のデータ不整合 | 中 | 中 | D1にインタラクティブ・トランザクションがないため、DB書き込み後にスプシ書き戻し→失敗時は補償処理(sessions/participants削除)でロールバック。失敗時はユーザーへエラー表示&再試行 |
| R4 | Cloudflare WorkersでGoogle Sheets APIクライアントが動かない | 中 | 中 | googleapisパッケージはNode.js依存のため使用不可。Web Crypto APIで自前JWT生成+fetch直叩きで対応(実装済み) |
| R5 | 新規スタック同時投入によるセットアップ遅延 | 高 | 中 | Honoはランタイム非依存に書く。最悪Vercel Functions退避可(Phase 1 では Workers で安定稼働) |
| R6 | iPadキオスクモードからの脱出(子どもの誤操作) | 低 | 中 | iOSアクセスガイドで物理ボタン無効化。スタッフ用パスコードで解除のみ可 |
| R7 | QRコード破損・ネームカード紛失 | 低 | 中 | 管理画面から内製IDを再表示できる機能。QRはIDから再生成可能 |
| R8 | スプシ更新の即時性(教員転記がリアルタイムでない) | 低 | 高 | 「初めての方」一覧は5秒キャッシュで運用。当日朝の事前登録者には対応できないことを運用上許容 |
Phase 1(MVP)は環境構築 → チェックイン・初めての方フローの中核実装 → 管理画面・Better Auth → リハーサルという順で進め、本番リリース済み。以降は運用と並行して Phase 1.5(メンターアプリ・活動ログ)を継続実装する。
進捗・残作業の最新状況は handoff.md を参照。
Phase 1 を運用に乗せるために満たすべき基準:
- iPadからのQRチェックイン/アウトが安定動作すること
- 「初めての方」フローでスプシから一覧取得→ID採番→書き戻しが動作すること
- 管理画面で当日の来場状況閲覧ができること
- Google OAuthでメンター/管理者がログインできること
- ネットワーク不安定時のフォールバック手順が運営側に共有されていること
| 用語 | 定義 |
|---|---|
| アクティベート | 事前登録済みの参加者が初回来場時に内製IDを発行され、内製DBに登録される行為 |
| 学生側スプシ | バックエンドが参照する転記版スプレッドシート。教員側スプシとは完全分離 |
| 教員側スプシ | 事前登録フォーム由来の本名等を含むスプレッドシート。学生側からは非アクセス |
| スロット | 30分単位の時間区切り(Phase 1.5以降で使用) |
| ターム | 会場の時間帯区分(朝 9–12 / 昼 13–16 / 夕方 16–19)。来場時刻から判定する |
| 参加回数 | タームごとの参加を数えた累計(朝+昼で2、30分ルール適用)。物理スキルカードのチェック数に対応(participationCount) |
| 来場回数 | チェックインの生の回数(=セッション数、visitCount)。受付プロフィールの活動カレンダーは1来場=1タイルで滞在時間が長いほど濃く表示する |
| 来場日数 | 重複排除した開催日数。参加回数・来場回数とは別指標 |
| 30分ルール | タームの残り30分未満に来た来場は参加回数に数えない(チェックイン/アウトは行う) |
| スキルカード | 利用者が所持し、参加ごとにチェックを付ける物理カード |
| ネームカード | QR/バーコード印字済みの紙カード。子どもが常設で利用 |
| 未記入ハイライト | Phase 1.5で実装。現スロットでログが未記入の子を赤く表示する機能 |
| GAS | Google Apps Script |
| MVP | Minimum Viable Product。本プロジェクトではPhase 1を指す |
| # | 判断項目 | 結論 | 根拠 |
|---|---|---|---|
| D1 | 事前登録の扱い | 学生側スプシ経由の片方向同期(教員側からの転記)。MVP期間は手作業 | 教員陣のプライバシー管理体制を尊重 |
| D2 | ネームカード | QR印字、事前準備、常設運用 | 運用シンプル化、儀式的UX、自動印刷不要 |
| D3 | ログ記入のパラダイム | 30分グリッド方式、入力UIを構造化(Phase 1.5) | イベント駆動だと観察疲れ・記入忘れリスク |
| D4 | 振り返りシート | 紙運用維持(教育方針) | 教員の方針、子どもの学習体験 |
| D5 | OCR取り込み | Phase 2 | 運用開始の制約 |
| D6 | リアルタイム同期方式 | 5秒ポーリング(Phase 1.5) | WebSocketはオーバーエンジニアリング、規模的に十分 |
| D7 | バックエンドフレームワーク | Hono on Cloudflare Workers | エッジ実行・型安全・学習価値・既存Cloudflare資産との親和性 |
| D8 | 認証 | Better Auth + Google OAuth + 許可リスト方式 | 自前パスワード管理リスク回避、メンター入れ替わり管理が楽 |
| D9 | リポジトリ構成 | モノレポ(pnpm + Turborepo) | 型共有・共通コンポーネント・実務標準 |
| D10 | ネットワーク前提 | 100%オンライン前提(Phase 2でオフライン対応) | 実装複雑度を抑え運用開始を優先 |
| D11 | events テーブル | 残す(チェックイン時に自動生成) | 集計クエリのシンプルさ・将来の研究分析時のメタ情報付与 |
| D12 | ID採番ロジック | 来場順・年度2桁+連番(例: 26001) | 来場しなかった事前登録者にIDを発行しない。短く覚えやすいID |
| D13 | スプシ書き戻し | あり(アクティベート時に内製ID・日時・フラグを書き戻す) | 教員側もアクティベート状況が見える、双方向の状態管理 |
| D14 | Phase 1スコープ | チェックイン基盤のみに絞る。ログ機能はPhase 1.5 | 運用開始に絶対必要なものだけに集中 |
| D15 | データベース選定 | Cloudflare D1(SQLite)。Neon/Hyperdrive構成からの変更 | Workersネイティブで接続管理不要・レイテンシゼロ、本プロジェクトの規模(数百人・同時数十接続)には十分。トレードオフとしてインタラクティブ・トランザクションは使えないため、アクティベート処理は補償処理ベースのsagaパターンに切替 |
| # | 判断項目 | 結論 | 根拠 |
|---|---|---|---|
| S1 | 認証 | checkin/admin と同じメンター・ホワイトリストを共有(共有の管理用アカウントで運用) | 公開面だが信頼端末のみで運用・実装と運用を簡素化 |
| S2 | 公開面のPII | 個人特定情報を出さない(人数・にぎわい・前回開催はすべて集計表現) | ニックネーム主・最小PII原則との一貫性 |
| S3 | 動画 | YouTube(プレイリスト管理・運用者が編集可)+自前キューで関連動画/終了画面を抑止。自前ホストはフォールバック | 運用者が編集しやすく、埋め込みの関連動画 UI を抑止できる(広告は埋め込み側で消せない制約は受容) |
| S4 | BGM | OS 側 Spotify(アプリに SDK/OAuth を統合しない)。チャイムのみ Web Audio で独立合成 | 音楽配信の権利・統合コストを避け運用を簡素化 |
| S5 | サイクル・チャイムのロジック | 時刻・サイクル・チャイムを @tecnova/shared/activity-cycle に純粋ロジック化 |
テスト可能・他アプリと共有 |