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>
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 |
|
|
|
|
|
|
|
|
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.ServeCommandopens the uploads bucket afterlagoon.Publishand publishes it beforeAssemble; an empty URL fails boot.app.Handlerdoes the same so UAT and parity replay match CLI serve.testConfig/testConfigCORSsetmem://so assembled tests boot without a filesystem uploads dir.TestAvatarAssembledregisters a user, logs in, POSTs a JPEG throughapp.Handler, then POSTs remove — without callingattach.Publishitself.
Task Commits
- Task 1: Publish the uploads bucket on serve and Handler —
44900f0insummercms.go,bc1adf2infonoteka.go - Task 2: Assembled-app avatar upload and remove —
b91b728infonoteka.go - Task 3: Race gate both modules — verification only (no code change)
Plan metadata: this docs commit
Files Created/Modified
surf/serve.go—publishUploadsafterlagoon.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—testConfigsetsmem://and/storage/uploads../fonoteka.go/parity/genre_security_test.go— same keys ontestConfigCORS../fonoteka.go/parity/avatar_assembled_test.go— JPEG upload/remove againstapp.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_modifiedlistedavatar_test.go, but that package cannot reachapp.Handlerwithout a reverse import. - Fix: Added
parity/avatar_assembled_test.gobesidenewConfiguredTarget, which the plan already allowed. - Verification:
go test ./parity/ -run TestAvatarAssembledpassed - 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,TestUserAPINuxtFlowsgreengo vet ./... && go test ./... -racegreen insummercms.goandfonoteka.goplus nested plugin packages
Phase: 07-user-plugin-and-authentication Completed: 2026-09-23