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:
@@ -0,0 +1,50 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"financeiro-carvalho/internal/middleware"
|
||||
"financeiro-carvalho/internal/model"
|
||||
)
|
||||
|
||||
type SettingsRepository interface {
|
||||
Get(ctx context.Context) (*model.UserSettings, error)
|
||||
Upsert(ctx context.Context, s model.UserSettings) (*model.UserSettings, error)
|
||||
}
|
||||
|
||||
type settingsRepo struct{ pool *pgxpool.Pool }
|
||||
|
||||
func NewSettingsRepository(pool *pgxpool.Pool) SettingsRepository {
|
||||
return &settingsRepo{pool: pool}
|
||||
}
|
||||
|
||||
func (r *settingsRepo) Get(ctx context.Context) (*model.UserSettings, error) {
|
||||
pid := middleware.ProfileIDFromCtx(ctx)
|
||||
var s model.UserSettings
|
||||
err := r.pool.QueryRow(ctx, `
|
||||
SELECT savings_goal_pct FROM user_settings WHERE profile_id = $1
|
||||
`, pid).Scan(&s.SavingsGoalPct)
|
||||
if err != nil {
|
||||
// Return defaults if not yet configured
|
||||
return &model.UserSettings{SavingsGoalPct: 40}, nil
|
||||
}
|
||||
return &s, nil
|
||||
}
|
||||
|
||||
func (r *settingsRepo) Upsert(ctx context.Context, s model.UserSettings) (*model.UserSettings, error) {
|
||||
pid := middleware.ProfileIDFromCtx(ctx)
|
||||
var out model.UserSettings
|
||||
err := r.pool.QueryRow(ctx, `
|
||||
INSERT INTO user_settings (profile_id, savings_goal_pct)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (profile_id) DO UPDATE
|
||||
SET savings_goal_pct = EXCLUDED.savings_goal_pct, updated_at = NOW()
|
||||
RETURNING savings_goal_pct
|
||||
`, pid, s.SavingsGoalPct).Scan(&out.SavingsGoalPct)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
Reference in New Issue
Block a user