← 成果物一覧に戻る1. 文書管理情報
| 文書名 | データベース設計書 |
| バージョン | v1.0.0 |
| 作成日 | 2026-03-18 |
| プロジェクト | 保険リードマーケットプレイス |
| 対象システム | hoken_Leads_2026_0317 |
| RDBMS | PostgreSQL 16 |
| ORM | Prisma ORM 7 |
| テーブル数 | 17テーブル |
| ENUM数 | 18 ENUM型 |
2. データベース概要
本システムのデータベースは PostgreSQL 16 を採用し、Prisma ORM 7 を介してアクセスする。 保険見込客(リード)の収集からオークション形式での販売、購入後の案件管理、 請求・決済までを一貫して管理する17テーブルで構成される。
スキーマ構成
テーブルは以下の6つのドメイン領域に分類される。各ドメインは明確な責務を持ち、 外部キーによって適切にリレーションが設定されている。
| ドメイン領域 | テーブル | 概要 |
|---|
| ユーザー・認証 | User, Agency, AgencyInvitation, AgencyBudgetAlert | 営業担当者・代理店の管理、認証・MFA、招待・予算管理 |
| リード管理 | Lead | 見込客情報の登録・スコアリング・SMS認証・重複排除 |
| オークション | Auction, Bid, AuctionSettings | 入札オークションの実行・設定管理 |
| 購入・案件管理 | Purchase, ContactLog, RefundRequest | 落札後の案件進捗追跡・連絡記録・返金管理 |
| 請求・決済 | Invoice, InvoiceItem | 月次請求書の生成・明細管理 |
| 運用・分析 | ABTest, ABTestVariant, Notification, AuditLog | A/Bテスト・通知・監査ログ |
ID生成方式: 全テーブルの主キーは CUID(Collision-resistant Unique Identifier)を採用。 連番と異なり推測不可能で、分散環境でも衝突しない。Prisma の @default(cuid()) で自動生成される。
3. ER図(エンティティ関連図)
以下に全17テーブルのリレーションを示す。(1) は「1」側、(*) は「多」側を表す。
┌─────────────────────────────────────────────────────────────────────────────┐
│ 保険リードマーケットプレイス ER図 │
└─────────────────────────────────────────────────────────────────────────────┘
┌──────────┐ ┌──────────────────┐
│ Agency │(1)───(*) │ AgencyInvitation │
│ │ └──────────────────┘
│ │(1)───(*) ┌──────────────────┐
│ │ │ AgencyBudgetAlert │
│ │ └──────────────────┘
│ │(1)──┐
└──────────┘ │
│(1) │
│ │
(*) │
┌──────────┐ │ ┌──────────┐
│ User │ │ │ Lead │
│ │ │ │ │
└──────────┘ │ └──────────┘
│(1) │(1) │ │(1)
│ │ │ │
(*) (*) │ (*)
┌────┐ ┌─────────────┐ ┌──────────┐ ┌─────────────────┐
│Bid │ │ Purchase │ │ Auction │(*)──│ AuctionSettings │(1)
└────┘ │ │ │ │ └─────────────────┘
│ │ └──────────┘ │(1)
└─────────────┘ │(1) (*) │
│(1) │(1) │(1)│ ┌────┐ (*)
│ │ │ └─────│Bid │ ┌───────────────┐
(*) (*) (*) └────┘ │ ABTestVariant │
┌───────────┐ ┌──────────┐ ┌───────────┐└───────────────┘
│ContactLog │ │RefundReq │ │InvoiceItem│ │(*)
└───────────┘ └──────────┘ └───────────┘ │
│(*) ┌────────┐
│ │ ABTest │(1)
┌─────────┐ └────────┘
│ Invoice │(1)
└─────────┘
│(*)
┌──────────┐
│ Agency │(1)
└──────────┘
┌──────────────┐ ┌────────────┐
│ Notification │(*)──(1) │ User │
└──────────────┘ └────────────┘
┌──────────────┐ ┌────────────┐
│ AuditLog │(*)──(1) │ User │
└──────────────┘ └────────────┘
リレーション一覧
| 親テーブル (1) | 子テーブル (*) | 外部キー | 関係の説明 |
|---|
| Agency | User | agencyId | 代理店に所属する営業担当者 |
| Agency | Purchase | agencyId | 代理店ごとの購入実績 |
| Agency | Invoice | agencyId | 代理店宛の請求書 |
| Agency | AgencyInvitation | agencyId | 代理店への招待 |
| Agency | AgencyBudgetAlert | agencyId | 代理店の予算アラート |
| User | Bid | userId | ユーザーの入札 |
| User | Purchase | userId | ユーザーの購入 |
| User | RefundRequest | userId | ユーザーの返金申請 |
| User | RefundRequest | reviewedBy | 管理者による返金審査 |
| User | Notification | userId | ユーザーへの通知 |
| User | AuditLog | userId | ユーザーの操作ログ |
| User | AgencyInvitation | invitedById | 招待を送ったユーザー |
| Lead | Auction | leadId | リードに対するオークション |
| Lead | Purchase | leadId | リードの購入 |
| Auction | Bid | auctionId | オークションへの入札 |
| Auction | Purchase | auctionId | オークションの落札 |
| AuctionSettings | Auction | settingsId | オークション設定 |
| AuctionSettings | ABTestVariant | settingsId | A/Bテスト用設定 |
| Purchase | ContactLog | purchaseId | 購入案件の連絡記録 |
| Purchase | RefundRequest | purchaseId | 購入案件の返金申請 |
| Purchase | InvoiceItem | purchaseId | 購入案件の請求明細 |
| Invoice | InvoiceItem | invoiceId | 請求書の明細行 |
| ABTest | ABTestVariant | abTestId | A/Bテストのバリアント |
4. テーブル定義
4.1 User(ユーザー)
システムを利用する営業担当者・代理店管理者・運用者を管理するテーブル。 認証情報(パスワードハッシュ、MFA)、アカウントロック機能を持つ。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
emailUNIQUE | String | NO | - | メールアドレス(一意) |
passwordHash | String | NO | - | bcryptハッシュ化パスワード |
name | String | NO | - | 表示名 |
roleENUM | UserRole | NO | SALES_AGENT | ユーザー権限ロール |
agencyIdFK | String | YES | NULL | 所属代理店ID |
isActive | Boolean | NO | true | アカウント有効フラグ |
mfaEnabled | Boolean | NO | false | 二要素認証の有効/無効 |
mfaSecret | String | YES | NULL | MFA用シークレットキー |
lastLoginAt | DateTime | YES | NULL | 最終ログイン日時 |
loginAttempts | Int | NO | 0 | 連続ログイン失敗回数 |
lockedUntil | DateTime | YES | NULL | アカウントロック解除日時 |
createdAt | DateTime | NO | now() | 作成日時 |
updatedAt | DateTime | NO | @updatedAt | 更新日時(自動) |
4.2 Agency(代理店)
保険代理店の組織情報を管理するテーブル。請求先メールアドレス、決済方法(クレジットカード/請求書払い)、 Stripe顧客ID、月次予算上限を保持する。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
name | String | NO | - | 代理店名 |
address | String | YES | NULL | 住所 |
phone | String | YES | NULL | 電話番号 |
invoiceEmail | String | NO | - | 請求書送付先メール |
paymentMethodENUM | PaymentMethod | NO | CREDIT_CARD | 決済方法 |
stripeCustomerId | String | YES | NULL | Stripe顧客ID |
monthlyBudget | Int | YES | NULL | 月次予算上限(円) |
isActive | Boolean | NO | true | 有効フラグ |
createdAt | DateTime | NO | now() | 作成日時 |
updatedAt | DateTime | NO | @updatedAt | 更新日時(自動) |
4.3 AgencyInvitation(代理店招待)
代理店管理者が営業担当者を招待するためのトークン管理テーブル。 一意のトークンを発行し、有効期限内に承諾されることで User が作成される。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
agencyIdFK | String | NO | - | 対象代理店ID |
email | String | NO | - | 招待先メールアドレス |
invitedByIdFK | String | NO | - | 招待者のユーザーID |
tokenUNIQUE | String | NO | - | 招待トークン(一意) |
expiresAt | DateTime | NO | - | トークン有効期限 |
acceptedAt | DateTime | YES | NULL | 承諾日時 |
createdAt | DateTime | NO | now() | 作成日時 |
4.4 AgencyBudgetAlert(予算アラート)
代理店の月次予算消化率が閾値に達した際のアラート記録テーブル。 同一代理店・閾値・月の組み合わせで一意制約を持ち、重複通知を防止する。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
agencyIdFK | String | NO | - | 対象代理店ID |
threshold | Int | NO | - | アラート閾値(%: 80, 100) |
alertedAt | DateTime | NO | now() | アラート発生日時 |
month | String | NO | - | 対象月(例: 2026-03) |
複合一意制約: @@unique([agencyId, threshold, month]) により、 同一代理店の同一月・同一閾値で重複アラートが発生しない。
4.5 Lead(リード/見込客)
保険相談を希望する見込客の情報を管理するテーブル。個人情報(氏名・電話番号・メール)は 購入前は非公開。スコアリング(入力充実度・温度感・属性スコア)で品質を数値化する。 SMS認証による本人確認機能を持ち、電話番号ハッシュによる重複排除を実装。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
name | String | NO | - | 氏名(購入前は非公開) |
phone | String | NO | - | 電話番号(購入前は非公開) |
email | String | NO | - | メールアドレス(購入前は非公開) |
addressFull | String | YES | NULL | 住所(詳細) |
age | Int | NO | - | 年齢 |
genderENUM | Gender | NO | - | 性別 |
prefecture | String | NO | - | 都道府県 |
city | String | YES | NULL | 市区町村 |
occupationENUM | OccupationCategory | YES | NULL | 職業カテゴリ |
incomeRangeENUM | IncomeRange | YES | NULL | 年収帯 |
familySize | Int | YES | NULL | 家族人数 |
hasChildren | Boolean | YES | NULL | 子供の有無 |
housingStatusENUM | HousingStatus | YES | NULL | 住居形態 |
insuranceCategoryENUM | InsuranceCategory | NO | - | 相談希望の保険種別 |
consultationMethodENUM | ConsultationMethod | NO | - | 希望相談方法 |
consultationDetail | String | YES | NULL | 相談詳細・備考 |
urgencyENUM | Urgency | YES | NULL | 相談の緊急度 |
score | Int | NO | 0 | 総合スコア |
inputScore | Int | NO | 0 | 入力充実度スコア |
temperatureScore | Int | NO | 0 | 温度感スコア |
attributeScore | Int | NO | 0 | 属性スコア |
statusENUM | LeadStatus | NO | NEW | リードステータス |
smsVerified | Boolean | NO | false | SMS認証済みフラグ |
smsCode | String | YES | NULL | SMS認証コード(一時) |
smsCodeExpiresAt | DateTime | YES | NULL | SMS認証コード有効期限 |
failedAuctionCount | Int | NO | 0 | 不成立オークション回数 |
phoneHash | String | NO | - | 電話番号ハッシュ(重複排除用) |
createdAt | DateTime | NO | now() | 作成日時 |
updatedAt | DateTime | NO | @updatedAt | 更新日時(自動) |
4.6 Auction(オークション)
リードに対するオークションを管理するテーブル。スケジュール予約から開始・延長・完了までの ライフサイクルを追跡する。即決価格(instantPrice)による即時落札にも対応。 A/Bテストバリアントとの紐付けにより、オークション設定の最適化実験が可能。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
leadIdFK | String | NO | - | 対象リードID |
statusENUM | AuctionStatus | NO | SCHEDULED | オークション状態 |
startPrice | Int | NO | - | 開始価格(円) |
currentPrice | Int | NO | - | 現在価格(円) |
instantPrice | Int | NO | - | 即決価格(円) |
bidCount | Int | NO | 0 | 入札数 |
startAt | DateTime | NO | - | 開始予定日時 |
endAt | DateTime | NO | - | 終了予定日時 |
extendCount | Int | NO | 0 | 延長回数 |
maxExtensions | Int | NO | 3 | 最大延長回数 |
winnerId | String | YES | NULL | 落札者ユーザーID |
abTestVariant | String | YES | NULL | A/Bテストバリアント名 |
settingsIdFK | String | YES | NULL | オークション設定ID |
createdAt | DateTime | NO | now() | 作成日時 |
updatedAt | DateTime | NO | @updatedAt | 更新日時(自動) |
4.7 Bid(入札)
オークションに対する入札を記録するテーブル。通常入札と即決入札を区別し、 現在の最高額入札を isWinning フラグで管理する。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
auctionIdFK | String | NO | - | 対象オークションID |
userIdFK | String | NO | - | 入札者ユーザーID |
amount | Int | NO | - | 入札額(円) |
isInstant | Boolean | NO | false | 即決入札フラグ |
isWinning | Boolean | NO | false | 現在の最高額フラグ |
createdAt | DateTime | NO | now() | 入札日時 |
4.8 Purchase(購入/案件)
オークション落札後の案件を管理するテーブル。購入金額・Stripe決済ID・案件ステータス・ 連絡試行回数・商談日・商談結果などを追跡する。返金申請・連絡記録・請求明細と紐づく。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
auctionIdFK | String | NO | - | 落札オークションID |
userIdFK | String | NO | - | 購入者ユーザーID |
agencyIdFK | String | NO | - | 所属代理店ID |
leadIdFK | String | NO | - | 対象リードID |
amount | Int | NO | - | 購入金額(円) |
stripePaymentId | String | YES | NULL | Stripe決済ID |
caseStatusENUM | CaseStatus | NO | NOT_CONTACTED | 案件ステータス |
contactAttempts | Int | NO | 0 | 連絡試行回数 |
lastContactAt | DateTime | YES | NULL | 最終連絡日時 |
meetingDate | DateTime | YES | NULL | 商談日 |
meetingResultENUM | MeetingResult | YES | NULL | 商談結果 |
memo | String | YES | NULL | メモ・備考 |
createdAt | DateTime | NO | now() | 作成日時 |
updatedAt | DateTime | NO | @updatedAt | 更新日時(自動) |
4.9 ContactLog(連絡記録)
購入案件に対する連絡履歴を時系列で記録するテーブル。電話・メール等の連絡方法と備考を記録する。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
purchaseIdFK | String | NO | - | 対象購入案件ID |
method | String | NO | - | 連絡方法(phone / email) |
note | String | YES | NULL | 備考・内容メモ |
createdAt | DateTime | NO | now() | 連絡日時 |
4.10 RefundRequest(返金申請)
購入案件に対する返金申請を管理するテーブル。申請理由(重複・不正・不達)、 証拠資料パス、審査者・審査結果を記録する。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
purchaseIdFK | String | NO | - | 対象購入案件ID |
userIdFK | String | NO | - | 申請者ユーザーID |
reasonENUM | RefundReason | NO | - | 返金理由 |
description | String | NO | - | 返金理由の詳細説明 |
evidence | String | YES | NULL | 証拠ファイルパス |
statusENUM | RefundStatus | NO | PENDING | 審査ステータス |
amount | Int | NO | - | 返金申請額(円) |
reviewedByFK | String | YES | NULL | 審査者ユーザーID |
reviewedAt | DateTime | YES | NULL | 審査日時 |
reviewNote | String | YES | NULL | 審査コメント |
createdAt | DateTime | NO | now() | 申請日時 |
4.11 Invoice(請求書)
代理店への月次請求書を管理するテーブル。請求期間・小計・消費税・返金控除額・合計額を保持し、 下書き(DRAFT)から発行(ISSUED)、支払済(PAID)、延滞(OVERDUE)までのステータスを追跡する。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
agencyIdFK | String | NO | - | 対象代理店ID |
invoiceNumberUNIQUE | String | NO | - | 請求書番号(例: INV-2026-03-001) |
periodStart | DateTime | NO | - | 請求期間(開始) |
periodEnd | DateTime | NO | - | 請求期間(終了) |
subtotal | Int | NO | - | 小計(税抜、円) |
tax | Int | NO | - | 消費税額(円) |
refundAmount | Int | NO | 0 | 返金控除額(円) |
total | Int | NO | - | 合計額(税込、円) |
statusENUM | InvoiceStatus | NO | DRAFT | 請求書ステータス |
issuedAt | DateTime | YES | NULL | 発行日時 |
dueDate | DateTime | NO | - | 支払期限 |
paidAt | DateTime | YES | NULL | 支払日時 |
createdAt | DateTime | NO | now() | 作成日時 |
4.12 InvoiceItem(請求明細)
請求書の明細行を管理するテーブル。各購入案件と請求書を紐づけ、明細ごとの金額を記録する。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
invoiceIdFK | String | NO | - | 請求書ID |
purchaseIdFK | String | NO | - | 購入案件ID |
amount | Int | NO | - | 明細金額(円) |
createdAt | DateTime | NO | now() | 作成日時 |
4.13 AuctionSettings(オークション設定)
オークションの動作パラメータを管理するマスタテーブル。基本価格・スコア係数・即決価格倍率・ 入札単位・延長ルール・表示フィールド・カテゴリ別価格倍率などを設定する。 複数の設定を定義してA/Bテストで比較できる。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
name | String | NO | - | 設定名 |
basePrice | Int | NO | 8000 | 基本開始価格(円) |
scoreCoefficient | Int | NO | 200 | スコア係数(スコア*係数で加算) |
instantPriceMultiplier | Float | NO | 2.0 | 即決価格倍率 |
auctionDuration | Int | NO | 30 | オークション時間(分) |
bidUnit | Int | NO | 500 | 入札単位(円) |
extensionThreshold | Int | NO | 3 | 延長判定閾値(分) |
extensionDuration | Int | NO | 5 | 延長時間(分) |
maxExtensions | Int | NO | 3 | 最大延長回数 |
maxPurchasePerAuction | Int | NO | 1 | 1オークション最大購入数 |
maxActiveCases | Int | NO | 10 | 同時進行最大案件数 |
cooldownMinutes | Int | NO | 0 | クールダウン時間(分) |
scheduleTimes | String[] | NO | ["09:00","17:00"] | 定時スケジュール |
displayFields | Json | NO | [] | オークション表示フィールド |
categoryMultipliers | Json | NO | {} | カテゴリ別価格倍率 |
isActive | Boolean | NO | true | 有効フラグ |
createdAt | DateTime | NO | now() | 作成日時 |
updatedAt | DateTime | NO | @updatedAt | 更新日時(自動) |
4.14 ABTest(A/Bテスト)
オークション設定のA/Bテスト実験を管理するテーブル。テスト名・ステータス・実施期間を保持する。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
name | String | NO | - | テスト名 |
statusENUM | ABTestStatus | NO | DRAFT | テスト状態 |
startAt | DateTime | NO | - | テスト開始日時 |
endAt | DateTime | YES | NULL | テスト終了日時 |
createdAt | DateTime | NO | now() | 作成日時 |
updatedAt | DateTime | NO | @updatedAt | 更新日時(自動) |
4.15 ABTestVariant(A/Bテストバリアント)
A/Bテストの各パターン(バリアント)を管理するテーブル。トラフィック配分比率・ 表示回数・入札数・購入数・収益を集計し、バリアント間の効果比較を行う。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
abTestIdFK | String | NO | - | 所属A/BテストID |
name | String | NO | - | バリアント名(A, B, C...) |
ratio | Int | NO | - | トラフィック配分率(%) |
settingsIdFK | String | YES | NULL | 適用するオークション設定ID |
impressions | Int | NO | 0 | 表示回数 |
bids | Int | NO | 0 | 入札数 |
purchases | Int | NO | 0 | 購入数 |
revenue | Int | NO | 0 | 累計収益(円) |
createdAt | DateTime | NO | now() | 作成日時 |
4.16 Notification(通知)
ユーザーへのシステム通知を管理するテーブル。オークション開始・競り負け・落札・ 返金結果・請求書発行・予算警告など、各種イベントの通知を記録する。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
userIdFK | String | NO | - | 通知先ユーザーID |
typeENUM | NotificationType | NO | - | 通知種別 |
title | String | NO | - | 通知タイトル |
message | String | NO | - | 通知メッセージ本文 |
data | Json | YES | NULL | 追加データ(JSON) |
isRead | Boolean | NO | false | 既読フラグ |
createdAt | DateTime | NO | now() | 通知日時 |
4.17 AuditLog(監査ログ)
システム上の重要な操作を記録する監査ログテーブル。操作者・アクション・対象リソース・ 詳細情報・IPアドレス・UserAgentを記録し、セキュリティ監査とトレーサビリティを担保する。
| カラム名 | 型 | NULL | デフォルト | 説明 |
|---|
idPK | String (CUID) | NO | cuid() | 主キー |
userIdFK | String | YES | NULL | 操作者ユーザーID |
action | String | NO | - | 実行アクション名 |
resource | String | NO | - | 対象リソース種別 |
resourceId | String | YES | NULL | 対象リソースID |
details | Json | YES | NULL | 操作詳細(JSON) |
ipAddress | String | YES | NULL | 送信元IPアドレス |
userAgent | String | YES | NULL | ブラウザUserAgent |
createdAt | DateTime | NO | now() | 記録日時 |
5. ENUM定義
本システムで使用する18種類のENUM型の定義一覧。すべてPostgreSQLのENUM型としてマイグレーション時に作成される。
5.1 UserRole(ユーザーロール)
| 値 | 日本語名 | 説明 |
|---|
SALES_AGENT | 営業担当者 | リード入札・案件管理の実行者 |
AGENCY_ADMIN | 代理店管理者 | 代理店のユーザー管理・請求閲覧 |
ADMIN | システム管理者 | 全機能へのフルアクセス |
OPERATOR | 運用担当者 | オークション・リード管理 |
ACCOUNTANT | 経理担当者 | 請求書・返金の管理 |
VIEWER | 閲覧者 | 読み取り専用アクセス |
5.2 PaymentMethod(決済方法)
| 値 | 日本語名 | 説明 |
|---|
CREDIT_CARD | クレジットカード | Stripeによるカード決済 |
INVOICE | 請求書払い | 月末締め翌月払い |
5.3 Gender(性別)
| 値 | 日本語名 |
|---|
MALE | 男性 |
FEMALE | 女性 |
OTHER | その他 |
5.4 IncomeRange(年収帯)
| 値 | 日本語名 |
|---|
UNDER_200 | 200万円未満 |
RANGE_200_400 | 200万円〜400万円 |
RANGE_400_600 | 400万円〜600万円 |
RANGE_600_800 | 600万円〜800万円 |
RANGE_800_1000 | 800万円〜1,000万円 |
RANGE_1000_1500 | 1,000万円〜1,500万円 |
RANGE_1500_2000 | 1,500万円〜2,000万円 |
OVER_2000 | 2,000万円以上 |
5.5 OccupationCategory(職業カテゴリ)
| 値 | 日本語名 |
|---|
COMPANY_EMPLOYEE | 会社員 |
PUBLIC_SERVANT | 公務員 |
SELF_EMPLOYED | 自営業 |
PART_TIME | パート・アルバイト |
HOMEMAKER | 専業主婦(主夫) |
STUDENT | 学生 |
RETIRED | 定年退職者 |
OTHER | その他 |
5.6 HousingStatus(住居形態)
| 値 | 日本語名 |
|---|
OWN_WITH_LOAN | 持ち家(ローンあり) |
OWN_NO_LOAN | 持ち家(ローンなし) |
RENT | 賃貸 |
COMPANY_HOUSING | 社宅・寮 |
LIVING_WITH_FAMILY | 実家 |
OTHER | その他 |
5.7 InsuranceCategory(保険種別)
| 値 | 日本語名 | 説明 |
|---|
LIFE | 生命保険 | 死亡保障・収入保障 |
MEDICAL | 医療保険 | 入院・手術・がん保険 |
EDUCATION | 学資保険 | 教育費積立 |
CASUALTY | 損害保険 | 火災・自動車・地震保険 |
PENSION | 年金保険 | 個人年金・iDeCo |
GENERAL | 総合相談 | 複数保険の見直し相談 |
5.8 ConsultationMethod(相談方法)
| 値 | 日本語名 |
|---|
ONLINE | オンライン |
IN_PERSON | 対面 |
EITHER | どちらでも可 |
5.9 Urgency(緊急度)
| 値 | 日本語名 |
|---|
WITHIN_1_MONTH | 1ヶ月以内 |
WITHIN_3_MONTHS | 3ヶ月以内 |
NOT_URGENT | 急ぎではない |
5.10 LeadStatus(リードステータス)
| 値 | 日本語名 | 説明 |
|---|
NEW | 新規 | 登録直後、オークション未開始 |
IN_AUCTION | オークション中 | オークション進行中 |
SOLD | 販売済 | 落札されリード情報開示済 |
UNSOLD | 未販売 | オークション不成立 |
INVALID | 無効 | SMS未認証・重複等で無効化 |
5.11 AuctionStatus(オークションステータス)
| 値 | 日本語名 | 説明 |
|---|
SCHEDULED | 予約済 | 定時スケジュールで開始待ち |
ACTIVE | 進行中 | 入札受付中 |
EXTENDED | 延長中 | 終了間際の入札により延長 |
COMPLETED | 完了 | 正常終了(落札あり) |
NO_BID | 入札なし | 入札ゼロで終了 |
CANCELLED | キャンセル | 運用により中止 |
5.12 CaseStatus(案件ステータス)
| 値 | 日本語名 | 説明 |
|---|
NOT_CONTACTED | 未連絡 | 購入後、まだ連絡していない |
IN_PROGRESS | 対応中 | 連絡済、商談調整中 |
UNREACHABLE | 不達 | 連絡がつかない |
MET | 面談済 | 商談実施済 |
REFUND_REQUESTED | 返金申請中 | 返金申請が提出された |
CLOSED | 完了 | 案件クローズ |
5.13 MeetingResult(商談結果)
| 値 | 日本語名 |
|---|
CONTRACTED | 契約成立 |
CONTINUING | 継続検討 |
DECLINED | 辞退 |
5.14 RefundReason(返金理由)
| 値 | 日本語名 | 説明 |
|---|
DUPLICATE | 重複 | 同一リードが複数回販売された |
FRAUDULENT | 不正 | リード情報が虚偽だった |
UNREACHABLE | 不達 | 複数回連絡しても応答なし |
5.15 RefundStatus(返金ステータス)
| 値 | 日本語名 |
|---|
PENDING | 審査中 |
APPROVED | 承認 |
REJECTED | 却下 |
5.16 InvoiceStatus(請求書ステータス)
| 値 | 日本語名 | 説明 |
|---|
DRAFT | 下書き | 作成中、未発行 |
ISSUED | 発行済 | 代理店に送付済 |
PAID | 支払済 | 入金確認済 |
OVERDUE | 延滞 | 支払期限超過 |
5.17 ABTestStatus(A/Bテストステータス)
| 値 | 日本語名 |
|---|
DRAFT | 下書き |
RUNNING | 実行中 |
COMPLETED | 完了 |
CANCELLED | 中止 |
5.18 NotificationType(通知種別)
| 値 | 日本語名 | 説明 |
|---|
AUCTION_START | オークション開始 | 対象リードのオークション開始通知 |
BID_OUTBID | 競り負け | 自分の入札が他者に上回られた |
AUCTION_WON | 落札 | オークション落札通知 |
AUCTION_ENDING | 終了間近 | オークション終了間近のリマインダー |
REFUND_RESULT | 返金結果 | 返金申請の審査結果通知 |
INVOICE_ISSUED | 請求書発行 | 月次請求書の発行通知 |
BUDGET_WARNING | 予算警告 | 月次予算の80%消化通知 |
BUDGET_EXCEEDED | 予算超過 | 月次予算の100%到達通知 |
SYSTEM | システム | メンテナンス等のシステム通知 |
6. インデックス設計
クエリパフォーマンスを最適化するため、以下のインデックスを定義する。 Prismaの @@index ディレクティブにより、マイグレーション時にPostgreSQLインデックスとして作成される。
| テーブル | インデックスカラム | 種別 | 用途 |
|---|
| User | agencyId | INDEX | 代理店別ユーザー一覧取得 |
| User | email | INDEX | メールアドレスによるログイン検索(@unique併用) |
| User | role | INDEX | ロール別ユーザーフィルタリング |
| AgencyInvitation | agencyId | INDEX | 代理店別招待一覧取得 |
| AgencyInvitation | token | INDEX | トークンによる招待検証(@unique併用) |
| AgencyBudgetAlert | agencyId + threshold + month | UNIQUE | 重複アラート防止(複合一意制約) |
| Lead | status | INDEX | ステータス別リード一覧取得 |
| Lead | phoneHash | INDEX | 電話番号ハッシュによる重複チェック |
| Lead | insuranceCategory | INDEX | 保険種別フィルタリング |
| Lead | prefecture | INDEX | 都道府県フィルタリング |
| Lead | createdAt | INDEX | 新着順ソート |
| Auction | status | INDEX | ステータス別オークション一覧 |
| Auction | leadId | INDEX | リード別オークション履歴 |
| Auction | startAt | INDEX | 開始予定時刻でのスケジュール検索 |
| Auction | endAt | INDEX | 終了予定時刻でのタイマー処理 |
| Bid | auctionId | INDEX | オークション別入札一覧 |
| Bid | userId | INDEX | ユーザー別入札履歴 |
| Bid | auctionId + amount | COMPOUND | オークション内の最高額検索 |
| Purchase | userId | INDEX | ユーザー別購入案件一覧 |
| Purchase | agencyId | INDEX | 代理店別購入案件一覧 |
| Purchase | caseStatus | INDEX | ステータス別案件フィルタリング |
| Purchase | createdAt | INDEX | 新着順ソート |
| ContactLog | purchaseId | INDEX | 案件別連絡履歴取得 |
| RefundRequest | purchaseId | INDEX | 案件別返金申請取得 |
| RefundRequest | status | INDEX | 審査ステータス別一覧 |
| Invoice | agencyId | INDEX | 代理店別請求書一覧 |
| Invoice | status | INDEX | ステータス別請求書フィルタリング |
| Invoice | periodStart | INDEX | 請求期間での検索 |
| InvoiceItem | invoiceId | INDEX | 請求書別明細取得 |
| ABTestVariant | abTestId | INDEX | テスト別バリアント一覧 |
| Notification | userId + isRead | COMPOUND | 未読通知の取得 |
| Notification | userId + createdAt | COMPOUND | 通知の新着順取得 |
| AuditLog | userId | INDEX | ユーザー別操作ログ |
| AuditLog | resource + resourceId | COMPOUND | リソース別操作ログ |
| AuditLog | createdAt | INDEX | 時系列ログ検索 |
インデックス設計方針:- 外部キーカラムには原則インデックスを設定(JOIN最適化)
- 検索・フィルタリングで頻繁に使用されるカラムにインデックスを設定
- 複合インデックスは使用頻度の高いクエリパターンに基づいて設計
- @unique制約は暗黙的にインデックスを生成するため重複定義しない
7. データ量見積
サービス開始後の想定データ量を以下に示す。月間のリード流入数を500件、 代理店数50社、営業担当者数200名を基準に算出。
| テーブル | 月間増加(件) | 1年後(件) | 推定行サイズ | 1年後容量 | 備考 |
|---|
| User | 10 | 320 | 512B | 160KB | 新規営業担当者の追加 |
| Agency | 2 | 74 | 256B | 19KB | 新規代理店契約 |
| AgencyInvitation | 10 | 120 | 256B | 30KB | 招待トークン(承諾後も保持) |
| AgencyBudgetAlert | 100 | 1,200 | 128B | 150KB | 月次アラート(50社x2閾値) |
| Lead | 500 | 6,000 | 1KB | 6MB | 月間リード流入数 |
| Auction | 600 | 7,200 | 256B | 1.8MB | リード毎1〜2回(再掲載含む) |
| Bid | 3,000 | 36,000 | 128B | 4.5MB | 1オークション平均5入札 |
| Purchase | 400 | 4,800 | 512B | 2.4MB | 落札率約70% |
| ContactLog | 1,200 | 14,400 | 256B | 3.6MB | 1案件平均3回連絡 |
| RefundRequest | 40 | 480 | 512B | 240KB | 購入の約10%が返金申請 |
| Invoice | 50 | 600 | 256B | 150KB | 代理店毎月1枚 |
| InvoiceItem | 400 | 4,800 | 128B | 600KB | 購入件数と同数 |
| AuctionSettings | 1 | 12 | 512B | 6KB | 設定変更・A/Bテスト |
| ABTest | 2 | 24 | 128B | 3KB | 月平均2テスト |
| ABTestVariant | 6 | 72 | 128B | 9KB | テスト毎3バリアント |
| Notification | 5,000 | 60,000 | 256B | 15MB | 各種イベント通知 |
| AuditLog | 10,000 | 120,000 | 512B | 60MB | 全操作ログ |
容量見積の前提条件:- 月間リード流入: 500件(初期)、年間成長率20%を想定
- 1年後の合計データ容量: 約94MB(インデックス込みで約150MB)
- AuditLogとNotificationが全体の80%を占めるため、定期的なアーカイブを推奨
- 3年後には約500MB超を見込むが、PostgreSQLの性能上問題なし