On first boot create the single household_settings row with the zone from MEALQUEST_DEFAULT_TZ and the seed times and days (dinner 17:30, reminder 16:30, rotation check 09:00, plan draft Fri 09:00, suggestions Sun 08:00, chat autosend Sat 08:00). Boot fails if the row is missing and the zone is unset; an existing row is never overwritten. Config validates the zone whenever it is set. Add household.SettingsService with Get, a validating Update (IANA zone, zero-padded 24-hour HH:MM, day of week 0-6) that records updated_by, and in-process Subscribe for the scheduler. Serve it as GET and PATCH /api/v1/settings/household; invalid input is a 400 in the standard error body. Migration 0002 adds household_settings.updated_by, and internal/actor carries the member name in the request context. Link time/tzdata from internal/household so zones load in the minimal image, which has no system zone database. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
29 lines
871 B
Go
29 lines
871 B
Go
package household
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
// Embeds the IANA zone database in the binary, so zones load the same
|
|
// way in a minimal image with no /usr/share/zoneinfo.
|
|
_ "time/tzdata"
|
|
)
|
|
|
|
// LoadZone loads the IANA zone name, such as "America/New_York". The empty
|
|
// name and "Local", which time.LoadLocation maps to UTC and the process zone,
|
|
// are refused: the household zone is never implied.
|
|
func LoadZone(name string) (*time.Location, error) {
|
|
if name == "" {
|
|
return nil, errors.New("time zone is empty (want an IANA zone such as America/New_York)")
|
|
}
|
|
if name == "Local" {
|
|
return nil, errors.New(`time zone "Local" is not an IANA zone (want e.g. America/New_York)`)
|
|
}
|
|
loc, err := time.LoadLocation(name)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unknown time zone %q (want an IANA zone such as America/New_York)", name)
|
|
}
|
|
return loc, nil
|
|
}
|