チャット・通知
位置づけ: 後続フェーズ
チャット・通知基盤は、営業・事務・施工店・代理店の連絡を CRM 上のチャットに一元化し、社内向けには Slack 通知を併用するハイブリッド構成である。会話は案件(Deal)に紐づくルームとして存在し、雑談チャンネルは対象外とする「文脈必須」原則をとる。
試作実装(crm_app、React + TS)には案件単位のチャット機能が実装済みである。ルームは相手スコープ(社内/施工店/代理店)で固定分割され、案件詳細画面のチャットタブおよび受信箱型の一覧ページから閲覧する。Slack通知は、設定画面のイベント×宛先マトリクスとして定義済みであり、タスク依頼フローでは Incoming Webhook による実送信も動作する。
一方、バックエンド永続化・リアルタイム配信・チャットメッセージ発火のSlack通知配線は未実装である。永続化は現状ブラウザの localStorage(キー crm:chats)に限られ、試作段階のモックデータとして扱う。
スコープ/対象
Section titled “スコープ/対象”第1弾(先行リリース: 催事・アイテム(商品マスタ)・商社(卸))には含まれない。本ページはその後続フェーズの仕様である。
出典は3系統に分かれる。混同を避けるため下表で整理する。
| 対象 | 内容 | 実装状況 |
|---|---|---|
| 旧システム向け拡張見積(BT社「チャットシステム拡張開発」) | 顧客ごとのチャットルーム。Pusherでリアルタイム配信 | 未実装(旧システム側の見積案件) |
ChatworkService | 社内ツール ChatWork への通知連携 | 実装済(本件のCRM内チャットとは別物) |
| 新CRM試作の案件チャット | 案件(Deal)×相手スコープでルーム分割 | 実装済(フロント・localStorage 永続化のみ) |
| Slack Incoming Webhook 通知 | タスク依頼・通知マトリクスから Slack へ送信 | 実装済(設定画面から Webhook URL を登録して送信) |
| リアルタイム配信基盤(Pusher/WebSocket) | メッセージのプッシュ配信 | 未実装 |
データ(エンティティ表)
Section titled “データ(エンティティ表)”会話は案件(Deal)×スコープの組み合わせごとに1ルームとし、1案件につき最大3ルームとする。トピック分けはメッセージ本文側の運用に委ねる。
| エンティティ | 主なフィールド | 紐付け先 | 実装状況 |
|---|---|---|---|
| ChatThread(ルーム) | id, dealId, scope, members, messages, unread | Deal × RoomScope | 実装済(フロントのみ) |
| ChatMessage | id, author, role, text, at | ChatThread | 実装済(フロントのみ) |
| ChatMember | name, role(表示用 ChatRole:営業/事務/施工店/代理店) | ChatThread | 実装済(フロントのみ) |
| ReadReceipt(ユーザー別既読) | userId, threadId, lastReadAt | ChatThread | 未実装(現状はルーム単位の unread カウンタのみ) |
| 添付ファイル | ファイル種別・保存先・紐付け先 | ChatMessage | 未実装 |
ChatThread は dealId と scope を主キー的に持つ。メンバーごとの既読管理ではなく、ルーム単位の単純な未読カウンタで運用する。
| 画面/機能 | 内容 | 実装状況 |
|---|---|---|
案件詳細「チャット」タブ(DealChatTab) | 案件に紐づく最大3ルームをタブ切替で閲覧 | 実装済 |
/chat 受信箱一覧(ChatPage) | 案件を1行に畳み、ルーム・未読・最新メッセージを横断表示 | 実装済 |
ロールベース可視スコープ(visibleScopes()) | 施工店ロールは施工店ルームのみ、代理店ロールは代理店ルームのみ、社内ロールは3スコープすべてを閲覧 | 実装済 |
Slack通知マトリクス(SettingsPage) | イベント×宛先の一覧表示とON/OFF切替 | 実装済 |
| アプリ内通知センター(ベルアイコン・未読一覧) | チャットタブ内バッジ表示と /chat の未読集計で代替 | 未実装 |
モバイル対応の要否・優先度は、催事現場からの利用ニーズに応じて判断する。
業務ルール/ワークフロー
Section titled “業務ルール/ワークフロー”ルーム自動生成
Section titled “ルーム自動生成”案件ステータスが変化した際、useDeals から createRoomsFor が呼ばれ、成約時に社内ルーム(代理店経由の場合は代理店ルームも)、施工着手時に施工店ルームを自動作成する。既定メンバーはスコープに応じて defaultMembers() が自動セットする。社内ルームは営業担当者本人、代理店ルームは営業担当者と代理店窓口、施工店ルームは営業担当者と施工店名を初期メンバーとする。
第三者を既存ルームへ追加招待する機能は未実装である。内部ロールは未作成のルームをボタン一つで作成できるが、これは招待ではなくルーム作成にとどまる。
Slack通知連携
Section titled “Slack通知連携”src/lib/notifications.ts に23件の通知ルール(NOTIFY_RULES)が定義されており、SettingsPage の通知マトリクスで宛先・タイミングを一覧・ON/OFF切替する。宛先は3系統に整理する。
- 担当DM — 割当・催促など「その人が動く」通知
- 機能チャンネル —
#商談前確#成約#施工#発注#申請#催事などチームで拾う通知 - 顧客チャンネル — 成約時に案件ごとへ自動作成する
実送信が動作するのはタスク依頼(前確・太陽光調査設計、TaskRequestSheet)のみで、設定画面に保存した Incoming Webhook URL へ POST する。Webhook未設定時は「Slack未設定」のトースト表示にフォールバックする。それ以外の通知ルールは、設定UI・ルール定義のレベルにとどまり、バックエンドからの自動発火(cronやイベントトリガー)は行わない。
CRM内チャットのメッセージ送信とSlack通知は未接続である。notifications.ts には chat-message ルールが定義されているが、ChatPanel の送信処理からSlack送信を呼び出すコードはない。
| イベントグループ | 代表イベント | 宛先 | 実装状況 |
|---|---|---|---|
| 架電(前確) | 担当割当・リマインド・結果・不出再架電 | 担当DM/#商談前確/営業DM | ルール定義・設定UIのみ |
| 商談 | 結果入力の催促、保留の再連絡リマインド | 営業DM | ルール定義・設定UIのみ |
| 成約・契約後 | 成約時の顧客チャンネル自動作成、審査結果 | #成約/顧客チャンネル/営業DM | ルール定義・設定UIのみ |
| 施工 | 現地写真格納漏れ、完了報告・完工書督促、入金超過 | #施工/担当DM/営業DM | ルール定義・設定UIのみ |
| 発注 | 納期回答メールの案件紐付け(order-reply) | 担当DM | ルール定義・設定UIのみ |
| 発注 | 欠品・納期遅延アラート(order-stock) | #発注 | ルール定義・設定UIのみ |
| 申請 | 印鑑証明期限、申請期限、連携結果未着 | #申請 | ルール定義・設定UIのみ |
| 催事 | 開始/終了報告未提出、日次ファネル集計 | #催事/担当DM | ルール定義・設定UIのみ |
| タスク依頼(前確・太陽光調査設計) | 依頼→担当割振→通知→結果/成果物 | 担当DM | 実送信まで実装済(TaskRequestSheet) |
| チャット | CRMチャット新着(Slack併用期間) | 担当DM | ルール定義のみ(送信処理は未配線) |
質問窓口としての運用
Section titled “質問窓口としての運用”部門ごとの質問窓口スレッドを常設する運用は、コード上に該当概念(区分・専用チャンネル等)を持たない構想段階の機能である。実装するにはスレッドにステータス(未回答/解決済等)を持たせるスキーマ拡張が必要になる。解決済みQ&Aをナレッジとして蓄積し、AIエージェントが一次回答する構想は将来構想とし、AIエージェント構想の方針と接続する。
催事・商社タスクとの連携
Section titled “催事・商社タスクとの連携”催事モジュール(催事モジュール仕様)との接続では、通知ルール ev-start-missing(開始報告未提出)・ev-end-missing(終了報告未提出)・ev-daily(日次ファネル集計)が #催事 チャンネル向けに定義済みである。催事単位のチャットルーム自動生成は未実装である。
商社(卸)業務(商社(卸)モジュール仕様)との接続では、通知ルール order-reply(納期回答メールの案件紐付け)が担当DM向け、order-stock(欠品・納期遅延アラート)が #発注 チャンネル向けに、それぞれ定義済みである。発注管理・決済フローとの詳細な状態遷移(発注→入荷→請求等)への通知拡張は今後の検討課題とする。
各モジュールは通知イベントを発行するだけとし、配信先の解決は notifications.ts のルールテーブルで一元管理する設計原則をとる。ルールがモジュール横断で1ファイルに集約されている現状は、この原則に沿う。
配信基盤とリアルタイム化
Section titled “配信基盤とリアルタイム化”現状は Step0 に位置づけられる。チャットはフロントの状態管理(zustand + localStorage)のみで、ページを開いている間の表示更新はできるが、他ユーザー・他端末へのリアルタイム配信・プッシュ通知の仕組みはない。
| 段階 | 配信方式 | できること | 実装状況 |
|---|---|---|---|
| Step0(現状) | zustand + localStorage(フロントのみ) | 案件チャットの閲覧・送信・未読表示。Slack通知はタスク依頼のみ実送信 | 実装済(試作範囲) |
| Step1 | バックエンド永続化+ポーリング | 複数端末・複数ユーザーでの状態同期 | 未着手 |
| Step2 | Pusher等リアルタイム配信 | 新着メッセージ・通知のプッシュ配信 | 未着手(採用可否を再評価) |
| Step3 | 双方向同期・AI一次応答 | Slack↔CRM相互反映、質問窓口のAI回答 | 将来構想 |
Pusher採用は旧システム向け見積時点の前提であり、新CRM試作では未採用である。自前WebSocketやSupabase Realtime等との比較は未実施とする。メッセージと通知ログの保持期間は未定である。
ロール別の可視スコープは visibleScopes() により自動的に絞り込む。権限判定に使うのは既存CRMのロール体系(lib/permissions.ts の Role:管理者/営業/事務(BO)/発注・申請担当/代理店/代理店(メンバー)/施工店の7種)のみであり、チャット専用の権限ロールは追加しない。これとは別に、ChatMember.role(lib/chat.ts の ChatRole:営業/事務/施工店/代理店の4種)は発言者アイコン・ラベルを出し分けるための表示専用の型で、権限判定には関与しない。
| ロール | 閲覧できるルーム |
|---|---|
| 管理者・営業・事務・発注/申請担当(社内ロール) | 社内/施工店/代理店の3スコープすべて |
| 代理店/代理店(メンバー) | 代理店ルームのみ |
| 施工店 | 施工店ルームのみ |
外部(商社・代理店)ユーザーのログイン主体・アカウント発行方式は、役割・権限で定める所属・組織軸(Google Workspace正)の設計と合わせて別途定める。
- チャットメッセージ送信時のSlack通知(
chat-messageルール)を配線するかどうか - バックエンド永続化(Supabase等)への移行時期
- 第三者を既存ルームへ追加する招待フローのUI設計
- ユーザー別既読モデル(
ReadReceipt)への拡張要否 - 質問窓口スレッドの新規実装可否とスケジュール
- Pusher採用可否の再評価、および自前WebSocket・Supabase Realtime等との比較
- メッセージ・通知ログの保持期間