Refonte qualité (shared / back / front) #1
@@ -1,9 +1,9 @@
|
|||||||
import { IsString, IsNotEmpty, IsIn, IsOptional, IsUUID, IsInt, Min, IsEmail } from 'class-validator';
|
import { IsString, IsNotEmpty, IsIn, IsOptional, IsUUID, IsInt, Min, IsEmail } from 'class-validator';
|
||||||
import { Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
import { ApiType, ApiConvention } from '@datacat/shared';
|
import { ApiType, ApiConvention, API_CONVENTIONS, API_TYPES } from '@datacat/shared';
|
||||||
|
|
||||||
export class CreateApiEntryDto {
|
export class CreateApiEntryDto {
|
||||||
@IsIn(['CONSULTER', 'ENREGISTRER', 'ETRE_NOTIFIE'])
|
@IsIn([...API_CONVENTIONS])
|
||||||
convention!: ApiConvention;
|
convention!: ApiConvention;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
@@ -33,7 +33,7 @@ export class CreateApiEntryDto {
|
|||||||
@IsOptional()
|
@IsOptional()
|
||||||
description?: string;
|
description?: string;
|
||||||
|
|
||||||
@IsIn(['ASYNCAPI', 'OPENAPI'])
|
@IsIn([...API_TYPES])
|
||||||
type!: ApiType;
|
type!: ApiType;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { IsString, IsOptional, IsUUID, IsIn, IsInt, Min, IsEmail } from 'class-validator';
|
import { IsString, IsOptional, IsUUID, IsIn, IsInt, Min, IsEmail } from 'class-validator';
|
||||||
import { Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
import { ApiConvention } from '@datacat/shared';
|
import { ApiConvention, API_CONVENTIONS } from '@datacat/shared';
|
||||||
|
|
||||||
export class UpdateApiEntryDto {
|
export class UpdateApiEntryDto {
|
||||||
@IsIn(['CONSULTER', 'ENREGISTRER', 'ETRE_NOTIFIE'])
|
@IsIn([...API_CONVENTIONS])
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
convention?: ApiConvention;
|
convention?: ApiConvention;
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
"lint": "ng lint"
|
"lint": "ng lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@datacat/shared": "workspace:*",
|
||||||
"@angular/animations": "^19.0.0",
|
"@angular/animations": "^19.0.0",
|
||||||
"@angular/common": "^19.0.0",
|
"@angular/common": "^19.0.0",
|
||||||
"@angular/compiler": "^19.0.0",
|
"@angular/compiler": "^19.0.0",
|
||||||
|
|||||||
31
shared/README.md
Normal file
31
shared/README.md
Normal file
@@ -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).
|
||||||
@@ -1,9 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "@datacat/shared",
|
"name": "@datacat/shared",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
"description": "Types et constantes partagés entre le back (NestJS) et le front (Angular) de Datacat.",
|
||||||
|
"license": "UNLICENSED",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc --project tsconfig.build.json"
|
"build": "tsc --project tsconfig.build.json"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_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;
|
export const API_CONVENTIONS = ['CONSULTER', 'ENREGISTRER', 'ETRE_NOTIFIE'] as const;
|
||||||
|
|||||||
@@ -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<ApiConvention, string> = {
|
export const API_CONVENTION_LABELS: Record<ApiConvention, string> = {
|
||||||
CONSULTER: 'Consulter',
|
CONSULTER: 'Consulter',
|
||||||
|
|||||||
Reference in New Issue
Block a user