ドメインモデル
システム概要
Section titled “システム概要”Speakeasy は店舗と顧客をつなぐコミュニケーションプラットフォームです。小売・サービス業の店舗が顧客と 1対1 のチャットを行い、一括配信で情報を届け、複数チャネルで通知を送ることができます。
コアエンティティ
Section titled “コアエンティティ”エンティティ詳細
Section titled “エンティティ詳細”Organization(組織)
Section titled “Organization(組織)”テナントの最上位単位。ユーザーはいずれかの Organization に所属し、その配下の Shop を操作します。
| プロパティ | 説明 |
|---|---|
type | individual(個人事業主)または group(企業グループ) |
parentId | グループの場合、親 Organization の ID |
metadata | JSONB の拡張情報 |
ビジネスルール:
- 1つの Organization に複数の Shop を紐付け可能
- Organization 間で Shop を移管可能(
shop_transferで履歴追跡) groupタイプは階層構造を持てる(parentId)
Shop(店舗)
Section titled “Shop(店舗)”実際の店舗を表すエンティティ。連絡先管理・チャット・一括配信の基本単位です。
| プロパティ | 説明 |
|---|---|
chatAvailability | online(チャット対応可能)/ away(離席中) |
availabilityMode | auto(自動切替)/ manual(手動切替) |
welcomeMessage | 顧客がチャットを開始した際に表示されるメッセージ |
ビジネスルール:
- 在席状態は WebSocket 経由でリアルタイムに顧客へ通知
autoモードではスタッフの接続状況に応じて自動でonline/awayを切替- purelovers と連携する場合は
shop_pureloversで外部 ID を紐付け
Contact(連絡先)
Section titled “Contact(連絡先)”顧客情報。1つの Shop に紐付きます。
| プロパティ | 説明 |
|---|---|
userType | 顧客分類: 優良 / 普通 / 要注意 / NG |
tags | 自由テキストのタグ配列 |
groupIds | 所属グループ ID の配列 |
userId | Vault DB のユーザー ID(ログイン連携時) |
index | 読み仮名(カナ) |
ビジネスルール:
userIdが紐付くと、その顧客はチャットにログイン可能NGユーザーは一括配信の対象から自動除外- Chat NG ステータスにより個別にチャットを制限可能
- purelovers 連携時は
contact_pureloversで外部プロフィールを保持
ChatRoom(チャットルーム)
Section titled “ChatRoom(チャットルーム)”店舗と顧客の 1対1 チャットルーム。
| プロパティ | 説明 |
|---|---|
roomId | {shopId}:{contactId} 形式の複合キー |
customerEntered | 顧客がチャットに参加済みか |
lastMessage | 最新メッセージのプレビューテキスト |
lastMessageAt | 最新メッセージの送信日時 |
lastUserMessageAt | 最新の「顧客からの」メッセージ日時 |
ビジネスルール:
- 1つの Shop と 1つの Contact の組み合わせに対して最大1つの ChatRoom
lastUserMessageAtは店舗側の一覧ソートに使用(システムメッセージを除外)customerEnteredがfalseの場合、顧客側にはルームを非表示
ChatMessage(メッセージ)
Section titled “ChatMessage(メッセージ)”チャットルーム内の個別メッセージ。
| プロパティ | 説明 |
|---|---|
messageType | normal(通常)/ advertisement(広告)/ broadcast(一括配信)/ system(システム) |
contentType | text / html |
displayDays | 表示期限(日数、デフォルト90日) |
metadata | JSONB の拡張情報(一括配信 ID 等) |
ビジネスルール:
displayDays経過後のメッセージは自動的に非表示- 一括配信メッセージは
broadcastタイプで metadata にbroadcastIdを保持 - 添付ファイルは
chat_attachmentテーブルで R2 上のファイルを参照
Broadcast(一括配信)
Section titled “Broadcast(一括配信)”複数の顧客に対して同一メッセージを一括送信するタスク。
ビジネスルール:
- 配信条件(criteria)はタグ・ユーザー種別・グループ・purelovers 状態の組み合わせ
- 配信予定が8時間以内の場合は直接
QUEUEDに移行 - 失敗時は最大3回リトライ(300秒間隔)
- 送信は5,000件単位でバッチ処理
ユーザーロールと権限
Section titled “ユーザーロールと権限”| ロール | 説明 | 主な権限 |
|---|---|---|
owner | オーナー | 全権限、Organization 削除 |
admin | 管理者 | メンバー管理、設定変更 |
member | メンバー | チャット、連絡先操作、一括配信 |
staff | スタッフ | チャットのみ(限定的) |
システムロール
Section titled “システムロール”| ロール | 説明 |
|---|---|
user | 一般ユーザー |
admin | Penthouse 管理者(全テナント横断) |
通知チャネル
Section titled “通知チャネル”顧客・店舗スタッフへの通知は複数チャネルで配信可能です。
| チャネル | 説明 | 対象 |
|---|---|---|
BOX | アプリ内通知ボックス | 店舗スタッフ |
PUSH | Web Push 通知(VAPID) | 店舗スタッフ・顧客 |
LINE | LINE メッセージ通知 | 店舗スタッフ |
EMAIL | メール通知(Resend) | 店舗スタッフ |
通知タイプごとにチャネルの有効/無効を設定できます(shop_notification_setting)。
purelovers 連携
Section titled “purelovers 連携”purelovers は外部のロイヤリティプラットフォームです。
- セッション発行: purelovers の API キーで Tap 経由の Bearer トークンを取得
- 連絡先同期: purelovers ユーザー → Contact + ContactPurelovers
- 店舗同期: purelovers 店舗 → ShopPurelovers
- Webhook: 店舗更新・スケジュール変更・レビュー投稿等のイベントを受信
LINE 連携
Section titled “LINE 連携”- 店舗に LINE アカウントを紐付け(
shop_line_account) - LIFF(LINE Front-end Framework)でチャット UI を LINE 内で提供
- 通知チャネルとして LINE Messaging API を使用