finance-api/FRONTEND_FUNCTIONS.md
Заид Омар Медхат 997bac5d1f chore: frontend schema
2025-12-13 15:59:21 +05:00

9.9 KiB

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.)