All checks were successful
CI / ci (push) Successful in 12s
- model/finance.go: FinanceCategory, FinanceTransaction, Summary, Analytics - repository/finance.go: CRUD + summary/analytics queries - service/finance.go: business logic with auto-seed default categories - handler/finance.go: REST endpoints with owner-only check (user_id=1) - db.go: finance_categories + finance_transactions migrations - main.go: register /finance/* routes Endpoints: GET/POST/PUT/DELETE /finance/categories, /finance/transactions GET /finance/summary, /finance/analytics
115 lines
3.8 KiB
Go
115 lines
3.8 KiB
Go
package model
|
|
|
|
import (
|
|
"database/sql"
|
|
"time"
|
|
)
|
|
|
|
type FinanceCategory struct {
|
|
ID int64 `db:"id" json:"id"`
|
|
UserID int64 `db:"user_id" json:"user_id"`
|
|
Name string `db:"name" json:"name"`
|
|
Emoji string `db:"emoji" json:"emoji"`
|
|
Type string `db:"type" json:"type"`
|
|
Budget sql.NullFloat64 `db:"budget" json:"-"`
|
|
BudgetVal *float64 `db:"-" json:"budget"`
|
|
Color string `db:"color" json:"color"`
|
|
SortOrder int `db:"sort_order" json:"sort_order"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
}
|
|
|
|
func (c *FinanceCategory) ProcessForJSON() {
|
|
if c.Budget.Valid {
|
|
c.BudgetVal = &c.Budget.Float64
|
|
}
|
|
}
|
|
|
|
type FinanceTransaction struct {
|
|
ID int64 `db:"id" json:"id"`
|
|
UserID int64 `db:"user_id" json:"user_id"`
|
|
CategoryID int64 `db:"category_id" json:"category_id"`
|
|
Type string `db:"type" json:"type"`
|
|
Amount float64 `db:"amount" json:"amount"`
|
|
Description string `db:"description" json:"description"`
|
|
Date time.Time `db:"date" json:"date"`
|
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
// Joined fields
|
|
CategoryName string `db:"category_name" json:"category_name,omitempty"`
|
|
CategoryEmoji string `db:"category_emoji" json:"category_emoji,omitempty"`
|
|
}
|
|
|
|
type CreateFinanceCategoryRequest struct {
|
|
Name string `json:"name"`
|
|
Emoji string `json:"emoji,omitempty"`
|
|
Type string `json:"type"`
|
|
Budget *float64 `json:"budget,omitempty"`
|
|
Color string `json:"color,omitempty"`
|
|
SortOrder int `json:"sort_order,omitempty"`
|
|
}
|
|
|
|
type UpdateFinanceCategoryRequest struct {
|
|
Name *string `json:"name,omitempty"`
|
|
Emoji *string `json:"emoji,omitempty"`
|
|
Type *string `json:"type,omitempty"`
|
|
Budget *float64 `json:"budget,omitempty"`
|
|
Color *string `json:"color,omitempty"`
|
|
SortOrder *int `json:"sort_order,omitempty"`
|
|
}
|
|
|
|
type CreateFinanceTransactionRequest struct {
|
|
CategoryID int64 `json:"category_id"`
|
|
Type string `json:"type"`
|
|
Amount float64 `json:"amount"`
|
|
Description string `json:"description,omitempty"`
|
|
Date string `json:"date"`
|
|
}
|
|
|
|
type UpdateFinanceTransactionRequest struct {
|
|
CategoryID *int64 `json:"category_id,omitempty"`
|
|
Type *string `json:"type,omitempty"`
|
|
Amount *float64 `json:"amount,omitempty"`
|
|
Description *string `json:"description,omitempty"`
|
|
Date *string `json:"date,omitempty"`
|
|
}
|
|
|
|
type FinanceSummary struct {
|
|
Balance float64 `json:"balance"`
|
|
TotalIncome float64 `json:"total_income"`
|
|
TotalExpense float64 `json:"total_expense"`
|
|
ByCategory []CategorySummary `json:"by_category"`
|
|
Daily []DailySummary `json:"daily"`
|
|
}
|
|
|
|
type CategorySummary struct {
|
|
CategoryID int64 `json:"category_id" db:"category_id"`
|
|
CategoryName string `json:"category_name" db:"category_name"`
|
|
CategoryEmoji string `json:"category_emoji" db:"category_emoji"`
|
|
Type string `json:"type" db:"type"`
|
|
Amount float64 `json:"amount" db:"amount"`
|
|
Percentage float64 `json:"percentage"`
|
|
Budget *float64 `json:"budget,omitempty"`
|
|
}
|
|
|
|
type DailySummary struct {
|
|
Date string `json:"date" db:"date"`
|
|
Amount float64 `json:"amount" db:"amount"`
|
|
}
|
|
|
|
type FinanceAnalytics struct {
|
|
MonthlyTrend []MonthlyTrend `json:"monthly_trend"`
|
|
AvgDailyExpense float64 `json:"avg_daily_expense"`
|
|
ComparisonPrevMonth Comparison `json:"comparison_prev_month"`
|
|
}
|
|
|
|
type MonthlyTrend struct {
|
|
Month string `json:"month" db:"month"`
|
|
Income float64 `json:"income" db:"income"`
|
|
Expense float64 `json:"expense" db:"expense"`
|
|
}
|
|
|
|
type Comparison struct {
|
|
Current float64 `json:"current"`
|
|
Previous float64 `json:"previous"`
|
|
DiffPercent float64 `json:"diff_percent"`
|
|
}
|