feat: book monthly AI-plan invoices as facts and commitments
Add ai-plan ingest that stores one current booked fact per provider-account × plan × period. Subscriptions become recurring commitments; usage top-ups do not. Session-level rows are rejected.
This commit is contained in:
parent
38d0bf21c9
commit
ce4f791a63
11 changed files with 511 additions and 5 deletions
|
|
@ -8,7 +8,11 @@ from pathlib import Path
|
|||
from fin_hub.coupling.canon import emit_viability_alert
|
||||
from fin_hub.coupling.dev_hub import emit_resource_pressure
|
||||
from fin_hub.services.alerts import evaluate_budget_alerts
|
||||
from fin_hub.services.ledger import get_opening_balance, monthly_burn_series
|
||||
from fin_hub.services.ledger import (
|
||||
get_opening_balance,
|
||||
list_current_commitments,
|
||||
monthly_burn_series,
|
||||
)
|
||||
from fin_hub.services.runway import compute_runway
|
||||
|
||||
|
||||
|
|
@ -30,6 +34,13 @@ def evaluate_runway(
|
|||
|
||||
effective_currency = currency or stored_currency
|
||||
burns = monthly_burn_series(ledger_path=ledger_path, currency=effective_currency)
|
||||
commitments = list_current_commitments(
|
||||
ledger_path=ledger_path, currency=effective_currency
|
||||
)
|
||||
if not burns:
|
||||
committed = sum((float(item.amount) for item in commitments), 0.0)
|
||||
if committed > 0:
|
||||
burns = [committed]
|
||||
runway = compute_runway(
|
||||
current_balance=balance,
|
||||
monthly_burns=burns,
|
||||
|
|
@ -42,6 +53,7 @@ def evaluate_runway(
|
|||
"runway": runway.as_dict(),
|
||||
"alerts": [alert.as_dict() for alert in alerts],
|
||||
"monthly_burns": burns,
|
||||
"commitments": [item.as_dict() for item in commitments],
|
||||
"ledger_path": str(ledger_path.resolve()),
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue