diff --git a/back/package.json b/back/package.json index e0c6bb0..c25487f 100644 --- a/back/package.json +++ b/back/package.json @@ -10,7 +10,11 @@ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\"", "test": "vitest run", "test:watch": "vitest", - "test:cov": "vitest run --coverage" + "test:cov": "vitest run --coverage", + "migration:generate": "typeorm-ts-node-commonjs migration:generate -d src/data-source.ts", + "migration:run": "typeorm-ts-node-commonjs migration:run -d src/data-source.ts", + "migration:revert": "typeorm-ts-node-commonjs migration:revert -d src/data-source.ts", + "migration:show": "typeorm-ts-node-commonjs migration:show -d src/data-source.ts" }, "dependencies": { "@asyncapi/bundler": "^1.0.1", diff --git a/back/src/app.module.ts b/back/src/app.module.ts index cf459a6..f9f83a7 100644 --- a/back/src/app.module.ts +++ b/back/src/app.module.ts @@ -22,7 +22,11 @@ import { validateEnv } from './config/env.validation'; password: config.getOrThrow('DATABASE_PASSWORD'), database: config.getOrThrow('DATABASE_NAME'), entities: [__dirname + '/**/*.entity{.ts,.js}'], + migrations: [__dirname + '/migrations/*{.ts,.js}'], + // Dev : synchronize auto (itération rapide). Prod : pas de synchronize, + // le schéma est appliqué par les migrations exécutées au démarrage. synchronize: config.get('NODE_ENV') !== 'production', + migrationsRun: config.get('NODE_ENV') === 'production', logging: config.get('NODE_ENV') === 'development', }), }), diff --git a/back/src/data-source.ts b/back/src/data-source.ts new file mode 100644 index 0000000..271ab74 --- /dev/null +++ b/back/src/data-source.ts @@ -0,0 +1,20 @@ +import 'reflect-metadata'; +import { DataSource } from 'typeorm'; + +/** + * DataSource dédié à la CLI TypeORM (migrations). Lit l'environnement + * directement (les mêmes DATABASE_* que l'app). Utilisé par les scripts + * migration:generate / migration:run / migration:revert. + * + * NB : la config runtime de l'app vit dans app.module.ts (TypeOrmModule). + */ +export default new DataSource({ + type: 'postgres', + host: process.env.DATABASE_HOST ?? 'localhost', + port: Number(process.env.DATABASE_PORT ?? 5432), + username: process.env.DATABASE_USER ?? 'datacat', + password: process.env.DATABASE_PASSWORD ?? 'datacat', + database: process.env.DATABASE_NAME ?? 'datacat', + entities: ['src/**/*.entity.ts'], + migrations: ['src/migrations/*.ts'], +}); diff --git a/back/src/migrations/1782543826810-InitialSchema.ts b/back/src/migrations/1782543826810-InitialSchema.ts new file mode 100644 index 0000000..33355fc --- /dev/null +++ b/back/src/migrations/1782543826810-InitialSchema.ts @@ -0,0 +1,16 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class InitialSchema1782543826810 implements MigrationInterface { + name = 'InitialSchema1782543826810' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE "categories" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" character varying(255) NOT NULL, "description" text, "parent_id" character varying(36), "order_index" integer NOT NULL DEFAULT '0', "created_at" TIMESTAMP NOT NULL DEFAULT now(), "updated_at" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_24dbc6126a28ff948da33e97d3b" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE TABLE "api_entries" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "convention" character varying(30) NOT NULL DEFAULT 'CONSULTER', "name" character varying(255) NOT NULL DEFAULT '', "description" text, "type" character varying(10) NOT NULL, "provider" character varying(255) NOT NULL DEFAULT '', "version_major" integer NOT NULL DEFAULT '0', "version_minor" integer NOT NULL DEFAULT '0', "version_patch" integer NOT NULL DEFAULT '0', "yaml_content" text NOT NULL, "html_path" character varying(500), "status" character varying(10) NOT NULL DEFAULT 'PENDING', "error_message" text, "category_id" character varying(36), "is_current" boolean NOT NULL DEFAULT true, "contact_functional_name" character varying(255) NOT NULL DEFAULT '', "contact_functional_entity" character varying(255) NOT NULL DEFAULT '', "contact_functional_email" character varying(255) NOT NULL DEFAULT '', "contact_technical_name" character varying(255) NOT NULL DEFAULT '', "contact_technical_entity" character varying(255) NOT NULL DEFAULT '', "contact_technical_email" character varying(255) NOT NULL DEFAULT '', "created_at" TIMESTAMP NOT NULL DEFAULT now(), "updated_at" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_d7b668541d2539a0c212b198d32" PRIMARY KEY ("id"))`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE "api_entries"`); + await queryRunner.query(`DROP TABLE "categories"`); + } + +}