diff --git a/back/src/modules/apis/dto/create-api-entry.dto.ts b/back/src/modules/apis/dto/create-api-entry.dto.ts index 3a30d25..9a61d0a 100644 --- a/back/src/modules/apis/dto/create-api-entry.dto.ts +++ b/back/src/modules/apis/dto/create-api-entry.dto.ts @@ -1,9 +1,9 @@ import { IsString, IsNotEmpty, IsIn, IsOptional, IsUUID, IsInt, Min, IsEmail } from 'class-validator'; import { Type } from 'class-transformer'; -import { ApiType, ApiConvention } from '@datacat/shared'; +import { ApiType, ApiConvention, API_CONVENTIONS, API_TYPES } from '@datacat/shared'; export class CreateApiEntryDto { - @IsIn(['CONSULTER', 'ENREGISTRER', 'ETRE_NOTIFIE']) + @IsIn([...API_CONVENTIONS]) convention!: ApiConvention; @IsString() @@ -33,7 +33,7 @@ export class CreateApiEntryDto { @IsOptional() description?: string; - @IsIn(['ASYNCAPI', 'OPENAPI']) + @IsIn([...API_TYPES]) type!: ApiType; @IsString() diff --git a/back/src/modules/apis/dto/update-api-entry.dto.ts b/back/src/modules/apis/dto/update-api-entry.dto.ts index 9e87bd9..5e15f80 100644 --- a/back/src/modules/apis/dto/update-api-entry.dto.ts +++ b/back/src/modules/apis/dto/update-api-entry.dto.ts @@ -1,9 +1,9 @@ import { IsString, IsOptional, IsUUID, IsIn, IsInt, Min, IsEmail } from 'class-validator'; import { Type } from 'class-transformer'; -import { ApiConvention } from '@datacat/shared'; +import { ApiConvention, API_CONVENTIONS } from '@datacat/shared'; export class UpdateApiEntryDto { - @IsIn(['CONSULTER', 'ENREGISTRER', 'ETRE_NOTIFIE']) + @IsIn([...API_CONVENTIONS]) @IsOptional() convention?: ApiConvention; diff --git a/front-public/package.json b/front-public/package.json index ab9604c..ff9aa45 100644 --- a/front-public/package.json +++ b/front-public/package.json @@ -10,6 +10,7 @@ "lint": "ng lint" }, "dependencies": { + "@datacat/shared": "workspace:*", "@angular/animations": "^19.0.0", "@angular/common": "^19.0.0", "@angular/compiler": "^19.0.0", diff --git a/shared/README.md b/shared/README.md new file mode 100644 index 0000000..456bcc8 --- /dev/null +++ b/shared/README.md @@ -0,0 +1,31 @@ +# @datacat/shared + +Types et constantes partagés entre le **back** (NestJS) et le **front** (Angular). + +## Contenu + +- `src/types/` — interfaces et types (`ApiEntry`, `Category`, réponses d'API…). +- `src/schemas/api-entry.schema.ts` — **source de vérité** des énumérations + (`API_TYPES`, `API_STATUSES`, `API_CONVENTIONS`). Les types `ApiType` / + `ApiStatus` / `ApiConvention` en sont **dérivés** (`typeof X[number]`), et la + validation back (`@IsIn`) réutilise ces mêmes constantes. Ajouter une valeur + dans le tableau suffit donc à propager type + validation. + +## Double build (piège récurrent) + +Ce paquet est consommé de **deux façons différentes** : + +| Consommateur | Mécanisme | Config | +|--------------|-----------|--------| +| **front** (Angular) | alias TypeScript vers la **source** | `tsconfig.json` (ES2022) + `paths` dans `front-public/tsconfig.json` | +| **back** (NestJS) | paquet **compilé** (`dist/`) en CommonJS | `tsconfig.build.json` (CommonJS) → `dist/` | + +⚠️ Le back lit `dist/`, pas la source. Après toute modification de `shared`, il +faut **rebuild** avant que le back voie le changement : + +```sh +pnpm --filter @datacat/shared build +# (le docker-compose le fait déjà : voir infra/docker-compose.yml, étape tsc) +``` + +Le front, lui, voit la source directement (pas de rebuild nécessaire). diff --git a/shared/package.json b/shared/package.json index d346909..16dc6b9 100644 --- a/shared/package.json +++ b/shared/package.json @@ -1,9 +1,17 @@ { "name": "@datacat/shared", "version": "0.1.0", + "description": "Types et constantes partagés entre le back (NestJS) et le front (Angular) de Datacat.", + "license": "UNLICENSED", "private": true, "main": "dist/index.js", "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, "scripts": { "build": "tsc --project tsconfig.build.json" } diff --git a/shared/src/schemas/api-entry.schema.ts b/shared/src/schemas/api-entry.schema.ts index 762be48..d2e0532 100644 --- a/shared/src/schemas/api-entry.schema.ts +++ b/shared/src/schemas/api-entry.schema.ts @@ -1,3 +1,7 @@ +// Source de vérité unique pour les énumérations d'API. +// Les types (`ApiType`, `ApiStatus`, `ApiConvention`) sont dérivés de ces +// constantes dans `../types/api-entry.types.ts`, et la validation back +// (class-validator `@IsIn`) les réutilise — pas de duplication. export const API_TYPES = ['ASYNCAPI', 'OPENAPI'] as const; -export const API_STATUSES = ['PENDING', 'GENERATED', 'ERROR'] as const; +export const API_STATUSES = ['PENDING', 'GENERATED', 'ERROR', 'NO_YAML'] as const; export const API_CONVENTIONS = ['CONSULTER', 'ENREGISTRER', 'ETRE_NOTIFIE'] as const; diff --git a/shared/src/types/api-entry.types.ts b/shared/src/types/api-entry.types.ts index 27ee89c..47a8c30 100644 --- a/shared/src/types/api-entry.types.ts +++ b/shared/src/types/api-entry.types.ts @@ -1,8 +1,12 @@ -export type ApiType = 'ASYNCAPI' | 'OPENAPI'; +import { API_TYPES, API_STATUSES, API_CONVENTIONS } from '../schemas/api-entry.schema'; -export type ApiStatus = 'PENDING' | 'GENERATED' | 'ERROR' | 'NO_YAML'; +// Types dérivés des constantes (source de vérité dans api-entry.schema.ts) : +// ajouter une valeur dans le tableau suffit à mettre à jour le type. +export type ApiType = (typeof API_TYPES)[number]; -export type ApiConvention = 'CONSULTER' | 'ENREGISTRER' | 'ETRE_NOTIFIE'; +export type ApiStatus = (typeof API_STATUSES)[number]; + +export type ApiConvention = (typeof API_CONVENTIONS)[number]; export const API_CONVENTION_LABELS: Record = { CONSULTER: 'Consulter',