SOUZOHSPECS

業務システム ・ RELATE

顧客・商談管理

Excelをやめられる、中小企業のための顧客・商談管理システム

v1.0・作成 2026-08-13

デモを触る ↗MD

本番で使いたい方へデータの保存・セキュリティ・運用ルール・公開は、このデモには入っていません
  1. 要件定義書を保存する

    パソコンに relate-app のようなフォルダを作り、その中に保存します。

    要件定義書.md として保存

  2. ChatGPT で画面イメージを作る デザインにこだわりたい人

    ChatGPT に要件定義書を添付して、下の文を送ります。雰囲気のところは、好きな言葉に書きかえてください。

    ChatGPT に送る
    添付の要件定義書は、これから作るアプリ「顧客・商談管理」のものです。
    このアプリのいちばん大事な画面を、デザイン画像にしてください。
    実際のアプリのように、文字やボタンまで入れてください。
    雰囲気:(例:やさしい/高級感/ポップ/シンプル など、好きな言葉で)

    気に入るまで「もっと明るく」「ボタンを大きく」のように直してもらい、できた画像を保存します。ほかの画面も欲しければ、同じように作ってもらえます。

  3. Claude Code に渡して「作って」と頼む

    Claude のデスクトップアプリで「Code」タブを開き、「Select folder」から relate-app を選びます。画面イメージがある人は、入力欄に画像をドラッグして貼りつけてから、下の文を送ります。詳しく

    Claude Code に送る(画像あり)
    @要件定義書.md をもとに、このアプリを作ってください。
    デザインは添付の画像に合わせてください。
    Claude Code に送る(画像なし)
    @要件定義書.md をもとに、このアプリを作ってください。

    作り終わるまで、しばらくかかります。途中で「許可しますか」と聞かれたら、内容を見て許可してください。

  4. 動かして確かめる・直す

    できたら、実際に画面を開いて触ります。直してほしいところは、スクリーンショットを貼りつけて、言葉で伝えれば大丈夫です。

    Claude Code に送る
    アプリを起動して、ブラウザで開けるようにしてください。
    Claude Code に送る
    (画面名)で(操作)をすると(今の動き)になります。
    (こうなってほしい動き)にしてください。
    Claude Code に送る
    このエラーを直してください。
    
    (ここにエラーの文をそのまま貼る)
  5. 途中で止まったら 必要なときだけ

    要件定義書が長いので、一度で作りきれないことがあります。そのときは新しい会話で、こう送ります。

    Claude Code に送る
    @要件定義書.md の続きを作ってください。
    まず、どこまでできているかを確かめてから進めてください。

    それでも進まないときは、30分無料相談でお手伝いします。公式LINEからのご相談もどうぞ。

    1段階ずつ頼みたいとき(全6段階)

    要件定義書には、作る順番が Phase 0〜5 で書かれています。止まりやすいときは、1つずつ頼むと確実です。

    Phase 0基盤とデザインシステム
    Claude Code に送る
    @要件定義書.md の「実装タスク」にある Phase 0 を作ってください。
    Phase 1一覧基盤と顧客管理
    Claude Code に送る
    @要件定義書.md の「実装タスク」にある Phase 1 を作ってください。
    Phase 2商談・パイプライン
    Claude Code に送る
    @要件定義書.md の「実装タスク」にある Phase 2 を作ってください。
    Phase 3活動・タスク・見積
    Claude Code に送る
    @要件定義書.md の「実装タスク」にある Phase 3 を作ってください。
    Phase 4分析と設定
    Claude Code に送る
    @要件定義書.md の「実装タスク」にある Phase 4 を作ってください。
    Phase 5仕上げ
    Claude Code に送る
    @要件定義書.md の「実装タスク」にある Phase 5 を作ってください。
  6. 本番で使うなら

    できたアプリはデモです。データの保存・セキュリティ・運用のルール・公開の仕方は入っていないので、そのまま公開すると誰でも中身を見られます。本番で使うのに何が要るかは、このページの下にまとめました。

    自社向けに作り変えるなら、まずこう聞いてみてください。

    Claude Code に送る
    この要件定義書は、記事に埋め込むデモ用に書かれています。
    自分の会社で実際に使えるように変えたいです。外したほうがいいところと、残したほうがいいところを教えてください。

    本番運用について相談する

準備や、うまくいかないときの対処は 作り方ガイド にまとめています。分からないときは 30分無料相談 へどうぞ。

これはデモ用の要件定義書です。本番で使うには、あと4つ必要です

MDでダウンロード

RELATE — 要件定義書 兼 Claude Code 実装指示書

版数 1.0(DBレス構成)/ 作成日 2026-08-13 / 発行 ソウゾウ合同会社 用途 「爆速アプリ開発」LP 実演デモ / 顧客管理システム編


このドキュメントの使い方(Claude Code へ)

