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
+11 -1
View File
@@ -61,12 +61,22 @@ func (m *mockPendingBillRepo) GetByID(_ context.Context, _ int) (*model.PendingB
}
func (m *mockPendingBillRepo) Delete(_ context.Context, _ int) error { return nil }
type mockSettingsRepo struct{}
func (m *mockSettingsRepo) Get(_ context.Context) (*model.UserSettings, error) {
return &model.UserSettings{SavingsGoalPct: 40}, nil
}
func (m *mockSettingsRepo) Upsert(_ context.Context, s model.UserSettings) (*model.UserSettings, error) {
return &s, nil
}
func newDashboardSvc(income, expenses float64) *service.DashboardService {
repo := &mockAccountRepo{}
recurrSvc := service.NewRecurringService(newMockRecurring(nil), &mockTxRepo{})
billSvc := service.NewCreditBillService(&mockCreditBillRepo{}, repo)
pendingBillSvc := service.NewPendingBillService(&mockPendingBillRepo{}, &mockImportTxRepo{})
return service.NewDashboardService(&mockDashboardRepo{income: income, expenses: expenses}, recurrSvc, &mockPatrimony{}, billSvc, pendingBillSvc)
settingsSvc := service.NewSettingsService(&mockSettingsRepo{})
return service.NewDashboardService(&mockDashboardRepo{income: income, expenses: expenses}, recurrSvc, &mockPatrimony{}, billSvc, pendingBillSvc, settingsSvc)
}
func TestDashboard_SavingsPct_40(t *testing.T) {