Files
carvalho-finances/apps/api/internal/handler/dashboard.go
T
Mlcavalho1andClaude Sonnet 4.6 1d59cb2a0e feat: #45 meta de poupança configurável + conquistas genéricas
- Nova tabela user_settings com savings_goal_pct (default 40%)
- API GET /api/settings, PUT /api/settings
- DashboardService inclui savings_goal_pct no payload
- DashboardHandler dispara savings_checked com goal configurado
- GameService.NotifyAction: checa pct >= goal (sem hardcode de 40%)
- SettingsView: painel META DE POUPANÇA com input configurável
- HomeView: widget mostra meta dinâmica (META: X%) e usa savingsGoal
- stores/settings.ts: store com fetch e update

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-28 22:32:08 -03:00

41 lines
975 B
Go

package handler
import (
"net/http"
"time"
"financeiro-carvalho/internal/service"
)
type DashboardHandler struct {
svc *service.DashboardService
gameSvc *service.GameService
}
func NewDashboardHandler(svc *service.DashboardService, gameSvc *service.GameService) *DashboardHandler {
return &DashboardHandler{svc: svc, gameSvc: gameSvc}
}
func (h *DashboardHandler) Get(w http.ResponseWriter, r *http.Request) {
month := r.URL.Query().Get("month")
if month == "" {
month = time.Now().Format("2006-01")
}
data, err := h.svc.Get(r.Context(), month)
if err != nil {
respondError(w, http.StatusInternalServerError, "failed to load dashboard")
return
}
// Notify game engine about savings percentage for the current month only
if month == time.Now().Format("2006-01") {
h.gameSvc.NotifyAction(r.Context(), "savings_checked", map[string]any{
"pct": data.SavingsPct,
"goal": data.SavingsGoalPct,
})
}
respondJSON(w, http.StatusOK, data)
}