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]>
This commit is contained in:
2026-05-28 22:32:08 -03:00
co-authored by Claude Sonnet 4.6
parent 9fada4997a
commit 1d59cb2a0e
15 changed files with 296 additions and 15 deletions
+6 -2
View File
@@ -165,9 +165,13 @@ func (s *GameService) NotifyAction(ctx context.Context, action string, extra map
case "savings_checked":
pct, _ := extra["pct"].(float64)
goal, _ := extra["goal"].(float64)
if goal <= 0 {
goal = 40
}
_ = s.repo.UpdateQuestPct(ctx, monthlyPeriod, pct)
if pct >= 40 {
_, _ = s.AwardXP(ctx, "savings_goal_met", 200, "Meta de 40% atingida!")
if pct >= goal {
_, _ = s.AwardXP(ctx, "savings_goal_met", 200, "Meta de poupança atingida!")
s.tryUnlockAchievement(ctx, "first_40pct")
}
}