Skip to content

docs(identity): document the profile ETag/If-Match precondition - #246

Open
marcelo-maciel wants to merge 1 commit into
fullstackhero:mainfrom
marcelo-maciel:docs/identity-profile-concurrency
Open

docs(identity): document the profile ETag/If-Match precondition#246
marcelo-maciel wants to merge 1 commit into
fullstackhero:mainfrom
marcelo-maciel:docs/identity-profile-concurrency

Conversation

@marcelo-maciel

@marcelo-maciel marcelo-maciel commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Documents the optimistic-concurrency precondition added to PUT /identity/profile in
fullstackhero/dotnet-starter-kit#1366 (fixes fullstackhero/dotnet-starter-kit#1359).

Identity module page

New Profile concurrency section under Public API highlights: what the lost update looked
like, the ETag/If-Match exchange with a short HTTP sample, and the details a caller actually
trips over:

  • the header is optional, so existing callers are unaffected, and If-Match: * is accepted
  • a weak validator never matches, because If-Match mandates the strong comparison function
  • a malformed header answers 400, not 412 (a 412 would trap a client in a retry loop it
    cannot win)
  • the precondition runs before any storage call, so a rejected update never orphans an uploaded
    avatar nor clears the current one
  • clients should refetch and retry once on 412, since the stamp also rotates on writes a user
    does not think of as profile edits (password change, new avatar, failed sign-in)
  • the CORS requirement: the contract is invisible to a browser on another origin without the
    ETag exposure and the if-match allow-entry

The two /profile rows in the endpoints table now mention the ETag and the If-Match / 412
behaviour.

Changelog

One dated entry for the fix plus a second for the CORS change, since anyone who replaced the
kit's CORS policy with their own has to carry the ETag exposure and the if-match allow-entry
or the precondition silently degrades back to a lost update.

npx astro check: 0 errors, 0 warnings (21 pre-existing hints).

The changelog heading is dated 2026-08-17, the day the code PR opened, following docs#239. Happy to
move it to the merge date if the code PR lands later.

`PUT /identity/profile` gained an optimistic concurrency precondition: `GET /profile`
returns the user's `ConcurrencyStamp` as a strong `ETag`, `PUT` honours `If-Match`, and
a stale token is answered with `412` instead of overwriting the newer write.

Documents the optional-header behaviour, the `*` and weak-validator rules, why a
malformed header is a `400`, the guard running ahead of any storage call, and the
retry-once guidance for clients (the stamp rotates on writes a user does not perceive
as profile edits). Also notes the CORS requirement, since the contract is invisible to
a browser on another origin without the `ETag` exposure and the `if-match` allow-entry.

Accompanies fullstackhero/dotnet-starter-kit#1366.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant