Skip to content

feat(server-nestjs): migrer vers Zod 4 (catalog runtime + @ts-rest ClientInfer->z.infer) - #2559

Closed
shikanime wants to merge 1 commit into
mainfrom
feat/zod4-migration
Closed

feat(server-nestjs): migrer vers Zod 4 (catalog runtime + @ts-rest ClientInfer->z.infer)#2559
shikanime wants to merge 1 commit into
mainfrom
feat/zod4-migration

Conversation

@shikanime

Copy link
Copy Markdown
Member

Issues liées

#2558


Quel est le comportement actuel ?

apps/server-nestjs utilise Zod 3 via le catalog runtime, et dérive ses types de contrat @ts-rest via ClientInferRequest / ClientInferResponseBody. @ts-rest/core@3.52.1 lit les internals Zod 3 : face à des schémas Zod 4, ces types résolvent en never et empoisonnent ~36 types dérivés (ProjectV2, CreateProjectBody, etc.).

Quel est le nouveau comportement ?

  • Le catalog runtime passe à zod ^4.4.3 (et zod-validation-error ^5.0.0). @cpn-console/shared et apps/server (gelé) restent sur Zod 3.
  • @ts-rest/* n'est pas remonté en version : on substitue nativement z.infer<typeof contrat.route.body/query/params/responses[200]> aux sites ClientInfer* dans packages/shared/src/contracts/* (26 sites). Aucun type never résiduel.
  • pluginUpdateBody corrigé en z.record(z.string(), z.record(z.string(), z.string())) (forme imbriquée 2 niveaux valide en Zod 4).
  • Adaptation des points d'API Zod 3 -> Zod 4 : z._type -> z.infer, SafeParseReturnType -> ZodSafeParseResult, ZodError.flatten, z.string().url()/.ip()/.cidr(), z.record à 2 arguments, pipe de transform.
  • @ts-rest/* retiré de apps/server-nestjs/package.json (0 import source vérifié).

Cette PR introduit-elle un breaking change ?

Non pour l'API. apps/server (Zod 3) n'est pas modifié ; l'isolation de catalog évite toute régression de type runtime.

Autres informations

Vérifications : shared/hooks/logger/server-nestjs build verts (zod 4.4.3 partout), pnpm run build nest sans erreur, vitest server-nestjs 574 passés / 0 échoué (16 skippés). Le test anciennement refusant (project-services.service.spec.ts) passe désormais.

Mise à niveau de dépendance : nécessite l'approbation de l'équipe CPiN pour le merge (conformément à CONTRIBUTING.md).

@shikanime shikanime self-assigned this Aug 24, 2026
@shikanime shikanime changed the title feat(server-nestjs): migraterer vers Zod 4 (catalog runtime + @ts-rest ClientInfer->z.infer) feat(server-nestjs): migrer vers Zod 4 (catalog runtime + @ts-rest ClientInfer->z.infer) Aug 24, 2026
@shikanime shikanime added the technical debt Résoud de la dette technique label Aug 24, 2026
@shikanime
shikanime requested a review from almorelle August 24, 2026 15:32
@shikanime
shikanime force-pushed the feat/zod4-migration branch 2 times, most recently from df283fa to 5c9b030 Compare August 24, 2026 17:58
Keep @cpn-console/shared, @cpn-console/hooks, apps/server and apps/client
on zod 3. Pin only apps/server-nestjs to zod ^4.4.3 as a direct
dependency so zod 4 stays nested under server-nestjs.

Root cause of the earlier CI failures: @anatine/zod-openapi (reached via
@ts-rest/open-api in apps/server) declares a zod peer range `^3.22 || ^4`.
As soon as zod 4 existed anywhere in the workspace, pnpm resolved it to
zod 4, which dragged @ts-rest/core (apps/server) onto zod 4 and broke the
@ts-rest AppRouter contract typing (zod-3 ZodObject missing zod-4 internals).

Fix:
- pnpm-workspace.yaml: override `@anatine/zod-openapi>zod` to 3.25.76 so
  apps/server's @ts-rest subtree stays on zod 3 (matches main).
- apps/server-nestjs/package.json: zod ^4.4.3; drop the unused
  @ts-rest/core / @ts-rest/fastify / @ts-rest/open-api declarations (0
  source imports) that also pulled zod 4 into the shared graph.
- src/config/validators.ts: localize atomicValidators / pluginConfig /
  editStrippersGenerator / editStrippers (zod-4 copies of the shared/hooks
  zod-3 values) to avoid crossing the schema-major boundary at runtime
  (.merge of a zod-3 schema into a zod-4 object throws).
- project-services.utils.ts & system-config.service.ts: consume the
  localized validators instead of the zod-3 exports from shared/hooks.
- zod-4 internal config fixes (base.config, config.utils, keycloak utils,
  version-agnostic ZodValidationPipe).

Verified: shared/hooks/apps-server/client byte-identical to main;
apps/server AppRouter error resolved; server-nestjs builds + 574 tests
pass; shared 74 + hooks 17 tests pass.

Related: #2558
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: Ib9877eaacb3e1de19186b24d277c0dd56a6a6964
@cloud-pi-native-sonarqube

Copy link
Copy Markdown

@shikanime
shikanime removed the request for review from almorelle August 31, 2026 09:41
@shikanime

Copy link
Copy Markdown
Member Author

Not feasible because of legacy server

@shikanime shikanime closed this Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

built technical debt Résoud de la dette technique

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant