Fix offline onboarding lockout and stale candidates after rename
CI / ci (push) Successful in 2m40s
CI / ci (pull_request) Successful in 2m28s

MQ-98-04: the household settings read that OnboardingGate makes before
every page now runs with networkMode 'always', like /me. After the
browser emits an offline event it fails into the saved pages instead of
pausing on the loading screen. A test emits a real offline event before
/me fails.

MQ-98-05: renaming a dinner now clears its candidate offers and makes a
running candidate search stale, and an offer is bound to the normalized
name it was searched for, so a candidate offered before a rename cannot
ground the renamed dinner. Regression tests cover a pending dinner
renamed after candidates were offered, and a rename during a running
search.

Maestro task: 4fd737b2-fdcb-48ad-858a-ecdd95595e0c

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-06 23:36:31 -04:00
co-authored by Claude Opus 5.5
parent cb920714b0
commit 3c0a7fd398
6 changed files with 129 additions and 27 deletions
+7 -2
View File
@@ -309,7 +309,8 @@ func (s *Service) List(ctx context.Context, status string) ([]Dinner, error) {
// clears its recipe_url, raises its grounding_revision and enqueues a fresh
// KindGroundDinner job that grounds the new name: a job queued or running
// for the old name or link carries the old revision, so it can no longer
// write the dinner, and one running is stopped.
// write the dinner, and one running is stopped. Renaming any dinner drops
// the candidates offered for its old name: none of them grounds it.
func (s *Service) Update(ctx context.Context, id string, p Patch, updatedBy string) (Dinner, error) {
if updatedBy == "" {
return Dinner{}, errors.New("dinners: update: no member to record as updated_by")
@@ -320,7 +321,7 @@ func (s *Service) Update(ctx context.Context, id string, p Patch, updatedBy stri
}
var row db.Dinner
var regrounding bool
var renamed, regrounding bool
err = s.st.WithTx(ctx, func(tx *sql.Tx) error {
q := db.New(tx)
cur, err := q.GetDinner(ctx, id)
@@ -374,12 +375,16 @@ func (s *Service) Update(ctx context.Context, id string, p Patch, updatedBy stri
if err != nil {
return fmt.Errorf("dinners: update %s: %w", id, err)
}
renamed = row.NormalizedName != cur.NormalizedName
regrounding = row.GroundingRevision != cur.GroundingRevision
return nil
})
if err != nil {
return Dinner{}, err
}
if renamed {
s.clearOffers(row.ID)
}
if regrounding {
s.stopGroundings(row.ID, row.GroundingRevision)
jobID, err := s.enqueueGrounding(ctx, row.ID, row.GroundingRevision)