feat: add finance module (categories, transactions, summary, analytics)
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
This commit is contained in:
Cosmo
2026-03-01 04:22:10 +00:00
parent 8d9fe818f4
commit 23939ccc92
7 changed files with 970 additions and 1 deletions

View File

@@ -127,3 +127,40 @@ func RunMigrations(db *sqlx.DB) error {
return nil
}
func RunFinanceMigrations(db *sqlx.DB) error {
migrations := []string{
`CREATE TABLE IF NOT EXISTS finance_categories (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
name VARCHAR(100) NOT NULL,
emoji VARCHAR(10) DEFAULT '',
type VARCHAR(10) NOT NULL,
budget DECIMAL(12,2),
color VARCHAR(7) DEFAULT '#6366f1',
sort_order INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)`,
`CREATE TABLE IF NOT EXISTS finance_transactions (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
category_id INTEGER REFERENCES finance_categories(id) ON DELETE SET NULL,
type VARCHAR(10) NOT NULL,
amount DECIMAL(12,2) NOT NULL,
description TEXT DEFAULT '',
date DATE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)`,
`CREATE INDEX IF NOT EXISTS idx_finance_categories_user ON finance_categories(user_id)`,
`CREATE INDEX IF NOT EXISTS idx_finance_transactions_user ON finance_transactions(user_id)`,
`CREATE INDEX IF NOT EXISTS idx_finance_transactions_date ON finance_transactions(date)`,
`CREATE INDEX IF NOT EXISTS idx_finance_transactions_category ON finance_transactions(category_id)`,
`CREATE INDEX IF NOT EXISTS idx_finance_transactions_user_date ON finance_transactions(user_id, date)`,
}
for _, m := range migrations {
if _, err := db.Exec(m); err != nil {
return err
}
}
return nil
}