コンテンツにスキップ

データ移行 計画

位置づけ: 後続フェーズ

新CRMのデータ移行は、旧BT社DBを移行元、新CRMのデータベースを移行先とする。移行方式は年末休業期間中の一括移行を基本線とし、業務を一時停止して切り替える。申請系業務は他業務からの独立性が高いため、移行本体から切り離して先行納品する方向とする(meeting-log 2026-07 では「先行納品を検討」で先方合意。納品時期の確定は今後)。旧システムとの並行運用は行わない。切替直後の参照用に、旧DBは読み取り専用で残す。

本ページは、2026-07定例会(P4/P5ヒアリング)で確定したスケジュールとデータ移行方針を、移行計画の観点でマスタ・トランザクション・コード体系・クレンジング・検証基準まで展開したものである。フィールド定義・算出式は crm_app/app/src/lib/*.ts の実装型・実装関数を根拠とする(型そのものが移行先スキーマの実体)。

移行対象の規模感は、BT社資料「既存データ移行 お見積」に基づく旧見積の実績値(成約顧客一覧 137項目・1,687件)を参考値として引き継ぐ。対象範囲・スキーマは新CRM側の再設計に合わせて改めて棚卸しする。実データの件数・容量・PIIは本ページに記載しない。

区分内容
移行元旧BT社DB
移行先新CRMのデータベース
対象範囲マスタ系(商品・商社・メーカー・営業マン・価格表。商品・商社は第1弾で先行実装済みのため、旧DBの新マスタへの差分取込に限る)+トランザクション系(顧客・世帯、商談、活動ログ、見積、KPI実績)
対象外第1弾で先行稼働済みの催事・アイテム・商社データ(継続利用扱い。IDの衝突回避のみが論点)
先行納品申請系(独立業務)は移行本体と切り離し、先行納品・先行運用とする方向(定例会では「検討」で先方合意)

データ(エンティティ表:旧DB→新DB マッピング)

Section titled “データ(エンティティ表:旧DB→新DB マッピング)”
対象マスタ新DB側の受け皿移行方式備考
商品(アイテム)マスタ新CRMのアイテムマスタ(第1弾実装済み)突合・差分取込Product.model(型番=主キー、crm_app/app/src/lib/masters.ts)をキーに照合する。SalesPrice.productNo は型番を指す名称参照であり主キーではないため、照合は Product.model 基準で行う。旧DBの型番表記ゆれ(全角/半角・大文字小文字・ハイフン有無等)は現時点で未正規化のため、移行時に正規化ルールを別途定める
商社・仕入先マスタ商社(卸)マスタ(第1弾実装済み)差分取込商社別軸案件管理との整合を確認する
メーカーマスタManufacturer(試作実装あり)新規整備+旧DB照合価格表・見積モジュールの前提
営業マンマスタ(インセンティブ等級含む)新設テーブル(KPI予実で使用)Excel等級表からの初期投入本番DBに評価テーブルが存在しないため新規構築。フィールド定義は Excel等級表の受領後に確定(未実装・確認事項)
価格表(PriceBook/SalesPrice)CRM側で価格を保持(2026-07-17方針)現行価格の初期投入+反映日設定反映日起点の現在価格導出を移行時に検証する(算出式は後述)

フィールド表:商品・価格系(lib/masters.ts / lib/pricing.ts)

Section titled “フィールド表:商品・価格系(lib/masters.ts / lib/pricing.ts)”

Product(商品マスタ。型番=主キー)

フィールド型必須既定制約・備考
modelstring必須なし主キー。型番。旧DB表記ゆれの正規化対象
kind”PV”|“BT”|“EQ”|“IH”|“AC”|“付帯”必須なし商材種別(ItemKind)
makerstring必須なしメーカー名(自由文字列。Manufacturer.id への正規化は未実装)
seriesstring任意undefinedシリーズマスタ(Series)と名寄せ
namestring任意undefined商品名
specstring任意undefined容量・枚数等の既定表記
leadTimeDaysnumber任意undefined納期目安。無ければメーカー単位フォールバック(LEADTIME_MASTER)
stock”潤沢”|“少”|“欠品”任意undefined在庫状態
notestring任意undefined自由記述

無効化フラグ(廃番商品を示す論理削除列)は現行 Product 型に存在しない。「廃番商品は削除せず無効フラグ付きで移行する」という業務ルールを満たすには型拡張が前提になる(後述エッジケース参照)。

Series(シリーズマスタ)

フィールド型必須既定制約・備考
idstring必須なし主キー
namestring必須なしシリーズ名(例: UFOシリーズ)
makerstring任意undefinedメーカー名
notestring任意undefined自由記述

Supplier(商社・仕入先マスタ)

フィールド型必須既定制約・備考
idstring必須なし主キー
namestring必須なし商社名
type”商社”|“メーカー直送”必須なし
closingDaystring任意undefined締日(例: “月末”)
paymentSitestring任意undefined支払サイト(例: “翌月末払い”)
creditLimitnumber任意undefined与信枠(円)
notestring任意undefined

Product と同様、取引終了商社の無効化フラグは現行 Supplier 型に存在しない(同上)。

Manufacturer(メーカーマスタ)

フィールド型必須既定制約・備考
idstring必須なし主キー
namestring必須なしメーカー名

LoanCompany(ローン会社/信販マスタ)

フィールド型必須既定制約・備考
idstring必須なし主キー
namestring必須なし
daysDirectnumber必須なし2社間: 完工書到着→入金の営業日数
daysViaTradernumber必須なし3社間: 商社経由の営業日数

PriceBook(価格表。仕入先/催事×メーカー×件名×反映日)

フィールド型必須既定制約・備考
idstring必須なし主キー
sourcestring必須なし仕入先/催事の名称
category”商社”|“施工店”|“アライアンス”|“催事”必須なし
manufacturerIdstring必須なしManufacturer.id 参照
titlestring必須なし件名
effectiveDatestring(YYYY-MM-DD)必須なし反映日(適用開始)。現在価格導出のキー
notestring任意undefined

Part(価格表の1行=部材)

フィールド型必須既定制約・備考
idstring必須なし主キー
bookIdstring必須なしPriceBook.id 参照
nonumber必須なし部材No(価格表内の識別番号)
namestring必須なし部材名
productNostring任意undefined商品No(型番参照。主キーではない)
retailPricenumber任意undefined希望小売価格
netPricenumber必須なし貴社仕切(仕入)。値引き行は負値
tier”必須”|“選択必須”|“オプション”必須なし部材そのものの区分

PackageSet/PackageMember(パッケージ=標準構成部材セット)

フィールド型必須既定制約・備考
PackageSet.idstring必須なし主キー
PackageSet.bookIdstring必須なしPriceBook.id 参照
PackageSet.namestring必須なし
PackageSet.membersPackageMember[]必須なし構成部材の配列
PackageSet.setPricenumber必須なしセット価格
PackageMember.nonumber必須なしPart.no 参照(構成部材No)
PackageMember.qtynumber必須なし数量
PackageMember.tier”必須”|“選択必須”|“オプション”必須なしこのパッケージでの必要度(Part.tier とは独立管理。2026-07-22定例で確定)

SalesPrice(販売価格。商品/部材×商流/代理店×反映日)

フィールド型必須既定制約・備考
idstring必須なし主キー
productNostring必須なし型番(Product.model への名称参照。主キーではない)
productNamestring任意undefined表示用の商品名スナップショット
channelstring任意undefined(=標準)商流/代理店。空は標準価格を意味する
pricenumber必須なし販売価格(税抜)
startDatestring(YYYY-MM-DD)必須なし反映日
endDatestring(YYYY-MM-DD)任意undefined(=無期限)未設定は「終了日なし=恒久有効」と解釈される(後述エッジケース)
memostring任意undefined
対象データ新DB側の受け皿移行方式論点
顧客・世帯(Household)Household テーブル(試作あり)名寄せ後に一括投入クレンジングの主戦場。PII取扱いルールを別途定める
商談(Deal:channel/venue/createdAt 等)Deal テーブル(試作あり)channel区分をマッピングして投入旧DB区分値→訪問販売/催事/反響/パートナーの対応表を作成する
活動ログ・架電(前確)・申込・タスク各試作モデル直近分を優先して投入過去分の保持期間は「確認事項」参照。活動ログは独立テーブルではない(後述)
見積(quotes)Quote テーブル(試作あり)。見積モジュールの画面は後続実装進行中案件のみ移行し、完了案件はアーカイブ参照とする移行範囲の線引きは「確認事項」参照
KPI実績(営業マン別 M1/M2実績)実績テーブル(新設)Excelからの初期投入予算・評価テーブルが本番DBに存在せず、移行ではなく新規構築。フィールド定義は未実装

旧見積(BT社資料)の「成約顧客一覧」137項目は、現行CRMの customers / contracts / contract_additional_materials 等に分解してマッピングされると推測される(未検証。data-migration 参照)。新CRMへの移行では、この旧Excel項目群を Household・Deal・見積等の新スキーマへ再マッピングする対応表を移行成果物として整備する。

フィールド表:Household/Person(lib/crm.ts)

Section titled “フィールド表:Household/Person(lib/crm.ts)”

Household(世帯)

フィールド型必須既定制約・備考
idstring必須なし主キー。実装シードは Hnnn(3桁連番)形式
namestring必須なし世帯名(代表姓)
postalstring必須なし郵便番号
prefstring必須なし都道府県
citystring必須なし市区町村
addrstring必須なし番地以下
adultsnumber必須なし大人の人数
childrennumber必須なし子供の人数
taxableboolean必須なし課税事業者フラグ
memostring任意undefined運営メモ(自由記述)
personsPerson[]必須なし世帯構成員(最低1名を代表者として扱う運用)

Person(世帯構成員)

フィールド型必須既定制約・備考
idstring必須なし主キー
namestring必須なし氏名
kanastring必須なしフリガナ。名寄せの主要キーの一つ
relation”夫”|“妻”|“子”|“本人”|“その他”必須なし世帯内の続柄
birthstring任意undefined生年月日
mobilestring任意undefined携帯番号
telstring任意undefined固定電話
emailstring任意undefined

フィールド表:Deal(商談・案件。主要フィールド)

Section titled “フィールド表:Deal(商談・案件。主要フィールド)”
フィールド型必須既定制約・備考
idstring必須なし主キー。実装シードは D-YYMM-NNN 形式(年月+連番)
statusDealStatus必須なしアポ/前確/商談/成約/工事/完了/保留/失注/クーリングオフ の9値
channelChannel必須なし訪問販売/催事/反響/パートナー の4値
hankyoMediastring任意undefinedchannel=“反響” のときの大元媒体(タイナビ等)
subject”自社”|“代理店”任意自社実施主体。登録時にログインユーザー所属から自動判定(手選択しない)
agencystring任意undefinedsubject=“代理店” のときの代理店名
venuestring任意undefined催事場所
householdIdstring必須なしHousehold.id 参照。参照整合性の要
propertyProperty必須なし物件情報(既存設備配列 Existing[] を含む)
rolesRoles必須なし獲得/前確/クローザー/設計(ユーザー名。実装ではFK)
respondentId / contractorIdstring任意undefinedPerson.id 参照(商談応対者/契約名義人)
itemsDealItem[]必須なし商材明細(kind/maker/model/spec/warranty/supplier/deliveryDate)
milestonesMilestone[]必須なし現調・着工・完工・連携・設備認定・入金の標準6点(defaultMilestones())のキー付き進捗
tasksDealTask[]必須なしtype は「前確」「太陽光調査設計」の2種のみ
notesDealNote[]任意undefinedid/date/author/text
postContractPostContract任意undefinedサンキューコール/ローン審査/審査確認コール/団信(成約時に生成)
constructionConstruction任意undefined施工店・現調・完了報告・完工書・連携日(着工フェーズで生成)
paymentPayment任意undefined決済方式・頭金・前金/後金・ローン条件
ordersOrder[]任意undefined発注(工事日確定後に発生)
applicationsApplication[]任意undefined申請(新規認定/変更認定/補助金/保証等の別軸)
proposalnumber任意undefinedご提案金額(税込)
costnumber任意undefined仕切り(原価)
marginnumber任意undefined粗利
memostring任意undefined運営メモ
lostReasonstring任意undefined失注・前確NGの理由。KPI分析用に必須で残す運用
createdAtstring必須なし作成日
closeDatestring任意undefined成約日

活動ログ・架電・申込・タスクの旧DB区分は、新CRMでは以下のように分解されて保持される(1テーブルに集約しない)。

旧DB区分(想定)新CRM側の対応
活動ログ独立テーブルなし。Deal.milestones/tasks/notes/createdAt・closeDate・postContract・construction・applications の各日付から画面表示時に動的生成される派生ビュー(ActivityPage.tsx の collectActivities())。旧DBの活動ログレコードは、この派生元(tasks/notes/milestones 等)へ分解して投入する必要がある
架電(前確)Deal.tasks(DealTask.type=“前確”、assignee/status/due/result/gate)
契約後の架電(サンキューコール・審査確認コール・完工コール)Deal.postContract.thanksCall/reviewCall、Deal.construction.kankoCall(いずれも CallResult: 未/不出/OK/NG)
申込専用エンティティなし。Deal.status=“成約” への遷移と createdAt/closeDate で表現される
タスクDeal.tasks(種別は前確・太陽光調査設計の2種に限定。それ以外の旧タスク種別は要マッピング)
フィールド型必須既定制約・備考
idstring必須なし主キー
datestring(YYYY-MM-DD)必須なし
tostring必須なし宛名(「様」は付けない運用)
subjectstring必須なし件名
paymentTermsstring必須なし支払条件
systemItemsQuoteItem[]必須なしシステム(商品)明細。小計①相当
workItemsQuoteItem[]必須なし工事明細。小計②相当
discountsQuoteDiscount[]必須なしlabel/amount。amount は負値
taxRatenumber必須なし消費税率(シードは 0.10)
dealIdstring任意undefinedDeal.id 参照
owner/ownerMobilestring任意undefined担当者・担当者携帯

QuoteItem: { name, model?, qty, unit, amount, cost? }。cost を持つ明細のみ原価集計対象(原価売り検知に使用)。

画面・機能(移行ツールと手順)

Section titled “画面・機能(移行ツールと手順)”

移行はETL方式の使い捨てスクリプトで実施する。恒久的な移行専用画面は用意しない。リハーサルで同一スクリプトを繰り返し実行し、精度と所要時間を計測する。

フェーズ時期内容
申請系 先行納品年末休業より前独立業務のため単独で納品・運用を開始する
リハーサル移行(第1回〜N回)本番移行の数週間前本番相当データで全スクリプトを通し、所要時間と疑義件数を計測する
データ凍結(フリーズ)年末休業初日旧DBへの入力を停止し、最終バックアップを取得する
本移行実行休業期間中抽出→変換→投入→整合チェックを一括実行する
検証・受入判定休業期間中〜年始直前「検証・受入基準」節の基準で判定する。不合格の場合はロールバックし、旧システムで年始業務を再開する
切替・年始稼働年始営業初日新CRMで業務を開始する。旧DBは参照用に読み取り専用で保持する

この工程は、meeting-log 2026-07(P4/P5ヒアリング)で確定した「12月末に本丸(P1〜P5)納品→12月に研修・検証→1月完全切替」「データ移行は年末休業中」「申請系は独立業務のため先行納品を検討」(先方合意)を、移行計画の観点で展開したものである。時期・所要時間の具体値はリハーサルの実測で確定する。

フェーズ遷移(ワークフロー)

Section titled “フェーズ遷移(ワークフロー)”
stateDiagram-v2
    [*] --> 申請系先行納品
    申請系先行納品 --> リハーサル移行
    リハーサル移行 --> リハーサル移行: 再実行(精度・所要時間の計測、複数回)
    リハーサル移行 --> データ凍結: リハーサル結果を確定手順に反映
    データ凍結 --> 本移行実行: 最終バックアップ取得後
    本移行実行 --> 検証受入判定
    検証受入判定 --> 切替年始稼働: 合格(件数突合・金額整合・サンプル目検・業務シナリオ)
    検証受入判定 --> ロールバック: 不合格・重大不整合
    切替年始稼働 --> [*]
    ロールバック --> [*]: 旧システムで年始業務を再開
sequenceDiagram
    participant Old as 旧BT社DB(読取専用)
    participant ETL as 移行スクリプト(使い捨てETL)
    participant Map as 旧→新コード対応表
    participant New as 新CRM DB
    participant Ops as 移行担当(Ouver/VE)

    Ops->>Old: データ凍結(入力停止・最終バックアップ取得)
    ETL->>Old: 抽出(マスタ→トランザクションの依存順)
    ETL->>Map: コード変換(channel/ステータス/型番の正規化)
    ETL->>New: 投入(legacy_id 付与。参照整合性順: マスタ→Household→Deal→見積…)
    ETL->>New: 整合チェック(件数突合・金額整合)
    New-->>Ops: 疑義リスト・不整合レポート
    Ops->>Ops: 検証・受入判定(件数突合/金額整合/サンプル目検/業務シナリオ検証)
    alt 合格
        Ops->>New: 切替(年始営業初日に稼働開始)
    else 不合格・重大不整合
        Ops->>Old: ロールバック(旧システムで年始業務を再開)
    end
  • 新DBの各テーブルに旧DBのIDを保持する引継ぎカラム(legacy_id)を設け、移行後も新旧の突合・遡及調査を可能にする。将来構想(AIエージェント、商社明細スキャンの自動取込、SaaS化・分社化)を見据え、この引継ぎカラムは拡張余地を残す設計とする。現行実装のいずれの型(Product/Household/Deal 等)にも legacy_id 相当のカラムは存在せず、新規追加が前提(未実装)。
  • 現行実装のID採番は、エンティティごとに異なる書式で個別に発番されている(統一採番基盤はない)。例: Household=Hnnn(3桁連番)、Deal=D-YYMM-NNN(年月+連番)、催事店舗マスタ=STnnn(3桁連番、event-stores.ts)、価格表・マスタ各種=英字接頭辞+2桁連番(例: SUP01, MK01, PB01)、部材・パッケージ=英字接頭辞+価格表番号2桁+連番2桁(例: PT0101, PK0101)。旧DB由来データを同じ書式帯へそのまま投入すると採番衝突の恐れがあるため、旧DB由来レコードは書式単位で採番帯を分離する。
  • 商品の業務キーは Product.model(型番=主キー)であり、そのまま引き継ぐ。SalesPrice.productNo は型番を指す名称参照であり主キーではない点に注意し、Product.model×channel×反映日の複合構造と整合させる。旧DBの型番表記ゆれ(全角/半角・大文字小文字・ハイフン有無等)は現時点で未正規化のため、移行時に正規化・突合表の整備が必要。
  • channel・ステータス等の区分値は「旧コード→新コード対応表」を移行成果物として作成し、先方レビューを経て確定する。対応表に存在しない旧コード値のフォールバック挙動(既定チャンネルへ丸めるか、疑義リストに回すか)は未定義(確認事項)。
  • 参照整合性(Deal→Household、見積→価格表 等)は、投入順序を依存関係順に固定して担保する。
  • 第1弾稼働分(催事・アイテム・商社)で発番済みのIDと旧DB由来データは、採番帯を分離して衝突を回避する。

現在価格・現在価格表の導出(反映日ロジック)

Section titled “現在価格・現在価格表の導出(反映日ロジック)”

価格・価格表は反映日を持つ時間軸マスタとして保持し、「基準日時点で有効な最新版」を都度導出する(保存済みの「現在値」列は持たない)。実装は lib/pricing.ts の以下2関数が正本。

  • currentSalesPrice(list, productNo, channel?, baseDate):productNo 一致(かつ channel 指定時は一致)で、startDate <= baseDate かつ(endDate 未設定 または endDate >= baseDate)を満たすレコードのうち startDate 降順の先頭1件を返す。該当が無ければ undefined(=現在有効な価格が存在しない)。
  • currentBooks(books, baseDate):source × manufacturerId × title をキーに、effectiveDate <= baseDate を満たす中で effectiveDate が最大の1件を採用する。

移行時は、この2関数と同じロジックで新DB投入後のデータを検算し、「移行直後の基準日(年始稼働日)時点で1件も有効版が無いマスタ」が無いことを受入判定に含める。

  • 営業日加算は addBusinessDays(dateISO, days)。土日および JP_HOLIDAYS_2026(年別祝日マスタ。祝日APIやマスタからの取得は未実装、シードはハードコード)を除外して加算する。
  • 入金までの営業日数 settlementDays(deal, loanCompanies):決済方式が3社間かどうかで分岐し、loanCompanies に一致するローン会社があればその daysDirect/daysViaTrader を使用。一致しない場合は 3社間=6営業日/それ以外=3営業日にフォールバックする。
  • 入金予定日 paymentDueDate(deal, loanCompanies):決済方式が「ローン」かつ construction.kankoshoAt(完工書原本回収日)がある案件のみ算出対象。入金マイルストーン(milestones の key: "nyukin")が既に完了していれば undefined。それ以外は kankoshoAt + settlementDays 営業日。
  • 現金半金の後金は入金タイミングの定義が未確定のため receivables()(経理向け入金予定一覧)の対象外(実装コードのコメントに明記)。現金一括も paymentDueDate が決済方式「ローン」のみを算出対象とするため同様に対象外となる。旧DBの入金実績データをこれらの対象外パターンに含めて移行する場合、経理向け画面には表示されない点に注意する。
  • 見積の消費税率はレコードごとに taxRate を持つ(シード値は 0.10)。税額 quoteTax(q) = Math.round(quoteNet(q) * q.taxRate) で四捨五入。
  • 経理向け入金予定額 amount = Math.max(0, proposal - downPayment)(負値は0に丸める)。
  • 移行時の金額整合検証(後述)は、これらの端数処理ロジックと突合方法を揃えたうえで実施する(丸め方式の相違は不整合として検出されうる)。

CSV出力の実装パターン(移行検証への転用)

Section titled “CSV出力の実装パターン(移行検証への転用)”

現行実装には CSV出力機能が複数画面に実装済みで、移行後の検証・受入判定でそのまま流用できる。CSV**取込(インポート)**機能は現状どの画面にも実装されていない(成約顧客一覧のインポートは新規実装が前提)。

画面実装出力対象
顧客一覧CustomersPage.tsx の exportCsv()世帯ID・世帯名・〒・都道府県・市区町村・番地・大人・子供・課税事業者・案件数・代表者・フリガナ・携帯番号・メモ
案件一覧DealsPage.tsx の exportCsv()案件明細
タスク一覧TasksPage.tsxタスク明細
活動フィードActivityPage.tsx派生ビュー(Deal横断のタイムライン)
レポートReportsPage.tsx の exportReportsCsv()集計セクション

共通仕様:UTF-8 BOM付き Blob("" + csv)をブラウザ内で生成しダウンロード、サーバ保存なし。ファイル名は <種別名>_<YYYY-MM-DD>.csv。値のクォート・エスケープ処理は画面ごとに実装が異なる(案件一覧は全列をダブルクォートで囲む、活動フィードは " → "" エスケープ、タスク一覧は顧客名列のみクォート等。統一仕様ではない)。canExport(role) によるボタン表示ガードが実装されているのは顧客一覧・案件一覧のみで、タスク一覧・活動フィード・レポートのCSVボタンは権限ガードなしで表示される(外部ロールは NAV_ALLOW 上これらの画面自体に到達できないため実害はない。権限節を参照)。

  • 世帯・顧客の名寄せは、氏名・住所・電話の表記ゆれによる重複を自動統合し、判定困難な組は疑義リストとして目検する。Person.kana(フリガナ)を名寄せの主要キーの一つとして使う。
  • 必須項目の欠損(連絡先なし等)や日付異常は移行前に疑義リスト化し、先方確認のうえ補正または欠損のまま取込むかを判断する。
  • 廃番商品・取引終了商社は、過去トランザクションから参照が残るため削除せず、無効フラグ付きで移行する。現行 Product/Supplier 型に無効化フラグは存在しないため、移行を前提にスキーマ拡張が必要(未実装)。
  • クレンジングの実施は、機械処理をOuver、業務判断をバリューエコロジー側が担当する分担とする。
  • 疑義件数・補正件数は移行報告書にプレースホルダで記録し、受入判定の材料とする。
  • 件数突合: 旧DB抽出件数=新DB投入件数+除外件数(除外理由付き)が全テーブルで成立すること。
  • 金額整合: 売上・粗利等の集計値が現行KPI Excel(営業マン別シート)の値と一致すること。KPIダッシュボードの正しさの前提になる。丸め方式(Math.round 等)を突合前に揃える。
  • サンプル目検: 世帯・商談・見積からN件ずつ抽出し、先方担当者が画面上で旧システムと突合する。
  • 業務シナリオ検証: 架電→商談→申込→タスク(前確・太陽光工程)の一連の流れが移行データ上で成立することを確認する。
  • 反映日整合: currentSalesPrice/currentBooks と同一ロジックで、移行直後の基準日時点に有効な価格・価格表が全対象商品・全対象マスタで導出できることを確認する。
  • 不合格・重大不整合が生じた場合は旧システムへロールバックし、年始業務を旧システムで再開する。
  • 移行実行そのもの(ETLスクリプトの実行)はDBレイヤーへの直接操作であり、アプリケーションの認可(lib/permissions.ts)を経由しない。「移行担当」という恒久ロールは現行 Role 型(管理者/営業/事務(BO)/発注・申請担当/代理店/代理店(メンバー)/施工店)に存在せず、未実装。移行作業は管理者権限を持つ運用者が個別に実行する運用を前提とする。
  • 移行後の検証で使うCSV出力は、既存の canExport(role) = !isExternal(role) をそのまま踏襲する想定。isExternal(role) は代理店・代理店(メンバー)・施工店を true とする。ただし現行実装でこのガードが効いているのは顧客一覧・案件一覧のCSVボタンのみで、タスク一覧・活動フィード・レポートはボタン自体にガードがない(外部3ロールは NAV_ALLOW で当該画面に到達できないため、画面到達制限で実質的に守られている)。
  • マスタ関連画面(/master-products 等)は NAV_ALLOW(lib/permissions.ts)上、事務(BO)と管理者のみアクセス可能。よって移行後のマスタ差分確認・補正は事務(BO)・管理者に限定される。
  • 未知ロール(旧値の残存等)は canSeeNav が何も許可しない設計(クラッシュ回避のフォールバック)。旧DB由来のユーザー・ロール値をそのまま新ロール体系に投入する場合、対応表に無い値は「何も見えないロール」になりうる点に注意する。
  • 型番表記ゆれ(全角/半角・大文字小文字・ハイフン有無)により Product.model 突合に失敗するケース。正規化ルール未確定のため、現時点では未マッチを疑義リスト化する運用が前提。
  • SalesPrice.productNo が対応する Product.model を持たない(名称参照が孤立している)ケース。整合チェックで検知する必要がある。
  • currentSalesPrice/currentBooks は該当版が無ければ undefined を返す。移行直後の基準日時点で有効版が1件も無いマスタは受入不合格として扱う。
  • SalesPrice の endDate が未設定のレコードは「無期限に有効」と解釈される(フィルタ条件 !s.endDate || s.endDate >= baseDate)。旧DB側で終了日が単に未入力なだけのレコードをそのまま投入すると、意図せず恒久有効になる。終了日の有無は移行時に精査する。
  • Deal.householdId が指す Household が存在しない参照切れ(孤立商談)。投入順序を Household→Deal に固定しても、旧DB側の参照自体が壊れているケースは疑義リストに回す。
  • 活動ログは新CRM側に永続テーブルが無く、Deal 配下の milestones/tasks/notes/createdAt 等から画面表示時に動的生成される派生ビュー。旧DBの活動ログをそのまま1テーブルへ投入する先が無いため、旧レコードを tasks/notes/milestones への分解ルールとして再設計する必要がある。
  • channel・ステータス等の区分値で「旧コード→新コード対応表」に存在しない値が来た場合のフォールバック挙動は未定義。既定値へ丸める/疑義リストに回すのいずれにするかは要決定。
  • 廃番商品・取引終了商社の無効フラグは現行 Product/Supplier 型に存在しない。「削除せず無効フラグ付きで移行する」を実現するには型拡張が前提となる。
  • 現金一括・現金半金の後金入金は receivables() の対象外(未定義のタイミング)。旧DBの入金実績をこのパターンで移行すると、経理向け入金予定画面には反映されない。
  • 祝日マスタ(JP_HOLIDAYS_2026)は年別ハードコードのシードであり、祝日APIやマスタからの取得は未実装。年をまたぐ移行データの営業日計算で年が変わった場合、祝日マスタの更新漏れに注意する。
  • 申請系は移行本体から独立して先行納品・先行運用されるため、本移行のロールバック判断とは別に、申請系データの巻き戻し要否を個別に判断する必要がある(申請系はロールバック対象に含まれない前提)。
  • 旧BT社DBのスキーマ・データ品質の詳細調査は未実施。調査結果次第でクレンジング工数と移行範囲が変動する。
  • 営業マンマスタ・等級表の整備状況に応じて、KPI実績(予算・評価テーブル)の新規構築スケジュールが変動する。新設テーブルのフィールド定義は未確定。
  • 年末休業の実日数と移行所要時間のバランスはリハーサル計測後に確定する。不足時は範囲縮小か凍結前倒しを協議する。
  • 申請系の先行納品期間中は旧新の二重メンテ(マスタ変更の反映漏れ等)が発生しうるため、同期ルールを別途定める。
  • ロールバックの判断期限(年始稼働に間に合う最終判断日時)は先方と合意していない。
  • 活動ログ・見積等の過去データの保持期間(過去N年分等)は先方と協議中。
  • 「旧コード→新コード対応表」に存在しない区分値のフォールバック挙動(既定値への丸め/疑義リスト送り)は未確定。
  • 廃番商品・取引終了商社の無効フラグをどのテーブル・カラムで持つか(Product/Supplier型の拡張仕様)は未確定。