···1616 - `export GOCACHE=/tmp/go-build`
1717 - `export GOMODCACHE=/tmp/go-modcache`
1818 - Alternative persistent path inside repo: `export GOCACHE=$PWD/.cache/go-build && export GOMODCACHE=$PWD/.cache/go-modcache`
1919-- `go fmt ./...` then `go vet ./...`: Baseline formatting and static checks.
1919+- `gofumpt -l -w .` then `go vet ./...`: Baseline formatting and static checks.
2020- From the repo root, run `golangci-lint run ./...`: Expanded Go linters.
2121- `export ENABLE_MOCKS=1`: to test without kroger, openai credentials
2222- `go test ./...`: Run unit tests across all packages; add `-cover` when changing core logic.
···2626- `tailwind\generate.sh`: run when ever you change css or html
27272828## Coding Style & Naming Conventions
2929-- Go 1.24; keep code `gofmt`-clean before review. Favor small, focused functions and table-driven tests.
2929+- Go 1.24; keep code `gofumpt`-clean before review. Favor small, focused functions and table-driven tests.
3030- Exported identifiers in `CamelCase`; package-private helpers in `lowerCamel`. Template names mirror file names in `internal/templates`.
3131- Prefer standard library first; add dependencies sparingly and record rationale in PR description if new.
3232- Prefer simple html to javascript frameworks
+2-3
internal/mail/mail.go
···173173 for _, recipe := range recent {
174174 hashes = append(hashes, recipe.Hash)
175175 }
176176- cooked := rio.CookedHashes(ctx, hashes)
176176+ cooked := rio.FeedbackByHash(ctx, hashes)
177177 p.LastRecipes = lo.FilterMap(recent, func(r utypes.Recipe, _ int) (string, bool) {
178178- return r.Title, cooked[r.Hash]
178178+ return r.Title, cooked[r.Hash].Cooked
179179 })
180180-181180 // can orphan recipes here with crash or shutdown. Params should have a start time
182181183182 shoppingList, err = m.generator.GenerateRecipes(ctx, p)