docs(admin): fold admin-origin CORS into phase 3a Task 1

This commit is contained in:
Bas van Rossem
2026-06-17 18:49:16 +02:00
parent 7cdc88e824
commit bb0a0b2a57
2 changed files with 24 additions and 7 deletions

View File

@@ -60,16 +60,23 @@ apps/admin/ NEW workspace (mirror apps/worker)
--- ---
### Task 1: Backend — `role` on `/api/me` ### Task 1: Backend — `role` on `/api/me` + allow the admin origin (CORS)
**Files:** **Files:**
- Modify: `packages/shared/src/index.ts` (PublicUser) - Modify: `packages/shared/src/index.ts` (PublicUser)
- Modify: `apps/api/src/routes/me.ts` - Modify: `apps/api/src/routes/me.ts`
- Test: `apps/api/test/me.test.ts` (extend; or `apps/api/src/routes/me.test.ts` — match - Modify: `apps/api/src/env.ts` (default `WEB_ORIGINS`), `apps/api/.env.example` (comment +
where existing route tests live) default `CORS_ORIGINS`)
- Test: `apps/api/test/me.test.ts` (extend), `apps/api/test/cors.test.ts` (extend)
**Interfaces:** **Interfaces:**
- Produces: `PublicUser` now has `role: Role`; `MeResponse.user.role` is `'worker' | 'admin'`. - Produces: `PublicUser` now has `role: Role`; `MeResponse.user.role` is `'worker' | 'admin'`.
The default CORS/trustedOrigins list includes the admin dev origin `http://localhost:5174`.
**Why CORS:** the admin app runs on dev port 5174 and calls the API on :3000 cross-origin.
`env.WEB_ORIGINS` (used for both `hono/cors` and better-auth `trustedOrigins`) currently
defaults to only `http://localhost:5173`, so without this the admin app's sign-in and every
request are blocked in the browser.
- [ ] **Step 1: Write/extend the failing test.** Using the test helpers - [ ] **Step 1: Write/extend the failing test.** Using the test helpers
(`apps/api/test/helpers.ts`: `createTestUser`, `authToken`/`bearer`), assert that (`apps/api/test/helpers.ts`: `createTestUser`, `authToken`/`bearer`), assert that
@@ -92,10 +99,16 @@ export const PublicUser = z.object({
- [ ] **Step 4: Return `role` from the route.** In `apps/api/src/routes/me.ts`, add to the - [ ] **Step 4: Return `role` from the route.** In `apps/api/src/routes/me.ts`, add to the
`user` body: `role: ((session.user as { role?: string | null }).role ?? 'worker') as Role` `user` body: `role: ((session.user as { role?: string | null }).role ?? 'worker') as Role`
(import `Role`/`MeResponse` type from `@solelog/shared`). Keep the `MeResponse` typing. (import `Role`/`MeResponse` type from `@solelog/shared`). Keep the `MeResponse` typing.
- [ ] **Step 5: Run tests — pass.** Also run `yarn workspace @solelog/api typecheck`. - [ ] **Step 5: CORS — allow the admin origin.** Add `http://localhost:5174` to the
- [ ] **Step 6: Confirm worker app unaffected**`yarn workspace @solelog/worker test` default `WEB_ORIGINS` array in `apps/api/src/env.ts`
(`['http://localhost:5173', 'http://localhost:5174']`) and to the `CORS_ORIGINS=` line +
comment in `apps/api/.env.example`. Extend `apps/api/test/cors.test.ts` with a case
asserting the preflight allows `http://localhost:5174` (parametrize or add a second
origin assertion). Run the cors test — green.
- [ ] **Step 6: Run tests — pass.** Also run `yarn workspace @solelog/api typecheck`.
- [ ] **Step 7: Confirm worker app unaffected**`yarn workspace @solelog/worker test`
still green (it ignores the extra field). still green (it ignores the extra field).
- [ ] **Step 7: Commit**`feat(api): include role in /api/me response`. - [ ] **Step 8: Commit**`feat(api): include role in /api/me + allow admin origin in CORS`.
--- ---

View File

@@ -48,12 +48,16 @@ The admin app is a **client only** — it talks to the existing backend over HTT
bearer token. No DB access. It mirrors `apps/worker`'s toolchain and conventions exactly bearer token. No DB access. It mirrors `apps/worker`'s toolchain and conventions exactly
so the build can copy proven patterns. so the build can copy proven patterns.
### Backend change (the only one in 3a) ### Backend changes (minimal, in 3a)
- `packages/shared/src/index.ts`: add `role: Role` to `PublicUser` (so `MeResponse.user` - `packages/shared/src/index.ts`: add `role: Role` to `PublicUser` (so `MeResponse.user`
carries it). carries it).
- `apps/api/src/routes/me.ts`: include `role` in the response (read from the session user, - `apps/api/src/routes/me.ts`: include `role` in the response (read from the session user,
default `'worker'`). The worker app ignores the extra field — no worker change needed. default `'worker'`). The worker app ignores the extra field — no worker change needed.
- `apps/api/src/env.ts` + `.env.example`: add `http://localhost:5174` (the admin dev
origin) to the default `WEB_ORIGINS` / `CORS_ORIGINS`. Required because `WEB_ORIGINS`
drives both `hono/cors` and better-auth `trustedOrigins`; the admin app at :5174 calls
the API at :3000 cross-origin and would otherwise be blocked.
## Components ## Components