属性ベース思考
1. 「控除」ではなく「属性」で考える
従来の年末調整(制度起点)
- 「配偶者控除の申告をしてください」
- 「扶養控除等申告書を記入してください」
- 「保険料控除申告書に保険料を記入してください」
- → 従業員が税制の知識を持っている前提。ほとんどの人には分からない。
TASHIKAの考え方(申告者起点)
- 従業員は「自分自身の属性」を答えるだけ
- 属性から該当する控除をシステムが自動判定する
- 〇〇控除という概念を従業員に意識させない
属性の例と、自動判定される控除
| 従業員が答える属性 | システムが自動判定する控除 |
|---|---|
| 配偶者がいる、配偶者の所得は○万円 | 配偶者控除 or 配偶者特別控除 |
| 子が19歳、所得は○万円 | 扶養控除(特定) or 特定親族特別控除 |
| 本人が障害者手帳を持っている | 障害者控除(本人) |
| 保険証明書のインポート(自動) | 生命保険料控除、地震保険料控除 |
| 給与データ(自動) | 基礎控除の区分、所得金額調整控除 |
Born Digital との関係
TASHIKAはBorn Digital(データが最初からデジタルで存在する前提)なので、 そもそも「人に属性を答えてもらう」場面すら最小限にする:
- 家族構成員 / 親族関係: 家族構成は既に登録済み。年齢は自動計算。
- 電子的控除証明書 (TEG800等): 保険料は証明書XMLからインポート。
- PayrollImport (DM-506): 給与・社会保険料は自動連携。
- 確認フロー (GL-004): 変更がなければ確認ボタンを押すだけ。
結果として、従業員が実際に「入力」するのは:
- 家族構成の変更(結婚・出産・離婚等)があった場合
- 電子化されていない証明書がある場合(手入力 or 画像アップロード)
- 前年から変わった事実がある場合
「控除」はViewであり、Modelではない
- データモデルは「属性」(人、家族、保険契約、住宅ローン等)を中心に設計する
- 「〇〇控除」はその属性から計算される結果(=計算ロジックの出力)
- 源泉徴収票や申告書の様式は、計算結果を特定のフォーマットで出力するView
2. Fact → Judgment → View 3層モデル
データモデルはドメイン概念に基づき設計する。紙の申告様式はViewに過ぎず、データの源泉ではない。
事実(Fact) 判定(Judgment) 出力(View)
────────────── ────────────── ──────────────
家族の属性 → 控除適用可否 → 源泉徴収票
保険契約 → 控除額の計算 → 申告書XML
給与・所得 → 判定理由の記録 → 紙の様式
住宅ローン → → 法定調書合計表
※ 事実は控除可否に関係なく常に保持
※ 判定は事実から計算で導出(Tax Calculation Core)
※ 出力は判定結果を特定フォーマットで表現この3層分離が、「紙の様式はViewに過ぎない」という原則と、 「属性で考える」という設計思想の両方を実現する。
3. 事実と控除判定結果の分離
問題: 控除対象外のデータを記録しないアプローチの弊害
従来の年末調整システムでは「控除が受けられない家族は記録しない」という設計が多い。 これには2つの問題がある:
問題1: 控除可否の判断を申告者に押し付ける
- 合計所得金額133万円超の配偶者 → 配偶者控除も配偶者特別控除も障害者控除も受けられない
- しかし「この家族は控除を受けられるか?」を申告者が判断するのは困難
- 「属性で考える」設計思想と矛盾する
問題2: 年度をまたいだデータ繰り越しが壊れる
- 前年: 配偶者の合計所得金額が133万円超 → 控除対象外 → データなし
- 今年: 配偶者が退職して合計所得金額が下がった → 控除対象に
- 前年のデータが0なので、今年1から入力が必要になる
- 「確認するだけで完了」という確認フローが崩壊する
設計原則: 事実は常に記録する
事実データ(常に保持) 控除判定結果(計算で導出)
────────────────────── ──────────────────────
配偶者がいる → 配偶者控除: 対象外
配偶者の合計所得金額: 200万円 → 配偶者特別控除: 対象外
配偶者は障害者手帳を持つ → 障害者控除: 対象外(合計所得金額の要件未達)- 控除を受けられるか・受けられないかにかかわらず、事実(属性)は申告データとして保持する
- 控除の適用可否・控除額は 別レイヤーの判定結果 として管理する
- 翌年に合計所得金額が下がって控除対象になっても、事実データは引き継がれているので確認のみで済む
前年データ引き継ぎ時の注意: 判定結果は引き継がない
前年の申告データを翌年に引き継ぐ際、事実データは引き継ぐが、判定結果は引き継いではならない。 同じ事実でも年齢が1歳加算されるだけで判定結果が変わるケースがある。
引き継いでよいもの(事実):
親族の続柄、生年月日、障害の有無、同居関係、事実婚の有無 等
引き継いではいけないもの(判定結果):
扶養親族の区分(一般/特定/老人)、控除額、特定親族の該当性 等年齢が判定に関わる控除の一覧
| 控除・判定 | 年齢閾値 | 年度またぎで変わる例 |
|---|---|---|
| 扶養控除: 16歳未満の扶養親族 → 控除対象 | 16歳以上 | 15歳→16歳で扶養控除の対象に |
| 扶養控除: 一般 → 特定扶養親族 | 19歳以上 | 18歳→19歳で控除額38万円→63万円に増加 |
| 扶養控除: 特定 → 一般 | 23歳以上 | 22歳→23歳で控除額63万円→38万円に減少 |
| 扶養控除: 一般 → 老人扶養親族 | 70歳以上 | 69歳→70歳で控除額38万円→48万円/58万円に増加 |
| 特定親族特別控除: 対象年齢 | 19〜22歳 | 18歳→19歳で対象に / 22歳→23歳で対象外に |
| 配偶者控除: 一般 → 老人控除対象配偶者 | 70歳以上 | 69歳→70歳で控除額が増加 |
| 非居住者の扶養控除: 年齢による適用制限 | 30歳未満 / 70歳以上 | 29歳→30歳で年齢要件を失う(留学等が必要に) |
| 所得金額調整控除: 23歳未満の扶養親族の有無 | 23歳未満 | 22歳→23歳で適用要件を失う可能性 |
→ 年齢は毎年必ず1歳加算されるため、すべての年齢閾値をまたぐ年度で判定結果が変わる。 判定結果を前年からそのまま引き継ぐと誤った控除が適用される。 判定結果は必ず当年の年齢・所得・税制パラメータで再計算する。
データモデルへの影響
避けるべき設計(控除起点)
Declaration
└── DependentClaim ← 控除を受ける場合のみレコードが存在
└── FamilyMember (参照)この設計では「控除対象外の家族」のデータが消える。
望ましい設計(事実起点)
Declaration
├── 事実データ: 家族の属性(全員分、控除可否に関係なく保持)
│ ├── FamilyMember の年度スナップショット(所得見積額、障害者区分等)
│ └── 保険契約、住宅ローン等(全件保持)
└── 控除判定結果: Tax Calculation Core が算出
├── 各家族に対する控除の適用可否
├── 各控除の金額
└── 判定理由(なぜ対象外なのか)4. カスケード再計算(事実変更時の全控除再判定)
問題: 1つの事実が複数の控除に影響する
控除の判定は独立ではなく、同じ事実(属性)が複数の控除の入力になっている。 特に「本人の合計所得金額」は多くの控除判定の入力パラメータであり、 この値が変わると連鎖的に複数の控除の判定結果が変わる。
本人の合計所得金額が影響する控除
| 控除 | 影響の仕方 |
|---|---|
| 基礎控除 | 合計所得金額に応じて控除額が段階的に変動 |
| 配偶者控除 | 本人の合計所得金額の区分(A/B/C)で控除額が変動。1,000万円超で適用不可 |
| 配偶者特別控除 | 同上 |
| 寡婦控除 | 合計所得金額500万円超で適用不可 |
| ひとり親控除 | 合計所得金額500万円超で適用不可 |
| 勤労学生控除 | 合計所得金額85万円超で適用不可(令和7年〜)。さらに不労所得10万円超でも不可 |
| 所得金額調整控除 | 給与収入850万円超が適用条件 |
| 源泉控除対象配偶者の判定 | 本人の合計所得金額900万円以下が要件の一つ |
配偶者の合計所得金額が影響する控除
| 控除 | 影響の仕方 |
|---|---|
| 配偶者控除 | 配偶者の合計所得金額が共通閾値以下が適用条件(R7: 58万円以下) |
| 配偶者特別控除 | 配偶者の合計所得金額が共通閾値超〜133万円以下で段階的に適用 |
| 障害者控除(配偶者分) | 同一生計配偶者の合計所得金額の要件(共通閾値以下)を満たす必要あり |
設計方針: 事実変更時の全控除再判定
事実データが変更された場合、変更された事実に依存するすべての控除を再判定する 仕組みが必要。部分的な再計算ではなく、依存関係を追跡して連鎖的に更新する。
本人の合計所得金額を訂正
→ 基礎控除を再判定
→ 配偶者控除を再判定
→ 配偶者特別控除を再判定
→ 寡婦控除を再判定(500万円超で不可)
→ ひとり親控除を再判定(500万円超で不可)
→ 勤労学生控除を再判定(85万円超で不可 + 不労所得10万円超で不可)
→ 所得金額調整控除を再判定
→ 源泉控除対象配偶者の判定を更新実装アプローチ
- 事実変更イベント → 全控除一括再計算 が最もシンプルで安全
- 個別の依存関係を管理するより、「事実が変わったら全部再計算」の方が確実
- 税額計算エンジン は純粋関数なので、全控除を再計算してもコストは低い
- 部分再計算の最適化は、パフォーマンス問題が実際に発生してからで良い
- Draft状態ではモードレス自動保存 (GL-007) のタイミングで再計算を実行
- 再計算結果は即座にUIに反映し、従業員が結果を確認できるようにする
将来の税制改正への備え
- 現時点で扶養控除は本人の所得に依存しないが、将来要件が追加される可能性がある
- 依存関係をハードコードせず、「事実変更→全控除再計算」のアプローチなら 新しい依存関係が生まれても計算エンジンの更新だけで対応できる
5. 紙の様式はViewに過ぎない
国税庁の申告様式(NTAAPP001-008)はデータの出力形式である。データモデルは様式に依存せず独立に設計する。
「扶養控除等申告書」「保険料控除申告書」「配偶者控除等申告書」といった紙の様式の構造は、データモデルの設計を規定しない。データモデルは属性(人、家族、保険契約、住宅ローン等)を中心に設計し、様式への出力はViewレイヤーの責務とする。
属性(Model) 計算(Logic) 出力(View)
────────────── ────────────── ──────────────
FamilyMember → 控除判定エンジン → 源泉徴収票 (TEG109)
保険契約データ → (Tax Calculation → 申告書XML (NTAAPP001-008)
給与データ → Core) → 紙の様式 (PDF)
住宅ローンデータ → → 法定調書合計表