月次予算モデル¶
関連: Discord の使い方 / Grafana / テーブル定義 / src/finance_manager/taxonomy.py
考え方(固定費/変動枠/別枠貯金)¶
1. 前月の給与合計 (incomes.category = '給与')
= budget_months.ceiling_yen
2. − 固定貯金 (budget_months.savings_yen)
3. − 固定費マスタ合計 (fixed_cost_items.active の月額)
4. = 変動に使える枠 (variable_pool_yen)
5. 変動カテゴリへ割当 (budget_month_categories)
5a. 月初確定: 未割当余り → 別枠貯金 (surplus_ledger / month_unallocated)
確定後に上限や枠を直したら、同じ行の額を載せ直す(INSERT したまま放置しない)
「確定取り消し」でこの行を消し、status を draft に戻す
5b. 月末締め: (変動枠 − 5aで計上済み − 変動実支出)の余り → 別枠貯金 (month_end_remainder)
余りが 0 以下(超過)なら別枠へは 1 円も移らない。month_end_surplus_yen も 0 になる
臨時収入とボーナスは 予算上限に使わない。
固定貯金(savings_yen)と 別枠貯金(surplus_ledger)を別プールに置く。
上限は前月の給与
今月(例: 2026-08)の上限は、前月(2026-07) の category=給与 合計から取る。
今月受け取った給料は 来月 の上限に効く。
draft 中は前月給与と固定費マスタから上限/変動枠を取り直す。
confirmed / closed 後は天井の自動更新はしない。
確定後に上限が違っていたら Discord で「上限を○円にして」(set_budget の ceiling_yen)。未割当の別枠額も載せ直す。
「確定取り消し」は confirmed → draft だけ(closed は不可)。
前月給与が無いときだけ budget_settings.monthly_income_yen(例: 280000)にフォールバックする。
確定すると「その他」の枠は 0 になる
draft 中の「その他」枠は 変動枠 − 明示枠の合計、つまり未割当ぶんである。
確定(5a)でその額は別枠貯金へ移るので、確定後の「その他」枠は 0 になる。
以降「その他」に落ちた支出はそのまま超過になり、月末締め(5b)で別枠へ移る額を削る。
「その他」に枠は付けられない(taxonomy.VARIABLE_LIMIT_CATEGORIES から除外)。
その他が積もるなら、その支出を食費/日用品/趣味/医療のどれかに振り直す。
例(2026-08): 変動枠 111,260、明示枠合計 108,000、未割当 3,260 を 5a で別枠へ。 実支出 108,117(うちその他 5,300)で 108,000 − 108,117 = −117 となり、5b では 0 円。 その他が無ければ 5,183 円が別枠へ移っていた。
| 経路 | 役割 |
|---|---|
| Discord | 月初の確定、固定費、枠変更、月末締め、支出直後の残り、今月の内訳と訂正 |
| Grafana | 給与→固定→変動の内訳、変動消化、「別枠貯金」 |
テーブル¶
| テーブル | 内容 |
|---|---|
budget_months |
月ヘッダ(ceiling / savings / fixed_costs / variable_pool / status) |
budget_month_categories |
変動カテゴリのみの枠 |
fixed_cost_items |
固定費マスタ(name, monthly_yen, expense_category, active) |
surplus_ledger |
「別枠貯金」の入出金(month_unallocated / month_end_remainder / manual) |
budget_settings / category_budgets |
初回フォールバック、旧 seed 用 |
定義:
sql/007_budget_months.sqlsql/011_fixed_and_surplus.sql
Bot 起動時に自動適用する。
当月行が無ければ、前月給与、固定費、前月枠(または旧 seed)から draft を作る。
固定費実績の簡易判定: fixed_cost_items.expense_category が設定されていれば、同名の expenses.category は「変動枠」の消化に入れない。
未設定ならマスタは「引く額」だけであり、実績は手動確認する。
支出の大分類(taxonomy.py):
- 「変動枠」: 食費 / 日用品 / 趣味 / 医療(その他は自動)
- 固定の実績: 家賃 / 通信 / 光熱費 / 仕送り / サブスク
- 趣味に含めるもの: 衣服、車(ガソリン、高速)、帰省、交際
- 旧分類: 娯楽、衣服、交通 → 趣味、教育 → その他(
sql/010_remap_expense_categories.sql)
Discord での運用¶
- 月初(status=draft): 前月給与、固定貯金、固定費、変動枠、割当、未割当を表示
- 「このままで」→
confirm_budget(未割当 → 別枠貯金) - 「貯金6万、食費7万にして」「上限を30万に」→
set_budget(確定済みでも上限・枠を直せる。未割当の別枠額は載せ直す) 3a. 「確定取り消し」→reopen_budget(confirmed→draft。別枠の月初未割当を戻す。closedは不可) - 「家賃を8万に」→
set_fixed_cost(マスタ更新。draft なら変動枠を再計算) - 支出を記録するたびに【変動の残り】が付く
- 週目安(月曜始まり): 週開始時点の月残りを日数で按分する。
月残り × 今週の月内日数 ÷ 週開始から月末までの日数。週の余りは翌週以降へ再配分される 残り「週数」で割らない。8/31 が月曜のような 1 日しかない週が 1 週ぶんを取り、その日だけ枠が跳ね上がるためである - 今日目安: 今朝の今日枠 − 今日の使用。週に余裕があれば余りを残日へ再配分し、週超過済みなら週枠÷今週日数を今日枠とする(週の赤字は今日枠に載せない)
- 頭打ちは無い: 使い残しは繰り越すので、使い控えた月は月末の日枠が大きくなる。月の最終日は「月残り = その週の枠 = その日の枠」になる(残っている額はそのまま使える額である。使わなければ
close_monthで別枠貯金へ回る) - 「今日いくら」「食費の残り」→ 内訳ではなく【変動の残り】(
show_remaining) - 使いすぎると「超過」と出る。月の残÷残日数の単純ペースではない
- 「月末締め」→
close_month(変動実残 → 別枠、status=closed) 超過していれば別枠へは 0 円。文面は実際に移した額を出す(format_close_month_note) - 「別枠貯金いくら」→
show_surplus - 「今月の内訳」→ カテゴリ合計と明細。続けて自然言語で分類を直せる
既存データからの移行¶
sql/budget_seed.example.sql に 2026-08 スプシの実数(固定費、変動枠)が入っている。
VM で psql -f sql/budget_seed.example.sql したあと Bot を再起動する。
通信、光熱、家賃などは fixed_cost_items 側。
budget_month_categories には変動だけ残す。
draft 中なら seed が当月の変動枠も上書きする。
confirmed 以降は Discord で直す。
欲しいもの/大型出費(プラスアルファ)¶
欲しいものと大型出費は、「固定貯金」「別枠貯金」とは別のプールに置く。
wishlist_items… 欲しいものplanned_expenses… 期限付き大型出費
Discord 例: 「欲しいもの Switch 3万」「旅行で8万、期限9/30」
PayPay 通知(後段)¶
INGEST_BEARER_TOKEN をセットすると同一プロセスで POST /ingest/notifications が立つ。
支出化したあと、手動 Discord と同じ残り返信をチャンネルへ送る。
詳細は Tasker / Cloudflare。