Initial commit: MyMidas personal finance tracker
Full-stack self-hosted finance app with FastAPI backend and React frontend. Features: - Accounts, transactions, budgets, investments with GBP base currency - CSV import with auto-detection for 10 UK bank formats - ML predictions: spending forecast, net worth projection, Monte Carlo - 7 selectable themes (Obsidian, Arctic, Midnight, Vault, Terminal, Synthwave, Ledger) - Receipt/document attachments on transactions (JPEG, PNG, WebP, PDF) - AES-256-GCM field encryption, RS256 JWT, TOTP 2FA, RLS, audit log - Encrypted nightly backups + key rotation script - Mobile-responsive layout with bottom nav Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
61a7884ee5
127 changed files with 13323 additions and 0 deletions
109
frontend/src/api/predictions.ts
Normal file
109
frontend/src/api/predictions.ts
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
import { api } from "./client";
|
||||
|
||||
export interface CategoryForecast {
|
||||
category_id: string;
|
||||
category_name: string;
|
||||
monthly_avg: number;
|
||||
actuals: { date: string; amount: number }[];
|
||||
forecast: { date: string; amount: number; lower: number; upper: number }[];
|
||||
}
|
||||
|
||||
export interface SpendingForecastResponse {
|
||||
categories: CategoryForecast[];
|
||||
}
|
||||
|
||||
export interface NetWorthProjectionResponse {
|
||||
history: { date: string; value: number }[];
|
||||
projections: {
|
||||
conservative: { date: string; value: number }[];
|
||||
base: { date: string; value: number }[];
|
||||
optimistic: { date: string; value: number }[];
|
||||
};
|
||||
insufficient_data: boolean;
|
||||
}
|
||||
|
||||
export interface PercentilePath {
|
||||
date: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
export interface MonteCarloResponse {
|
||||
dates: string[];
|
||||
percentiles: {
|
||||
p10: PercentilePath[];
|
||||
p25: PercentilePath[];
|
||||
p50: PercentilePath[];
|
||||
p75: PercentilePath[];
|
||||
p90: PercentilePath[];
|
||||
};
|
||||
current_value: number;
|
||||
expected_value: number;
|
||||
probability_of_gain: number;
|
||||
insufficient_data: boolean;
|
||||
}
|
||||
|
||||
export interface BudgetForecastItem {
|
||||
category_id: string;
|
||||
category_name: string;
|
||||
budget_amount: number;
|
||||
spent_so_far: number;
|
||||
forecast_month_total: number;
|
||||
daily_velocity: number;
|
||||
probability_overspend: number;
|
||||
days_remaining: number;
|
||||
}
|
||||
|
||||
export interface BudgetForecastResponse {
|
||||
forecasts: BudgetForecastItem[];
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export interface CashFlowDay {
|
||||
date: string;
|
||||
balance: number;
|
||||
avg_inflow: number;
|
||||
avg_outflow: number;
|
||||
negative_risk: boolean;
|
||||
}
|
||||
|
||||
export interface CashFlowResponse {
|
||||
current_balance: number;
|
||||
avg_daily_inflow: number;
|
||||
avg_daily_outflow: number;
|
||||
forecast: CashFlowDay[];
|
||||
negative_risk_days: string[];
|
||||
history_days: number;
|
||||
}
|
||||
|
||||
export async function getSpendingForecast(): Promise<SpendingForecastResponse> {
|
||||
const res = await api.get("/predictions/spending");
|
||||
return res.data;
|
||||
}
|
||||
|
||||
export async function getNetWorthProjection(years = 5): Promise<NetWorthProjectionResponse> {
|
||||
const res = await api.get("/predictions/net-worth", { params: { years } });
|
||||
return res.data;
|
||||
}
|
||||
|
||||
export async function postMonteCarlo(params: {
|
||||
years?: number;
|
||||
n_simulations?: number;
|
||||
annual_contribution?: number;
|
||||
}): Promise<MonteCarloResponse> {
|
||||
const res = await api.post("/predictions/monte-carlo", {
|
||||
years: params.years ?? 5,
|
||||
n_simulations: params.n_simulations ?? 1000,
|
||||
annual_contribution: params.annual_contribution ?? 0,
|
||||
});
|
||||
return res.data;
|
||||
}
|
||||
|
||||
export async function getBudgetForecast(): Promise<BudgetForecastResponse> {
|
||||
const res = await api.get("/predictions/budget-forecast");
|
||||
return res.data;
|
||||
}
|
||||
|
||||
export async function getCashFlowForecast(): Promise<CashFlowResponse> {
|
||||
const res = await api.get("/predictions/cashflow");
|
||||
return res.data;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue