Skip to content

Latest commit

 

History

History
328 lines (257 loc) · 13.1 KB

File metadata and controls

328 lines (257 loc) · 13.1 KB

Setsuna - 仕様書

概要

Setsuna(刹那)は、デバイス間でテキストをリアルタイム共有するWebアプリケーションです。 スマートフォンでコピーしたテキストを、PCでそのまま取得するといった用途に使用できます。

基本情報

項目 内容
アプリケーション名 Setsuna
バージョン 1.3.4
ライセンス MIT

技術スタック

カテゴリ 技術
フロントエンド Next.js 15 (App Router), React 19
スタイリング Tailwind CSS
データベース Turso (SQLite互換)
ORM Prisma
リアルタイム通信 Server-Sent Events (SSE)
テスト Vitest, Testing Library, Playwright
Linter/Formatter oxlint, Prettier
Gitフック husky, lint-staged
デプロイ先 Vercel
言語 TypeScript
国際化 next-intl

開発方針

テスト駆動開発(TDD)

本プロジェクトではt-wada氏のTDDを採用。詳細は TEST.md#テスト戦略 を参照。

概要:

  • src/lib/, src/app/api/: TDD(テスト先行)
  • src/components/, E2E: 後付けテスト

機能要件

1. ルーム管理

1.1 ルーム作成

  • ユーザーは新しいルームを作成できる
  • ルーム作成時に6文字の英数字コードが自動生成される
  • ルームは作成から24時間後に自動削除される

