Appendix — Portrait of the Cook
05 JUL AT 08:40 PM

Appendix — Portrait of the Cook

0 LOVES 2 VIEWS
Eager-load the author avatar.

V3 — Request: eager-load the guide author's avatar on the api/v1 post-detail path

One-line parity gap found while closing UTS punchlist item V3 (Flutter guide-lightbox masthead medallion). No Flutter change needed — the app already reads the field; the payload just never contains it.

Go-team review folded in (2026-07-04). All 6 claims verified at the cited lines across the three codebases; the fix is exact web parity. Safety review (the doc originally left this for the Go team to re-derive): - PII: User's sensitive fields (password_hash, mfa_secret, sign-in IPs, payout_email) are ent .Sensitive() → excluded from JSON regardless. The change adds only a Media object — the same shape cover_image already exposes in the same payload. - Redaction interplay: RedactGuideAnswers (handlers/posts.go:158) touches step answer options only — unaffected. - Serialization path: guides ride the PostDetail response (posts.go:130 → route /posts/{slug}); unloaded ent edges don't marshal, loaded ones do — so the one-liner is the whole change. - Perf: one extra eager-load per guide author on a post (1–5 guides) — negligible.

Problem

The Flutter guide masthead (GuideBand) renders an author medallion from guide.created_by, preferring the avatar image and falling back to initials:

  • flutter/gokonversed/lib/shared/widgets/organisms/guide_lightbox/guide_band.dart:96 reads guide.edges?.createdBy?.edges?.avatar

The kontent web path eager-loads exactly that:

  • internal/http/web/kontent/v1/services/guide.go:68 (and :114): WithCreatedBy(func(uq *ent.UserQuery) { uq.WithAvatar() })

But the api/v1 path Flutter calls loads the author WITHOUT the avatar edge:

  • internal/http/api/v1/services/guide_read.go:69 (GetGuidesForPost): WithCreatedBy(). — the only WithCreatedBy in the file.

Result: created_by.edges.avatar is never present in the api/v1 payload, so the Flutter medallion can only ever show initials — the author photo path is dead code.

Requested change

In internal/http/api/v1/services/guide_read.go:69, match kontent:

// before
WithCreatedBy().

// after
WithCreatedBy(func(uq *ent.UserQuery) { uq.WithAvatar() }).

(If the me-guides path should show author photos later: [Review precision] its guide load — GetAllProgressForUser, same file — carries no WithCreatedBy at all, so "same treatment" there means adding the whole WithCreatedBy(func(uq *ent.UserQuery) { uq.WithAvatar() }) call, not extending an existing one. Nothing consumes it there today — Flutter's createdBy reads exist only in the models and guide_band.dart.)

Verification

  1. GET /api/v1/{site}/{locale}/posts/{slug} for a post with an attached guide whose creator has an avatar → guides[n].edges.created_by.edges.avatar present.
  2. Flutter: open that guide's lightbox → the masthead medallion shows the photo instead of the initial. [Review precision] dev has EXACTLY ZERO user avatars (media.user_avatar count = 0, measured 2026-07-04) — not "mostly none" — so this step requires setting one first (profile admin), or assert the payload shape only (the as-built Go test does exactly that).

No schema/codegen change; no Flutter change; one service line.

As-built (implemented 2026-07-04)

  • guide_read.go GetGuidesForPost: WithCreatedBy()WithCreatedBy(func(uq *ent.UserQuery) { uq.WithAvatar() }) — byte-parity with kontent guide.go:68. Build + existing api/v1 test suite green.
  • Verification handed to the Flutter team (operator decision 2026-07-04): no Go payload-shape test was added; the Flutter track verifies end-to-end (set an avatar on a dev user — dev currently has zero — then confirm the masthead medallion renders the photo; the payload shape rides along). The medallion code path itself was already verified Flutter-side in 22.4.
← Back to Under the Tuscan Sun