データモデル技術設計書
設計思想
なぜスタースキーマか
BizLP GAS Accounting は、スプレッドシート上に暗黙的なスタースキーマを採用している。
スタースキーマでは、中心にトランザクションデータを格納するファクトテーブルを配置し、その周囲に分析軸となるディメンションテーブルを一対多で接続する。対照的に、スノーフレークスキーマではディメンションをさらにサブテーブルに正規化するが、以下の理由からスタースキーマを選択した:
| 観点 | スタースキーマ | スノーフレークスキーマ |
|---|---|---|
| クエリの複雑性 | 低(1段階の参照) | 高(多段階の結合が必要) |
| データ冗長性 | 許容(ディメンション値を直接埋め込み) | 低(正規化で排除) |
| GAS環境との適合 | 適合 — JOIN不可の環境では平坦な構造が必須 | 不適合 — サブテーブル参照のコストが高い |
| 保守性 | マスタ変更時にファクト側の更新が必要 | マスタ変更が自動伝播 |
非正規化を許容する理由
Google Spreadsheet はリレーショナルDBではない。SQL の JOIN に相当する操作は GAS の indexOf / buildHeaderIndex_ による手動ルックアップで代替しており、参照コストが高い。このため、ファクトテーブル(32_wrk_invoice 等)には以下の非正規化を意図的に適用している:
| 非正規化パターン | 例 | 理由 |
|---|---|---|
| ディメンション値の直接埋め込み | INV に 科目名・取引先名・PJ名・組織名 を文字列で保持 | 集計時にマスタ参照を最小化し GAS 6分制限内で処理を完了させる |
| 派生属性の事前計算 | INV に 諸表区分・大分類 を保持 (科目マスタから転記) | P/L・B/S の分類判定を集計時ではなく起票時に確定させる |
| 残高の直接保持 | INV に 未決済残高(自動計算) を保持 | STL 消込のたびに再集計せず Action B で即時更新する |
SSOT (Single Source of Truth) としての INV
全ての財務諸表(P/L・B/S・C/F)およびPJ別損益の集計は 32_wrk_invoice (INV) を起点とする。42_trn_journal (TRN) は監査証跡であり、集計ソースとしては使用しない。
詳細は ADR-0001: SSOTとしてのINV を参照。
ファクトテーブル
本システムのファクトテーブルは、トランザクションの発生を記録するテーブル群である。
| テーブル | キー | 粒度 | 主キー形式 | 主要メジャー | 役割 |
|---|---|---|---|---|---|
| 32_wrk_invoice | WRK_INVC | 1 請求 | INV_… | 計画 3 額 + 残高 | SSOT・全集計の起点 |
| 33_wrk_bank | WRK_BANK | 1 決済 | STL_… | 決済額 + 差額 | キャッシュ移動・CF 起点 |
| 42_trn_journal | TRN_JOUR | 1 仕訳行 | TRN_… | 実績 3 額 | 監査証跡(集計不使用) |
| 31_wrk_order | WRK_ORDR | 1 発注 | ORD_… | 発注額 + 残高 | RPA 親 / INV 紐づけ |
主キー形式: 全て
<TYPE>_YYYYMMDD_NNNN。計画 3 額 = 税抜/消費税/税込(INV 列)。実績 3 額 = 同(TRN 列)。
32_wrk_invoice (INV) — 請求・債権債務台帳
| # | 列名 | 型 | 入力/自動 | ディメンション参照 | 説明 |
|---|---|---|---|---|---|
| 1 | 有効フラグ | BOOLEAN | 入力 | — | FALSE の行は全処理でスキップ |
| 2 | 請求ID(INV) | TEXT | 自動 | — | 主キー(INV_…) |
| 3 | 親発注ID(ORD) | TEXT | 自動 | → 31_wrk_order | RPA起票時に自動紐づけ |
| 4 | 起票日時 | DATETIME | 自動 | — | RPA起票のタイムスタンプ |
| 5 | 起票者 | TEXT | 自動 | — | 実行ユーザー |
| 6 | 申請種別 | TEXT | 自動 | — | APL_xxx (HC/TR/DD/AP/EX/JE) |
| 7 | 発生日(P/L計上日) | DATE | 入力 | — | P/L計上月の決定に使用 |
| 8 | 決済日_計画 | DATE | 入力 | — | 期ずれ判定 (発生月 vs 決済月) |
| 9 | 請求ステータス | TEXT | 入力 | → 15_mst_dict | 未処理→承認済→決済完了 |
| 10 | 収支区分 | TEXT | 入力 | → 15_mst_dict | 収入 / 支出 |
| 11 | 取引先名 | TEXT | 入力 | → 12_mst_partner | 非正規化: 名称を直接保持 |
| 12 | PJ名 | TEXT | 入力 | → 14_mst_project | 非正規化: PJ名を直接保持 |
| 13 | 組織名 | TEXT | 入力 | → 13_mst_org | 非正規化: 組織名直接保持 |
| 14 | 諸表区分 | TEXT | 自動 | → 11_mst_account | 科目マスタから転記(P/L or B/S) |
| 15 | 大分類 | TEXT | 自動 | → 11_mst_account | 科目マスタから転記 |
| 16 | 科目名 | TEXT | 入力 | → 11_mst_account | 完全一致必須。マスタ未登録はエラー |
| 17 | 税区分 | TEXT | 入力 | → 15_mst_dict | 課税 / 非課税 / 不課税 |
| 18 | 通貨 | TEXT | 自動 | — | JPY 固定 (現行) |
| 19 | 税抜金額_計画 | NUMBER | 入力 | — | メジャー: 税抜金額 |
| 20 | 消費税額_計画 | NUMBER | 入力 | — | メジャー: 消費税額 |
| 21 | 税込金額_計画 | NUMBER | 入力 | — | メジャー: 税込金額 |
| 22 | 未決済残高 | NUMBER | 自動 | — | 請求総額 − Σ STL(逆算) |
| 23 | 決済手段 | TEXT | 入力 | → 15_mst_dict | 銀行/クレカ/資産計上 等 |
| 24 | 摘要 | TEXT | 入力 | — | 自由記述 |
| 25 | 証憑URL | TEXT | 入力 | — | Drive リンク |
| 26 | 自動仕訳JNL_ID | TEXT | 自動 | → 42_trn_journal | Action A 採番・冪等性チェック |
33_wrk_bank (STL) — 入出金・消込台帳
| # | 列名 | 型 | 入力/自動 | ディメンション参照 | 説明 |
|---|---|---|---|---|---|
| 1 | 有効フラグ | BOOLEAN | 入力 | — | |
| 2 | 決済ID(STL) | TEXT | 自動 | — | 主キー (STL_YYYYMMDD_NNNN) |
| 3 | 消込対象請求ID(INV) | TEXT | 自動 | → 32_wrk_invoice | ファクト間結合: INV→STL |
| 4 | 決済日_計画 | DATE | 自動 | — | INV の決済日_計画を転記 |
| 5 | 立替日 | DATE | 入力 | — | クレカ立替の場合 |
| 6 | 決済日_実績 | DATE | 入力 | — | 実際の入出金日 |
| 7 | 決済ステータス | TEXT | 入力 | → 15_mst_dict | 未処理→消込済 |
| 8 | 入出金区分 | TEXT | 自動 | → 15_mst_dict | 入金 / 出金 |
| 9 | 決済口座 | TEXT | 入力 | — | 銀行口座名 |
| 10 | 取引先名 | TEXT | 自動 | → 12_mst_partner | INV から転記 |
| 11 | 税込金額_決済 | NUMBER | 入力 | — | メジャー: 決済金額 |
| 12 | 差額(手数料等) | NUMBER | 入力 | — | 振込手数料等 |
| 13 | 差額処理科目 | TEXT | 入力 | → 11_mst_account | 差額の計上科目 |
| 14 | 組織名 | TEXT | 自動 | → 13_mst_org | INV から転記 |
| 15 | 摘要 | TEXT | 入力 | — | |
| 16 | 消込手段 | TEXT | 自動 | — | 自動 / 手動 / クレカ |
| 17 | 自動仕訳JNL_ID | TEXT | 自動 | → 42_trn_journal | Action B で採番 |
ディメンションテーブル
ディメンションテーブルは、ファクトの分析軸を提供するマスタデータである。
| テーブル | キー | 種別 | 主キー | 結合キー | 用途 |
|---|---|---|---|---|---|
| 11_mst_account | MST_ACCT | 勘定科目 | ACC_… | INV.科目名 | P/L・B/S 分類 |
| 12_mst_partner | MST_PART | 取引先 | PTN_… | INV.取引先名 | 取引先識別 |
| 13_mst_organization | MST_ORGN | 組織 | ORG_… | INV.組織名 | 組織別集計 |
| 14_mst_project | MST_PROJ | PJ | PRJ_… | INV.PJ 名 | PJ 別損益・配賦 |
| 15_mst_dict | MST_DICT | コード辞書 | カテゴリ + コード | INV ステータス等 | プルダウン値定義 |
| 03_sys_params | SYS_PARAM | パラメータ | キー | — | 会計年度等 |
結合メカニズム
本システムでは SQL の JOIN に代わり、以下のメカニズムでファクト↔ディメンションを結合する:
1. ファクトテーブルにディメンション値を「名称」で直接埋め込み(非正規化)
INV.科目名 = "旅費交通費" ← 11_mst_account.科目名 と文字列完全一致
2. 集計時に必要な派生属性のみマスタ参照
buildHeaderIndex_(mstAcctData) で科目マスタを連想配列化
→ 科目名をキーに 諸表区分・表示区分・固変区分 を取得
3. 参照はヘッダー名ベース(列番号ハードコード禁止)
const idx = headers.indexOf("科目名");
設計トレードオフ: 名称ベースの結合は、マスタ側の名称変更時にファクト側の不整合を生む。これは 06. データ整合性チェック の科目マスタ存在チェックで検出する。
11_mst_account — 勘定科目マスタ
| # | 列名 | 説明 | ファクトでの役割 |
|---|---|---|---|
| 1 | 有効フラグ | FALSE で論理削除 | — |
| 2 | 主科目コード | ACC_NNNN | コード参照用 (TRN で使用) |
| 3 | 諸表区分 | P/L or B/S | INV 起票時に転記 → データマートで P/L・B/S 振り分け |
| 4 | 大分類 | 流動資産/固定資産/売上/販管費 等 | INV 起票時に転記 → P/L セクション分類 |
| 5 | 表示区分 | 財務諸表上の表示グループ | データマートでの表示行の決定 |
| 6 | 表示科目 | 財務諸表上の表示科目名 | — |
| 7 | 正式科目名 | 法的・会計基準上の正式名称 | — |
| 8 | 固変区分 | 固定費 / 変動費 | PJ別損益の限界利益計算 |
| 9 | デフォルト税率 | 10% / 8% / 0% | RPA 起票時の消費税計算 |
| 10 | 科目名 | 結合キー: INV.科目名と完全一致 | ファクト↔ディメンション結合の基準 |
14_mst_project — プロジェクトマスタ
| # | 列名 | 説明 | ファクトでの役割 |
|---|---|---|---|
| 1 | 有効フラグ | — | |
| 2 | PJコード | PRJ_NNNN | コード参照用 |
| 3 | プロジェクト名 | INV.PJ名 と文字列一致で結合 | |
| 4 | PJ小区分 | 受託/自社/研究 等 | PJ別損益のグループ化 |
| 5 | PJ大区分 | 上位グループ化 | |
| 6 | PJ区分 | — | |
| 7 | 契約形態 | 準委任/請負 等 | — |
| 8 | 配賦区分 | 配賦元 / 配賦先 / 対象外 | 共通費配賦ロジックで使用 |
| 9-14 | (その他) | 社内外、資産化、ステータス等 | — |
ER図
erDiagram
MST_ACCT ||--o{ WRK_INVC : "科目名"
MST_ACCT ||--o{ WRK_BANK : "差額処理科目"
MST_PART ||--o{ WRK_INVC : "取引先名"
MST_PART ||--o{ WRK_BANK : "取引先名"
MST_ORGN ||--o{ WRK_INVC : "組織名"
MST_ORGN ||--o{ WRK_BANK : "組織名"
MST_PROJ ||--o{ WRK_INVC : "PJ名"
MST_DICT ||--o{ WRK_INVC : "ステータス/区分"
MST_DICT ||--o{ WRK_BANK : "ステータス/区分"
MST_DICT ||--o{ MST_PROJ : "PJ区分/契約形態"
WRK_ORDR ||--o{ WRK_INVC : "親発注ID(ORD)"
WRK_INVC ||--o{ WRK_BANK : "消込対象請求ID(INV)"
WRK_INVC ||--o| TRN_JOUR : "自動仕訳JNL_ID"
WRK_BANK ||--o| TRN_JOUR : "自動仕訳JNL_ID"
MST_ACCT {
string 主科目コード PK
string 科目名 UK
string 諸表区分
string 大分類
string 表示区分
string 固変区分
number デフォルト税率
}
MST_PART {
string 取引先コード PK
string 取引先名
string 取引先区分
}
MST_ORGN {
string 組織コード PK
string 組織名
}
MST_PROJ {
string PJコード PK
string プロジェクト名
string PJ区分
string 配賦区分
}
MST_DICT {
string カテゴリ PK
string 設定コード PK
string 表示名
}
WRK_ORDR {
string 発注ID_ORD PK
string 取引先名 FK
string PJ名 FK
number 税込金額_発注
number 発注残高
}
WRK_INVC {
string 請求ID_INV PK
string 親発注ID_ORD FK
date 発生日
date 決済日_計画
string 請求ステータス FK
string 科目名 FK
string 取引先名 FK
string PJ名 FK
string 組織名 FK
number 税込金額_計画
number 未決済残高
string 自動仕訳JNL_ID FK
}
WRK_BANK {
string 決済ID_STL PK
string 消込対象請求ID_INV FK
date 決済日_実績
string 決済ステータス FK
number 税込金額_決済
string 自動仕訳JNL_ID FK
}
TRN_JOUR {
string 取引ID PK
date 発生日
string 科目名 FK
number 税込金額_実績
string 仕訳ステータス
}
ER図の読み方
- 実線: ファクト↔ディメンションの結合(名称ベースの文字列一致)
- ||--o{: 一対多(1つのマスタレコードが複数のファクト行で参照される)
- ||--o|: 一対零or一(1つのINV/STLに対して0件or1件のTRNが紐づく)
- FK列: スプレッドシート上は外部キー制約なし。データ整合性チェック (03_data_validator.js) で検証
データフロー図
flowchart TB
subgraph MST["10s マスタデータ"]
MST_A["11_mst_account
勘定科目"]
MST_P["12_mst_partner
取引先"]
MST_O["13_mst_organization
組織"]
MST_J["14_mst_project
プロジェクト"]
MST_D["15_mst_dict
コード辞書"]
end
subgraph BUD["20s 予算・契約マスタ"]
B1["21_bud_pipeline
売上パイプライン"]
B2["22_bud_headcount
人員・給与"]
B3["23_bud_subscription
SaaS"]
B4["24_bud_capex_loan
設備投資"]
B5["25_bud_finance
資金移動"]
B6["26_bud_adhoc
単発経費"]
end
subgraph WRK["30s サブ元帳"]
ORD["31_wrk_order
発注台帳 (ORD)"]
INV["32_wrk_invoice
請求台帳 (INV)
★ SSOT"]
STL["33_wrk_bank
入出金台帳 (STL)"]
end
subgraph TRN["40s 総勘定元帳"]
JNL["42_trn_journal
仕訳台帳 (TRN)
監査証跡"]
end
subgraph OUT["60s-90s 財務諸表"]
PL["61/62 P/L"]
BS["71/73 B/S"]
CF["73/74 C/F"]
PJ["78/79 PJ損益"]
DCF["83-85 日次CF"]
FS["91/92 財務諸表"]
end
MST --> BUD
BUD -->|"RPA起票
401_bat_rpa.js"| ORD
BUD -->|"RPA起票"| INV
ORD -.->|"ORD_ID紐づけ"| INV
INV -->|"Action A
承認→仕訳転記"| JNL
INV -->|"Action A
STL自動作成"| STL
STL -->|"Action B
消込→決済仕訳"| JNL
STL -->|"Action B
残高更新"| INV
INV -->|"PHASE 1
承認済INV"| OUT
STL -->|"PHASE 2
消込済STL"| OUT
MST_A -.->|"科目分類"| OUT
style INV fill:#4a90d9,color:#fff,stroke:#2c5f8a
style JNL fill:#95a5a6,color:#fff,stroke:#7f8c8d
データフローの段階
| # | フェーズ | トリガー | 入力 | 処理 | 出力 |
|---|---|---|---|---|---|
| 1 | RPA 起票 | メニュー実行 | 20s 予算 | 04_bat_rpa.js | ORD + INV |
| 2 | Action A | INV 承認 | 承認済 INV | 08_subledger.js | TRN + STL |
| 3 | Action B | STL 消込 | 消込済 STL | 08_subledger.js | TRN + INV 残高 |
| 4 | マート更新 | メニュー実行 | INV + STL | 06_datamart_*.js | 財務 3 表 + PJ + 日次 |
テーブル拡張ガイドライン
タブ番号体系
| 番号帯 | 用途 | 命名規則 | 例 |
|---|---|---|---|
| 01-09 | システム設定 | NN_sys_xxx | 01_sys_config, 03_sys_params |
| 10-19 | マスタデータ | NN_mst_xxx | 11_mst_account |
| 20-29 | 予算・契約 | NN_bud_xxx | 22_bud_headcount |
| 30-39 | サブ元帳(ワーク) | NN_wrk_xxx | 32_wrk_invoice |
| 40-49 | 仕訳・総勘定元帳 | NN_trn_xxx | 42_trn_journal |
| 60-69 | P/L 関連出力 | NN_pl_xxx | 61_pl, 63_pl_plan |
| 70-79 | B/S・PJ 関連出力 | NN_bs_xxx / NN_pj_xxx | 71_bs, 78_pj_pl |
| 80-89 | CF 関連出力 | NN_cf_xxx | 83_cf_daily |
| 90-99 | 財務諸表・テスト | NN_fs_xxx / NN_test_xxx | 91_fs_bs, 90_test_results |
全タブ一覧(処理段階ツリー)
[10s MST] マスタデータ ─────────────────────────────────
11_mst_account 科目マスタ(正式科目名・科目名・表示区分・固変区分)
12_mst_partner 取引先マスタ
13_mst_organization 組織マスタ
14_mst_project プロジェクトマスタ(配賦区分: 配賦元/先/対象外)
15_mst_dict コード辞書(プルダウン値の定義)
↓
[20s BUD] 予算・契約マスタ ──────────────────────────────
21_bud_pipeline 売上パイプライン(確度・MRR・スポット)
22_bud_headcount 人員・給与マスタ(社保・源泉税の自動計算)
23_bud_subscription SaaS・サブスク管理
24_bud_capex_loan 設備投資・借入管理
25_bud_finance 資金移動・財務取引
26_bud_adhoc 単発経費(領収書→自動登録連携)
27_bud_resource 要員稼働率(PJ別工数配賦)
28_bud_allocation 共通費配賦ルール
↓ RPA起票 (401_bat_rpa.js)
[30s WRK] サブ元帳 ─────────────────────────────────────
31_wrk_order 発注・契約台帳 (ORD)
32_wrk_invoice 請求・債権債務台帳 (INV) ← Single Source of Truth
33_wrk_bank 入出金・消込台帳 (STL)
34_wrk_card クレカ明細(JCBインポート→STLマッチング)
35_wrk_receipt 領収書・請求書(PDF→Gemini API解析)
↓ 仕訳エンジン (403_subledger_engine.js)
[40s TRN] 総勘定元帳 ───────────────────────────────────
41_trn_budget 予算仕訳
42_trn_journal 仕訳台帳 (JNL) — 監査証跡
↓ データマート (6xx_datamart_*.js)
[60s-90s] 財務諸表・管理会計レポート ──────────────────
61/62_pl P/L(単月/YTD)
63/64_pl_plan P/L計画(単月/YTD)
71/73_bs B/S(実績/計画)
73/74_cf C/F 間接法(実績/計画)
78_pj_pl PJ別P/L(通期・共通費配賦込み)
79_pj_monthly PJ別月次採算(限界利益)
83/84/85_cf_daily CF日次(計上/計画/実績)
91/92_fs 財務諸表レンダリング(B/S・P/L)
| タブ番号帯 | 主要タブ | 関連仕様書 |
|---|---|---|
| 10s マスタ | 11_mst_account | 01 / 02 / 03 |
| 20s 予算 | 21〜28 | 6 種 RPA: 07-12 |
| 30s サブ元帳 | 31_wrk_order | 14. ORD自動作成 |
| 32_wrk_invoice | 13. 仕訳エンジン / 16. データ取込 | |
| 33_wrk_bank | 15. STL自動作成 / 13. 仕訳エンジン | |
| 34_wrk_card | 04. クレカマッチング | |
| 35_wrk_receipt | 05. 領収書マッチング | |
| 40s 仕訳 | 42_trn_journal | 13. 仕訳エンジン |
| 60-90s 出力 | 61/62 P/L | 18. P/L / 25. 法人税 |
| 71/91 B/S | 19. B/S | |
| 73/74 C/F | 20. C/F | |
| 78/79 PJ | 26. PJ別損益 | |
| 83/84/85 日次CF | 21. 日次CF |
新規タブ追加の手順
- 番号の割り当て: 上記番号帯から適切な範囲を選択。同番号帯内で空き番号を使用
- システムキーの定義:
01_sys_configにシステムキー_GASを追加 (例:WRK_NEWT) - スキーマの定義:
101_sys_config.jsのsetupAllSchemas内に列定義を追加 - IDプレフィックスの定義:
002_constants.jsのID_PREFIXESに追加 (例:NEW_) - ディメンション結合の設計: ファクトテーブルの場合、どのマスタと結合するかを決定
- 結合キーはヘッダー名ベース(列番号ハードコード禁止)
- 非正規化する属性(INVに直接埋め込む値)を明確にする
- DDL実行:
setupAllSchemasを実行してスキーマを同期 - 仕様書の更新:
docs/配下に対応する spec_xxx.md を作成
列追加のルール
| ルール | 説明 |
|---|---|
| ヘッダー名ベース | 列番号のハードコード禁止。indexOf / buildHeaderIndex_ で動的参照 |
| 命名規則 | ADR-0004 に準拠: 金額_計画 / 金額_決済 / 決済日_計画 / 決済日_実績 |
| 色分け | 入力列 = 薄青 (#dce6f1)、自動列 = 薄灰 (#f3f3f3) |
| 入力規則 | プルダウン値は 15_mst_dict から参照。数値制限・TRUE/FALSE も DDL で設定 |
| 有効フラグ | 全マスタ・ワークテーブルの先頭列に配置。FALSE で論理削除 |
付録: アーキテクチャ決定記録
スタースキーマ型データモデルの採用根拠は ADR-0047: スタースキーマ型データモデルを採用する を参照。
本付録は元々「ADR-0008: スタースキーマ型データモデルの採用」として埋め込まれていたが、正規 ADR-0008 (Vertex AI 集約) との番号衝突を解消するため、ADR-0047 として独立採番した (2026-05-16)。決定内容に変更はない。