世代マトリックス データ設計書
最終更新: 2026-09-21 関連 Issue: MorningStatusApp#1571(親Issue)/ #128(初版の設計書作成)/ #141(原仕様に沿った表示への改訂)/ MorningStatusApp#1632(実装)
1. 概要
OGメンバーの子供の誕生年と、現役メンバーの誕生年が交差する「世代の重なり」を年×メンバーのグリッドで可視化する世代マトリックス(Generational Matrix)機能のデータ設計。
親Issue(MorningStatusApp#1571)での検討の結果、以下の方針で設計する。
- OGの子供について、性別・氏名等の機微な属性は一切保持せず、生年(西暦)のみを新規データとして追加する
- 既存の Vercel Blob 書き込みはすべて
access: 'public'であり非公開データの置き場に使えないため、子供の生年データは Neon(Vercel Postgres)に格納する - 画面自体もナビゲーションから一切リンクしない隠しルートとし、加えてシークレットモード(本書§3)で保護する。詳細な画面仕様は 世代マトリックス 画面設計書 を参照
本人(OG・現役問わず全メンバー)の生年月日・加入日・卒業日は、既存の Member.profile.dob・joinDate・gradDate(Vercel Blob members.json)をそのまま使う。新規に追加するのは子供の生年データのみ。
2. テーブル設計
2-1. member_children(MemberChild)
OGメンバーの子供1人につき1レコードを持つ。同じメンバーが複数の子供を持つ場合は複数行になる(一意制約なし)。
| カラム | 型 | 制約 | 説明 |
|---|---|---|---|
id |
INT | PK, AUTO INCREMENT | ID |
memberId |
VARCHAR(50) | NOT NULL | 親であるメンバーの ID(Blob members.json の Member.id を参照。member_relationships(メンバー関係性マップ データ設計書 §2-1)と同様、DBレベルのFK制約は持たない) |
birthYear |
INT | NOT NULL | 子供の生年(西暦)。月日は保持しない |
- インデックス:
memberId(単列) - Prisma モデル名:
MemberChild(@@map("member_children")) - 運用上、
memberIdは現時点でOGメンバーのみを想定する(現役メンバーの子供は本書執筆時点で公表情報が存在しないため)。ただしDBレベルでOG限定を強制する制約は設けない。将来的に現役メンバーの子供が公表された場合も、同じテーブル・同じ手順でそのまま追加できる
氏名・性別・誕生日(月日)を持たない理由は本書§1の通り。本人の誕生(●)・加入(▲)・卒業(▼)と、子供の誕生(☆)の描画仕様は 世代マトリックス 画面設計書 §4を参照。
3. シークレットモードのアクセス制御
環境変数・ガード関数の定義は 環境変数一覧 §4「シークレットモードとは」を正とする。本節では世代マトリックスに固有の認証フローのみを記載する。
- 合言葉の検証:
POST /api/secret-mode/verify(body:{ passcode: string })でprocess.env.SECRET_MODE_PASSCODEと一致するか検証する - セッションCookie: 検証成功時、
secret_mode_sessionという httpOnly Cookie を発行する(secure: 本番のみ、sameSite: 'lax'、有効期限30日)。値は{expiresAt(epoch秒)}.{signature}の形式で、signatureはSECRET_MODE_PASSCODEを鍵としたcrypto.createHmac('sha256', ...)によるHMAC署名(Node.js標準のcryptoモジュールのみで完結させ、新規パッケージは追加しない) - 検証:
requireSecretMode()(lib/secret-mode.ts)がsecret_mode_sessionCookieを読み、expiresAtを鍵に再計算した署名と一致し、かつexpiresAtが現在時刻より未来であることを確認する。いずれかを満たさない場合は未認証として扱う - デスクトップモード(
requireDesktopMode()、lib/desktop-mode.ts)は「ビルド時に固定される実行モード」を見るだけの単純な環境変数チェックだが、シークレットモードは「同一デプロイ上でブラウザセッションごとに認証状態が変わる」ため、Cookie発行・署名検証が必要になる点がデスクトップモードとの違い
4. データ投入運用
子供の生年データは今後も継続的に追加・更新される想定のため、拡張可能な手動運用スクリプトとして設計する。既存の手動登録スクリプト(scripts/console/register-tour-festival.ts 等)と同じ「CSV入力 → スクリプト実行 → Neonへ反映」のパターンを踏襲する。
- スクリプト:
scripts/console/import-member-children.ts(実装は MorningStatusApp#1632) - 入力:
data/inputs/member-children.csv(1行目ヘッダー:memberId,birthYear) - 動作: CSVの各行を
member_childrenにINSERTする。既存の完全一致行(同じmemberId・birthYear)がある場合はスキップし重複登録を防ぐ(一意制約はテーブル側に持たせず、スクリプト側のロジックで判定する。同じ親から同じ年に複数の子供が生まれるケース(双子等)は稀だが、その場合は完全一致になり後発分がスキップされてしまうため、既知の制約として実装Issue側に申し送る) --dry-run: 実データへの書き込み前に差分(追加予定行)を表示するドライランモードを持たせる(本リポジトリの手動データ操作スクリプトの既定パターン)
初期データ投入時は、本書§5の参考データをCSV化して1回だけ実行する想定。
5. 初期データ(参考データ)
親Issue(MorningStatusApp#1571)のコメントに記載された実データ。列=メンバー(誕生年順)、行=西暦年、セル内 * は本人の誕生年、+ は子供の誕生年を表す。表記ゆれ・体裁は原文のまま記録する(CSV化・整形は実装Issue側で行う)。なお、*・+ は親Issueでイメージを伝えるために使われた表記で、画面の記号(●・☆)とは異なる(世代マトリックス 画面設計書 §4-2)。
6期まで(ママがたくさん)
| 中澤裕子 | 石黒彩 | 安倍なつみ | 飯田圭織 | 福田明日香 | 保田圭 | 矢口真里 | 市井紗耶香 | 後藤真希 | 石川梨華 | 吉澤ひとみ | 辻希美 | 加護亜依 | 高橋愛 | 紺野あさ美 | 小川麻琴 | 新垣里沙 | 藤本美貴 | 亀井絵里 | 道重さゆみ | 田中れいな | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1973 | * | ||||||||||||||||||||
| 1978 | * | ||||||||||||||||||||
| 1980 | * | ||||||||||||||||||||
| 1981 | * | * | |||||||||||||||||||
| 1983 | * | * | |||||||||||||||||||
| 1984 | * | ||||||||||||||||||||
| 1985 | * | * | * | * | |||||||||||||||||
| 1986 | * | ||||||||||||||||||||
| 1987 | * | * | * | ||||||||||||||||||
| 1988 | * | * | * | ||||||||||||||||||
| 1989 | * | * | |||||||||||||||||||
| 2000 | + | ||||||||||||||||||||
| 2002 | + | ||||||||||||||||||||
| 2004 | + | + | |||||||||||||||||||
| 2007 | + | + | |||||||||||||||||||
| 2010 | + | ||||||||||||||||||||
| 2012 | + | + | + | ||||||||||||||||||
| 2013 | + | + | + | ||||||||||||||||||
| 2015 | + | + | + | + | |||||||||||||||||
| 2016 | + | + | + | ||||||||||||||||||
| 2017 | + | + | + | + | |||||||||||||||||
| 2018 | + | + | + | + | + | ||||||||||||||||
| 2019 | + | + | |||||||||||||||||||
| 2020 | + | + | |||||||||||||||||||
| 2021 | + | + | |||||||||||||||||||
| 2022 | + | ||||||||||||||||||||
| 2024 | + | + | |||||||||||||||||||
| 2025 | + | ||||||||||||||||||||
| 2026 | + |
7期から14期
| 久住小春 | 光井愛佳 | ジュンジュン | リンリン | 譜久村聖 | 生田衣梨奈 | 鞘師里保 | 鈴木香音 | 飯窪春菜 | 石田亜佑美 | 佐藤優樹 | 工藤遥 | 小田さくら | 尾形春水 | 野中美希 | 牧野真莉愛 | 羽賀朱音 | 加賀楓 | 横山玲奈 | 森戸知沙希 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1988 | * | |||||||||||||||||||
| 1991 | * | |||||||||||||||||||
| 1992 | * | |||||||||||||||||||
| 1993 | * | |||||||||||||||||||
| 1994 | * | |||||||||||||||||||
| 1996 | * | |||||||||||||||||||
| 1997 | * | * | ||||||||||||||||||
| 1998 | * | * | ||||||||||||||||||
| 1999 | * | * | * | * | * | * | ||||||||||||||
| 2000 | * | |||||||||||||||||||
| 2001 | * | * | ||||||||||||||||||
| 2002 | * |
15期以降
| 北川莉央 | 岡村ほまれ | 山﨑愛生 | 櫻井梨央 | 井上春華 | 弓桁朱琴 | 杉原明紗 | 安田美結 | 鈴木もあ | 石川華望 | |
|---|---|---|---|---|---|---|---|---|---|---|
| 2004 | * | |||||||||
| 2005 | * | * | * | |||||||
| 2006 | * | |||||||||
| 2008 | * | |||||||||
| 2011 | * | |||||||||
| 2012 | * | |||||||||
| 2013 | * | * |
改訂履歴(バージョン降順に記載)
| 版 | 更新日 | 変更内容 |
|---|---|---|
| 1.1 | 2026-09-21 | 【v10.6.1(MorningStatusApp#1650。実装後の改修)】§1に、画面で使う加入日・卒業日も既存の Member.profile を使う旨を追記。§2-1の描画仕様の参照先を、記号の変更(*・+ → ●・☆)に合わせて画面設計書 §4 に改め、§5に参考データの表記(*・+)が画面の記号と異なる旨を追記した(morning-status-blume#141) |
| 1.0 | 2026-09-20 | 【v10.6.0(MorningStatusApp#1632)】初版作成(morning-status-blume#128) |