T1: restructure to domain/application/infrastructure + schema version 1

- Move cashflow_model/ -> domain/
- Move engine/ -> application/
- Move cli/, sync/, ai/ -> infrastructure/
- Update all imports across codebase and tests
- Add version=1 to FinancialModel.to_dict() with migration hook in from_dict
- Update pyproject.toml: cf entry point and packages.find

Tests: 63/63 pass.
This commit is contained in:
2026-10-08 16:34:10 +03:00
parent 12611edd6f
commit feb77ef217
32 changed files with 1945 additions and 109 deletions
+69
View File
@@ -0,0 +1,69 @@
import json
from infrastructure.ai import prompts
from domain import CurrencyConverter, FinancialModel
from application.forecast import ForecastService
class AssistantError(Exception):
pass
class AssistantService:
def __init__(
self,
model: FinancialModel,
converter: CurrencyConverter | None = None,
display_currency: str | None = None,
):
self.model = model
self.converter = converter or CurrencyConverter(model.exchange_rates)
self.display_currency = display_currency or model.base_currency
def analyze(self, months: int = 12) -> dict:
forecast_service = ForecastService(self.model)
forecast_result = forecast_service.forecast_cashflow(months)
summary = forecast_service.summary(months)
prompt = prompts.format_context(
model_json=json.dumps(self.model.to_dict(), indent=2, ensure_ascii=False),
forecast_json=json.dumps(forecast_result, indent=2, ensure_ascii=False),
months=months,
base_currency=self.model.base_currency,
display_currency=self.display_currency,
)
return {
"prompt": prompt,
"summary": summary,
"forecast": forecast_result,
"ai_response": None,
}
def advice(self, question: str, months: int = 12) -> dict:
forecast_service = ForecastService(self.model)
forecast_result = forecast_service.forecast_cashflow(months)
prompt = prompts.ADVICE_PROMPT.format(
model_json=json.dumps(self.model.to_dict(), indent=2, ensure_ascii=False),
forecast_json=json.dumps(forecast_result, indent=2, ensure_ascii=False),
question=question,
base_currency=self.model.base_currency,
display_currency=self.display_currency,
)
return {
"prompt": prompt,
"ai_response": None,
}
def compare_scenarios(self, scenarios_json: str) -> dict:
prompt = prompts.SCENARIO_COMPARISON_PROMPT.format(
scenarios_json=scenarios_json,
base_currency=self.model.base_currency,
display_currency=self.display_currency,
)
return {
"prompt": prompt,
"ai_response": None,
}