feat: update smoke profile area handling

This commit is contained in:
你çšnepiedg
2026-03-19 15:41:26 +08:00
parent 9278260681
commit 515fba0b55
6 changed files with 60 additions and 0 deletions
@@ -16,6 +16,11 @@ var (
ErrSmokeProfileInvalidTime = errors.New("invalid time format, expected HH:MM")
)
const (
SmokeModeQuit = "quit"
SmokeModeRecord = "record"
)
type SmokeProfileService struct {
db *gorm.DB
}
@@ -47,6 +52,7 @@ func (s *SmokeProfileService) GetView(ctx context.Context, uid int) (SmokeProfil
BaselineIntervalMinute: 0,
}, nil
}
profile.Mode = normalizedSmokeMode(profile.Mode)
awakeMinutes, err := awakeMinutesWithFallback(profile.WakeUpTime, profile.SleepTime)
if err != nil {
@@ -83,6 +89,7 @@ type UpsertSmokeProfileRequest struct {
BaselineCigsPerDay *int
SmokingYears *float64
PackPriceCent *int
Mode *string
SmokeMotivations *[]string
QuitMotivations *[]string
@@ -116,6 +123,12 @@ func (s *SmokeProfileService) Upsert(ctx context.Context, uid int, req UpsertSmo
*dst = *v
}
}
applyMode := func(dst *string, v *string) {
if v == nil {
return
}
*dst = normalizedSmokeMode(*v)
}
applyTimeStr := func(dst *string, v *string) error {
if v == nil {
return nil
@@ -135,6 +148,7 @@ func (s *SmokeProfileService) Upsert(ctx context.Context, uid int, req UpsertSmo
applyInt(&profile.BaselineCigsPerDay, req.BaselineCigsPerDay)
applyFloat(&profile.SmokingYears, req.SmokingYears)
applyInt(&profile.PackPriceCent, req.PackPriceCent)
applyMode(&profile.Mode, req.Mode)
if req.SmokeMotivations != nil {
profile.SmokeMotivations = smokemodel.StringSlice(*req.SmokeMotivations)
@@ -154,6 +168,7 @@ func (s *SmokeProfileService) Upsert(ctx context.Context, uid int, req UpsertSmo
}
now := time.Now()
profile.Mode = normalizedSmokeMode(profile.Mode)
if profile.OnboardingCompletedAt == nil && isSmokeProfileCompleted(profile) {
profile.OnboardingCompletedAt = &now
}
@@ -215,6 +230,17 @@ func baselineIntervalMinutes(awakeMinutes int, baselineCigsPerDay int) int {
return interval
}
func normalizedSmokeMode(mode string) string {
switch strings.TrimSpace(mode) {
case SmokeModeQuit:
return SmokeModeQuit
case SmokeModeRecord:
return SmokeModeRecord
default:
return SmokeModeRecord
}
}
func parseHHMMToMinutes(s string) (int, error) {
s = strings.TrimSpace(s)
if len(s) != 5 || s[2] != ':' {
@@ -106,3 +106,23 @@ func TestIsSmokeProfileCompleted(t *testing.T) {
t.Fatalf("isSmokeProfileCompleted: expected false when quit_motivations missing")
}
}
func TestNormalizedSmokeMode(t *testing.T) {
t.Parallel()
cases := []struct {
in string
want string
}{
{in: SmokeModeQuit, want: SmokeModeQuit},
{in: SmokeModeRecord, want: SmokeModeRecord},
{in: "", want: SmokeModeRecord},
{in: "unknown", want: SmokeModeRecord},
}
for _, c := range cases {
if got := normalizedSmokeMode(c.in); got != c.want {
t.Fatalf("normalizedSmokeMode(%q): got %q, want %q", c.in, got, c.want)
}
}
}