- POST /account/avatar with no multipart part (NextPart io.EOF) or a broken
boundary fell through to the generic 500; it is now the invalid-body 422
- a body over the cap still answers 413 payload_too_large
- cabana.BackendUser is an attach.Owner (MorphName Backend\Models\User,
cabana.BackendUserMorphType) with one public attachOne avatar
(cabana.BackendUserAvatarField), as WinterCMS stores it
- POST /account/avatar stores one file_data image (jpg, jpeg, png, gif or
webp, image guard, at most cabana.AvatarMaxBytes = 2 MiB, under a
server-generated name) and replaces the previous avatar: old rows are
deleted in the transaction, their blobs after the commit
- DELETE /account/avatar removes the avatar and is idempotent
- GET /auth/me and the account routes return avatar {url, thumb_url}
(250x250 crop); cabana.BackendUserAvatar lets plugins read it
- swag annotations, regenerated admin.json and schema.d.ts; route
inventories, CSRF walk (29) and OpenAPI conformance learn both routes
- SPA: avatar upload and remove on My account, avatar image in the user
menu trigger and header; backend::lang.myaccount avatar strings
- rebuilt boardwalk dist; cabana README, users-and-permissions and
admin-spa docs
- lagoon: 202610090001_backend_users_metadata adds WinterCMS's nullable
jsonable backend_users.metadata column (TEXT); rollback drops only it
- cabana.BackendUser.Metadata and Subtitle read metadata.subtitle leniently
(NULL, blank, null, [], invalid JSON and non-strings read as empty)
- GET /auth/me returns subtitle; PUT /account edits the signed-in admin's
own names, email and subtitle, and the password with current_password;
any other key is a 422 and nothing is written
- email: required, valid, 6-255 chars, unique against other admins' email
and login ignoring case (soft-deleted included); a unique-index race is 422
- a password change sets tokens_valid_after, revokes the presented token and
gives a cookie session a fresh cookie
- swag annotation, regenerated admin.json and schema.d.ts; route inventories,
CSRF walk (27) and OpenAPI conformance learn the route
- SPA: My account item in the user menu opens /account (AccountView), which
saves through PUT /account and updates the top bar via setCurrentUser
- backend::lang.myaccount strings (en, pl), rebuilt boardwalk dist
- cabana and lagoon READMEs, users-and-permissions and admin-spa docs