refactor(admin): fusionne apps/admin-web dans apps/web sous /admin/* #18

Merged
kyuno merged 3 commits from feat/merge-admin-into-web into main 2026-08-29 21:15:44 +02:00
Owner

L'admin avait été livré (PR #15) comme une 2ᵉ application front Vite indépendante (apps/admin-web, port 5174, Dockerfile nginx, service admin-web dans docker-compose, job CI propre) — non demandé. Toute l'UI passe dans apps/web sous /admin/*. Seul le frontend est fusionné ; l'authentification admin reste entièrement séparée.

Front — tout dans apps/web/src

  • Pages → pages/admin/{login,dashboard,monitoring,corrections,catalog}/ ; layout → layouts/AdminLayout.tsx ; contexte + garde → features/admin/.
  • Client API → api/admin-client.ts : classe renommée AdminApiError (évite la collision avec le ApiError de api/client.ts), lit VITE_API_URL (plus de VITE_ADMIN_API_URL).
  • Routes /admin/* dans App.tsx, enveloppées d'AdminAuthProvider + RequireAdmin → le probe GET /admin/auth/me ne tourne que sous /admin, jamais sur les pages utilisateur.
  • Réutilise l'i18n, lib/zod-errors, services/error-message.service et le thème SCSS de apps/web. Bloc i18n admin.* fusionné dans locales/fr/translation.json (les clés errors étaient déjà toutes présentes).
  • Bug corrigé au passage : CatalogPage avait une race (la réponse d'un onglet précédent écrasait l'onglet courant, exposée par le double-mount React 18 StrictMode) → ajout d'un ref requestSeq.

Auth admin — inchangée

Table AdminUser, cookie admin_session, ADMIN_JWT_SECRET, script create-admin.ts, middleware requireAdmin. Séparation des privilèges conservée.

Infra

  • docker-compose.yml : service admin-web + ADMIN_WEB_PORT supprimés (le conteneur app sert déjà le front construit, qui contient maintenant les routes /admin).
  • ADMIN_CORS_ORIGIN retiré (même origine désormais) : apps/api/src/config/env.ts, app.ts, .env.example.
  • Job CI « Run admin-web E2E tests » supprimé ; les specs admin (apps/web/cypress/e2e/admin-*.{cy.ts,feature}) tournent dans le job web.
  • apps/api/.env.example : ajout de ADMIN_JWT_SECRET / ADMIN_INITIAL_* (absents jusqu'ici — cause du « je ne vois pas l'admin »).
  • recharts ajouté à apps/web/package.json ; pnpm-lock.yaml régénéré (net −76 lignes).
  • specs/backend-architecture.md : section ## admin mise à jour.

Vérification

  • biome check propre ; tsc -b (web + api) OK ; pnpm -r build 6/6 OK.
  • Cypress web e2e : 102/103. L'unique échec est le flake pré-existant recipe-form.feature « Preloads an existing recipe's ingredients when editing » (.ingredient-row__name non visible — clipping viewport headless, échoue à l'identique sur main), sans rapport avec l'admin.
  • 16/16 specs Cypress admin (admin-login.feature, admin-layout, admin-dashboard, admin-monitoring, admin-corrections, admin-catalog).
  • 45/45 tests composants.

Pour utiliser l'admin en local

ADMIN_JWT_SECRET=... (≥32 c, ≠ JWT_SECRET) dans apps/api/.env, créer un admin (pnpm --filter api exec tsx src/scripts/create-admin.ts --email=… --password=… --name=…), puis pnpm --filter web dev → http://localhost:5173/admin/login

🤖 Generated with Claude Code

L'admin avait été livré (PR #15) comme une **2ᵉ application front Vite indépendante** (`apps/admin-web`, port 5174, Dockerfile nginx, service `admin-web` dans `docker-compose`, job CI propre) — non demandé. Toute l'UI passe dans `apps/web` sous `/admin/*`. **Seul le frontend est fusionné** ; l'authentification admin reste entièrement séparée. ## Front — tout dans `apps/web/src` - Pages → `pages/admin/{login,dashboard,monitoring,corrections,catalog}/` ; layout → `layouts/AdminLayout.tsx` ; contexte + garde → `features/admin/`. - Client API → `api/admin-client.ts` : classe renommée `AdminApiError` (évite la collision avec le `ApiError` de `api/client.ts`), lit `VITE_API_URL` (plus de `VITE_ADMIN_API_URL`). - Routes `/admin/*` dans [`App.tsx`](apps/web/src/App.tsx), enveloppées d'`AdminAuthProvider` + `RequireAdmin` → le probe `GET /admin/auth/me` **ne tourne que sous `/admin`**, jamais sur les pages utilisateur. - Réutilise l'i18n, `lib/zod-errors`, `services/error-message.service` et le thème SCSS de `apps/web`. Bloc i18n `admin.*` fusionné dans `locales/fr/translation.json` (les clés `errors` étaient déjà toutes présentes). - **Bug corrigé au passage** : `CatalogPage` avait une race (la réponse d'un onglet précédent écrasait l'onglet courant, exposée par le double-mount React 18 StrictMode) → ajout d'un ref `requestSeq`. ## Auth admin — inchangée Table `AdminUser`, cookie `admin_session`, `ADMIN_JWT_SECRET`, script `create-admin.ts`, middleware `requireAdmin`. Séparation des privilèges conservée. ## Infra - `docker-compose.yml` : service `admin-web` + `ADMIN_WEB_PORT` supprimés (le conteneur `app` sert déjà le front construit, qui contient maintenant les routes `/admin`). - `ADMIN_CORS_ORIGIN` retiré (même origine désormais) : `apps/api/src/config/env.ts`, `app.ts`, `.env.example`. - Job CI « Run admin-web E2E tests » supprimé ; les specs admin (`apps/web/cypress/e2e/admin-*.{cy.ts,feature}`) tournent dans le job `web`. - `apps/api/.env.example` : ajout de `ADMIN_JWT_SECRET` / `ADMIN_INITIAL_*` (absents jusqu'ici — cause du « je ne vois pas l'admin »). - `recharts` ajouté à `apps/web/package.json` ; `pnpm-lock.yaml` régénéré (net −76 lignes). - `specs/backend-architecture.md` : section `## admin` mise à jour. ## Vérification - `biome check` propre ; `tsc -b` (web + api) OK ; `pnpm -r build` 6/6 OK. - Cypress `web` e2e : **102/103**. L'unique échec est le flake pré-existant `recipe-form.feature` « Preloads an existing recipe's ingredients when editing » (`.ingredient-row__name` non visible — clipping viewport headless, échoue à l'identique sur `main`), sans rapport avec l'admin. - **16/16** specs Cypress admin (`admin-login.feature`, `admin-layout`, `admin-dashboard`, `admin-monitoring`, `admin-corrections`, `admin-catalog`). - **45/45** tests composants. ## Pour utiliser l'admin en local `ADMIN_JWT_SECRET=...` (≥32 c, ≠ `JWT_SECRET`) dans `apps/api/.env`, créer un admin (`pnpm --filter api exec tsx src/scripts/create-admin.ts --email=… --password=… --name=…`), puis `pnpm --filter web dev` → http://localhost:5173/admin/login 🤖 Generated with [Claude Code](https://claude.com/claude-code)
kyuno added 1 commit 2026-08-29 17:03:01 +02:00
refactor(admin): fusionne apps/admin-web dans apps/web sous /admin/*
Some checks failed
CI / lint (push) Failing after 23s
CI / build (push) Successful in 3m11s
CI / e2e (push) Failing after 8m16s
CI / intent-service-test (push) Successful in 12m49s
CI / test (push) Successful in 21m34s
bbd9afe8aa
L'admin etait une 2e app front Vite independante (apps/admin-web, port 5174,
Dockerfile nginx, service compose dedie, job CI propre) non demandee. Toute
l'UI passe dans apps/web sous le prefixe /admin ; seul le frontend est
fusionne, l'authentification admin reste entierement separee.

Front (apps/web/src) :
- pages -> pages/admin/{login,dashboard,monitoring,corrections,catalog}/,
  layout -> layouts/AdminLayout.tsx, contexte + garde -> features/admin/.
- client API -> api/admin-client.ts : classe AdminApiError (evite la
  collision avec ApiError), lit VITE_API_URL (plus de VITE_ADMIN_API_URL).
- routes /admin/* dans App.tsx, enveloppees d'AdminAuthProvider +
  RequireAdmin -> le probe GET /admin/auth/me ne tourne que sous /admin.
- reutilise l'i18n, lib/zod-errors, services/error-message.service et le
  theme SCSS de apps/web ; bloc i18n admin.* fusionne dans la locale fr
  (les cles errors etaient deja toutes presentes).
- corrige une race dans CatalogPage (reponse d'un onglet precedent qui
  ecrasait l'onglet courant, exposee par le double-mount StrictMode) via
  un ref requestSeq.

Auth admin inchangee : table AdminUser, cookie admin_session,
ADMIN_JWT_SECRET, script create-admin.ts.

Infra :
- docker-compose : service admin-web + ADMIN_WEB_PORT supprimes (l'app
  `app` sert deja le front construit).
- ADMIN_CORS_ORIGIN retire (meme origine) : env.ts, app.ts, .env.example.
- job CI "Run admin-web E2E tests" supprime ; les specs admin-* tournent
  dans le job web (apps/web/cypress/e2e/admin-*.{cy.ts,feature}).
- apps/api/.env.example : ajout ADMIN_JWT_SECRET / ADMIN_INITIAL_*.
- recharts ajoute a apps/web ; pnpm-lock regenere.
- specs/backend-architecture.md : section admin mise a jour.

Verifie : biome + tsc -b (web/api) + pnpm -r build verts ; Cypress web
102/103 (l'unique echec est le flake pre-existant recipe-form.feature
"Preloads ..." de clipping headless, sans rapport) ; 16/16 specs admin ;
45/45 composants.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
kyuno added 1 commit 2026-08-29 19:28:56 +02:00
test(admin): fixe l'intercept monitoring (route page == chemin API)
Some checks failed
CI / build (push) Successful in 2m48s
CI / lint (push) Successful in 3m0s
CI / e2e (push) Successful in 12m51s
CI / intent-service-test (push) Successful in 16m53s
CI / test (push) Failing after 17m9s
1a28d67218
La route page `/admin/monitoring` et le chemin API `GET /admin/monitoring`
sont identiques : un glob `**/admin/monitoring` capturait aussi la requete
document du `cy.visit()`. Le hardcode `http://localhost:3000/...` marchait
en local (VITE_API_URL dans apps/web/.env) mais pas en CI (pas de .env ->
API en meme origine sur :5173, donc collision totale) : `cy.wait
(@getMonitoring)` timeout.

`resourceType: "fetch"` epingle l'intercept sur le seul XHR d'AdminApiClient.
Verifie en simulant la CI (sans apps/web/.env) : 16/16 specs admin verts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
kyuno added 1 commit 2026-08-29 20:54:54 +02:00
chore: re-declenche la CI
All checks were successful
CI / build (push) Successful in 2m36s
CI / lint (push) Successful in 2m39s
CI / e2e (push) Successful in 7m45s
CI / intent-service-test (push) Successful in 12m0s
CI / test (push) Successful in 20m12s
ccec30b2e8
Le job `test` du run precedent a echoue sur un flake du conteneur Postgres
`services:` du runner act (`relation "user_profile_allergy" does not exist`
juste apres « All migrations successfully applied », 0 test execute). Aucun
fichier lie a la DB n'a change dans cette PR, et le superset feat/temperature-
metadata a fait tourner `test` vert (516 passing).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
kyuno merged commit d5dca82af4 into main 2026-08-29 21:15:44 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: kyuno/batchCooking#18
No description provided.