これ1枚が、規約・仕様・タスクのすべて。リポジトリ直下に CLAUDE.md として置き、毎回読み込むこと。

  • 実装は「11. 実装タスク」の順に進める。フェーズを飛ばさない。
  • 各タスクの括弧内は要件ID。着手前に該当章を読むこと。
  • 仕様がここに書かれていない場合は、推測で実装せず質問する。
  • スコープ外(3章 Won't have)は、思いついても実装しない。
  • 「デモだから」を理由に品質を落とす判断はしない。

姉妹プロジェクト HIREBASE との関係 同じ「爆速アプリ開発」LPに並べるデモ。両方を見た人に「同じテンプレで作っている」と思われた時点で失敗。 HIREBASE は求職者に読ませる消費者向けサイト(明朝体・余白・静けさ)。 RELATE は毎日8時間触る業務システム(ゴシック・高密度・キーボード操作)。 8章のデザイン要件は意図的に別方向に振っている。トークンを流用しないこと。


目次

  1. プロジェクト概要
  2. アーキテクチャ方針 — データベースを持たない
  3. スコープ定義
  4. ロールとデモ切替
  5. 画面一覧とユーザーフロー
  6. 機能要件
  7. データ設計
  8. デザイン要件
  9. 技術要件・ディレクトリ構成
  10. 非機能要件
  11. 実装タスク
  12. 受入基準

1. プロジェクト概要

背景と目的

「爆速アプリ開発」LPの見込み客の多くは、Excelとスプレッドシートで顧客・商談を管理している中小企業。SalesforceやHubSpotは高機能すぎて高い、しかしExcelでは限界がある——という層が中心。

この層に対して「あなたの業務に合わせた顧客管理システムを、この価格・この期間で作れます」を示すデモを用意する。求人サイト(HIREBASE)が消費者向けサービスの実装力を示すのに対し、RELATE は業務システムの実装力を示す。

目的 内容
業務システムの実装力の証明 一覧・検索・一括操作・権限・帳票・分析まで、実運用に耐える機能密度を示す
操作効率の設計力の証明 キーボード操作、一括更新、保存ビュー、コマンドパレット。「毎日使う人の速度」を設計できることを示す
カスタマイズ性の証明 カスタム項目・パイプライン段階の編集。「うちの業務に合わせられるのか」という最大の懸念に答える
横展開の資産化 業種特化版(不動産/建設/士業/介護)のベースとして再利用できる構造にする

プロダクト定義

項目 内容
プロダクト名 RELATE(リレート)※仮称
一言定義 Excelをやめられる、中小企業のための顧客・商談管理システム
提供形態 レスポンシブWebアプリ。フロントエンド完結(サーバー側の永続化なし)
主戦場 デスクトップ(業務時間中の利用が前提)。モバイルは外出先での確認・活動記録に最適化
想定利用者 LP訪問者。誰でも即座に、登録なしで全ロールを体験できる

プロダクトコンセプト

「入力の手間より、次に何をすべきかを返す。」

多くのCRMは入力項目が多く、現場が入力しなくなって死ぬ。RELATE は入力を最小にし、代わりに「今日やるべきこと」を毎朝返すことを設計の中心に置く。放置されている商談、期限切れのタスク、久しく接触のない顧客を、システム側から提示する。

デモとしての成功条件

  1. 触った瞬間に「業務で使えそう」と分かる — 空の画面が1つもなく、リアルな商談データが入っている
  2. 速い — 一覧の絞り込み、ステータス変更、活動記録が、待たされずに終わる
  3. ロールで見え方が変わる — 営業担当は自分の案件、マネージャーはチーム全体。権限設計ができていることを示す
  4. カスタマイズできる — 項目とパイプライン段階を画面上で足せる
  5. リセットできる — 誰が触った後でも、初期状態に戻せる

2. アーキテクチャ方針 — データベースを持たない

基本方針

バックエンドとデータベースを持たない。すべてブラウザ内で完結させる。

一般的な構成 本プロジェクト
PostgreSQL / Supabase シードデータ(TypeScript)+ ブラウザ内ストア
認証・SSO デモ用ロール切替(ワンクリック)
REST / GraphQL API ストア上の同期的な操作
メール送信・カレンダー連携 送信内容のプレビュー表示で再現
PDF生成(サーバー側) ブラウザ内で生成し、実際にダウンロードできる
CSVインポート/エクスポート 実際に動く。 ブラウザ内でパース/生成する

なぜこの構成にするか

  • LPデモとして最適 — 訪問者は登録もログインもせずに、全機能を即座に触れる
  • 顧客データを一切預からない — 入力されたデータはブラウザから出ない。デモに自社の顧客リストをCSVで投入して試すこともできる(これは営業上かなり強い)
  • 開発速度 — 認証・権限のサーバー実装・マイグレーションが不要になり、UIと操作効率の作り込みに全時間を投下できる
  • 運用コストゼロ — Vercel の静的配信のみ

差し替え可能性の担保(重要)

データアクセスは必ず lib/repo/ のリポジトリ層を経由すること。 コンポーネントからストアを直接触らない。

[ コンポーネント ]
        ↓  呼ぶのはこの層だけ
[ lib/repo/*.ts ]   ← 全メソッドを async にしておく
        ↓
[ lib/store/*.ts ]  ← Zustand + persist(localStorage)
        ↓
[ lib/seed/*.ts ]   ← 初期データ

リポジトリの各メソッドは、中身が同期処理でも async で定義し、await で呼ぶ。実案件へ転用する際、リポジトリの実装だけをAPI呼び出しに差し替えれば、UI層は一行も変更せずに済む。

// lib/repo/deals.ts — 中身は同期でも async にする
export async function findDeals(q: DealQuery): Promise<Result<Deal[]>> {
  await delay()
  const deals = useDataStore.getState().deals
  return { ok: true, data: applyScope(filterAndSort(deals, q)) }  // 将来ここがAPI呼び出しになる
}

永続化の範囲

対象 挙動
シードデータ(顧客・商談・活動履歴) 初期投入。以降は編集可能
ユーザーの操作結果(登録・編集・ステータス変更・活動記録・タスク) localStorage に保存。リロードしても保持される
CSVインポートしたデータ localStorage に保存される
添付ファイル セッション内のみ(Object URL)。リロードでファイル名のみ残る
リセット ヘッダーの「デモをリセット」で localStorage をクリアし初期状態へ

擬似的な非同期を必ず入れること。 リポジトリの各操作に 150〜400ms のディレイを挟み、ローディング状態を実際に見せる。

HIREBASE との差: 業務システムは「速さ」が価値なので、ディレイは HIREBASE(200〜600ms)より短く設定する。一覧の絞り込みなど体感速度が重要な操作は 100ms 以下にする。


3. スコープ定義

顧客・担当者管理

ID 機能 概要 優先度
F-A01 顧客(企業)一覧 テーブル表示、絞り込み、並び替え、列カスタマイズ、保存ビュー Must
F-A02 顧客詳細 基本情報、担当者一覧、商談一覧、活動タイムライン、関連ファイル Must
F-A03 顧客の登録・編集 インライン編集とモーダル編集の両対応 Must
F-A04 担当者(コンタクト)管理 顧客に紐づく人物情報。役職、連絡先、決裁権の有無 Must
F-A05 重複検出 会社名・電話番号の類似から重複候補を検出し、統合(マージ)できる Should
F-A06 CSVインポート 列マッピングUI、プレビュー、エラー行の表示、部分取り込み Must
F-A07 CSVエクスポート 現在の絞り込み条件・表示列でエクスポート Must
F-A08 一括操作 チェックボックス選択 → 担当者変更/タグ付与/削除を一括実行 Must
F-A09 タグ管理 顧客・商談へのタグ付与、タグでの絞り込み Should

商談(案件)管理

ID 機能 概要 優先度
F-D01 パイプライン(カンバン) 段階別の列表示、D&D移動、列ごとの合計金額 Must
F-D02 商談一覧(テーブル) カンバンと同じデータの表形式表示。切替可能 Must
F-D03 商談詳細 金額、確度、予定クローズ日、段階、担当、関連顧客、活動履歴、タスク Must
F-D04 商談の登録・編集 顧客からの新規作成、複製 Must
F-D05 段階変更 D&D またはキーボード。段階ごとの必須項目チェック Must
F-D06 受注・失注処理 受注理由/失注理由の記録(定型選択 + 自由記述) Must
F-D07 停滞検出 一定期間動きのない商談を自動でフラグ表示 Must
F-D08 パイプライン段階のカスタマイズ 段階の追加・名称変更・並び替え・確度の初期値設定 Should
F-D09 商談の予実 予定金額と受注金額、月次の着地見込み Should

活動・タスク

ID 機能 概要 優先度
F-T01 活動記録 訪問/電話/メール/打合せ/その他。日時、相手、内容、次アクション Must
F-T02 活動タイムライン 顧客・商談ごとの時系列表示。種別フィルタ Must
F-T03 クイック活動記録 一覧画面から離れずに、モーダルで活動を記録できる Must
F-T04 タスク管理 期限、担当、関連レコード、完了チェック Must
F-T05 今日のタスク ダッシュボード上の当日・期限超過タスク一覧 Must
F-T06 活動からのタスク自動生成 活動記録時に「次アクション」を入力すると、タスクが生成される Should
F-T07 メール送信 テンプレート選択、差し込み変数、送信内容のプレビュー、活動履歴への自動記録 Should

見積・売上

ID 機能 概要 優先度
F-Q01 商品マスタ 商品名、単価、原価、単位、カテゴリ Should
F-Q02 見積作成 明細行の追加・並び替え、数量・単価・値引き、小計/消費税/合計の自動計算 Should
F-Q03 見積PDF出力 自社ロゴ入りの見積書PDFを生成し、実際にダウンロードできる Should
F-Q04 見積の版管理 改訂版の作成、版ごとの履歴 Could
F-Q05 受注時の売上計上 受注した商談の金額を、月次の売上実績に反映 Should

分析・管理

ID 機能 概要 優先度
F-R01 ダッシュボード 今日のタスク、要対応商談、今月の着地見込み、活動サマリ Must
F-R02 パイプライン分析 段階別の件数・金額、転換率ファネル、平均滞留日数 Should
F-R03 担当者別実績 個人別の商談数・受注額・活動件数。マネージャーのみ閲覧 Should
F-R04 予実管理 月次目標と実績の対比、着地見込み Should
F-R05 失注分析 失注理由の集計、段階別の失注率 Could
F-R06 カスタム項目管理 顧客・商談に独自項目(テキスト/数値/日付/選択/チェック)を追加できる Should
F-R07 ユーザー・チーム管理 メンバー一覧、ロール変更、チーム編成 Should
F-R08 操作ログ 誰が・いつ・何を変更したかの履歴 Could

共通・基盤

ID 機能 概要 優先度
F-S01 ロール切替 営業担当/マネージャー/管理者をワンクリックで切替。切替バーは常時表示 Must
F-S02 グローバル検索 顧客・担当者・商談を横断検索。ヘッダーから常時アクセス Must
F-S03 コマンドパレット ⌘K / Ctrl+K で検索・画面遷移・新規作成を呼び出す Must
F-S04 通知センター 担当割当、期限接近、停滞アラート、メンション Should
F-S05 保存ビュー 絞り込み条件 + 表示列 + 並び順を名前を付けて保存。個人/共有を選択 Must
F-S06 デモリセット localStorage をクリアして初期状態に戻す Must
F-S07 ガイドツアー 初回訪問時に「何を試せるか」を3ステップで案内 Should

対象外(Won't have)

項目 理由
データベース・バックエンドAPI 2章の方針に基づく
本物の認証・SSO ロール切替で代替
実際のメール送受信・メールボックス同期 プレビュー表示で再現
カレンダー連携(Google / Outlook) 日程は内部で保持。ics ダウンロードのみ対応
電話・SFA連携(CTI)、名刺スキャンOCR 対象外
ワークフロー自動化のビルダー 停滞検出など固定ルールのみ実装
会計・請求書発行・入金消込 見積までを対象とする
モバイルネイティブアプリ レスポンシブWebで対応
複数ブラウザ間でのデータ共有 各ブラウザで独立。デモとして問題ない

スコープリスク: CRMは「あれもこれも」が最も起きやすい領域。特にワークフロー自動化ビルダー帳票の自由レイアウト編集は、単体で数週間かかる。要望が出た場合は別フェーズとして見積り、この文書のスコープは変えない。


4. ロールとデモ切替

ロール定義

ロールID 名称 見えるデータ 特徴的な権限
sales 営業担当 自分が担当する顧客・商談のみ 自分のレコードの作成・編集。他人の商談は閲覧のみ
manager マネージャー 自チーム全員のデータ 担当者の割当変更、チーム実績の閲覧、共有ビューの作成
admin 管理者 全社のデータ カスタム項目・パイプライン段階の編集、ユーザー管理、操作ログ

認証は行わない。ロールはストアの状態として保持し、切替バーから即座に変更できる。

データスコープ(デモの見せ場)

ロールによって同じ画面の表示件数が変わることを、明確に体験させる。

  • 営業担当(田中)でパイプラインを開く → 自分の商談 18件
  • マネージャーに切替 → 同じ画面がチーム全体の 62件になり、担当者フィルタが出現する
  • 管理者に切替 → 全社 140件。設定メニューが出現する

スコープの適用は lib/repo/_scope.ts に集約し、全リポジトリメソッドが必ず通す。コンポーネント側でフィルタしない(実案件でRLSに置き換わる箇所であるため)。

デモ切替バー(F-S01)

画面上部に常時表示する固定バー。

  • 現在のロールと担当者名の表示、3ロールの切替
  • 営業担当ロール時:3名のメンバーから選択(見え方の違いを体験できる)
  • 「デモをリセット」ボタン(確認ダイアログ付き)
  • 「これはデモです」の明示

デザイン上の扱い: プロダクト本体のUIとは意図的に別扱い(ダークな帯 + 小さめのタイポ)にし、「アプリの外側にある操作パネル」であることを視覚的に区別する。

ロールを跨ぐ体験(必ず動くようにする)

  1. 営業担当で商談を「提案中」→「最終交渉」に移動 → マネージャーに切替 → ダッシュボードの着地見込みが増えている
  2. マネージャーが商談の担当者を田中から鈴木に変更 → 田中で見ると一覧から消え、鈴木で見ると現れる
  3. 営業担当が活動を記録し「次アクション」を入力 → タスクが自動生成され、今日のタスクに並ぶ
  4. 管理者がカスタム項目「導入時期」を追加 → 営業担当の商談詳細に、その項目が出現する

5. 画面一覧とユーザーフロー

全32画面。画面IDはディレクトリ構成と 1:1 で対応させる。

メイン画面

画面ID 画面名 パス 主要要素
SC-001 ダッシュボード / 今日のタスク、期限超過、要対応商談(停滞)、今月の着地見込み、最近の活動
SC-010 顧客一覧 /accounts テーブル、絞り込み、列カスタマイズ、保存ビュー、一括操作、CSV入出力
SC-011 顧客詳細 /accounts/[id] 基本情報(インライン編集)、担当者、商談、活動タイムライン、ファイル
SC-012 顧客の新規作成 /accounts/new フォーム。重複候補を入力中に検出
SC-013 重複マージ /accounts/merge 重複候補の並列比較、残す値を項目ごとに選択
SC-014 CSVインポート /accounts/import ファイル選択 → 列マッピング → プレビュー → 取込結果
SC-020 担当者一覧 /contacts テーブル、絞り込み、所属企業へのリンク
SC-021 担当者詳細 /contacts/[id] 基本情報、関連商談、活動履歴
SC-030 パイプライン(カンバン) /deals 段階別列、D&D、列ごとの件数・合計金額、絞り込み
SC-031 商談一覧(テーブル) /deals?view=table カンバンと同データの表形式。切替ボタンで往復
SC-032 商談詳細 /deals/[id] 概要、段階バー、活動タイムライン、タスク、見積、関連情報
SC-033 商談の新規作成 /deals/new フォーム。顧客詳細からの遷移時は顧客を自動セット
SC-034 受注・失注登録 モーダル 理由の定型選択 + 自由記述、受注日、最終金額
SC-040 活動一覧 /activities 全活動のタイムライン。種別・担当・期間で絞り込み
SC-041 活動記録 モーダル 種別、日時、相手、内容、次アクション(タスク自動生成)
SC-050 タスク一覧 /tasks 期限別グルーピング(超過/今日/今週/今後)、担当者フィルタ
SC-060 見積一覧 /quotes ステータス別、金額、有効期限
SC-061 見積作成・編集 /quotes/[id] 明細行の追加・並び替え、自動計算、プレビュー、PDF出力
SC-062 見積プレビュー モーダル 印刷レイアウトの表示 → PDFダウンロード

分析画面

画面ID 画面名 パス 主要要素
SC-100 パイプライン分析 /reports/pipeline 段階別件数・金額、転換率ファネル、平均滞留日数
SC-101 担当者別実績 /reports/members 個人別の商談数・受注額・活動件数(マネージャー以上)
SC-102 予実管理 /reports/forecast 月次目標と実績、着地見込み、達成率
SC-103 失注分析 /reports/lost 失注理由の集計、段階別失注率
SC-104 活動分析 /reports/activities 種別別・担当者別の活動件数推移

設定画面(管理者のみ)

画面ID 画面名 パス 主要要素
SC-200 設定トップ /settings 設定項目の一覧
SC-201 カスタム項目 /settings/fields 対象(顧客/商談)、型、選択肢、必須、並び順
SC-202 パイプライン段階 /settings/stages 段階の追加・名称変更・並び替え・確度初期値
SC-203 商品マスタ /settings/products 商品の CRUD、カテゴリ
SC-204 ユーザー・チーム /settings/members メンバー一覧、ロール変更、チーム編成
SC-205 タグ管理 /settings/tags タグの CRUD、色設定、使用件数
SC-206 メールテンプレート /settings/templates テンプレートの CRUD、差し込み変数
SC-207 操作ログ /settings/logs 変更履歴の検索
SC-208 目標設定 /settings/targets 月次目標の設定(全社/チーム/個人)

主要フロー

フローA:新規顧客の獲得から受注まで

SC-001 ダッシュボード ── コマンドパレット ⌘K →「顧客を作成」
   ↓
SC-012 顧客の新規作成 ── 会社名入力中に重複候補を検出して警告
   ↓
顧客登録 → SC-011 顧客詳細
   ↓
「商談を作成」→ SC-033(顧客は自動セット済み)
   商談名/金額/確度/予定クローズ日/段階「初回接触」
   ↓
SC-041 活動記録(クイック入力)
   種別「訪問」/内容/次アクション「見積を送付する(3日後)」
   ↓  ★ 次アクションからタスクが自動生成される
SC-050 タスク一覧に「見積を送付する」が期限付きで並ぶ
   ↓
SC-061 見積作成 ── 商品マスタから明細追加 → 自動計算 → PDFダウンロード
   ↓
SC-030 パイプライン ── カードを「提案中」→「最終交渉」へD&D
   ↓
SC-034 受注登録 ── 受注理由・受注日・最終金額
   ↓
SC-102 予実管理に売上として計上される

フローB:マネージャーの週次パイプラインレビュー

【ロール切替:マネージャー】
SC-001 ダッシュボード ── 「要対応商談 7件」(14日以上動きなし)
   ↓
SC-030 パイプライン ── 停滞商談が視覚的にフラグ表示されている
   ↓
停滞している商談を開く → SC-032 商談詳細
   最終活動日、滞留日数、これまでの経緯を確認
   ↓
担当者にタスクを割り当てる(担当:田中、期限:今週金曜)
   ↓
SC-101 担当者別実績 ── メンバーごとの進捗を確認
   ↓
SC-102 予実管理 ── 今月の着地見込みと目標のギャップを確認
   ↓
【ロール切替:営業担当(田中)】
SC-050 タスク一覧に、マネージャーから割り当てられたタスクが並んでいる

フローC:Excelからの移行(CSVインポート)

SC-010 顧客一覧 ──「インポート」
   ↓
SC-014 Step1 ファイル選択(CSVをドロップ)
   ↓
Step2 列マッピング
   CSVの列 → RELATEの項目 を対応付け。自動推測 + 手動修正
   未対応の列は「取り込まない」または「カスタム項目として追加」
   ↓
Step3 プレビュー
   先頭10行の変換結果を表示
   エラー行(必須項目の欠落・形式不正)を件数と理由付きで表示
   ↓
Step4 取込実行
   「エラー行をスキップして取り込む」/「中止する」を選択
   ↓
結果サマリ:成功 142件 / スキップ 8件(理由別内訳)
   ↓
SC-010 顧客一覧に反映。取り込んだレコードに「今回インポート」タグが自動付与される

6. 機能要件

各要件は判定可能な粒度で記述している。テスト項目と 1:1 で対応させる。

6.1 ロール・デモ基盤

ID 要件 優先
FR-001 画面上部の固定バーから、3ロール(営業担当/マネージャー/管理者)をワンクリックで切り替えられること P1
FR-002 営業担当ロールでは、3名のメンバーから操作主体を選択できること P1
FR-003 「デモをリセット」で localStorage をクリアし、確認ダイアログを経て初期状態に戻ること P1
FR-004 操作結果はブラウザをリロードしても保持されること P1
FR-005 データスコープは lib/repo/_scope.ts に集約し、全リポジトリメソッドが必ず通すこと。コンポーネント側でロールによるフィルタを行わないこと P1
FR-006 営業担当は自分が担当するレコードのみ、マネージャーは自チーム、管理者は全社のレコードが見えること P1
FR-007 権限外の操作(営業担当が他人の商談を編集する等)を試みた場合、ボタンを非活性にし、理由をツールチップで示すこと。実行してからエラーを出さないこと P1
FR-008 ロール権限外の画面(営業担当で /settings)にアクセスした場合、案内画面からロール切替できること。素の404を出さないこと P1
FR-009 初回訪問時に3ステップのガイドツアーを表示し、「今後表示しない」を選択できること P2
FR-010 リポジトリ層の各操作は 150〜400ms の擬似ディレイを持つこと。ただし一覧の絞り込み・並び替えは 100ms 以下とすること P1

6.2 一覧・検索・ビュー(業務システムの中核)

ID 要件 優先
FR-101 一覧テーブルは、表示する列をユーザーが選択・並び替えできること。設定は保持されること P1
FR-102 各列でソートでき、複数列でのソート(第1キー・第2キー)に対応すること P2
FR-103 絞り込みは項目ごとの条件指定(等しい/含む/以上/以下/期間/空である)に対応すること P1
FR-104 絞り込み条件はURLクエリに反映し、リロード・URL共有で同一結果を再現できること P1
FR-105 適用中の絞り込み条件をチップで一覧表示し、個別に解除できること P1
FR-106 絞り込み条件 + 表示列 + 並び順を「ビュー」として名前を付けて保存できること。個人ビューと共有ビュー(マネージャー以上が作成)を区別すること P1
FR-107 保存ビューはサイドバーに一覧表示し、ワンクリックで切り替えられること。件数バッジを表示すること P1
FR-108 行のチェックボックス選択で一括操作(担当者変更/タグ付与/削除)ができること。全選択・絞り込み結果全件選択に対応すること P1
FR-109 一括操作の実行前に、対象件数と操作内容の確認ダイアログを表示すること P1
FR-110 削除操作は取り消し可能なトースト(5秒間「元に戻す」を表示)とすること P1
FR-111 ヘッダーのグローバル検索から、顧客・担当者・商談を横断検索できること。種別ごとにグループ化して結果を表示すること P1
FR-112 ⌘K / Ctrl+K でコマンドパレットを開き、検索・画面遷移・新規作成を実行できること P1
FR-113 一覧の行数が多い場合も描画がもたつかないこと(仮想スクロールを実装すること) P2
FR-114 一覧の行の高さを「標準(40px)/コンパクト(32px)」で切り替えられること P2
FR-115 テーブル上でセルを直接編集できること(インライン編集)。Enterで確定、Escで取消、Tabで次のセルへ移動すること P2

6.3 顧客・担当者管理

ID 要件 優先
FR-201 顧客に、会社名・フリガナ・業種・従業員数・住所・電話・URL・担当営業・ステータス・タグ・メモ を登録できること P1
FR-202 顧客詳細で、基本情報の各項目をクリックしてその場で編集できること(インライン編集) P1
FR-203 顧客の新規作成時、会社名の入力中に既存レコードとの類似を検出し、重複候補を警告表示すること P2
FR-204 重複候補を並列比較し、項目ごとに残す値を選択してマージできること。マージ後、両者の商談・活動・担当者がすべて統合先に引き継がれること P2
FR-205 担当者(コンタクト)を顧客に複数紐付けられること。氏名・役職・部署・メール・電話・決裁権の有無 を持つこと P1
FR-206 顧客詳細に、担当者・商談・活動履歴・タスク・見積 をタブで表示すること P1
FR-207 CSVインポートで、列マッピング(自動推測 + 手動修正)、プレビュー、エラー行の理由表示、部分取込 ができること P1
FR-208 インポート時、未対応の列を「取り込まない」または「カスタム項目として新規追加」から選べること P2
FR-209 インポート結果を「成功N件/スキップN件(理由別内訳)」で表示すること P1
FR-210 インポートしたレコードに、実行日時のタグを自動付与すること P2
FR-211 現在の絞り込み条件・表示列のままCSVエクスポートでき、実際にファイルがダウンロードされること P1

6.4 商談・パイプライン

ID 要件 優先
FR-301 商談に、商談名・顧客・担当者・金額・確度・段階・予定クローズ日・獲得経路・商品・メモ を登録できること P1
FR-302 パイプラインはカンバン形式で表示し、各列のヘッダーに件数と合計金額を表示すること P1
FR-303 カードのD&Dで段階を変更でき、変更が即座に反映されること P1
FR-304 段階変更をキーボードのみでも行えること(カード選択 → 移動先選択) P1
FR-305 段階を移動した際、その段階で必須とされた項目が未入力の場合、モーダルで入力を求めること P2
FR-306 確度は段階に応じた初期値が自動設定され、手動で上書きもできること P2
FR-307 カンバンとテーブルを切り替えられること。絞り込み条件は切替後も維持されること P1
FR-308 最終活動日から一定日数(既定14日)動きのない商談を「停滞」として視覚的にフラグ表示すること P1
FR-309 予定クローズ日を過ぎた未クローズ商談を「期限超過」としてフラグ表示すること P1
FR-310 受注・失注の登録時、理由を定型選択(複数可)+ 自由記述で入力できること。失注理由は分析の集計対象とすること P1
FR-311 受注した商談の金額が、予実管理の実績に反映されること P2
FR-312 商談詳細に、段階の進捗バー(現在地と通過済みが分かる)を表示すること P1
FR-313 商談を複製して新規作成できること P2
FR-314 管理者はパイプライン段階を追加・名称変更・並び替え・削除でき、確度の初期値を設定できること。変更は既存の全商談に即座に反映されること P2

6.5 活動・タスク

ID 要件 優先
FR-401 活動に、種別(訪問/電話/メール/打合せ/その他)・日時・相手(担当者)・内容・次アクション を記録できること P1
FR-402 一覧画面や詳細画面から遷移せずに、モーダルで活動を記録できること P1
FR-403 活動記録時に「次アクション」と期限を入力すると、タスクが自動生成され、関連レコードに紐づくこと P1
FR-404 顧客詳細・商談詳細に、活動を時系列のタイムラインで表示すること。種別でフィルタできること P1
FR-405 タスクに、内容・期限・担当者・関連レコード・完了状態 を持つこと P1
FR-406 タスク一覧を「期限超過/今日/今週/今後/完了」でグルーピング表示すること P1
FR-407 ダッシュボードに、当日期限と期限超過のタスクを表示すること P1
FR-408 タスクの完了はチェックボックスのワンクリックで行え、取り消せること P1
FR-409 マネージャーは他メンバーにタスクを割り当てられること。割当時、対象者の通知に配信されること P2
FR-410 メールテンプレートを選択し、差し込み変数({{会社名}} {{担当者名}} {{自分の氏名}})を置換して本文を生成できること P2
FR-411 メール送信操作を行うと、実際に送信される内容のプレビューをモーダルで表示し、確定すると活動履歴に「メール」として自動記録されること P2

6.6 見積・商品

ID 要件 優先
FR-501 商品マスタに、商品名・単価・原価・単位・カテゴリ を登録できること P2
FR-502 見積の明細行を、商品マスタから選択または手入力で追加でき、ドラッグで並び替えられること P2
FR-503 数量・単価・値引きの入力に応じて、行小計・小計・消費税・合計が即座に再計算されること P2
FR-504 消費税の計算方式(内税/外税、端数処理)を設定でき、計算結果に反映されること P2
FR-505 見積書のプレビューを印刷レイアウトで表示し、実際にPDFをダウンロードできること。自社ロゴ・宛先・件名・有効期限・備考を含むこと P2
FR-506 見積は商談に紐づき、商談詳細から一覧・作成できること P2
FR-507 見積の改訂版を作成でき、版ごとの履歴を保持すること P3
FR-508 見積のステータス(作成中/送付済/承認/失注)を管理できること P2

6.7 分析・設定

ID 要件 優先
FR-601 ダッシュボードに、今日のタスク・期限超過・停滞商談・今月の着地見込み・最近の活動 を表示すること P1
FR-602 ダッシュボードの表示内容がロールによって変わること(営業担当は自分、マネージャーはチーム、管理者は全社) P1
FR-603 パイプライン分析で、段階別の件数・金額、段階間の転換率ファネル、平均滞留日数 を表示すること P2
FR-604 担当者別実績で、個人別の商談数・受注額・活動件数を表示すること。営業担当ロールでは非表示とすること P2
FR-605 予実管理で、月次目標と実績、着地見込み(受注済 + 確度加重)、達成率 を表示すること P2
FR-606 失注分析で、失注理由の集計と段階別失注率を表示すること P3
FR-607 全ての分析画面で、期間(今月/先月/四半期/任意)を指定できること P2
FR-608 管理者はカスタム項目を追加できること。型は テキスト/数値/日付/単一選択/複数選択/チェックボックス に対応すること P2
FR-609 追加したカスタム項目が、対象レコードの詳細画面・編集フォーム・一覧の列選択・絞り込み条件に即座に反映されること P2
FR-610 管理者はユーザーのロール変更とチーム編成ができること P2
FR-611 レコードの変更履歴(誰が・いつ・どの項目を・何から何に)を操作ログに記録し、検索できること P3
FR-612 通知センターに、担当割当・期限接近・停滞アラート・タスク割当 が配信されること P2

7. データ設計

型定義(lib/types/

すべての型を先に定義し、これを唯一の真実とする。

// ---- 組織・ユーザー ----
type User = {
  id: string
  name: string
  nameKana: string
  email: string
  avatarUrl: string
  role: 'sales' | 'manager' | 'admin'
  teamId: string
  monthlyTarget: number          // 月次目標(円)
  isActive: boolean
}
type Team = { id: string; name: string; managerId: string }

// ---- 顧客・担当者 ----
type Account = {
  id: string
  name: string
  nameKana: string
  industryId: string
  employeeCount: number | null
  postalCode: string
  prefCode: string
  address: string
  phone: string
  websiteUrl: string
  ownerId: string                // 担当営業。スコープ判定の起点
  status: 'prospect' | 'active' | 'inactive' | 'lost'   // 見込み / 取引中 / 休眠 / 失注
  source: string                 // 獲得経路
  tagIds: string[]
  note: string
  customFields: Record<string, CustomValue>
  lastActivityAt: string | null  // 活動記録時に自動更新
  createdAt: string
  updatedAt: string
}

type Contact = {
  id: string
  accountId: string
  lastName: string; firstName: string
  lastNameKana: string; firstNameKana: string
  department: string
  title: string                  // 役職
  email: string
  phone: string
  mobile: string
  isDecisionMaker: boolean       // 決裁権の有無
  note: string
  createdAt: string
}

// ---- 商談 ----
type Stage = {
  id: string
  name: string                   // 初回接触 / ヒアリング / 提案中 / 最終交渉 / 受注 / 失注
  sortOrder: number
  defaultProbability: number     // 確度の初期値(%)
  requiredFieldIds: string[]     // この段階へ移動する際に必須となる項目
  type: 'open' | 'won' | 'lost'
}

type Deal = {
  id: string
  name: string
  accountId: string
  contactIds: string[]
  ownerId: string
  amount: number
  probability: number            // 0-100
  stageId: string
  expectedCloseDate: string
  closedAt?: string
  closeReason?: { codes: string[]; note: string }   // 受注理由 / 失注理由
  source: string
  productIds: string[]
  tagIds: string[]
  note: string
  customFields: Record<string, CustomValue>
  lastActivityAt: string | null
  createdAt: string
  updatedAt: string
}

// 派生値。ストアには保存せず、リポジトリで算出する
type DealComputed = Deal & {
  stagnantDays: number           // 最終活動からの経過日数
  isStagnant: boolean            // 既定14日以上(FR-308)
  isOverdue: boolean             // 予定クローズ日超過(FR-309)
  weightedAmount: number         // amount * probability / 100
}

// ---- 活動・タスク ----
type Activity = {
  id: string
  type: 'visit' | 'call' | 'email' | 'meeting' | 'other'
  accountId: string
  dealId?: string
  contactId?: string
  ownerId: string
  occurredAt: string
  subject: string
  body: string
  nextAction?: string            // 入力するとタスクが自動生成される(FR-403)
  emailPreview?: { to: string; subject: string; html: string }  // メール送信時(FR-411)
  attachments: { name: string; size: number; objectUrl: string }[]
  createdAt: string
}

type Task = {
  id: string
  title: string
  dueDate: string
  ownerId: string
  assignedById?: string          // 他者から割り当てられた場合
  accountId?: string
  dealId?: string
  activityId?: string            // 自動生成元
  isDone: boolean
  doneAt?: string
  createdAt: string
}

// ---- 見積・商品 ----
type Product = { id: string; name: string; categoryId: string; unitPrice: number; cost: number; unit: string; isActive: boolean }

type Quote = {
  id: string
  quoteNumber: string            // 見積番号(自動採番)
  dealId: string
  accountId: string
  version: number
  title: string                  // 件名
  issuedDate: string
  validUntil: string
  items: QuoteItem[]
  taxMode: 'inclusive' | 'exclusive'
  taxRate: number                // 0.10
  roundingMode: 'floor' | 'ceil' | 'round'
  note: string
  status: 'draft' | 'sent' | 'accepted' | 'rejected'
  createdAt: string
}
type QuoteItem = {
  id: string
  productId?: string
  name: string
  quantity: number
  unit: string
  unitPrice: number
  discountRate: number           // 0-1
  sortOrder: number
}
// 小計・税・合計はストアに保存しない。lib/calc/quote.ts で常に算出する(FR-503)

// ---- カスタム項目・ビュー ----
type CustomField = {
  id: string
  target: 'account' | 'deal'
  label: string
  type: 'text' | 'number' | 'date' | 'select' | 'multiselect' | 'checkbox'
  options?: string[]
  isRequired: boolean
  sortOrder: number
}
type CustomValue = string | number | boolean | string[] | null

type SavedView = {
  id: string
  name: string
  target: 'account' | 'contact' | 'deal' | 'task'
  ownerId: string
  isShared: boolean              // マネージャー以上のみ true にできる
  filters: Filter[]
  visibleColumns: string[]
  sort: { field: string; dir: 'asc' | 'desc' }[]
  createdAt: string
}
type Filter = {
  field: string
  operator: 'eq' | 'contains' | 'gte' | 'lte' | 'between' | 'in' | 'isEmpty' | 'isNotEmpty'
  value: unknown
}

// ---- その他 ----
type Tag = { id: string; name: string; color: string }
type Notification = {
  id: string
  targetUserId: string
  type: 'assigned' | 'task_assigned' | 'due_soon' | 'stagnant' | 'deal_won' | 'deal_lost'
  title: string; body: string; link: string
  readAt?: string
  createdAt: string
}
type AuditLog = {
  id: string
  actorId: string
  action: 'create' | 'update' | 'delete' | 'merge' | 'import'
  targetType: 'account' | 'contact' | 'deal' | 'task' | 'quote' | 'setting'
  targetId: string
  changes: { field: string; before: unknown; after: unknown }[]
  createdAt: string
}
type MonthlyTarget = { id: string; yearMonth: string; scope: 'company' | 'team' | 'user'; scopeId: string; amount: number }

シードデータ(lib/seed/

ファイル 内容 件数
masters.ts 業種30、都道府県47、獲得経路8、タグ12、失注理由10、受注理由6
users.ts ユーザー(営業6・マネージャー2・管理者1)、チーム2 9名
stages.ts パイプライン段階6(初回接触/ヒアリング/提案中/最終交渉/受注/失注) 6件
accounts.ts 架空企業。ステータス・業種・規模・担当を分散配置 140社
contacts.ts 顧客に1〜4名ずつ紐付け 320名
deals.ts 商談(進行中90 / 受注35 / 失注15)。停滞・期限超過を意図的に含める 140件
activities.ts 活動履歴(過去6ヶ月分、自然な頻度で分散) 900件
tasks.ts タスク(期限超過8/今日6/今週12/今後20/完了40) 86件
products.ts 商品マスタ 24件
quotes.ts 見積(各ステータスに分散) 30件
targets.ts 月次目標(全社/チーム/個人、過去6ヶ月+今月)

シード作成のルール(品質を左右する)

  • 実在企業名・実在人名を使わない。 架空のものを使う
  • 商談名・活動内容をテンプレの繰り返しにしない。 業種・段階に応じて書き分ける。「〇〇の件」ばかりだと一瞬で作り物だと分かる
  • 金額の分布に偏りを持たせる(小口が多く、大口が少ない)。均等分布は不自然
  • 日付は現在日時からの相対で生成する。固定日付を埋め込まない
  • 活動の頻度に濃淡をつける。よく訪問している顧客と、半年放置の顧客が混在すること
  • 停滞商談・期限超過タスク・目標未達の担当者を意図的に配置する。 全部が順調だと、ダッシュボードのアラート機能が動いて見えない
  • 受注/失注の理由を分散させ、失注分析のグラフが意味を持つようにする

ストアとリポジトリ

lib/
├── types/          # 上記の型定義
├── seed/           # シードデータ
├── store/
│   ├── session.ts  # 現在のロール、操作中のユーザー
│   ├── data.ts     # accounts / contacts / deals / activities / tasks / quotes ...
│   ├── settings.ts # customFields / stages / tags / products / targets
│   └── ui.ts       # 表示密度、ガイドツアー表示済みフラグ
└── repo/           # ★ コンポーネントが触るのはここだけ
    ├── _delay.ts   # 擬似ディレイ
    ├── _scope.ts   # ★ ロールによるデータスコープ。全メソッドが通す
    ├── accounts.ts  contacts.ts  deals.ts
    ├── activities.ts  tasks.ts  quotes.ts
    ├── views.ts  settings.ts  notifications.ts  reports.ts

リポジトリ層の規約(厳守)

  • 全メソッドを async で定義する。中身が同期でも例外なく
  • 戻り値は { ok: true; data: T } | { ok: false; error: string } に統一する
  • コンポーネントから Zustand ストアを直接参照しない。 読み取りも書き込みもリポジトリ経由
  • スコープ適用(_scope.ts)を全メソッドが必ず通す。 ここが実案件でRLSに置き換わる箇所(FR-005)
  • 派生値(stagnantDaysweightedAmount、見積の合計)はストアに保存せず、リポジトリ/計算モジュールで都度算出する
// lib/repo/_scope.ts — 実案件では RLS に置き換わる箇所
export function scopeAccounts(accounts: Account[]): Account[] {
  const { role, userId, teamId } = useSessionStore.getState()
  if (role === 'admin') return accounts
  if (role === 'manager') {
    const memberIds = getTeamMemberIds(teamId)
    return accounts.filter(a => memberIds.includes(a.ownerId))
  }
  return accounts.filter(a => a.ownerId === userId)   // sales
}

8. デザイン要件

アートディレクション

「一望できる作業台」

RELATE は毎日8時間開かれる業務システム。読ませる画面ではなく、比べて・選んで・動かす画面。したがって設計の主眼は「一画面に必要な情報がどれだけ収まるか」と「手がどれだけ止まらないか」に置く。

  • 数字が主役。 金額・件数・確度・日数を等幅数字で揃え、桁を目で比較できるようにする
  • 密度を上げる。 余白でゆったり見せるのではなく、罫線と整列で情報量を担保する
  • 色は警告のためにある。 通常状態はほぼ無彩色。停滞・期限超過・目標未達だけが色を持つ
  • 手を止めない。 キーボード操作、インライン編集、コマンドパレット、一括操作

HIREBASE との差別化(重要) HIREBASE:明朝体・広い余白・静けさ・読ませる。 RELATE:ゴシック・高密度・等幅数字・操作させる。 トークンを流用しない。並べて見せたときに別のプロダクトに見えること自体が、LPでの説得材料になる。

カラートークン

app/globals.css に CSS 変数で定義し、tailwind.config.ts の theme から参照する。直書きの色指定を禁止する。

:root {
  --ink-900: #16181D;   /* 見出し・本文・数値 */
  --ink-600: #545A66;   /* 補助テキスト */
  --ink-400: #8A909C;   /* ラベル・非活性・罫線上のテキスト */
  --brand-700: #23407A; /* 主要CTA・選択状態 */
  --brand-500: #35589B; /* ホバー */
  --brand-50:  #EBF0F9; /* 選択行・アクティブなビュー */
  --surface:   #F6F6F4; /* ページ背景 */
  --card:      #FFFFFF; /* テーブル・カード背景 */
  --border:    #E3E2DE; /* 罫線 */
  --border-strong: #C9C7C1;  /* テーブルヘッダー下・区切り */

  /* シグナル:これ以外の色を画面に持ち込まない */
  --won:     #2E7D64;   /* 受注・達成 */
  --lost:    #8A909C;   /* 失注(無彩色。赤にしない) */
  --alert:   #C2453B;   /* 期限超過・目標未達 */
  --warn:    #B4741C;   /* 停滞・期限接近 */
}

配色ルール

  • 通常状態のテーブル行に色を持たせない。色がついている行は「対応が必要な行」だけ
  • 失注は赤ではなく無彩色にする。赤は「今действするべき」の意味に限定する
  • 段階(ステージ)に固有色を割り当てない。段階は位置と幅で表現する。6色のバッジが並ぶ画面にしない

タイポグラフィ

役割 書体 用途
UI全般 Noto Sans JP 400 / 500 / 700 見出しも本文もこれ1つ。ウェイトと文字サイズだけで階層を作る
数値 Roboto Mono 500(font-variant-numeric: tabular-nums 金額・件数・確度・日数・日付。桁を揃えて縦に比較できることが最優先
トークン サイズ 行間 用途
page-title 22px / 700 1.4 画面タイトル
section 15px / 700 1.5 セクション見出し
body 13px / 400 1.7 テーブルセル、本文
label 11px / 500 1.5 項目ラベル(letter-spacing: .04em
metric-lg 28px / 500 Mono 1.2 ダッシュボードの主要数値
metric-sm 15px / 500 Mono 1.4 テーブル内の金額

本文は13px。 HIREBASE の15pxより小さい。これは業務システムとして情報密度を優先するための意図的な選択であり、代わりに行間とコントラストで可読性を担保する。

レイアウトとスペーシング

項目 定義
スペーシング 4pxベース:4 / 8 / 12 / 16 / 24 / 32 / 48
アプリシェル 左サイドバー(240px、折りたたみで56px)+ メインエリア。ヘッダー56px固定
コンテンツ幅 最大幅を設けない。画面幅いっぱいに使う(テーブルの情報量を優先)
テーブル行高 標準40px / コンパクト32px(切替可能、FR-114)
角丸 4px(カード・入力・ボタン)/2px(バッジ)/999px(アバター)
1段階のみ。0 4px 12px rgba(22,24,29,.10)(ポップオーバー・モーダルのみ)。テーブルやカードに影を使わない
区切り 罫線1px #E3E2DE。テーブルヘッダー下のみ --border-strong

主要コンポーネント仕様

コンポーネント 仕様
データテーブル 固定ヘッダー、行ホバーで背景 --brand-50 の50%、選択行は --brand-50。金額列は右寄せ + 等幅数字。列幅リサイズ可
ツールバー テーブル上部に固定。左=ビュー切替・絞り込み・列設定、右=密度切替・エクスポート・新規作成
絞り込みチップ 適用中の条件を横並び表示。× で個別解除、「すべて解除」を末尾に
一括操作バー 行を選択するとテーブル下部からせり上がる。「N件を選択中」+ 操作ボタン + 解除
パイプラインカード 商談名/顧客名/金額(Mono・大)/確度/予定クローズ日/担当アバター/停滞バッジ。高さを揃える
パイプライン列ヘッダー 段階名/件数/合計金額。列の背景に薄いプログレスを敷き、全体に占める金額比率を示す
段階進捗バー 商談詳細の上部。通過済み・現在地・未通過を1本のバーで表現。クリックで段階変更
活動タイムライン 左に種別アイコン + 縦罫線、右に内容。日付でグルーピング。種別フィルタをタブで
タスク行 チェックボックス/内容/関連レコード/期限(超過は --alert)/担当アバター。チェックで即完了、取り消し可
メトリクスカード ラベル(label)/主数値(metric-lg)/前期比(増減の記号 + %)。装飾グラフを載せない
空状態 全一覧に専用の空状態。「何が表示されるか」+ 次の行動ボタン。絞り込み0件と、データ0件を別の文言にする
スケルトン テーブルは行形状のスケルトン。スピナーを使わない
コマンドパレット ⌘K。検索・遷移・新規作成をグループ化。矢印キー + Enter で実行
デモ切替バー プロダクトのトークンとは別扱い(ダークな帯 + 小さめタイポ)

インタラクション要件(業務システムの肝)

ID 要件
IX-01 一覧の絞り込み・並び替えは体感で即座に反映されること(100ms以下)
IX-02 テーブル上で ↑↓ 行移動、Enter 詳細を開く、Space 行選択、⌘A 全選択 ができること
IX-03 インライン編集は Enter 確定、Esc 取消、Tab で次のセルへ移動すること
IX-04 ⌘K コマンドパレット、/ グローバル検索フォーカス、N 新規作成 のショートカットを提供すること
IX-05 ショートカット一覧を ? キーで表示すること
IX-06 破壊的操作(削除・一括更新)は、実行後に5秒間「元に戻す」を表示すること
IX-07 保存はすべて楽観的更新とし、失敗時のみロールバックしてエラーを表示すること
IX-08 モーダルを開いても背後の一覧の状態(スクロール位置・選択)が保持されること

モーション

対象 duration 内容
ホバー・フォーカス 80ms 色のみ。業務システムでは反応が速いことが価値
モーダル・ポップオーバー 160ms フェード + 4px
一括操作バーのせり上がり 200ms 下から。cubic-bezier(.16,1,.3,1)
カンバンのドラッグ 150ms ドロップ時に着地
トースト 160ms 右下から
数値の変化 400ms ダッシュボードのメトリクスのみカウントアップ。テーブル内では行わない

全体的に **HIREBASE より短く設定する。**業務システムで待たされる感覚は品質の低さとして受け取られる。 prefers-reduced-motion: reduce 時は全アニメーションを無効化する。

アクセシビリティ(WCAG 2.1 AA)

ID 要件
A11Y-01 コントラスト比は通常4.5:1以上、18px以上は3:1以上。13px本文でも必ず満たすこと
A11Y-02 全ての操作をキーボードのみで完遂できる。カンバンのD&Dにはキーボード代替を用意(FR-304)
A11Y-03 フォーカスリングは2px・オフセット2pxで常時可視。outline:none の単独使用禁止
A11Y-04 情報を色のみで伝えない。停滞・期限超過は色 + アイコン + テキストで示す
A11Y-05 テーブルは <table> を用い、scope 属性と caption を適切に設定する
A11Y-06 フォームの各入力に label を関連付け、エラーは aria-describedbyrole="alert" で読み上げる
A11Y-07 モーダルはフォーカストラップ + Esc で閉じる + 起動元へフォーカス復帰
A11Y-08 一括操作の選択件数、絞り込み結果の件数を aria-live で通知
A11Y-09 ページタイトルは画面ごとに固有。見出しレベルを飛ばさない
A11Y-10 フォントサイズ200%指定でも内容が読め、テーブルは横スクロールで対応する

ライティング規約

原則
ボタンは「何が起きるか」 ○「受注として登録」/×「保存」「OK」
件数を明示する ○「12件を削除しますか?」/×「削除しますか?」
エラーは原因と対処 ○「3行目:金額が数値ではありません。半角数字で入力してください」/×「取り込みに失敗しました」
空状態を区別する データ0件:「まだ商談がありません。最初の商談を作成しましょう」/絞り込み0件:「条件に一致する商談はありません」+ 条件解除ボタン
謝罪しない ×「申し訳ございませんが〜」/○ 事実と次の行動
システム語を使わない ○「この商談を失注として記録する」/×「ステージをlostに更新」

9. 技術要件・ディレクトリ構成

技術スタック(固定・勝手に変更しない)

レイヤ 技術 備考
フレームワーク Next.js 15(App Router)/ TypeScript strict
スタイリング Tailwind CSS + CSS Variables トークンは CSS 変数で定義
UIコンポーネント shadcn/ui(Radix UI基盤) a11y要件を自前実装せずに満たす
状態管理 Zustand + persist ミドルウェア localStorage に永続化
テーブル TanStack Table v8 列制御・ソート・選択。UIは自前。ヘッドレスのまま使う
仮想スクロール TanStack Virtual FR-113
フォーム React Hook Form + Zod
D&D dnd-kit キーボード操作対応が必須のため
グラフ Recharts 分析画面
CSV Papa Parse インポート/エクスポート
PDF @react-pdf/renderer 見積書。ブラウザ内で生成する
日付 date-fns(ja locale)
アイコン lucide-react
コマンドパレット cmdk FR-112
ホスティング Vercel
テスト Vitest / Playwright / axe-core

上記以外のライブラリを入れる前に必ず提案し、承認を得ること。

ディレクトリ構成

/
├── CLAUDE.md                  # このファイル
├── app/
│   ├── layout.tsx             # アプリシェル(サイドバー・ヘッダー・デモ切替バー)
│   ├── page.tsx               # SC-001 ダッシュボード
│   ├── accounts/              # SC-010〜014
│   ├── contacts/              # SC-020, 021
│   ├── deals/                 # SC-030〜034
│   ├── activities/            # SC-040
│   ├── tasks/                 # SC-050
│   ├── quotes/                # SC-060〜062
│   ├── reports/               # SC-100〜104
│   ├── settings/              # SC-200〜208
│   └── dev/components/        # コンポーネントカタログ(本番では非公開)
├── components/
│   ├── ui/                    # shadcn/ui プリミティブ
│   ├── table/                 # DataTable, ColumnPicker, FilterBar, BulkActionBar, ViewSidebar
│   ├── domain/                # DealCard, StageBar, ActivityTimeline, TaskRow, MetricCard, QuoteEditor
│   ├── demo/                  # RoleSwitcher, ResetButton, GuideTour
│   └── layout/
├── lib/
│   ├── types/  seed/  store/  repo/   # 7章参照
│   ├── query/                 # 絞り込み・ソート・ビューの適用ロジック
│   ├── calc/                  # 見積計算、着地見込み、転換率、滞留日数
│   ├── csv/                   # インポート(列マッピング・検証)/エクスポート
│   ├── pdf/                   # 見積書テンプレート
│   ├── validation/            # Zod スキーマ
│   └── utils/
├── e2e/                       # Playwright
└── public/

コーディング規約

  • TypeScript strict。any 禁止。やむを得ない場合は unknown + 型ガード
  • ファイル名は kebab-case、コンポーネントは PascalCase
  • 1ファイル300行を超えたら分割を検討する
  • コンポーネントから Zustand ストアを直接参照しない。必ず lib/repo/ 経由
  • 絞り込み・計算ロジックは lib/query/lib/calc/ に置き、コンポーネントに埋め込まない(テスト対象にするため)
  • 派生値をストアに保存しない。常に算出する
  • コミットは1タスクごと。メッセージに要件IDを含める 例:feat(deals): パイプラインの停滞検出を実装 (FR-308)

10. 非機能要件

ID 要件 目標値
NFR-01 LCP(デスクトップ) 1.8秒以下
NFR-02 INP(操作への応答) 200ms以下
NFR-03 CLS 0.1以下
NFR-04 一覧1,000行での絞り込み・並び替えの反映 100ms以下
NFR-05 一覧1,000行のスクロールが60fpsを維持すること(仮想スクロール)
NFR-06 初期JSバンドルサイズ(gzip後) 250KB以下(PDF・グラフは動的import)
NFR-07 Lighthouse Performance 90 / Accessibility 95 以上
NFR-08 対応ブラウザ Chrome / Safari / Edge 最新2バージョン、iOS Safari 16以降
NFR-09 ユーザー入力はサニタイズし、CSVインポート時の数式インジェクション(=, +, -, @ 始まり)を無害化すること
NFR-10 localStorage の容量上限(5MB程度)に達した場合、警告を表示し、データを破損させないこと

実案件への転用時の注意(デモ本体の要件ではない)

将来この構成を実サービスへ転用する場合、以下が追加で必要になる。商談で聞かれた際に説明できるよう記録として残す。

  • データスコープはサーバー側(RLS等)で担保する必要がある。 本デモの lib/repo/_scope.ts がその置き換え地点であり、構造上そのまま差し替えられる
  • 顧客情報は個人情報保護法の対象。利用目的の明示、安全管理措置、委託先管理、開示・削除請求への対応が必要になる
  • CSVエクスポートは情報持ち出しの経路になるため、実運用では権限制御と操作ログが必須
  • 本デモは顧客データをサーバーに送信しないため、これらの義務は発生しない。 ただし「デモである」旨は画面上に常時明示する

11. 実装タスク

この順に進める。フェーズを飛ばさない。 完了時は [x] に更新する。

Phase 0 — 基盤とデザインシステム(3日)

0-1. 初期化

  • Next.js 15 / TypeScript strict / App Router / Tailwind で初期化
  • ESLint / Prettier / husky(pre-commit で lint + typecheck)
  • 9章のディレクトリ構成を作成

0-2. 型とシード

  • lib/types/ に7章の型定義をすべて実装
  • lib/seed/masters.ts / users.ts / stages.ts
  • lib/seed/accounts.ts(140社)/contacts.ts(320名)
  • lib/seed/deals.ts(140件。停滞・期限超過を意図的に含める
  • lib/seed/activities.ts(900件。頻度に濃淡をつける)/tasks.ts(86件)
  • lib/seed/products.ts / quotes.ts / targets.ts
  • 商談名・活動内容を業種と段階に応じて書き分ける。テンプレの使い回し禁止
  • 日付は現在日時からの相対で生成する

0-3. ストアとリポジトリ

  • lib/store/{session,data,settings,ui}.ts を Zustand + persist で実装
  • lib/repo/_scope.ts を最初に実装する(FR-005, FR-006)
  • lib/repo/ の全モジュールを実装。全メソッド async、擬似ディレイ、Result型、スコープ適用
  • lib/calc/ に 滞留日数・加重金額・着地見込み・見積計算 を実装
  • スコープとcalcの単体テストをこの時点で書く。後回しにしない

0-4. デザインシステム

  • app/globals.css にカラートークンを CSS 変数で定義
  • tailwind.config.ts から CSS 変数を参照するよう theme を拡張
  • フォント(Noto Sans JP / Roboto Mono)を next/font で最適化。数値に tabular-nums を適用
  • タイプスケールをユーティリティクラスとして定義
  • shadcn/ui を導入し、トークンに合わせて Button / Input / Select / Checkbox / Dialog / Sheet / Popover / Toast / Badge / Tabs / Tooltip / DropdownMenu を上書き
  • アプリシェル(サイドバー折りたたみ、ヘッダー、パンくず)
  • 共通コンポーネント:EmptyState(データ0件と絞り込み0件を出し分け)/Skeleton(テーブル行形状)/MetricCard / StatusBadge / TagChip / UserAvatar
  • prefers-reduced-motion の全体対応
  • /dev/components にコンポーネントカタログを作成

0-5. デモ基盤

  • RoleSwitcher(3ロール + 営業担当のメンバー選択)(FR-001, FR-002)
  • デモ切替バーを固定配置。プロダクトのトークンとは別扱いのデザイン
  • 「デモをリセット」(FR-003)
  • ロール権限外アクセス時の案内画面 (FR-008)

Phase 0 完了チェック

  • /dev/components で全コンポーネントがトークン通りに表示される
  • ロールを切り替えると、リポジトリが返す件数が変わる(スコープのテストが通る)
  • リロードしても状態が保持される

Phase 1 — 一覧基盤と顧客管理(4日)

1-1. データテーブル基盤(最重要。ここの品質が全画面に波及する

  • lib/query/ に 絞り込み・ソート・ビュー適用ロジックを実装(テスト付き)
  • DataTable(TanStack Table ヘッドレス + 自前UI)。固定ヘッダー、列幅リサイズ
  • 列カスタマイズ(表示・非表示・並び替え)(FR-101)
  • ソート(複数列対応)(FR-102)
  • FilterBar:項目ごとの条件指定 (FR-103)
  • URLクエリとの同期 (FR-104)
  • ConditionChips:適用条件の表示と個別解除 (FR-105)
  • 行選択と BulkActionBar(下からせり上がる)(FR-108, FR-109)
  • 取り消し可能な削除トースト (FR-110, IX-06)
  • 仮想スクロール (FR-113)
  • 密度切替(40px / 32px)(FR-114)
  • キーボード操作(↑↓ Enter Space ⌘A)(IX-02)
  • インライン編集(Enter Esc Tab)(FR-115, IX-03)

1-2. 保存ビュー

  • ViewSidebar:ビュー一覧、件数バッジ、ワンクリック切替 (FR-107)
  • ビューの保存・編集・削除。個人/共有の区別(共有はマネージャー以上)(FR-106)

1-3. 顧客・担当者

  • SC-010 顧客一覧(上記テーブル基盤を適用)
  • SC-011 顧客詳細(インライン編集、タブ構成)(FR-202, FR-206)
  • SC-012 顧客の新規作成 + 重複検出警告 (FR-203)
  • SC-013 重複マージ(並列比較、項目ごとの選択、関連レコードの引き継ぎ)(FR-204)
  • SC-020 担当者一覧 / SC-021 担当者詳細 (FR-205)

1-4. CSV入出力

  • lib/csv/ にインポート(列マッピング・検証)/エクスポートを実装
  • SC-014 インポート4ステップ(ファイル選択 → 列マッピング → プレビュー → 結果)(FR-207, FR-209)
  • 未対応列の「カスタム項目として追加」(FR-208)
  • インポートタグの自動付与 (FR-210)
  • 数式インジェクションの無害化 (NFR-09)
  • エクスポート(現在の絞り込み・表示列のまま、実際にダウンロード)(FR-211)

1-5. グローバル検索・コマンドパレット

  • ヘッダーのグローバル検索(種別グループ化)(FR-111)
  • ⌘K コマンドパレット(cmdk)(FR-112)
  • ショートカット:/ 検索フォーカス、N 新規作成、? 一覧表示 (IX-04, IX-05)

Phase 1 完了チェック

  • フローCが完走する(CSVインポート → 一覧に反映)
  • 1,000行でも絞り込みが100ms以下、スクロールが60fps
  • テーブルがキーボードのみで操作完遂できる
  • ロールを切り替えると一覧の件数が変わる

Phase 2 — 商談・パイプライン(4日)

  • SC-030 パイプライン(カンバン)。列ヘッダーに件数・合計金額・金額比率のプログレス (FR-302)
  • dnd-kit による D&D 段階変更 (FR-303)
  • キーボードでの段階変更代替 (FR-304, A11Y-02)
  • 段階移動時の必須項目チェックモーダル (FR-305)
  • 確度の自動設定と手動上書き (FR-306)
  • SC-031 商談一覧(テーブル)。カンバンとの切替で絞り込みを維持 (FR-307)
  • 停滞検出(既定14日)の算出とフラグ表示 (FR-308)
  • 期限超過フラグ (FR-309)
  • SC-032 商談詳細。段階進捗バー、活動タイムライン、タスク、見積 (FR-312)
  • SC-033 商談の新規作成(顧客詳細からの遷移で顧客を自動セット)/複製 (FR-313)
  • SC-034 受注・失注登録(理由の定型選択 + 自由記述)(FR-310)
  • SC-001 ダッシュボード(ロールで表示内容が変わる)(FR-601, FR-602)

Phase 2 完了チェック

  • 4章「ロールを跨ぐ体験」の1と2が動作する
  • 停滞・期限超過の商談が、ダッシュボードとパイプラインの両方で正しくフラグされる
  • カンバンがキーボードのみで操作できる

Phase 3 — 活動・タスク・見積(4日)

3-1. 活動・タスク

  • SC-041 活動記録モーダル(一覧・詳細から離れずに記録)(FR-401, FR-402)
  • 次アクション入力からのタスク自動生成 (FR-403)
  • ActivityTimeline(種別アイコン、日付グルーピング、種別フィルタ)(FR-404)
  • SC-040 活動一覧
  • SC-050 タスク一覧(期限別グルーピング)(FR-405, FR-406)
  • ダッシュボードの今日のタスク・期限超過 (FR-407)
  • チェックによる完了と取り消し (FR-408)
  • マネージャーによるタスク割当と通知 (FR-409)
  • 活動記録時に Account.lastActivityAt / Deal.lastActivityAt を更新する

3-2. メール

  • メールテンプレートと差し込み変数の置換 (FR-410)
  • 送信内容のプレビューモーダル → 確定で活動履歴に自動記録 (FR-411)

3-3. 見積・商品

  • SC-203 商品マスタ (FR-501)
  • SC-061 見積作成(明細行の追加・並び替え、商品マスタからの選択)(FR-502)
  • lib/calc/quote.ts:行小計・小計・消費税・合計の算出(内税/外税、端数処理)(FR-503, FR-504)
  • SC-062 見積プレビュー → @react-pdf/renderer でPDFを生成し、実際にダウンロードできること (FR-505)
  • SC-060 見積一覧、商談詳細からの作成 (FR-506, FR-508)

Phase 3 完了チェック

  • フローAが完走する(顧客登録 → 商談作成 → 活動記録 → タスク自動生成 → 見積PDF → 受注)
  • 4章「ロールを跨ぐ体験」の3が動作する
  • 見積PDFが実際にダウンロードでき、レイアウトが崩れていない

Phase 4 — 分析と設定(3日)

4-1. 分析

  • SC-100 パイプライン分析(段階別件数・金額、転換率ファネル、平均滞留日数)(FR-603)
  • SC-101 担当者別実績(営業担当ロールでは非表示)(FR-604)
  • SC-102 予実管理(目標・実績・着地見込み・達成率)(FR-605, FR-311)
  • SC-103 失注分析 (FR-606)
  • SC-104 活動分析
  • 全分析画面の期間指定 (FR-607)

4-2. 設定

  • SC-201 カスタム項目(6種の型)(FR-608)
  • カスタム項目が詳細画面・編集フォーム・列選択・絞り込みに即座に反映されること (FR-609)
  • SC-202 パイプライン段階の編集。変更が既存商談に即座に反映されること (FR-314)
  • SC-204 ユーザー・チーム管理 (FR-610)
  • SC-205 タグ管理 / SC-206 メールテンプレート / SC-208 目標設定
  • SC-207 操作ログ (FR-611)
  • 通知センター (FR-612)

Phase 4 完了チェック

  • フローBが完走する(マネージャーの週次レビュー)
  • 4章「ロールを跨ぐ体験」の4が動作する(カスタム項目の追加が営業担当の画面に反映)

Phase 5 — 仕上げ(3日)

5-1. 体験の総点検

  • 4章「ロールを跨ぐ体験」の4パターンをすべて手動で確認する
  • 全32画面を開き、空の画面が1つもないことを確認する
  • 全画面の空状態(データ0件/絞り込み0件の出し分け)・ローディング・エラー状態を確認する
  • ガイドツアーを実装 (FR-009)
  • localStorage 容量上限時の警告 (NFR-10)

5-2. アクセシビリティ監査

  • axe-core を全画面に実行し、Critical / Serious を0件に
  • キーボードのみで全画面を操作完遂する手動確認
  • 13px本文のコントラスト比を実測して 4.5:1 以上を確認 (A11Y-01)
  • フォントサイズ200%での確認 (A11Y-10)

5-3. パフォーマンス

  • PDF・グラフ・CSVを動的importに切り出し、初期バンドルを250KB以下に (NFR-06)
  • 1,000行での絞り込み100ms以下、スクロール60fps を実測 (NFR-04, NFR-05)
  • Lighthouse で Performance 90 / Accessibility 95 を達成 (NFR-07)

5-4. テストと公開

  • Playwright で フローA・B・C の E2E を実装・実行
  • Vitest:lib/query lib/calc lib/csv lib/repo/_scope のカバレッジ80%以上
  • /dev/components を本番で非公開に
  • Vercel へデプロイ
  • LP への導線設置(HIREBASE と並べる)
  • 各フェーズのキャプチャを整理し、LP掲載用の時系列コンテンツにまとめる

合計 18営業日(約3.5週間)/1名専任 + レビュー体制。 各フェーズ完了時点でプレビューURLと画面キャプチャを残し、「Day 3 でここまで」「Day 7 でここまで」という時系列コンテンツとして LP に掲載する。

工数配分の意図: Phase 1 に4日を割いているのは、データテーブル基盤が全画面に波及するため。ここを雑に作ると、以降の全一覧画面が作り直しになる。逆にここが良ければ、商談・タスク・見積の一覧はほぼ設定だけで完成する。


12. 受入基準

  1. 6章の優先度 P1 の要件がすべて実装されていること
  2. 5章の主要フローA・B・Cが、エンドツーエンドで完走すること
  3. 4章「ロールを跨ぐ体験」の4パターンがすべて動作すること
  4. ロールを切り替えると、一覧・ダッシュボード・分析の表示範囲が変わること。かつスコープ判定が lib/repo/_scope.ts に集約されていること
  5. 一覧テーブルが、絞り込み・列選択・保存ビュー・一括操作・キーボード操作のすべてに対応していること
  6. 1,000行での絞り込みが100ms以下、スクロールが60fpsを維持すること
  7. CSVインポートが列マッピングとエラー行表示に対応し、CSVエクスポートと見積PDFが実際にダウンロードできること
  8. 全32画面のいずれにも空の状態がなく、リアルなデータが表示されていること
  9. リロード後も操作結果が保持され、「デモをリセット」で初期状態に戻ること
  10. axe-core で Critical / Serious の指摘が0件であること
  11. Lighthouse の基準値を満たすこと
  12. データアクセスがすべて lib/repo/ を経由しており、コンポーネントが Zustand ストアを直接参照していないこと
  13. HIREBASE と並べたときに、明確に別のプロダクトとして見えること(8章のアートディレクションが実現されていること)

判断に迷ったときのルール

  1. 仕様がこの文書にない場合は、実装せずに質問する。 推測で作らない
  2. キーボード操作と「空の画面を作らない」は削減対象外。 速度を出すために削らない
  3. スコープ外(3章 Won't have)は、思いついても実装しない。特にワークフロー自動化ビルダーと帳票の自由レイアウト編集
  4. 「デモだから」を理由に品質を落とす判断はしない
  5. コンポーネントからストアを直接触りたくなったら、それはリポジトリ層に足りないメソッドがあるということ
  6. HIREBASE のトークン・コンポーネントをコピーしない。 別プロダクトとして設計する

FROM DEMO TO PRODUCTION

本番で使うには、あと4つ必要です

この要件定義書は、画面と動きを確かめるためのデモとして書かれています。「顧客・商談管理」を社内やお客さまに実際に使ってもらうには、見た目の裏側に次の4つが要ります。

  1. 1データの保存

    デモでは
    データはその端末のブラウザの中にしか残りません。ほかの端末やほかの人とは共有されず、消えることもあります。
    本番では
    サーバーのデータベースに保存し、バックアップと復元ができるようにします。
  2. 2セキュリティ

    デモでは
    ログインがなく、誰でもすべての画面とデータを見られます。
    本番では
    ログイン、権限(誰が何を見られるか)、通信とデータの暗号化、不正なアクセスへの対策を入れます。
  3. 3ガバナンス(運用ルール)

    デモでは
    決めていません。
    本番では
    誰がいつ何をしたかの記録、個人情報の扱い(プライバシーポリシー・同意)、アカウントの発行と削除、障害のときの連絡体制を決めます。
  4. 4公開・デプロイ

    デモでは
    手元で動かすか、デモとして公開するだけです。
    本番では
    独自ドメイン、本番とテストの環境分け、更新の手順、監視と障害対応、月々の費用の管理を整えます。

本番運用をお考えの方へ

ぜひ一度ご相談ください。最適なプランのご紹介と、進め方をお伝えします。代表の西澤が直接お話しします。

  • 自分で作ったアプリを、そのまま本番で使いたい
  • どこまで自分で作り、どこから任せるか決めたい
  • 社内の決まりやセキュリティの基準に合わせたい

下のカレンダーから、そのまま日程を選べます。

カレンダーが表示されないときは こちらから日程を選べます。日程を決める前に聞きたいことがあれば、公式LINEお問い合わせフォーム からどうぞ。

FREE CONSULTATION

分からないときは、お気軽に30分無料相談へ

途中で止まった、エラーが消えない、自社向けに作り変えたい。どんなことでも大丈夫です。

日程を決めて話す

代表の西澤と直接お話しできます。空いている日時を選ぶだけで予約できます。

代表 西澤と話す日程を選ぶ

まずは問い合わせる

要件定義書がほしい方・ご相談は公式LINEから。メールでのお問い合わせはフォームから。