freee-demo-kit 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +280 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +35 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/auth.d.ts +3 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +57 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/corrupt.d.ts +3 -0
- package/dist/commands/corrupt.d.ts.map +1 -0
- package/dist/commands/corrupt.js +72 -0
- package/dist/commands/corrupt.js.map +1 -0
- package/dist/commands/dry-run.d.ts +3 -0
- package/dist/commands/dry-run.d.ts.map +1 -0
- package/dist/commands/dry-run.js +59 -0
- package/dist/commands/dry-run.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +58 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/load-all.d.ts +3 -0
- package/dist/commands/load-all.d.ts.map +1 -0
- package/dist/commands/load-all.js +69 -0
- package/dist/commands/load-all.js.map +1 -0
- package/dist/commands/load.d.ts +25 -0
- package/dist/commands/load.d.ts.map +1 -0
- package/dist/commands/load.js +197 -0
- package/dist/commands/load.js.map +1 -0
- package/dist/commands/reset.d.ts +3 -0
- package/dist/commands/reset.d.ts.map +1 -0
- package/dist/commands/reset.js +117 -0
- package/dist/commands/reset.js.map +1 -0
- package/dist/commands/setup.d.ts +4 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +190 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +25 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/validate.d.ts +5 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +132 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/verify.d.ts +3 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +87 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/commands/whoami.d.ts +3 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +31 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/types/freee.d.ts +112 -0
- package/dist/types/freee.d.ts.map +1 -0
- package/dist/types/freee.js +3 -0
- package/dist/types/freee.js.map +1 -0
- package/dist/types/preset.d.ts +14 -0
- package/dist/types/preset.d.ts.map +1 -0
- package/dist/types/preset.js +2 -0
- package/dist/types/preset.js.map +1 -0
- package/dist/utils/accounting-validator.d.ts +13 -0
- package/dist/utils/accounting-validator.d.ts.map +1 -0
- package/dist/utils/accounting-validator.js +95 -0
- package/dist/utils/accounting-validator.js.map +1 -0
- package/dist/utils/auth-flow.d.ts +17 -0
- package/dist/utils/auth-flow.d.ts.map +1 -0
- package/dist/utils/auth-flow.js +137 -0
- package/dist/utils/auth-flow.js.map +1 -0
- package/dist/utils/config.d.ts +11 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +13 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/confirm-company.d.ts +7 -0
- package/dist/utils/confirm-company.d.ts.map +1 -0
- package/dist/utils/confirm-company.js +20 -0
- package/dist/utils/confirm-company.js.map +1 -0
- package/dist/utils/corrupt-injector.d.ts +17 -0
- package/dist/utils/corrupt-injector.d.ts.map +1 -0
- package/dist/utils/corrupt-injector.js +123 -0
- package/dist/utils/corrupt-injector.js.map +1 -0
- package/dist/utils/env-loader.d.ts +9 -0
- package/dist/utils/env-loader.d.ts.map +1 -0
- package/dist/utils/env-loader.js +12 -0
- package/dist/utils/env-loader.js.map +1 -0
- package/dist/utils/env-writer.d.ts +10 -0
- package/dist/utils/env-writer.d.ts.map +1 -0
- package/dist/utils/env-writer.js +40 -0
- package/dist/utils/env-writer.js.map +1 -0
- package/dist/utils/freee-api.d.ts +24 -0
- package/dist/utils/freee-api.d.ts.map +1 -0
- package/dist/utils/freee-api.js +175 -0
- package/dist/utils/freee-api.js.map +1 -0
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +22 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/pkce.d.ts +12 -0
- package/dist/utils/pkce.d.ts.map +1 -0
- package/dist/utils/pkce.js +18 -0
- package/dist/utils/pkce.js.map +1 -0
- package/dist/utils/preset-loader.d.ts +3 -0
- package/dist/utils/preset-loader.d.ts.map +1 -0
- package/dist/utils/preset-loader.js +47 -0
- package/dist/utils/preset-loader.js.map +1 -0
- package/dist/utils/preset-validator.d.ts +10 -0
- package/dist/utils/preset-validator.d.ts.map +1 -0
- package/dist/utils/preset-validator.js +23 -0
- package/dist/utils/preset-validator.js.map +1 -0
- package/dist/utils/state-store.d.ts +6 -0
- package/dist/utils/state-store.d.ts.map +1 -0
- package/dist/utils/state-store.js +37 -0
- package/dist/utils/state-store.js.map +1 -0
- package/dist/utils/token-store.d.ts +6 -0
- package/dist/utils/token-store.d.ts.map +1 -0
- package/dist/utils/token-store.js +30 -0
- package/dist/utils/token-store.js.map +1 -0
- package/package.json +58 -0
- package/presets/README.md +182 -0
- package/presets/accounting/README.md +3 -0
- package/presets/accounting/construction/preset.json +309 -0
- package/presets/accounting/freelance-invoice/preset.json +261 -0
- package/presets/accounting/full-year/preset.json +1534 -0
- package/presets/accounting/it-startup/preset.json +472 -0
- package/presets/accounting/manufacturing/preset.json +333 -0
- package/presets/accounting/medical/preset.json +453 -0
- package/presets/accounting/non-profit/preset.json +375 -0
- package/presets/accounting/npo-subsidy/preset.json +454 -0
- package/presets/accounting/payroll-agency/preset.json +286 -0
- package/presets/accounting/quickstart/preset.json +917 -0
- package/presets/accounting/real-estate/preset.json +453 -0
- package/presets/accounting/restaurant/preset.json +349 -0
- package/presets/accounting/retail/preset.json +536 -0
- package/presets/accounting/sole-proprietor/preset.json +408 -0
- package/presets/advanced/multi-company/README.md +3 -0
- package/presets/advanced/multi-company/preset.json +640 -0
- package/presets/advanced/multi-period/README.md +3 -0
- package/presets/advanced/multi-period/preset.json +633 -0
- package/presets/common/depreciation/preset.json +433 -0
- package/presets/errors/consumption-tax/preset.json +136 -0
- package/presets/errors/depreciation-method/preset.json +133 -0
- package/presets/errors/duplicate-journal/preset.json +181 -0
- package/presets/errors/entertainment/preset.json +108 -0
- package/presets/errors/mixed/preset.json +171 -0
- package/presets/errors/officer-pay/preset.json +100 -0
- package/presets/errors/overdue-receivable/preset.json +157 -0
- package/presets/errors/tax-code/preset.json +140 -0
- package/presets/errors/year-end-closing/preset.json +163 -0
- package/presets/expenses/README.md +3 -0
- package/presets/expenses/quickstart/preset.json +240 -0
- package/presets/hr/README.md +3 -0
- package/presets/hr/quickstart/preset.json +443 -0
- package/presets/invoices/README.md +3 -0
- package/presets/invoices/quickstart/preset.json +246 -0
- package/presets/invoices/subscription/preset.json +263 -0
- package/presets/unclassified/quickstart/preset.json +182 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yusuke Takita
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# freee-demo-kit
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/freee-demo-kit)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://nodejs.org/)
|
|
6
|
+
|
|
7
|
+
freee サンドボックス事業所に、対話式ウィザードでデモデータを一括投入するOSS CLIツール。
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## はじめかた
|
|
12
|
+
|
|
13
|
+
### ステップ 1 — Node.js のインストール
|
|
14
|
+
|
|
15
|
+
[Node.js 公式サイト](https://nodejs.org/ja/) から **v20 以上** をインストールしてください。
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
node --version
|
|
19
|
+
# v20.x.x 以上が表示されれば OK
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### ステップ 2 — freee アプリの作成
|
|
23
|
+
|
|
24
|
+
freee-demo-kit は freee の OAuth アプリ認証情報(Client ID / Client Secret)を使って API にアクセスします。
|
|
25
|
+
|
|
26
|
+
1. [freee Developers Console](https://app.freee.co.jp/developers) を開き、「新しいアプリを作成」をクリック
|
|
27
|
+
|
|
28
|
+
2. 以下のように入力して作成:
|
|
29
|
+
|
|
30
|
+
| 項目 | 値 |
|
|
31
|
+
|------|---|
|
|
32
|
+
| アプリ名 | (任意)例: `freee-demo-kit` |
|
|
33
|
+
| アプリ種別 | **プライベートアプリ** |
|
|
34
|
+
| コールバック URL | **`http://localhost:8080/callback`** |
|
|
35
|
+
|
|
36
|
+
> ⚠️ コールバック URL が違うと認証が失敗します。必ず `http://localhost:8080/callback` を入力してください。
|
|
37
|
+
|
|
38
|
+
3. 作成後に表示される **Client ID** と **Client Secret** を控えておきます(Client Secret は一度しか表示されません)
|
|
39
|
+
|
|
40
|
+
### ステップ 3 — インストール & セットアップ
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install -g freee-demo-kit
|
|
44
|
+
fdk setup
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`fdk setup` を実行すると、対話式ウィザードが起動します。
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
freee demo kit Sandbox セットアップウィザード
|
|
51
|
+
|
|
52
|
+
◇ はじめよう!3ステップでデモデータを投入します
|
|
53
|
+
|
|
54
|
+
┌─ Step 1/3 認証情報の設定 ─────────────────────┐
|
|
55
|
+
│ freee Developers Console でアプリを作成してください │
|
|
56
|
+
└────────────────────────────────────────────────┘
|
|
57
|
+
◆ Client ID を入力してください
|
|
58
|
+
◆ Client Secret を入力してください
|
|
59
|
+
✅ .env を作成しました
|
|
60
|
+
|
|
61
|
+
┌─ Step 2/3 freee 認証 ──────────────────────────┐
|
|
62
|
+
⠋ ブラウザで認証中...
|
|
63
|
+
✅ 認証成功: 山田 太郎
|
|
64
|
+
└────────────────────────────────────────────────┘
|
|
65
|
+
|
|
66
|
+
┌─ Step 3/3 プリセット選択 ──────────────────────┐
|
|
67
|
+
❯ accounting/quickstart — 架空ITサービス業・3ヶ月分
|
|
68
|
+
accounting/restaurant — 架空居酒屋・飲食業
|
|
69
|
+
invoices/quickstart — 請求書・売掛金管理
|
|
70
|
+
...
|
|
71
|
+
└────────────────────────────────────────────────┘
|
|
72
|
+
⠋ 取引を投入中 (23/52)...
|
|
73
|
+
✅ 投入完了!
|
|
74
|
+
|
|
75
|
+
🎊 accounting/quickstart のデモデータを投入しました!
|
|
76
|
+
📊 口座 3 件
|
|
77
|
+
💰 取引 52 件
|
|
78
|
+
📝 仕訳 5 件
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 認証画面について
|
|
84
|
+
|
|
85
|
+
freee ログイン後、以下のような画面が表示されます:
|
|
86
|
+
|
|
87
|
+

|
|
88
|
+
|
|
89
|
+
アカウント内の全事業所が表示されますが、これは freee の仕様です。「許可する」をクリックして問題ありません。
|
|
90
|
+
**実際にデータが書き込まれる事業所は `fdk whoami` で確認・切り替えできます。**
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 税理士・会計事務所の方へ
|
|
95
|
+
|
|
96
|
+
顧問先のサンドボックス事業所でデモをする場合、**アプリは顧問先ではなくご自身の事務所アカウントで作成**してください。
|
|
97
|
+
|
|
98
|
+
> ⚠️ 顧問先事業所(アドバイザーとして招待された事業所)ではアプリを作成できません。
|
|
99
|
+
|
|
100
|
+
ステップ 2 のアプリ作成を**事務所アカウント**で行った後、`fdk setup` を実行してください。
|
|
101
|
+
ログイン後の事業所選択画面で、デモを行いたい**顧問先のサンドボックス事業所**を選択します。
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## コマンド一覧
|
|
106
|
+
|
|
107
|
+
| コマンド | 説明 |
|
|
108
|
+
|---------|------|
|
|
109
|
+
| `fdk setup` | **対話式ウィザード**(初回セットアップはこれ一択) |
|
|
110
|
+
| `fdk auth` | freee OAuth ログイン(ブラウザ起動) |
|
|
111
|
+
| `fdk auth --status` | 認証状態・トークン有効期限確認 |
|
|
112
|
+
| `fdk auth --logout` | トークン削除 |
|
|
113
|
+
| `fdk whoami` | 認証済みユーザー・事業所情報表示 |
|
|
114
|
+
| `fdk list` | 利用可能なプリセット一覧 |
|
|
115
|
+
| `fdk status` | 投入済みプリセット一覧と件数を表示 |
|
|
116
|
+
| `fdk load <preset>` | 指定プリセットのデータを投入 |
|
|
117
|
+
| `fdk load <preset> --dry-run` | 投入シミュレーション(変更なし) |
|
|
118
|
+
| `fdk load <preset> --force` | 投入済みでも上書き投入 |
|
|
119
|
+
| `fdk load <preset> --yes` | 確認プロンプトをスキップ(自動化向け) |
|
|
120
|
+
| `fdk load-all` | 全プリセット一括投入 |
|
|
121
|
+
| `fdk reset` | 全デモデータを削除 |
|
|
122
|
+
| `fdk reset <preset>` | 指定プリセットのデータのみ削除 |
|
|
123
|
+
| `fdk validate` | 全プリセット JSON のスキーマ・貸借検証 |
|
|
124
|
+
| `fdk validate <preset>` | 指定プリセットのみ検証 |
|
|
125
|
+
| `fdk validate --accounting` | 会計・税務ルール検証(役員報酬・税区分・交際費) |
|
|
126
|
+
| `fdk verify <preset>` | 投入データを freee API で突合確認(CI/CD 対応) |
|
|
127
|
+
| `fdk corrupt <preset>` | 指定プリセットに会計エラーを注入した破損版を生成 |
|
|
128
|
+
| `fdk corrupt <preset> --rules officer-pay,tax-code` | 注入するエラールールを指定 |
|
|
129
|
+
| `fdk corrupt <preset> --output path/to/out.json` | 破損プリセットをファイルに出力 |
|
|
130
|
+
| `fdk corrupt <preset> --dry-run` | 注入内容の確認(変更なし) |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## プリセット一覧
|
|
135
|
+
|
|
136
|
+
### 通常プリセット
|
|
137
|
+
|
|
138
|
+
#### 汎用・スタンダード
|
|
139
|
+
|
|
140
|
+
| プリセット | 内容 | 口座 | 取引 | 仕訳 |
|
|
141
|
+
|-----------|------|:----:|:----:|:----:|
|
|
142
|
+
| `accounting/quickstart` | 架空ITサービス業・3ヶ月分(売掛金入金フロー含む) | 3 | 52 | 11 |
|
|
143
|
+
| `accounting/full-year` | 架空ITサービス業・12ヶ月分・異常値パターン付き | 3 | 98 | 12 |
|
|
144
|
+
| `invoices/quickstart` | 請求書・売掛金管理(入金消込フロー含む) | 2 | 22 | 6 |
|
|
145
|
+
| `expenses/quickstart` | 経費精算(交通費・接待費・消耗品費・通信費) | 2 | 24 | 3 |
|
|
146
|
+
| `hr/quickstart` | 給与・人事(基本給・残業代・夏季賞与・社会保険・源泉税)6ヶ月分 | 1 | 34 | 20 |
|
|
147
|
+
| `unclassified/quickstart` | 銀行明細インポート直後を再現(全費用を「雑費」で仮計上) | 1 | 20 | 0 |
|
|
148
|
+
| `common/depreciation` | 固定資産・月次減価償却(PC・サーバー・エアコン) | 1 | 18 | 9 |
|
|
149
|
+
|
|
150
|
+
#### 業種別
|
|
151
|
+
|
|
152
|
+
| プリセット | 内容 | 口座 | 取引 | 仕訳 |
|
|
153
|
+
|-----------|------|:----:|:----:|:----:|
|
|
154
|
+
| `accounting/restaurant` | 架空居酒屋・食材仕入の軽減税率(8%)と酒類(10%)を分岐 | 2 | 35 | 6 |
|
|
155
|
+
| `accounting/construction` | 架空外装工事業・完成工事高・外注費3分法 | 2 | 30 | 6 |
|
|
156
|
+
| `accounting/sole-proprietor` | 架空フリーランス(個人事業主)・事業主報酬・専従者対応 | 2 | 20 | 6 |
|
|
157
|
+
| `accounting/medical` | 架空内科クリニック・保険診療(非課税)と自費診療(課税)の混在 | 2 | 24 | 6 |
|
|
158
|
+
| `accounting/real-estate` | 架空不動産賃貸業・居住用(非課税)と事務所(課税)の混在 | 1 | 24 | 6 |
|
|
159
|
+
| `accounting/retail` | 架空雑貨小売店・商品仕入・棚卸・月次在庫調整 | 2 | 30 | 6 |
|
|
160
|
+
| `accounting/it-startup` | 架空SaaS企業・サブスク収益・ソフトウェア資産計上・前受収益 | 1 | 21 | 9 |
|
|
161
|
+
| `accounting/non-profit` | 架空NPO法人・収益事業(課税)と非収益事業(非課税)の区分管理 | 1 | 18 | 6 |
|
|
162
|
+
| `accounting/manufacturing` | 架空製造業・材料費・労務費・製造間接費の三分法・仕掛品・製品勘定 | 2 | 30 | 9 |
|
|
163
|
+
| `accounting/payroll-agency` | 社労士・給与計算代行事務所・顧問料収入・社会保険料預り金処理 | 2 | 27 | 6 |
|
|
164
|
+
| `accounting/npo-subsidy` | 補助金受給NPO法人・交付決定→入金→精算・前受金・会費収入 | 2 | 24 | 6 |
|
|
165
|
+
| `accounting/freelance-invoice` | インボイス制度対応フリーランス・登録番号あり/なし混在・源泉徴収 | 2 | 24 | 6 |
|
|
166
|
+
| `invoices/subscription` | SaaS月次サブスクリプション・年次一括・前受収益の月次振替 | 2 | 24 | 6 |
|
|
167
|
+
|
|
168
|
+
#### 高度・複合
|
|
169
|
+
|
|
170
|
+
| プリセット | 内容 | 口座 | 取引 | 仕訳 |
|
|
171
|
+
|-----------|------|:----:|:----:|:----:|
|
|
172
|
+
| `advanced/multi-period` | 複数期比較・前期繰越残高・期首仕訳(財務DD・年度比較デモ用) | 3 | 32 | 9 |
|
|
173
|
+
| `advanced/multi-company` | グループ会社・親子会社間取引・連結消去仕訳(M&A PMI デモ用) | 4 | 36 | 6 |
|
|
174
|
+
|
|
175
|
+
### エラーインジェクション・プリセット
|
|
176
|
+
|
|
177
|
+
意図的に会計・税務上の誤りを含むデータセットです。`fdk validate --accounting` で検出できます。
|
|
178
|
+
|
|
179
|
+
| プリセット | 混入エラー | 検出ルール |
|
|
180
|
+
|-----------|-----------|-----------|
|
|
181
|
+
| `errors/officer-pay` | 役員報酬を「給料手当」で誤計上 | OFFICER-PAY-001 |
|
|
182
|
+
| `errors/tax-code` | 売上高・外注費・給料手当の税区分誤り | TAX-CODE-001 |
|
|
183
|
+
| `errors/entertainment` | 交際費の月次上限(¥667,000)超過 | ENTERTAINMENT-001 |
|
|
184
|
+
| `errors/mixed` | 上記3種の複合エラー | 全ルール |
|
|
185
|
+
| `errors/consumption-tax` | インボイス未登録業者の控除過大・軽減税率/非課税の誤適用 | TAX-CODE-001 |
|
|
186
|
+
| `errors/year-end-closing` | 翌期売上の前倒し計上・前払費用の誤処理・未払費用計上漏れ・仮勘定未振替 | PERIOD-001/002, ACCRUAL-001, SUSPENSE-001 |
|
|
187
|
+
| `errors/depreciation-method` | 償却方法誤り(定額↔定率)・耐用年数誤適用・少額減価償却特例の誤適用 | DEPRECIATION-001/002/003 |
|
|
188
|
+
| `errors/overdue-receivable` | 長期未回収売掛金・貸倒引当金未計上・法的貸倒の未処理・合意なし相殺 | RECEIVABLE-001/002/003 |
|
|
189
|
+
| `errors/duplicate-journal` | 同一取引の二重入力・自動仕訳と手動仕訳の重複・月次締め後の再計上 | DUPLICATE-001/002/003 |
|
|
190
|
+
|
|
191
|
+
プリセットの仕様・カスタムプリセットの作り方は [`presets/README.md`](presets/README.md) を参照してください。
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## 会計・税務バリデーション
|
|
196
|
+
|
|
197
|
+
`fdk validate --accounting` で以下のルールをチェックします。
|
|
198
|
+
|
|
199
|
+
| ルールID | 内容 | 深刻度 |
|
|
200
|
+
|---------|------|:------:|
|
|
201
|
+
| `OFFICER-PAY-001` | 役員(取締役・監査役等)の取引に「給料手当」が使われていないか | ERROR |
|
|
202
|
+
| `TAX-CODE-001` | 勘定科目ごとの許容税区分と不一致(売上高: 21/13、外注費: 34/18 等) | ERROR |
|
|
203
|
+
| `ENTERTAINMENT-001` | 交際費の月合計が ¥667,000 を超過 | WARNING |
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
fdk validate --accounting # 全プリセットを検証
|
|
207
|
+
fdk validate errors/mixed --accounting # 特定プリセットのみ
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## テストカバレッジ
|
|
213
|
+
|
|
214
|
+
`npm test` で 167 テストが実行されます。
|
|
215
|
+
|
|
216
|
+
| テストファイル | 対象 |
|
|
217
|
+
|---|---|
|
|
218
|
+
| `accounting-validator.test.ts` | 役員報酬・税区分・交際費の会計バリデーションルール |
|
|
219
|
+
| `confirm-company.test.ts` | 事業所確認プロンプト(`--yes` / y/n 入力) |
|
|
220
|
+
| `corrupt-injector.test.ts` | エラー注入ロジック(3ルール・イミュータビリティ) |
|
|
221
|
+
| `env-loader.test.ts` | `.env` 読み込み・不存在時の安全性 |
|
|
222
|
+
| `env-writer.test.ts` | `.env` 書き込み・パーミッション 600 |
|
|
223
|
+
| `freee-api.test.ts` / `freee-api-write.test.ts` | API クライアント(正常系・トークンリフレッシュ) |
|
|
224
|
+
| `freee-api-errors.test.ts` | GET/POST/DELETE エラー・トークンリフレッシュ失敗 |
|
|
225
|
+
| `no-real-names.test.ts` | 全プリセットへの実在名混入防止(ブロックリスト 25 件) |
|
|
226
|
+
| `preset-loader.test.ts` | プリセット読み込み・スキーマ検証 |
|
|
227
|
+
| `preset-validator.test.ts` | パストラバーサル防止・文字種バリデーション |
|
|
228
|
+
| `run-load.test.ts` | `runLoad` ブランチ(dryRun・force・confirmCompany・onProgress 等) |
|
|
229
|
+
| `state-store.test.ts` / `token-store.test.ts` | ファイル永続化・パーミッション・`listAllStates` |
|
|
230
|
+
| `status.test.ts` | `fdk status` 出力フォーマット |
|
|
231
|
+
| `validate-balance.test.ts` | `validateAccountingBalance` 貸借一致チェック |
|
|
232
|
+
|
|
233
|
+
> freee API との実際の通信(load / reset / verify)は統合テスト未対応です。動作確認は実際のサンドボックス事業所に対して手動で実施してください。
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## コントリビューション
|
|
238
|
+
|
|
239
|
+
コントリビューションを歓迎します。[CONTRIBUTING.md](CONTRIBUTING.md) をお読みください。
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
git clone https://github.com/tackeyy/freee-demo-kit.git
|
|
243
|
+
cd freee-demo-kit
|
|
244
|
+
npm install
|
|
245
|
+
npm test
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## よくあるエラーと解決方法
|
|
251
|
+
|
|
252
|
+
### `fdk auth` / `fdk setup` 後のブラウザに「必須パラメータが不足しているか...」と表示される
|
|
253
|
+
|
|
254
|
+
**原因:** freee アプリのコールバック URL が正しく設定されていません。
|
|
255
|
+
|
|
256
|
+
**解決方法:**
|
|
257
|
+
1. [freee Developers Console](https://app.secure.freee.co.jp/developers/applications) を開く
|
|
258
|
+
2. 該当アプリをクリックして編集画面を開く
|
|
259
|
+
3. コールバック URL を `http://localhost:8080/callback` に変更して保存する
|
|
260
|
+
4. `fdk setup` または `fdk auth` を再実行する
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
### `fdk load` で「勘定科目が見つかりません」が表示され、取引/仕訳が一部投入されない
|
|
265
|
+
|
|
266
|
+
**原因:** freee の勘定科目はアカウント種別(法人/個人事業主)やプランによって異なります。業種別プリセット(`accounting/medical` など)が使用する科目が、お使いの事業所に存在しない場合に発生します。
|
|
267
|
+
|
|
268
|
+
**対処方法:**
|
|
269
|
+
- `fdk dry-run <preset>` で投入予定の科目名を事前確認する
|
|
270
|
+
- `fdk validate <preset>` でスキーマチェックを実施する
|
|
271
|
+
- freee の「勘定科目の設定」から対象科目を追加する
|
|
272
|
+
|
|
273
|
+
> **個人事業主プリセット(`accounting/sole-proprietor`)について:**
|
|
274
|
+
> `事業主貸`・`専従者給与` などの科目は個人事業主専用です。法人アカウントでは `役員報酬`・`給料手当` に置き換えて投入されます。
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## ライセンス
|
|
279
|
+
|
|
280
|
+
[MIT](LICENSE)
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { loadEnv } from './utils/env-loader.js';
|
|
3
|
+
loadEnv(); // .env ファイルがあれば自動読み込み(なくてもエラーにならない)
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import { authCommand } from './commands/auth.js';
|
|
6
|
+
import { whoamiCommand } from './commands/whoami.js';
|
|
7
|
+
import { listCommand } from './commands/list.js';
|
|
8
|
+
import { loadCommand } from './commands/load.js';
|
|
9
|
+
import { loadAllCommand } from './commands/load-all.js';
|
|
10
|
+
import { resetCommand } from './commands/reset.js';
|
|
11
|
+
import { validateCommand } from './commands/validate.js';
|
|
12
|
+
import { dryRunCommand } from './commands/dry-run.js';
|
|
13
|
+
import { verifyCommand } from './commands/verify.js';
|
|
14
|
+
import { statusCommand } from './commands/status.js';
|
|
15
|
+
import { setupCommand } from './commands/setup.js';
|
|
16
|
+
import { corruptCommand } from './commands/corrupt.js';
|
|
17
|
+
const program = new Command();
|
|
18
|
+
program
|
|
19
|
+
.name('fdk')
|
|
20
|
+
.description('freee demo kit — Load demo data into your freee test company')
|
|
21
|
+
.version('0.1.0');
|
|
22
|
+
program.addCommand(setupCommand); // ウィザード(最初に登録 = --help で先頭に表示)
|
|
23
|
+
program.addCommand(authCommand);
|
|
24
|
+
program.addCommand(whoamiCommand);
|
|
25
|
+
program.addCommand(listCommand);
|
|
26
|
+
program.addCommand(loadCommand);
|
|
27
|
+
program.addCommand(loadAllCommand);
|
|
28
|
+
program.addCommand(resetCommand);
|
|
29
|
+
program.addCommand(validateCommand);
|
|
30
|
+
program.addCommand(dryRunCommand);
|
|
31
|
+
program.addCommand(verifyCommand);
|
|
32
|
+
program.addCommand(statusCommand);
|
|
33
|
+
program.addCommand(corruptCommand);
|
|
34
|
+
program.parse();
|
|
35
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,CAAC,CAAC,oCAAoC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CAAC,8DAA8D,CAAC;KAC3E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAE,+BAA+B;AAClE,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AAEnC,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,WAAW,SAoDpB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { loadTokens, clearTokens, isTokenExpired } from '../utils/token-store.js';
|
|
3
|
+
import { FreeeApiClient } from '../utils/freee-api.js';
|
|
4
|
+
import { error as logError } from '../utils/logger.js';
|
|
5
|
+
import { runOAuthPkceFlow } from '../utils/auth-flow.js';
|
|
6
|
+
export const authCommand = new Command('auth')
|
|
7
|
+
.description('Authenticate with freee via OAuth 2.0')
|
|
8
|
+
.option('--status', 'Show current authentication status')
|
|
9
|
+
.option('--logout', 'Remove stored credentials')
|
|
10
|
+
.action(async (options) => {
|
|
11
|
+
if (options.status) {
|
|
12
|
+
const tokens = await loadTokens();
|
|
13
|
+
if (!tokens) {
|
|
14
|
+
console.log('Not authenticated. Run `fdk auth` to authenticate.');
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const expired = isTokenExpired(tokens);
|
|
18
|
+
const expiresAt = new Date(tokens.expires_at).toLocaleString('ja-JP');
|
|
19
|
+
console.log(`Authentication status:`);
|
|
20
|
+
console.log(` Token: ${expired ? '⚠️ Expired' : '✅ Valid'}`);
|
|
21
|
+
console.log(` Expires at: ${expiresAt}`);
|
|
22
|
+
if (tokens.company_id) {
|
|
23
|
+
console.log(` Company ID: ${tokens.company_id}`);
|
|
24
|
+
}
|
|
25
|
+
if (!expired) {
|
|
26
|
+
try {
|
|
27
|
+
const client = new FreeeApiClient();
|
|
28
|
+
const me = await client.getMe();
|
|
29
|
+
console.log(` User: ${me.display_name} (${me.email})`);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
console.log(' (Could not fetch user info)');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (options.logout) {
|
|
38
|
+
await clearTokens();
|
|
39
|
+
console.log('✅ Logged out. Credentials removed.');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
console.log('\nOpening browser for freee authentication...');
|
|
43
|
+
try {
|
|
44
|
+
const result = await runOAuthPkceFlow((url) => {
|
|
45
|
+
console.log(`If the browser does not open, visit:\n ${url}\n`);
|
|
46
|
+
});
|
|
47
|
+
console.log(`\n✅ Authenticated as: ${result.displayName} (${result.email})`);
|
|
48
|
+
if (result.companies.length > 0) {
|
|
49
|
+
console.log(` Companies available: ${result.companies.map(c => `${c.name} (ID:${c.id})`).join(', ')}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
logError(String(err));
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"corrupt.d.ts","sourceRoot":"","sources":["../../src/commands/corrupt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBpC,eAAO,MAAM,cAAc,SA6DvB,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import pc from 'picocolors';
|
|
5
|
+
import { loadPreset } from '../utils/preset-loader.js';
|
|
6
|
+
import { runCorrupt } from '../utils/corrupt-injector.js';
|
|
7
|
+
const VALID_RULES = ['officer-pay', 'tax-code', 'entertainment'];
|
|
8
|
+
function parseRules(input) {
|
|
9
|
+
const parts = input.split(',').map(s => s.trim());
|
|
10
|
+
for (const part of parts) {
|
|
11
|
+
if (!VALID_RULES.includes(part)) {
|
|
12
|
+
console.error(pc.red(`不明なルール: "${part}"`));
|
|
13
|
+
console.error(`有効なルール: ${VALID_RULES.join(', ')}`);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return parts;
|
|
18
|
+
}
|
|
19
|
+
export const corruptCommand = new Command('corrupt')
|
|
20
|
+
.description('Inject accounting errors into a preset for training/testing purposes')
|
|
21
|
+
.argument('<preset>', 'Target preset (e.g. accounting/quickstart)')
|
|
22
|
+
.option('--rules <rules>', `Comma-separated list of rules to inject: ${VALID_RULES.join(', ')}`, 'officer-pay,tax-code,entertainment')
|
|
23
|
+
.option('--output <path>', 'Write corrupted preset to a file instead of stdout')
|
|
24
|
+
.option('--dry-run', 'Show what would be injected without writing output')
|
|
25
|
+
.action(async (presetArg, options) => {
|
|
26
|
+
const rules = parseRules(options.rules);
|
|
27
|
+
let definition;
|
|
28
|
+
try {
|
|
29
|
+
definition = await loadPreset(presetArg);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
console.error(pc.red(`プリセット読み込みエラー: ${String(err)}`));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
const corruptOptions = { rules };
|
|
36
|
+
const { preset: corrupted, manifest } = runCorrupt(definition, corruptOptions);
|
|
37
|
+
// --dry-run: 変更内容だけ表示して終了
|
|
38
|
+
if (options.dryRun) {
|
|
39
|
+
console.log(pc.bold(`\n🔍 fdk corrupt ${presetArg} --rules ${rules.join(',')}`));
|
|
40
|
+
console.log(pc.dim('(dry-run: 実際には変更しません)\n'));
|
|
41
|
+
if (manifest.length === 0) {
|
|
42
|
+
console.log(pc.yellow(' 注入できるエラーが見つかりませんでした。'));
|
|
43
|
+
console.log(pc.dim(' ヒント: 対象プリセットに役員報酬・売上高・外注費・交際費が含まれているか確認してください。'));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
for (const item of manifest) {
|
|
47
|
+
console.log(` ${pc.red('●')} [${item.rule}] ${item.location}`);
|
|
48
|
+
console.log(` ${pc.dim(item.description)}`);
|
|
49
|
+
console.log(` ${pc.cyan('修正:')}} ${item.expected_fix}`);
|
|
50
|
+
}
|
|
51
|
+
console.log(`\n 合計 ${pc.bold(String(manifest.length))} 件のエラーを注入予定`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// error_manifest を追記
|
|
55
|
+
corrupted.error_manifest = manifest;
|
|
56
|
+
const json = JSON.stringify(corrupted, null, 2);
|
|
57
|
+
if (options.output) {
|
|
58
|
+
const outPath = path.resolve(process.cwd(), options.output);
|
|
59
|
+
await fs.mkdir(path.dirname(outPath), { recursive: true });
|
|
60
|
+
await fs.writeFile(outPath, json, 'utf-8');
|
|
61
|
+
console.log(pc.green(`✅ 破損プリセットを書き出しました: ${options.output}`));
|
|
62
|
+
console.log(pc.dim(` 注入エラー: ${manifest.length} 件`));
|
|
63
|
+
for (const item of manifest) {
|
|
64
|
+
console.log(pc.dim(` • [${item.rule}] ${item.location}`));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// stdout に JSON を出力
|
|
69
|
+
process.stdout.write(json + '\n');
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
//# sourceMappingURL=corrupt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"corrupt.js","sourceRoot":"","sources":["../../src/commands/corrupt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dry-run.d.ts","sourceRoot":"","sources":["../../src/commands/dry-run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,aAAa,SA0DtB,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { validatePresetName } from '../utils/preset-validator.js';
|
|
3
|
+
import { loadPreset } from '../utils/preset-loader.js';
|
|
4
|
+
import { error as logError } from '../utils/logger.js';
|
|
5
|
+
export const dryRunCommand = new Command('dry-run')
|
|
6
|
+
.description('Simulate loading a preset without making API calls')
|
|
7
|
+
.argument('<preset>', 'Preset name to simulate (e.g. accounting/quickstart)')
|
|
8
|
+
.action(async (preset) => {
|
|
9
|
+
try {
|
|
10
|
+
validatePresetName(preset);
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
logError(String(err));
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
let definition;
|
|
17
|
+
try {
|
|
18
|
+
definition = await loadPreset(preset);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
logError(String(err));
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
const { data, expected, name: presetName, description } = definition;
|
|
25
|
+
console.log(`\n🔍 ドライラン: ${presetName}`);
|
|
26
|
+
console.log(` ${description}\n`);
|
|
27
|
+
console.log(`口座 (${data.walletables.length}件):`);
|
|
28
|
+
console.log('┌─────────────────────┬──────────────────────────────────┐');
|
|
29
|
+
console.log('│ タイプ │ 名称 │');
|
|
30
|
+
console.log('├─────────────────────┼──────────────────────────────────┤');
|
|
31
|
+
for (const w of data.walletables) {
|
|
32
|
+
const type = w.type.padEnd(19);
|
|
33
|
+
const name = w.name.padEnd(32);
|
|
34
|
+
console.log(`│ ${type} │ ${name} │`);
|
|
35
|
+
}
|
|
36
|
+
console.log('└─────────────────────┴──────────────────────────────────┘');
|
|
37
|
+
console.log(`\n取引 (${data.deals.length}件):`);
|
|
38
|
+
console.log('┌────────────┬─────────┬──────────────────────┬──────────────┐');
|
|
39
|
+
console.log('│ 日付 │ 種別 │ 取引先 │ 金額 │');
|
|
40
|
+
console.log('├────────────┼─────────┼──────────────────────┼──────────────┤');
|
|
41
|
+
for (const d of data.deals) {
|
|
42
|
+
const total = d.details.reduce((s, x) => s + x.amount, 0);
|
|
43
|
+
const date = d.issue_date;
|
|
44
|
+
const type = (d.type === 'income' ? '収入' : '支出').padEnd(5);
|
|
45
|
+
const partner = (d.partner_name ?? '').slice(0, 18).padEnd(20);
|
|
46
|
+
const amount = `¥${total.toLocaleString()}`.padStart(12);
|
|
47
|
+
console.log(`│ ${date} │ ${type} │ ${partner} │ ${amount} │`);
|
|
48
|
+
}
|
|
49
|
+
console.log('└────────────┴─────────┴──────────────────────┴──────────────┘');
|
|
50
|
+
console.log(`\n手動仕訳 (${data.manualJournals.length}件):`);
|
|
51
|
+
for (const mj of data.manualJournals) {
|
|
52
|
+
const debitTotal = mj.details.filter(d => d.entry_side === 'debit').reduce((s, x) => s + x.amount, 0);
|
|
53
|
+
console.log(` ${mj.issue_date} — ${mj.details.length}明細 借方合計: ¥${debitTotal.toLocaleString()}`);
|
|
54
|
+
}
|
|
55
|
+
console.log(`\n─────────────────────────────────`);
|
|
56
|
+
console.log(`期待値: 口座${expected.walletables}件, 取引${expected.deals}件, 仕訳${expected.manualJournals}件`);
|
|
57
|
+
console.log('\n実際に投入するには: fdk load ' + preset);
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=dry-run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dry-run.js","sourceRoot":"","sources":["../../src/commands/dry-run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8CpC,eAAO,MAAM,WAAW,SAoBpB,CAAC"}
|