Files
summercms/.planning/phases/07-user-plugin-and-authentication/07-08-SUMMARY.md
Jakub Zych b74484eabc docs(07-08): complete the avatar bucket publish plan
Serve and Handler now publish the uploads bucket; assembled avatar
POST is 200. Record the gap-closure outcome.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-23 10:50:01 +02:00

5.1 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
07-user-plugin-and-authentication 08 auth
avatar
blob
gocloud
serve
handler
phase provides
07-user-plugin-and-authentication avatar HTTP handlers and attach.OpenBucket/Publish from Phase 5
phase provides
05-data-layer-full-fidelity lagoon/attach OpenBucket, Publish, and mem:// support
surf.ServeCommand and app.Handler publish *blob.Bucket before Assemble
assembled Handler JPEG upload/remove proof that does not hand-publish a memblob
phase-7-verification
phase-12-media
added patterns
OpenBucket + Publish sit next to lagoon.Publish on every HTTP boot path
assembled tests set storage.uploads.bucket_url=mem://; unit tests may still publish memblob by hand
created modified
surf/serve_test.go
../fonoteka.go/parity/avatar_assembled_test.go
surf/serve.go
../fonoteka.go/app/app.go
../fonoteka.go/parity/migrate_test.go
../fonoteka.go/parity/genre_security_test.go
Both CLI serve and in-process Handler must publish *blob.Bucket; unit tests that call attach.Publish themselves cannot stand in for boot
Assembled Handler avatar coverage lives in parity/ next to newConfiguredTarget, not in the user plugin package
Pattern: empty storage.uploads.bucket_url fails boot as loudly as an empty JWT secret
Pattern: TestAvatarAssembled boots app.Handler and curls the real routes; TestUploadAvatar stays handler-unit coverage
25min 2026-09-23

Phase 7 Plan 08: Avatar bucket publish Summary

Serve and Handler open storage.uploads.bucket_url and publish *blob.Bucket so assembled avatar POST is 200, not an opaque 500.

Performance

  • Duration: 25 min
  • Started: 2026-09-23T08:24:00Z
  • Completed: 2026-09-23T08:49:38Z
  • Tasks: 3
  • Files modified: 6

Accomplishments

  • surf.ServeCommand opens the uploads bucket after lagoon.Publish and publishes it before Assemble; an empty URL fails boot.
  • app.Handler does the same so UAT and parity replay match CLI serve.
  • testConfig / testConfigCORS set mem:// so assembled tests boot without a filesystem uploads dir.
  • TestAvatarAssembled registers a user, logs in, POSTs a JPEG through app.Handler, then POSTs remove — without calling attach.Publish itself.

Task Commits

  1. Task 1: Publish the uploads bucket on serve and Handler — 44900f0 in summercms.go, bc1adf2 in fonoteka.go
  2. Task 2: Assembled-app avatar upload and remove — b91b728 in fonoteka.go
  3. Task 3: Race gate both modules — verification only (no code change)

Plan metadata: this docs commit

Files Created/Modified

  • surf/serve.go — publishUploads after lagoon.Publish; defer bucket.Close()
  • surf/serve_test.go — empty URL fails; mem:// stores a lookupable *blob.Bucket
  • ../fonoteka.go/app/app.go — OpenBucket + Publish on the Handler boot path
  • ../fonoteka.go/parity/migrate_test.go — testConfig sets mem:// and /storage/uploads
  • ../fonoteka.go/parity/genre_security_test.go — same keys on testConfigCORS
  • ../fonoteka.go/parity/avatar_assembled_test.go — JPEG upload/remove against app.Handler

Decisions Made

Avatar 500s were a missing boot-path publish, not a handler bug. Phase 5 shipped OpenBucket/Publish but never wired them; Phase 7 added HTTP avatar on top. Both serve and Handler must publish, because UAT and corpus replay boot via Handler.

Assembled proof belongs next to newConfiguredTarget so it cannot import memblob and call attach.Publish. Existing TestUploadAvatar / TestRemoveAvatar stay as handler-unit coverage.

Deviations from Plan

Auto-fixed Issues

1. Assembled test file location

  • Found during: Task 2
  • Issue: Plan files_modified listed avatar_test.go, but that package cannot reach app.Handler without a reverse import.
  • Fix: Added parity/avatar_assembled_test.go beside newConfiguredTarget, which the plan already allowed.
  • Verification: go test ./parity/ -run TestAvatarAssembled passed
  • Committed in: b91b728

Total deviations: 1 auto-fixed (test placement) Impact on plan: Same proof the plan asked for, on the boot path that hid the gap. No scope creep.

Issues Encountered

None

User Setup Required

None - no external service configuration required.

Next Phase Readiness

UAT blocker closed. go vet and go test -race are green in both modules. Ready for phase verification — do not auto-advance to Phase 8.

Self-Check: PASSED

  • Serve empty-URL boot fails; mem:// publishes a bucket (go test ./surf/ -run 'TestPublishUploads|TestServe')
  • Assembled JPEG upload 200 + remove clears has_avatar (TestAvatarAssembled)
  • TestUploadAvatar, TestRemoveAvatar, TestParityCorpus, TestUserAPINuxtFlows green
  • go vet ./... && go test ./... -race green in summercms.go and fonoteka.go plus nested plugin packages

Phase: 07-user-plugin-and-authentication Completed: 2026-09-23