{
	"author": { "id": "U_kgDOEJnaPw", "is_bot": false, "login": "xpressmike", "name": "Mike" },
	"body": "## Summary\n\nEmDash's Cloudflare D1 session adapter (`@emdash-cms/cloudflare/src/db/d1.ts`) routes reads to either `first-primary`, the bookmark from a prior write, or `first-unconstrained` based on `opts.isAuthenticated`. In the Astro middleware (`src/astro/middleware.ts:282`), `isAuthenticated` is set to `!!sessionUser`, and `sessionUser` is read only from the `astro-session` cookie:\n\n```ts\nconst hasSessionCookie = cookies.get(\"astro-session\") !== undefined;\nconst sessionUser = context.isPrerendered || !hasSessionCookie\n    ? null\n    : await context.session?.get(\"user\");\n```\n\nAs a result, requests authenticated via `Authorization: Bearer <PAT>` (issued by `_emdash/api/auth` or directly to D1) are treated as anonymous by the D1 adapter:\n\n- **Writes** still hit primary (correct — `isWrite=true` forces `first-primary`).\n- **Reads** go to `first-unconstrained` (any replica), and the bookmark cookie is never persisted because `commit()` early-returns when `!opts.isAuthenticated`.\n\nThis means: a Bearer-authenticated client can POST data, get 200 back, and a subsequent GET (even seconds later) returns stale results from a replica that hasn't caught up.\n\n## Repro\n\nA Python script using `Authorization: Bearer ec_pat_…` to call `POST /content/posts/{slug}/terms/{tax}` and then immediately `GET` the same path: POST returns the term in the response body, GET returns empty.\n\n## Workaround we adopted\n\nSwitched `astro.config.mjs` `d1({ binding: \"DB\", session: \"primary-first\" })`. This forces every read (anonymous or not) to start at primary — kills replica reads entirely. Tolerable on a small site, but defeats the purpose of read replicas on larger ones.\n\n## Suggested fix\n\nPopulate `sessionUser` (or a sibling flag like `isApiAuthenticated`) from the resolved user when Bearer auth succeeded. The auth resolver already runs upstream of `createRequestScopedDb`; passing `user` rather than re-reading the cookie would let API clients benefit from primary-first / bookmark-resumed reads.\n\nTested against emdash 0.9.0. Happy to discuss approach if helpful.",
	"labels": [],
	"number": 1046,
	"title": "Bearer-token API clients don't get D1 read-your-writes (sessionUser only set from astro-session cookie)"
}
