ランダム短歌 — 全体要件整理
- バージョン: v1.0(2026-07 時点)
- ステータス: 本番運用中(MVP + 拡張機能)
- 本番 URL: https://random-tanka.vercel.app
- 実装:
tanka-party/(Life OS webapp/ とは別 Vercel プロジェクト)
この文書が 全体の正本 です。個別ドキュメント(MVP 原案・非同期・UI 整理など)は詳細や履歴用として残し、矛盾がある場合は 本書を優先 してください。
目次
- ゴール・コンセプト
- モード一覧
- 確定要件(全体)
- 画面・UX
- モード別詳細
- 合成ロジック
- データ・保存
- API 概要
- 技術構成
- 通知・メール
- 実装ステータス
- 将来案
- 関連ドキュメント
1. ゴール・コンセプト
2〜6人(1人練習も可)が、スマホ/PC から参加し、各自が書いた 5音・7音フレーズのカード をランダムに組み合わせて 短歌(57577) を作るパーティ向け Web アプリ。
- ログイン不要 — ニックネームのみで参加
- 匿名 — 短歌に作者名は出さない(参加者色分けは任意・試験機能)
- 結果は端末に保存 — サーバーに短歌 PNG は保存しない
2. モード一覧
| モード |
rooms.mode |
用途 |
TTL |
| 通常 |
normal |
同時に集まって遊ぶ |
24時間 |
| 曲水の宴 |
gokusui |
制限時間内にカードを書く |
24時間 |
| 非同期 |
async |
数日かけてカード入力 |
7日 |
| おひとりさま |
(人数1で自動) |
1人練習 |
24時間 |
作成時にモードを選択。1人参加時は おひとりさまモード が有効(過去の言葉プールと混合可)。
3. 確定要件(全体)
| ID |
項目 |
内容 |
| R-01 |
参加人数 |
1〜6人(MVP 原案は2〜6。1人練習を追加済み) |
| R-02 |
カード枚数 |
デフォルト 5音4枚 + 7音6枚(ホストがメニューで変更可、各1〜10) |
| R-03 |
入力ルール |
音数は目安表示のみ。送信は止めない |
| R-04 |
音数の数え方 |
仮名ベース(拗音・促音・長音・撥音も1音)。ベストエフォート |
| R-05 |
短歌の数 |
min(人数×5音枚数÷2, 人数×7音枚数÷3) |
| R-06 |
カード再利用 |
1セッション中1回まで(重複なし) |
| R-07 |
ルーム参加 |
ホスト作成 → 4桁コード + URL 共有 → コード入力で参加 |
| R-08 |
ニックネーム |
必須(8文字以内) |
| R-09 |
作者表示 |
なし(匿名) |
| R-10 |
結果表示 |
縦書き/横書き切替、1首ずつカード状、Canvas 画像保存 |
| R-11 |
結果保存 |
サーバーに PNG は保存しない(コピー/画像保存のみ) |
| R-12 |
ルーム寿命 |
通常・曲水: 24時間 / 非同期: 7日 |
| R-13 |
同期 |
3秒間隔ポーリング(非同期は30秒でも可) |
| R-14 |
書いた分だけ使う |
空でないカードのみ 合成プール。全部書けなくても参加 |
| R-15 |
再合成 |
同じカードで別の短歌 |
| R-16 |
もう一度遊ぶ |
カードを空にして入力から |
| R-17 |
ルーム一覧 |
端末 localStorage に最大12件 |
| R-18 |
テーマ |
ホストが任意設定(40文字以内) |
| R-19 |
参加者色 |
8色から選択(サーバー保存、ルーム全員に反映) |
| R-20 |
名称 |
ランダム短歌(random-tanka) |
非ゴール(現時点)
- アカウント登録・ログイン(Phase 2 設計のみ)
- 結果のサーバー永続保存・履歴 API
- 厳密な音数バリデーション(送信ブロック)
- WebSocket リアルタイム同期
- Life OS
webapp/ との UI 統合
4. 画面・UX
4.1 全体フロー
flowchart TB
subgraph home [ホーム]
H1[ルーム作成 / 参加]
H2[ルーム一覧]
end
subgraph room [ルーム内 — 3画面]
S1[カード入力]
S2[短歌を作る]
S3[できあがった短歌]
end
H1 --> S1
S1 -->|短歌を作る| S2
S2 -->|合成する| S3
S3 -->|もう一度遊ぶ| S1
S1 <-->|← カード入力| S2
S1 <-->|← カード入力| S3
room -->|ハンバーガー メニュー| home
タブではなく 状態に応じた画面遷移。合成完了時は自動で「できあがった短歌」へ。
4.2 ホーム
- 「ルームを作る」(ニックネーム、モード、枚数、テーマ、おひとりさま設定)
- 「ルームに参加」(4桁コード + ニックネーム)
- ルーム一覧 — この端末で参加・作成したルーム(最大12件)、開く/削除
4.3 ルーム内 — カード入力画面
- 参加者リスト — 折りたたみ(
<details>)、初期は開いたまま
- 参加者表示: 「参加/不参加」ではなく 「N枚」「未保存」 など
- 5音・7音の入力欄(ホスト設定枚数)
- 音数目安表示(送信は常に可能)
- 自動保存(曲水・非同期)— 下記 §5 参照
- ナビ: 短歌あり → 「できあがった短歌」 / なし → 「短歌を作る」
4.4 ルーム内 — 短歌を作る画面
- 合成可能条件を満たすとき 「合成する」(通常はホスト、条件により誰でも可)
- 曲水: 「宴を始める」(ホストのみ)
- 「← カード入力」で戻る
4.5 ルーム内 — できあがった短歌画面
- 短歌を縦書き/横書きで表示
- テキストコピー、1首ずつ画像保存
- 再合成 / もう一度遊ぶ(説明文ヒントは表示しない)
- 「← カード入力」で戻る
4.6 ハンバーガーメニュー
- ルームコード、招待 URL、LINE 招待
- 退室・ルーム終了・ホームに戻る
- ホスト設定: テーマ、枚数、モード、曲水の制限時間 など
- 任意: 結果をメールで受け取る
4.7 空白画面防止
- 合成済みなのに作成画面、未合成なのに結果画面、など 中身のない画面にならない
resolveRoomScreen / ensureRoomScreenHasContent で状態検証し正しい画面へ誘導
4.8 曲水タイマー(スティッキー)
- ヘッダー直下に sticky 表示
- キーボード表示中 は
visualViewport で見えている領域の上部に固定(画面外に消えない)
5. モード別詳細
5.1 通常モード
| 項目 |
内容 |
| 進行 |
全員カード入力 → 「準備OK」→ ホストが「合成する」 |
| ready |
意味あり(トグル) |
| 合成 |
入力済み2人以上、57577 が1首以上作れること |
| 最低人数 |
実質2人(1人はおひとりさま扱い) |
5.2 曲水の宴
コンセプト: 制限時間内にカードを書く短歌パーティ。
| 項目 |
内容 |
| 制限時間設定 |
ハンバーガーメニューのみ(合成画面に重複入力なし) |
| デフォルト |
180秒(空欄・未入力は180秒。0や空を60秒に丸めない) |
| 範囲 |
60〜600秒 |
| 設定反映 |
「設定を反映」→ サーバー保存 → 「宴を始める」 |
| 編集中 |
メニューで制限時間を編集中はポーリングで上書きしない |
| タイマー |
各端末のフロント主導(localDeadlineAt) |
| 途中参加 |
参加時点の 残り秒数 からカウント開始 |
| 宴終了時 |
① 0:00 検知 → ② カード保存 → ③ 最新ルーム取得 → ④ UI 更新 → ⑤ 「短歌を作る」画面 へ |
| 自動合成 |
しない — ユーザーが手動で「合成する」 |
| カード保存 |
「カードを保存」ボタン + 1秒デバウンス自動保存 |
| 合成対象 |
保存された 空でないカード のみ(ready は見ない) |
曲水 — ホスト操作フロー
- ルーム作成(モード: 曲水の宴)
- メニュー → 制限時間 → 設定を反映
- 参加者を待つ → 短歌を作る → 宴を始める
- カード入力 で書く(自動保存)
- 制限時間終了 → 自動で保存・短歌を作る 画面へ
- 合成する → できあがった短歌
5.3 非同期モード
コンセプト: 同時に集まらず、7日以内 に好きな時間でカードを書く。
| 項目 |
内容 |
| 入力締切 |
ルーム作成から 7日 |
| 合成タイミング |
入力済み2人以上 なら合成可(締切前でも OK) |
| 締切後 |
カード編集ロック、合成可能 |
| 合成操作 |
誰でも 合成可 |
| ready |
意味薄い — 保存済み = 入力完了 |
| 進捗 UI |
「入力済み: 2/3 人」など |
| 通知 |
任意メール登録 → 合成・再合成時に送信(SMTP 未設定なら no-op) |
| カード保存 |
曲水と同様の自動保存 + 「カードを保存」 |
詳細: random-tanka-async.md
5.4 おひとりさまモード(1人)
| 項目 |
内容 |
| 条件 |
参加者が1人 |
| フレーズ源 |
過去プール混合(phrase_pool)または 自分のカードのみ |
| 合成 |
1人でも可能(プールから補完) |
| 蓄積 |
合成成功時、使った言葉を匿名で phrase_pool に蓄積 |
6. 合成ロジック
- 対象参加者の 5音・7音カードをプール化(空文字は除外)
- 生成首数 =
min(人数×5音枚数÷2, 人数×7音枚数÷3)(整数除算)
- 各首: 5音プールから2枚、7音プールから3枚を 重複なし でランダム抽出 → 57577
- プール不足時: 作れる首数だけ生成
- 合成成功時: 使用フレーズを
phrase_pool に匿名蓄積(おひとりさま混合用)
- 再合成: 同じカードプールで再シャッフル
- もう一度遊ぶ: カードクリア + ステータスリセット
モード別の合成対象フィルタ:
| モード |
対象参加者 |
| 通常 |
ready または入力済み(実装に準拠) |
| 曲水 |
participantHasWrittenCards = true |
| 非同期 |
同上 + 締切・2人チェック |
7. データ・保存
7.1 サーバー(Turso / SQLite)
| テーブル |
内容 |
寿命 |
rooms |
状態、短歌 JSON、テーマ、モード、締切等 |
24h / 7d |
participants |
ニックネーム、カード、ready、accent_color、email |
ルーム連動 |
phrase_pool |
匿名フレーズ(合成時蓄積) |
永続 |
詳細: random-tanka-data.md
7.2 クライアント(localStorage)
| キー |
内容 |
random-tanka-session |
ルームコード、participant ID、host token |
random-tanka-rooms |
ルーム一覧(最大12件) |
random-tanka-layout |
縦書き/横書き設定 |
| 色分け ON/OFF |
端末のみ(localStorage) |
7.3 カード自動保存(曲水・非同期)
- 入力から 1秒 後にデバウンス保存
- フォーカス blur・タブ非表示時にも保存
- 12秒ごとの未保存チェック(バックアップ)
- 保存状態表示: 未保存 / 保存中 / 自動保存済
8. API 概要
| メソッド |
パス |
説明 |
| POST |
/api/rooms |
ルーム作成 |
| POST |
/api/rooms/{code}/join |
参加 |
| GET |
/api/rooms/{code} |
状態取得(ポーリング) |
| PUT |
/api/rooms/{code}/cards |
カード提出 |
| POST |
/api/rooms/{code}/ready |
準備OKトグル |
| POST |
/api/rooms/{code}/compose |
合成 |
| POST |
/api/rooms/{code}/reset |
もう一度遊ぶ |
| PUT |
/api/rooms/{code}/settings |
ホスト設定 |
| PUT |
/api/rooms/{code}/accent |
参加者色 |
| PUT |
/api/rooms/{code}/email |
通知メール登録 |
| POST |
/api/rooms/{code}/gokusui/start |
宴開始 |
| POST |
/api/rooms/{code}/leave |
退室 |
| DELETE |
/api/rooms/{code} |
ルーム終了 |
認証: participant ID + host token をクライアント保持(localStorage)。
9. 技術構成
tanka-party/
src/app/ # Next.js UI + API Routes
src/lib/ # DB・音数・合成・メール
public/app.js # クライアント UI ロジック
public/tanka-canvas.js # Canvas 画像生成
scripts/ # テスト・マイグレーション
| 層 |
技術 |
| フロント + API |
Next.js 16(Vercel) |
| DB |
Turso(libSQL)— webapp と共有可能 |
| 同期 |
3秒ポーリング |
| デプロイ |
Vercel Root Directory = tanka-party |
起動: cd tanka-party && npm install && npm run dev → http://localhost:8080
10. 通知・メール
| フェーズ |
内容 |
状態 |
| Phase 1 |
ルーム単位の任意メール、合成・再合成通知 |
✅ 実装済 |
| Phase 2 |
アカウント・マジックリンク・横断履歴・メルマガ |
設計のみ |
| Phase 3 |
メール画像添付(サーバー PNG) |
未着手 |
SMTP 設定: random-tanka-smtp.md
アカウント設計: random-tanka-auth-newsletter.md
11. 実装ステータス
✅ 実装済み
| カテゴリ |
機能 |
| コア |
ルーム作成/参加、カード入力、合成、結果表示 |
| モード |
通常、曲水の宴、非同期、おひとりさま |
| UI |
3画面構成、折りたたみ参加者、ハンバーガーメニュー、ルーム一覧 |
| 曲水 |
フロント主導タイマー、キーボード sticky、自動保存、自動合成なし |
| 入力 |
書いた分だけ使う、枚数変更(デフォルト 5音4/7音6) |
| 結果 |
再合成、もう一度遊ぶ、Canvas 画像保存、縦横切替 |
| その他 |
参加者色分け、退室、テーマ、メール通知(SMTP 時) |
| テスト |
test:async, test:partial-cards, test:line-colors 等 |
🔄 検討中・未確定
📋 Phase 2 以降(設計のみ)
- メールログイン・自分の短歌一覧
- 締切前リマインドメール
- 「○○さんが入力しました」通知
12. 将来案
random-tanka-ideas.md にアイデアメモを集約。
注意: ideas.md の曲水セクションは 初期案(「書けなかった人は不参加」「自動合成」)を含む。現行仕様は §5.2 本書 が正。
| アイデア |
概要 |
状態 |
| 人狼モード |
表/裏テーマ混在 |
未実装 |
| 一括保存・共有 |
全首を1アクションで |
未実装 |
| 曲水演出 |
流れ UI、お題切替 |
未実装 |
| メールログイン |
横断履歴・メルマガ |
設計のみ |
13. 関連ドキュメント
変更履歴
| 日付 |
内容 |
| 2026-07 |
全体要件整理 v1.0 — MVP・非同期・UI/曲水・会話確定事項を統合 |