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

@@ -33,6 +33,11 @@ func main() {
log.Fatalf("Failed to run migrations: %v", err)
}
// Run finance migrations
if err := repository.RunFinanceMigrations(db); err != nil {
log.Fatalf("Failed to run finance migrations: %v", err)
}
// Initialize repositories
userRepo := repository.NewUserRepository(db)
habitRepo := repository.NewHabitRepository(db)
@@ -40,12 +45,14 @@ func main() {
emailTokenRepo := repository.NewEmailTokenRepository(db)
habitFreezeRepo := repository.NewHabitFreezeRepository(db)
savingsRepo := repository.NewSavingsRepository(db)
financeRepo := repository.NewFinanceRepository(db)
// Initialize services
emailService := service.NewEmailService(cfg.ResendAPIKey, cfg.FromEmail, cfg.FromName, cfg.AppURL)
authService := service.NewAuthService(userRepo, emailTokenRepo, emailService, cfg.JWTSecret)
habitService := service.NewHabitService(habitRepo, habitFreezeRepo)
taskService := service.NewTaskService(taskRepo)
financeService := service.NewFinanceService(financeRepo)
// Initialize Telegram bot
telegramBot, err := bot.New(cfg.TelegramBotToken, userRepo, taskRepo, habitRepo)
@@ -72,6 +79,7 @@ func main() {
habitFreezeHandler := handler.NewHabitFreezeHandler(habitFreezeRepo, habitRepo)
savingsHandler := handler.NewSavingsHandler(savingsRepo)
interestHandler := handler.NewInterestHandler(db)
financeHandler := handler.NewFinanceHandler(financeService)
// Initialize middleware
authMiddleware := customMiddleware.NewAuthMiddleware(cfg.JWTSecret)
@@ -178,6 +186,20 @@ func main() {
// Savings stats
r.Get("/savings/stats", savingsHandler.Stats)
// Finance routes (owner-only, checked in handler)
r.Get("/finance/categories", financeHandler.ListCategories)
r.Post("/finance/categories", financeHandler.CreateCategory)
r.Put("/finance/categories/{id}", financeHandler.UpdateCategory)
r.Delete("/finance/categories/{id}", financeHandler.DeleteCategory)
r.Get("/finance/transactions", financeHandler.ListTransactions)
r.Post("/finance/transactions", financeHandler.CreateTransaction)
r.Put("/finance/transactions/{id}", financeHandler.UpdateTransaction)
r.Delete("/finance/transactions/{id}", financeHandler.DeleteTransaction)
r.Get("/finance/summary", financeHandler.Summary)
r.Get("/finance/analytics", financeHandler.Analytics)
})
port := os.Getenv("PORT")