feat: add eve chanting notif
This commit is contained in:
@@ -28,6 +28,11 @@ type ReminderCandidate struct {
|
||||
LastChantDate *time.Time // most recent completed chant day (UTC), nil if never
|
||||
ChantDoneToday bool
|
||||
QuoteDoneToday bool
|
||||
|
||||
// For the evening "incomplete chanting" reminder.
|
||||
RoundsToday int // rounds chanted so far today
|
||||
TargetRounds int // the user's daily target (16 if unset)
|
||||
LastChantIncompleteOn *time.Time // UTC date the evening reminder last fired
|
||||
}
|
||||
|
||||
// SetTimezone records the user's IANA timezone (validated by the caller).
|
||||
@@ -80,12 +85,18 @@ func (r *ReminderRepo) DueCandidates(ctx context.Context) ([]ReminderCandidate,
|
||||
AND l.log_date = (now() AT TIME ZONE 'UTC')::date),
|
||||
EXISTS(SELECT 1 FROM posts p
|
||||
WHERE p.user_id = u.id
|
||||
AND (p.created_at AT TIME ZONE 'UTC')::date = (now() AT TIME ZONE 'UTC')::date)
|
||||
AND (p.created_at AT TIME ZONE 'UTC')::date = (now() AT TIME ZONE 'UTC')::date),
|
||||
COALESCE((SELECT l.rounds_completed FROM sadhna_logs l
|
||||
WHERE l.user_id = u.id
|
||||
AND l.log_date = (now() AT TIME ZONE 'UTC')::date), 0),
|
||||
COALESCE(u.daily_chanting_rounds, 16),
|
||||
u.last_chant_incomplete_reminder_on
|
||||
FROM users u
|
||||
WHERE u.sadhna_reminders_enabled = TRUE
|
||||
AND (
|
||||
u.last_chant_reminder_on IS NULL OR u.last_chant_reminder_on < (now() AT TIME ZONE 'UTC')::date
|
||||
OR u.last_quote_reminder_on IS NULL OR u.last_quote_reminder_on < (now() AT TIME ZONE 'UTC')::date
|
||||
OR u.last_chant_incomplete_reminder_on IS NULL OR u.last_chant_incomplete_reminder_on < (now() AT TIME ZONE 'UTC')::date
|
||||
)`)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("due candidates: %w", err)
|
||||
@@ -99,6 +110,7 @@ func (r *ReminderRepo) DueCandidates(ctx context.Context) ([]ReminderCandidate,
|
||||
&c.UserID, &c.Email, &c.TZ, &c.ChantTime, &c.QuoteTime,
|
||||
&c.LastChantOn, &c.LastQuoteOn, &c.LastChantDate,
|
||||
&c.ChantDoneToday, &c.QuoteDoneToday,
|
||||
&c.RoundsToday, &c.TargetRounds, &c.LastChantIncompleteOn,
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("scan candidate: %w", err)
|
||||
}
|
||||
@@ -120,3 +132,11 @@ func (r *ReminderRepo) MarkQuoteReminded(ctx context.Context, userID string, utc
|
||||
`UPDATE users SET last_quote_reminder_on = $1 WHERE id = $2`, utcDate, userID)
|
||||
return err
|
||||
}
|
||||
|
||||
// MarkChantIncompleteReminded stamps the UTC date the evening "finish your
|
||||
// rounds" reminder went out, so it fires at most once per day.
|
||||
func (r *ReminderRepo) MarkChantIncompleteReminded(ctx context.Context, userID string, utcDate time.Time) error {
|
||||
_, err := r.pg.Pool.Exec(ctx,
|
||||
`UPDATE users SET last_chant_incomplete_reminder_on = $1 WHERE id = $2`, utcDate, userID)
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user