- 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]>
41 lines
975 B
Go
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)
|
|
}
|