Add day-of and crock-pot start-by reminders (Feature 20)
Register plan.Service.ReminderSchedules as the day_of_reminder schedule:
daily at the household reminder_time (period YYYY-MM-DD) it emits
day_of_reminder:YYYY-MM-DD, "Tonight: {dinner} · Recipe →" linking
/dinner/{id}; for a crock-pot dinner whose start_by is earlier than
reminder_time it also fires 15 minutes before start_by (period
start:YYYY-MM-DD) and emits day_of_reminder:start:YYYY-MM-DD, "Start the
crock pot by {time}". A date whose week has no plan emits nothing.
The scheduler gains DailyAt rules, whose fire time per date is looked up
from data on every pass (a failed lookup is retried every ClaimRetry),
and a Schedule Key that prefixes period keys so two schedules of one
name claim different periods.
Maestro task 30963b62-2803-4879-82ff-c351cc6628cf.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+11
-12
@@ -233,10 +233,10 @@ func (s *Service) Get(ctx context.Context, weekStart store.LocalDate) (p Plan, e
|
||||
}
|
||||
|
||||
// EmitDayOfReminder emits day_of_reminder for date, keyed by the date,
|
||||
// naming the dinner planned on it, and reports whether it did: a date whose
|
||||
// week has no plan emits nothing. The scheduler calls it at the
|
||||
// household's reminder_time (Feature 20); emitting a date again stores no
|
||||
// second notification.
|
||||
// "Tonight: {dinner} · Recipe →" for the dinner planned on it, and reports
|
||||
// whether it did: a date whose week has no plan emits nothing. The
|
||||
// day_of_reminder schedule calls it at the household's reminder_time
|
||||
// (ReminderSchedules); emitting a date again stores no second notification.
|
||||
func (s *Service) EmitDayOfReminder(ctx context.Context, date store.LocalDate) (bool, error) {
|
||||
p, err := s.Get(ctx, household.WeekStart(date))
|
||||
if errors.Is(err, ErrNotFound) {
|
||||
@@ -245,15 +245,14 @@ func (s *Service) EmitDayOfReminder(ctx context.Context, date store.LocalDate) (
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
for _, d := range p.Days {
|
||||
if d.Date == date.String() {
|
||||
if err := s.notifier.Emit(ctx, chat.DayOfReminder(date, d.Dinner.ID, d.Dinner.Name)); err != nil {
|
||||
return false, fmt.Errorf("plan: %w", err)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
d, err := p.day(date)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, fmt.Errorf("plan: week %s has no day %s", p.WeekStart, date)
|
||||
if err := s.notifier.Emit(ctx, chat.DayOfReminder(date, d.Dinner.ID, d.Dinner.Name)); err != nil {
|
||||
return false, fmt.Errorf("plan: %w", err)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// readPlan reads the plan of the week starting weekStart through q, with
|
||||
|
||||
Reference in New Issue
Block a user