242 lines
9.9 KiB
Markdown
242 lines
9.9 KiB
Markdown
# Recommended Frontend Functions (API Client)
|
|
|
|
This document lists recommended frontend functions to implement against the backend REST API.
|
|
|
|
Base URL:
|
|
|
|
- Development: `http://localhost:3000/api/v1`
|
|
|
|
Notes:
|
|
|
|
- Authentication uses **HTTP-only cookies**. The frontend should use `fetch`/Axios with `credentials: 'include'`.
|
|
- All endpoints below are assumed to require auth unless explicitly public (e.g. register/login).
|
|
- Suggested return types are illustrative; align with the backend DTO/response shapes.
|
|
|
|
## Shared HTTP Helpers
|
|
|
|
- **`apiFetch<T>(path: string, options?: RequestInit): Promise<T>`**
|
|
- Sets `baseUrl`, JSON headers, `credentials: 'include'`, error normalization.
|
|
|
|
- **`parseApiError(e: unknown): { messageRu: string; status?: number; details?: any }`**
|
|
- Normalizes backend error responses.
|
|
|
|
- **`toQueryString(params: Record<string, any>): string`**
|
|
- For query endpoints (transactions search, analytics ranges, etc.).
|
|
|
|
## Auth (Session/Cookies)
|
|
|
|
- **`authRegister(payload: { email: string; password: string; firstName?: string; lastName?: string; phone?: string }): Promise<User>`**
|
|
- `POST /auth/register`
|
|
|
|
- **`authLogin(payload: { email: string; password: string }): Promise<User>`**
|
|
- `POST /auth/login`
|
|
|
|
- **`authRefresh(): Promise<void>`**
|
|
- `POST /auth/refresh`
|
|
|
|
- **`authLogout(): Promise<void>`**
|
|
- `POST /auth/logout`
|
|
|
|
- **`authLogoutAll(): Promise<void>`**
|
|
- `POST /auth/logout-all`
|
|
|
|
- **`authGetProfile(): Promise<User>`**
|
|
- `GET /auth/profile`
|
|
|
|
- **`authUpdateProfile(payload: { firstName?: string; lastName?: string; phone?: string }): Promise<User>`**
|
|
- `PUT /auth/profile`
|
|
|
|
- **`authChangePassword(payload: { currentPassword: string; newPassword: string; confirmPassword: string }): Promise<void>`**
|
|
- `POST /auth/change-password`
|
|
|
|
Suggested UI helpers:
|
|
|
|
- **`useAuth()` hook**
|
|
- `user`, `isAuthenticated`, `login()`, `logout()`, `refresh()`, `loadProfile()`
|
|
|
|
## Categories
|
|
|
|
- **`categoriesList(params?: { type?: 'INCOME' | 'EXPENSE' }): Promise<Category[]>`**
|
|
- `GET /categories?type=...`
|
|
|
|
- **`categoriesGetGrouped(): Promise<{ ESSENTIAL: Category[]; PERSONAL: Category[]; SAVINGS: Category[]; UNCATEGORIZED: Category[] }>`**
|
|
- `GET /categories/grouped`
|
|
|
|
- **`categoriesCreate(payload: { nameRu: string; nameEn?: string; type: 'INCOME' | 'EXPENSE'; groupType?: 'ESSENTIAL' | 'PERSONAL' | 'SAVINGS'; icon?: string; color?: string; parentId?: string }): Promise<Category>`**
|
|
- `POST /categories`
|
|
|
|
- **`categoriesUpdate(id: string, payload: Partial<{ nameRu: string; nameEn?: string; type: 'INCOME' | 'EXPENSE'; groupType?: 'ESSENTIAL' | 'PERSONAL' | 'SAVINGS'; icon?: string; color?: string; parentId?: string }>): Promise<Category>`**
|
|
- `PUT /categories/:id`
|
|
|
|
- **`categoriesDelete(id: string): Promise<void>`**
|
|
- `DELETE /categories/:id`
|
|
|
|
Suggested UI helpers:
|
|
|
|
- **`getCategoryDisplayName(cat: Category, locale: 'ru' | 'en'): string`**
|
|
- **`getCategoryBadgeStyle(cat: Category): { color: string; icon: string }`**
|
|
|
|
## Transactions
|
|
|
|
Core CRUD:
|
|
|
|
- **`transactionsList(params?: { page?: number; limit?: number; type?: 'INCOME' | 'EXPENSE'; startDate?: string; endDate?: string; categoryId?: string; search?: string; minAmount?: number; maxAmount?: number; paymentMethod?: 'CASH' | 'CARD' | 'BANK_TRANSFER' }): Promise<{ data: Transaction[]; meta: PaginationMeta }>`**
|
|
- `GET /transactions?...`
|
|
|
|
- **`transactionsGet(id: string): Promise<Transaction>`**
|
|
- `GET /transactions/:id`
|
|
|
|
- **`transactionsCreate(payload: { amount: number; currency?: string; type: 'INCOME' | 'EXPENSE'; categoryId?: string; description?: string; transactionDate: string; paymentMethod?: 'CASH' | 'CARD' | 'BANK_TRANSFER'; receiptUrl?: string; isRecurring?: boolean; recurringPattern?: any; isPlanned?: boolean }): Promise<Transaction>`**
|
|
- `POST /transactions`
|
|
|
|
- **`transactionsUpdate(id: string, payload: Partial<{ amount: number; categoryId?: string; description?: string; transactionDate: string; paymentMethod?: 'CASH' | 'CARD' | 'BANK_TRANSFER'; receiptUrl?: string; isRecurring?: boolean; recurringPattern?: any; isPlanned?: boolean }>): Promise<Transaction>`**
|
|
- `PUT /transactions/:id`
|
|
|
|
- **`transactionsDelete(id: string): Promise<void>`**
|
|
- `DELETE /transactions/:id`
|
|
|
|
Bulk + reports:
|
|
|
|
- **`transactionsBulkImport(payload: { items: Array<CreateTransactionPayload> }): Promise<{ created: number; skipped: number; errors: any[] }>`**
|
|
- `POST /transactions/bulk-import`
|
|
|
|
- **`transactionsSummary(params: { startDate: string; endDate: string }): Promise<{ totalIncome: number; totalExpense: number; net: number }>`**
|
|
- `GET /transactions/summary?startDate=...&endDate=...`
|
|
|
|
- **`transactionsSpendingByCategory(params: { startDate: string; endDate: string }): Promise<Array<{ categoryId: string; nameRu: string; amount: number; percentage: number }>>`**
|
|
- `GET /transactions/spending-by-category?startDate=...&endDate=...`
|
|
|
|
Suggested UI helpers:
|
|
|
|
- **`formatMoneyRu(amount: number, currency: string = 'RUB'): string`**
|
|
- **`groupTransactionsByDay(transactions: Transaction[]): Record<string, Transaction[]>`**
|
|
|
|
## Budgets (50/30/20)
|
|
|
|
- **`budgetsList(): Promise<Budget[]>`**
|
|
- `GET /budgets`
|
|
|
|
- **`budgetsGetCurrent(): Promise<Budget | null>`**
|
|
- `GET /budgets/current`
|
|
|
|
- **`budgetsGetByMonth(month: string /* YYYY-MM-01 */): Promise<Budget>`**
|
|
- `GET /budgets/month?month=...`
|
|
|
|
- **`budgetsCreate(payload: { month: string; totalIncome: number; essentialsPercent?: number; personalPercent?: number; savingsPercent?: number }): Promise<Budget>`**
|
|
- `POST /budgets`
|
|
|
|
- **`budgetsUpdate(month: string, payload: Partial<{ totalIncome: number; essentialsPercent?: number; personalPercent?: number; savingsPercent?: number }>): Promise<Budget>`**
|
|
- `PUT /budgets?month=...`
|
|
|
|
- **`budgetsDelete(month: string): Promise<void>`**
|
|
- `DELETE /budgets?month=...`
|
|
|
|
- **`budgetsProgress(month: string): Promise<{ essentials: Progress; personal: Progress; savings: Progress; total: TotalProgress }>`**
|
|
- `GET /budgets/progress?month=...`
|
|
|
|
Suggested UI helpers:
|
|
|
|
- **`budgetProgressColor(pct: number): 'green' | 'yellow' | 'red'`**
|
|
|
|
## Goals
|
|
|
|
- **`goalsList(params?: { status?: 'ACTIVE' | 'COMPLETED' | 'PAUSED' | 'CANCELLED' }): Promise<Goal[]>`**
|
|
- `GET /goals?status=...`
|
|
|
|
- **`goalsGet(id: string): Promise<Goal>`**
|
|
- `GET /goals/:id`
|
|
|
|
- **`goalsCreate(payload: { titleRu: string; descriptionRu?: string; targetAmount: number; currentAmount?: number; targetDate?: string; priority?: 'LOW' | 'MEDIUM' | 'HIGH'; icon?: string; color?: string; autoSaveEnabled?: boolean; autoSaveAmount?: number; autoSaveFrequency?: 'DAILY' | 'WEEKLY' | 'MONTHLY' }): Promise<Goal>`**
|
|
- `POST /goals`
|
|
|
|
- **`goalsUpdate(id: string, payload: Partial<...same as create...>): Promise<Goal>`**
|
|
- `PUT /goals/:id`
|
|
|
|
- **`goalsDelete(id: string): Promise<void>`**
|
|
- `DELETE /goals/:id`
|
|
|
|
- **`goalsAddFunds(id: string, payload: { amount: number; note?: string }): Promise<Goal>`**
|
|
- `POST /goals/:id/add-funds`
|
|
|
|
- **`goalsWithdraw(id: string, payload: { amount: number; note?: string }): Promise<Goal>`**
|
|
- `POST /goals/:id/withdraw`
|
|
|
|
- **`goalsSummary(): Promise<{ totalGoals: number; activeGoals: number; completedGoals: number; totalTargetAmount: number; totalCurrentAmount: number; overallProgress: number }>`**
|
|
- `GET /goals/summary`
|
|
|
|
- **`goalsUpcomingDeadlines(days?: number): Promise<Goal[]>`**
|
|
- `GET /goals/upcoming?days=...`
|
|
|
|
Suggested UI helpers:
|
|
|
|
- **`goalProgress(goal: Goal): { percent: number; remaining: number }`**
|
|
- **`goalStatusLabelRu(status: string): string`**
|
|
|
|
## Recommendations
|
|
|
|
- **`recommendationsList(params?: { type?: 'SAVING' | 'SPENDING' | 'INVESTMENT' | 'TAX' | 'DEBT' | 'BUDGET' | 'GOAL' }): Promise<Recommendation[]>`**
|
|
- `GET /recommendations?type=...`
|
|
|
|
- **`recommendationsGet(id: string): Promise<Recommendation>`**
|
|
- `GET /recommendations/:id`
|
|
|
|
- **`recommendationsGenerate(): Promise<Recommendation[]>`**
|
|
- `POST /recommendations/generate`
|
|
|
|
- **`recommendationsMarkViewed(id: string): Promise<Recommendation>`**
|
|
- `POST /recommendations/:id/view`
|
|
|
|
- **`recommendationsApply(id: string): Promise<Recommendation>`**
|
|
- `POST /recommendations/:id/apply`
|
|
|
|
- **`recommendationsDismiss(id: string): Promise<Recommendation>`**
|
|
- `POST /recommendations/:id/dismiss`
|
|
|
|
- **`recommendationsStats(): Promise<{ total: number; new: number; viewed: number; applied: number; dismissed: number; potentialSavings: number }>`**
|
|
- `GET /recommendations/stats`
|
|
|
|
Suggested UI helpers:
|
|
|
|
- **`recommendationBadge(type: string): { labelRu: string; color: string }`**
|
|
|
|
## Analytics
|
|
|
|
- **`analyticsMonthlyOverview(month?: string /* YYYY-MM */): Promise<MonthlyOverview>`**
|
|
- `GET /analytics/overview?month=...`
|
|
|
|
- **`analyticsTrends(months?: number): Promise<SpendingTrend[]>`**
|
|
- `GET /analytics/trends?months=...`
|
|
|
|
- **`analyticsCategoryBreakdown(params: { startDate: string; endDate: string; type?: 'INCOME' | 'EXPENSE' }): Promise<CategoryBreakdown[]>`**
|
|
- `GET /analytics/categories?startDate=...&endDate=...&type=...`
|
|
|
|
- **`analyticsIncomeVsExpenses(months?: number): Promise<Array<{ period: string; income: number; expenses: number; savings: number }>>`**
|
|
- `GET /analytics/income-vs-expenses?months=...`
|
|
|
|
- **`analyticsFinancialHealth(): Promise<FinancialHealth>`**
|
|
- `GET /analytics/health`
|
|
|
|
- **`analyticsYearly(year?: number): Promise<YearlySummary>`**
|
|
- `GET /analytics/yearly?year=...`
|
|
|
|
Suggested UI helpers:
|
|
|
|
- **`financialHealthBadge(grade: 'A'|'B'|'C'|'D'|'F'): { labelRu: string; color: string }`**
|
|
|
|
## Suggested Frontend Architecture
|
|
|
|
- `src/api/`:
|
|
- `client.ts` (`apiFetch`, interceptors, base URL)
|
|
- `auth.ts`, `categories.ts`, `transactions.ts`, `budgets.ts`, `goals.ts`, `recommendations.ts`, `analytics.ts`
|
|
- `src/types/`:
|
|
- shared types mirrored from backend DTOs/entities
|
|
- `src/hooks/`:
|
|
- `useAuth`, `useTransactions`, `useBudgets`, `useGoals`, `useRecommendations`, `useAnalytics`
|
|
|
|
## Minimal Types (Suggested)
|
|
|
|
- `User`, `Category`, `Transaction`, `Budget`, `Goal`, `Recommendation`
|
|
- `PaginationMeta`
|
|
|
|
(Define based on Swagger at `/api/docs` once backend is running.)
|