1.2 ルーム参加

  • ユーザーはルームコードを入力してルームに参加できる
  • 存在しないまたは期限切れのルームにはアクセスできない
  • URLでの直接アクセスも可能(例: /room/A1B2C3

2. テキスト共有

2.1 テキスト送信

  • ユーザーはテキストを入力して送信できる
  • 最大10,000文字まで送信可能
  • 送信されたテキストは全参加者にリアルタイムで配信される

2.2 テキスト受信

  • 新しいテキストはリアルタイムで画面に表示される
  • 過去のテキストは時系列で一覧表示される

2.3 クリップボード操作

  • 各テキストにはコピーボタンが付属
  • ワンクリックでクリップボードにコピー可能

3. 国際化(i18n)

  • 英語(デフォルト)と日本語に対応
  • URL構造: /en(英語), /ja(日本語)
  • UIから言語切替が可能(LanguageSwitcherコンポーネント)
  • 翻訳ファイルはmessages/ディレクトリに配置

4. 自動削除

  • ルームは作成から24時間後に自動削除
  • 削除時にルーム内のすべてのメッセージも同時に削除
  • Vercel Cron Jobsにより1時間ごとに削除処理を実行

5. 管理ダッシュボード

5.1 認証

  • 管理者は環境変数(ADMIN_PASSWORD)で設定したパスワードでログイン
  • JWTトークン(ADMIN_JWT_SECRETで署名)をHttpOnly Cookieで管理(24時間有効)
  • 未認証の/adminアクセスはログインページへリダイレクト
  • 重要: ADMIN_PASSWORDADMIN_JWT_SECRET の両方を設定しないと認証が動作しない

5.2 統計ダッシュボード

  • アクティブルーム数
  • 総メッセージ数
  • 本日のルーム/メッセージ作成数
  • 過去7日間の日別統計グラフ

5.3 ルーム管理

  • ルーム一覧表示(ページネーション、10件/ページ)
  • 検索機能(ルームコードで検索)
  • フィルター(アクティブ/期限切れ)
  • ルーム詳細・メッセージ閲覧
  • ルーム強制削除

5.4 手動クリーンアップ

  • 期限切れルームの即時削除ボタン

非機能要件

セキュリティ

項目 対策
ルームコード 暗号学的に安全な乱数で生成(crypto.randomBytes
文字種 紛らわしい文字(0,O,1,I,L)を除外した31文字(A-HJ-NP-Z, 2-9)
組み合わせ数 31^6 ≒ 約8.9億通り
XSS対策 Reactの自動エスケープ機能を活用
HTTPS 本番環境ではHTTPS必須

パフォーマンス

項目 目標値
初期ロード 3秒以内
メッセージ配信遅延 500ms以内
同時接続数 ルームあたり100接続

可用性

  • Vercelの自動スケーリングを活用
  • TursoのエッジDBによる低レイテンシー

制限事項

項目 内容
SSEブロードキャスト インメモリ管理のため、単一インスタンス前提での運用
スケールアウト 複数インスタンス間でのSSE通知は非対応(将来的にRedis Pub/Sub導入検討)

環境変数

必須環境変数

変数名 説明 必須
DATABASE_URL ローカルSQLiteデータベースのパス 開発時 file:./dev.db
TURSO_DATABASE_URL TursoデータベースのURL 本番 libsql://your-db.turso.io
TURSO_AUTH_TOKEN Turso認証トークン 本番 (Tursoから取得)
CRON_SECRET Cronジョブ認証用シークレット 本番 (ランダム文字列)
ADMIN_PASSWORD 管理ダッシュボードのログインパスワード 任意 (任意のパスワード)
ADMIN_JWT_SECRET JWTトークン署名用のシークレットキー 管理機能使用時 (ランダム文字列、32バイト以上推奨)

環境変数の設定方法

1. .env ファイルの作成

cp .env.example .env

2. 開発環境の設定

# データベース
DATABASE_URL="file:./dev.db"

# 管理ダッシュボード(任意)
ADMIN_PASSWORD="your-password"
ADMIN_JWT_SECRET="your-jwt-secret"

3. 本番環境の設定

# データベース(Turso)
TURSO_DATABASE_URL="libsql://your-db.turso.io"
TURSO_AUTH_TOKEN="your-token"

# Cronジョブ認証
CRON_SECRET="your-cron-secret"

# 管理ダッシュボード
ADMIN_PASSWORD="your-secure-password"
ADMIN_JWT_SECRET="your-secure-jwt-secret"

4. シークレットキーの生成

安全なシークレットキーを生成するには、以下のコマンドを使用:

# ADMIN_JWT_SECRET用
openssl rand -base64 32

# CRON_SECRET用
openssl rand -hex 32

注意事項

  • 管理ダッシュボード: ADMIN_PASSWORDADMIN_JWT_SECRET の両方を設定しないと、管理画面へのログインが失敗します(500エラー)
  • 本番環境: シークレットキーは十分な長さ(32バイト以上)のランダム文字列を使用してください
  • Vercel: Vercelの環境変数設定画面から設定してください

ユーザーフロー

[開始]
   │
   ▼
┌─────────────────┐
│   ホームページ   │
│  (ルーム作成/参加) │
└─────────────────┘
   │
   ├─── 「ルームを作成」────┐
   │                       ▼
   │              ┌─────────────────┐
   │              │ ルームコード生成 │
   │              │   (例: ABCD23)   │
   │              └─────────────────┘
   │                       │
   │                       ▼
   │              ┌─────────────────┐
   │              │  ルームページへ  │
   │              │    自動遷移     │
   │              └─────────────────┘
   │                       │
   ├─── 「ルームに参加」───┤
   │         │             │
   │         ▼             │
   │  ┌───────────────┐   │
   │  │コード入力画面 │   │
   │  └───────────────┘   │
   │         │             │
   │         ▼             │
   │  ┌───────────────┐   │
   │  │ ルームページ  │◀──┘
   │  └───────────────┘
   │         │
   │         ▼
   │  ┌───────────────┐
   │  │テキスト入力・  │
   │  │ 送信・コピー   │
   │  └───────────────┘
   │         │
   │         ▼
   │  ┌───────────────┐
   │  │ リアルタイム  │
   │  │    同期      │
   │  └───────────────┘
   │
   ▼
[24時間後自動削除]

ディレクトリ構造

Setsuna/
├── docs/                          # 仕様書
│   ├── SPEC.md                    # 全体仕様(本ファイル)
│   ├── API.md                     # API仕様
│   ├── DB.md                      # データベース仕様
│   ├── UI.md                      # UI/UX仕様
│   └── TEST.md                    # テスト仕様
├── messages/                      # i18n翻訳ファイル
│   ├── en.json                    # 英語
│   └── ja.json                    # 日本語
├── .husky/                        # Gitフック
│   ├── pre-commit                 # コミット前にlint-staged実行
│   └── pre-push                   # プッシュ前にテスト実行
├── prisma/
│   └── schema.prisma              # DBスキーマ
├── src/
│   ├── app/                       # Next.js App Router
│   │   ├── layout.tsx
│   │   ├── page.tsx               # ルートリダイレクト
│   │   ├── globals.css
│   │   ├── [locale]/              # ロケール対応ルート
│   │   │   ├── layout.tsx         # ロケールレイアウト
│   │   │   ├── page.tsx           # ホームページ
│   │   │   └── room/[code]/       # ルームページ
│   │   ├── admin/                 # 管理ダッシュボード
│   │   │   ├── layout.tsx         # 管理画面レイアウト
│   │   │   ├── page.tsx           # ダッシュボード
│   │   │   ├── login/             # ログインページ
│   │   │   └── rooms/             # ルーム管理
│   │   └── api/                   # APIルート
│   ├── components/                # Reactコンポーネント
│   │   └── admin/                 # 管理用コンポーネント
│   │       ├── AdminHeader.tsx    # ナビゲーションヘッダー
│   │       └── StatsCard.tsx      # 統計カード
│   ├── i18n/                      # i18n設定
│   │   ├── routing.ts             # ルーティング設定
│   │   ├── request.ts             # リクエスト設定
│   │   └── navigation.ts          # ナビゲーションAPI
│   ├── lib/                       # ユーティリティ + テスト(*.test.ts)
│   ├── hooks/                     # カスタムフック
│   └── types/                     # 型定義
├── e2e/                           # E2Eテスト(Playwright)
├── middleware.ts                  # next-intlミドルウェア
├── .oxlintrc.json                 # Oxlint設定
├── prettier.config.mjs            # Prettier設定
├── lint-staged.config.mjs         # lint-staged設定
├── vitest.config.ts               # Vitest設定
├── playwright.config.ts           # Playwright設定
├── vercel.json                    # Vercel設定
├── package.json
└── README.md

関連ドキュメント