Skip to content

Set a real start date for the menu and count each week as 7 days from it #43

Description

@guplem

TL;DR: Today a menu has no calendar date at all: the week always runs Saturday to Friday (WeekDay enum, saturday(0)), and weeks are only "Week 1 / Week 2". This issue lets the user pick the first day of the menu, so every menu day maps to a real date and each following week is simply the next 7 days.

Context

The menu is a pure grid with no link to the calendar. MultiWeekMenu is only List<Menu> (multi_week_menu.dart:15), Menu is a flat List<Meal>, and each Meal is keyed by MealTime{WeekDay, MealType}. The day order is hardcoded in the WeekDay enum, Saturday-first (week_day.dart:1-24). The UI just renders List.generate(7, ...) with WeekDay.fromValue(i).name (menu_page.dart:134-145), and the week label is "Week N / M" (menu_page.dart:463).

Nothing in the menu domain stores a DateTime. The only date in the whole app builds a default save filename (Menu-<next Saturday>.tsm, persistency.dart:364); it is never written into the file or read back.

Two problems come from this:

  • The week start is not the user's week start. A user whose planning week begins on Wednesday cannot express it. Saturday-first is baked into an enum, a persisted string, and 21 hardcoded default MenuConfiguration entries (menu_provider.dart:24-137).
  • No day is a real day. While following a multi-week menu, the user must count "Week 2 Tuesday" by hand to know which actual date that is. The same is true when shopping: the trip banner says "Multi-trip mode: copy will split into 2 trips (Week 1, Week 2)" (shopping_page.dart:180-186), never a date to go shopping on.

Assumptions made while writing this issue (no human confirmed them):

  • "First day" means a real calendar date, not only "which weekday the week starts on". The date defines both the anchor and the day order: pick Wednesday 5 Aug and the grid runs Wednesday to Tuesday, and week 2 starts exactly 7 days later.
  • The scheduling math stays as it is. Everything today works in absolute day offsets from menu day 0: weekIndex * 7 + weekDay.value, used by maxStorageDays leftover windows (menu.dart:89-102), Product.mayBeExpiredOnDay (product.dart:38-42), and the trip planner's tripDay => weekIndex * 7 - 1 (multi_trip_planner.dart:35). The start date only translates those offsets into dates for display. Changing the planning algorithm to real dates (for example "I shop every Wednesday and Saturday", the deferred limitation in ADR 0014) is out of scope.
  • Old .tsm files stay loadable. A menu with no start date keeps behaving exactly as today (Saturday-first, no dates shown), following the existing key-migration pattern in Meal.fromJson (meal.dart:22-31).

Relevant ADRs: 0008 (multi-week structure and absolute day indices), 0012 (the weekIndex * 7 + weekDay.value formula), 0003 (.tsm format and format sniffing), 0014 / 0010 (the "shop the day before day 0" anchor).

Acceptance Criteria

  • The user can pick the menu's first day as a calendar date from the menu page, and can clear it back to "no date set".
  • The chosen date is stored on MultiWeekMenu and saved in / loaded from .tsm. A .tsm file without it loads without error and keeps today's Saturday-first, date-less behavior.
  • The 7 day columns on the menu page start at the chosen date's weekday and wrap around (start on a Wednesday, columns read Wednesday to Tuesday), and each column shows its real date.
  • The MenuConfiguration page uses the same day order as the menu page, so a slot means the same day on both screens.
  • Week navigation shows the week's date range next to "Week N / M", where week N covers day (N-1)*7 to N*7-1 counted from the first day.
  • Existing meal assignments are untouched when the start date changes: only labels, order, and dates change, never which recipe sits in which slot.
  • Leftover windows, expiry warnings, and the shopping trip split produce the same results as before for the same menu; only their user-facing labels gain dates.
  • The shopping page trip banner and each trip section name the real shopping date when a start date is set, and fall back to "Week N" when it is not.
  • Deletion-reference labels that today read "Week 1 - Saturday lunch" (recipes_page.dart:34-37) include the date when one is set.

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestmenuMenu generation and configurationshoppingShopping list featurewaiting-for-human-checkNo human has verified this yet -- direct AI output

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions