mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-05-19 10:28:48 +02:00
Add budget module and push notifications for transactions
All checks were successful
Deploy to VPS / deploy (push) Successful in 34s
All checks were successful
Deploy to VPS / deploy (push) Successful in 34s
Budget: recurring items CRUD, yearly/monthly projections with no-double-count logic, and full UI (overview, monthly detail, recurring items manager). Push notifications: Web Push via VAPID keys, triggered on transaction creation from n8n. Includes service worker handlers, frontend subscription flow, and a test button on the Dashboard (temporary). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -103,3 +103,125 @@ export interface Transaction {
|
||||
category: Category | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
// --- Budget / Recurring Items ---
|
||||
|
||||
export type RecurringItemType = 'INCOME' | 'EXPENSE' | 'SAVINGS';
|
||||
export type RecurringFrequency = 'WEEKLY' | 'MONTHLY' | 'QUARTERLY' | 'BIANNUAL' | 'YEARLY';
|
||||
|
||||
export interface RecurringItem {
|
||||
id: number;
|
||||
name: string;
|
||||
amount: number;
|
||||
currency: string;
|
||||
item_type: RecurringItemType;
|
||||
frequency: RecurringFrequency;
|
||||
day_of_month: number | null;
|
||||
month_of_year: number | null;
|
||||
override_amounts: Record<string, number> | null;
|
||||
category_id: number | null;
|
||||
is_active: boolean;
|
||||
notes: string | null;
|
||||
created_at: string;
|
||||
category: Category | null;
|
||||
}
|
||||
|
||||
export interface RecurringItemCreate {
|
||||
name: string;
|
||||
amount: number;
|
||||
currency?: string;
|
||||
item_type: RecurringItemType;
|
||||
frequency?: RecurringFrequency;
|
||||
day_of_month?: number | null;
|
||||
month_of_year?: number | null;
|
||||
override_amounts?: Record<string, number> | null;
|
||||
category_id?: number | null;
|
||||
is_active?: boolean;
|
||||
notes?: string | null;
|
||||
}
|
||||
|
||||
export interface RecurringItemUpdate {
|
||||
name?: string;
|
||||
amount?: number;
|
||||
currency?: string;
|
||||
item_type?: RecurringItemType;
|
||||
frequency?: RecurringFrequency;
|
||||
day_of_month?: number | null;
|
||||
month_of_year?: number | null;
|
||||
override_amounts?: Record<string, number> | null;
|
||||
category_id?: number | null;
|
||||
is_active?: boolean;
|
||||
notes?: string | null;
|
||||
}
|
||||
|
||||
export interface RecurringItemDetail {
|
||||
id: number;
|
||||
name: string;
|
||||
amount: number;
|
||||
projected_amount: number | null;
|
||||
used_actual: boolean;
|
||||
item_type: string;
|
||||
frequency: string;
|
||||
category_name: string | null;
|
||||
category_id: number | null;
|
||||
}
|
||||
|
||||
export interface ActualsBySource {
|
||||
source: string;
|
||||
total_compra: number;
|
||||
total_devolucion: number;
|
||||
net: number;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface MonthlyProjection {
|
||||
month: number;
|
||||
year: number;
|
||||
projected_income: number;
|
||||
projected_fixed_expenses: number;
|
||||
projected_savings: number;
|
||||
actual_credit_card: number;
|
||||
actual_cash: number;
|
||||
actual_transfers: number;
|
||||
uncovered_actual: number;
|
||||
gran_total_egresos: number;
|
||||
net_balance: number;
|
||||
}
|
||||
|
||||
export interface YearlyProjection {
|
||||
year: number;
|
||||
months: MonthlyProjection[];
|
||||
annual_income: number;
|
||||
annual_expenses: number;
|
||||
annual_savings: number;
|
||||
annual_net: number;
|
||||
}
|
||||
|
||||
export interface MonthlyDetail {
|
||||
year: number;
|
||||
month: number;
|
||||
income_items: RecurringItemDetail[];
|
||||
expense_items: RecurringItemDetail[];
|
||||
savings_items: RecurringItemDetail[];
|
||||
actuals_by_source: ActualsBySource[];
|
||||
total_projected_income: number;
|
||||
total_projected_expenses: number;
|
||||
total_projected_savings: number;
|
||||
uncovered_actual: number;
|
||||
gran_total_egresos: number;
|
||||
net_balance: number;
|
||||
}
|
||||
|
||||
// Budget API functions
|
||||
export const getRecurringItems = (params?: { item_type?: string; is_active?: boolean }) =>
|
||||
api.get<RecurringItem[]>('/budget/recurring', { params });
|
||||
export const createRecurringItem = (data: RecurringItemCreate) =>
|
||||
api.post<RecurringItem>('/budget/recurring', data);
|
||||
export const updateRecurringItem = (id: number, data: RecurringItemUpdate) =>
|
||||
api.patch<RecurringItem>(`/budget/recurring/${id}`, data);
|
||||
export const deleteRecurringItem = (id: number) =>
|
||||
api.delete(`/budget/recurring/${id}`);
|
||||
export const getYearlyProjection = (year: number) =>
|
||||
api.get<YearlyProjection>(`/budget/projection/${year}`);
|
||||
export const getMonthlyDetail = (year: number, month: number) =>
|
||||
api.get<MonthlyDetail>(`/budget/month/${year}/${month}`);
|
||||
|
||||
Reference in New Issue
Block a user