コンテンツにスキップ

ランダム短歌 — 全体要件整理

  • バージョン: v1.0(2026-07 時点)
  • ステータス: 本番運用中(MVP + 拡張機能)
  • 本番 URL: https://random-tanka.vercel.app
  • 実装: tanka-party/(Life OS webapp/ とは別 Vercel プロジェクト)

この文書が 全体の正本 です。個別ドキュメント(MVP 原案・非同期・UI 整理など)は詳細や履歴用として残し、矛盾がある場合は 本書を優先 してください。


目次

  1. ゴール・コンセプト
  2. モード一覧
  3. 確定要件(全体)
  4. 画面・UX
  5. モード別詳細
  6. 合成ロジック
  7. データ・保存
  8. API 概要
  9. 技術構成
  10. 通知・メール
  11. 実装ステータス
  12. 将来案
  13. 関連ドキュメント

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 は見ない)

曲水 — ホスト操作フロー

  1. ルーム作成(モード: 曲水の宴)
  2. メニュー → 制限時間 → 設定を反映
  3. 参加者を待つ → 短歌を作る宴を始める
  4. カード入力 で書く(自動保存)
  5. 制限時間終了 → 自動で保存・短歌を作る 画面へ
  6. 合成するできあがった短歌

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. 合成ロジック

  1. 対象参加者の 5音・7音カードをプール化(空文字は除外
  2. 生成首数 = min(人数×5音枚数÷2, 人数×7音枚数÷3)(整数除算)
  3. 各首: 5音プールから2枚、7音プールから3枚を 重複なし でランダム抽出 → 57577
  4. プール不足時: 作れる首数だけ生成
  5. 合成成功時: 使用フレーズを phrase_pool に匿名蓄積(おひとりさま混合用)
  6. 再合成: 同じカードプールで再シャッフル
  7. もう一度遊ぶ: カードクリア + ステータスリセット

モード別の合成対象フィルタ:

モード 対象参加者
通常 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

🔄 検討中・未確定

  • 非同期モードの締切表示も曲水と同様にフロント主導に揃えるか
  • デバッグ UI(DEV_TOOLS)の本番可否
  • 一括画像保存・共有(random-tanka-ideas.md
  • 人狼モード、曲水の演出 UI

📋 Phase 2 以降(設計のみ)

  • メールログイン・自分の短歌一覧
  • 締切前リマインドメール
  • 「○○さんが入力しました」通知

12. 将来案

random-tanka-ideas.md にアイデアメモを集約。

注意: ideas.md の曲水セクションは 初期案(「書けなかった人は不参加」「自動合成」)を含む。現行仕様は §5.2 本書 が正。

アイデア 概要 状態
人狼モード 表/裏テーマ混在 未実装
一括保存・共有 全首を1アクションで 未実装
曲水演出 流れ UI、お題切替 未実装
メールログイン 横断履歴・メルマガ 設計のみ

13. 関連ドキュメント

文書 用途
本書 (random-tanka-overview.md) 全体要件の正本
random-tanka-requirements.md MVP 原案(履歴・初期合意)
random-tanka-ui-gokusui-requirements.md UI・曲水の会話整理(本書 §4–5 に統合済)
random-tanka-async.md 非同期モード詳細・ロードマップ
random-tanka-participant-requirements.md 参加者向けシンプル説明
random-tanka-data.md データ保存先
random-tanka-testing.md テスト手順
random-tanka-smtp.md SMTP / Vercel 設定
random-tanka-auth-newsletter.md メールログイン設計
random-tanka-ideas.md 将来アイデア

変更履歴

日付 内容
2026-07 全体要件整理 v1.0 — MVP・非同期・UI/曲水・会話確定事項を統合