From 4bb337e28b929252411f1c5ad959cca1690fddf9 Mon Sep 17 00:00:00 2001 From: Yusuf Falade Date: Wed, 25 Feb 2026 14:43:06 +0100 Subject: [PATCH] created the validation service and swagger set up --- src/config/env.validation.ts | 34 +++++++++++++++++++++++++++++++ src/config/swagger.config.ts | 39 ++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/config/env.validation.ts create mode 100644 src/config/swagger.config.ts diff --git a/src/config/env.validation.ts b/src/config/env.validation.ts new file mode 100644 index 0000000..be3256b --- /dev/null +++ b/src/config/env.validation.ts @@ -0,0 +1,34 @@ +import * as Joi from 'joi'; + +export const envValidationSchema = Joi.object({ + // App + NODE_ENV: Joi.string() + .valid('development', 'production', 'test', 'staging') + .default('development'), + PORT: Joi.number().default(3000), + + // Database + DB_HOST: Joi.string().required(), + DB_PORT: Joi.number().default(5432), + DB_USERNAME: Joi.string().required(), + DB_PASSWORD: Joi.string().required(), + DB_NAME: Joi.string().required(), + DB_SSL: Joi.boolean().default(false), + + // JWT + JWT_SECRET: Joi.string().min(32).required(), + JWT_EXPIRATION: Joi.string().default('7d'), + JWT_REFRESH_SECRET: Joi.string().min(32).required(), + JWT_REFRESH_EXPIRATION: Joi.string().default('30d'), + + // Cloudinary + CLOUDINARY_CLOUD_NAME: Joi.string().required(), + CLOUDINARY_API_KEY: Joi.string().required(), + CLOUDINARY_API_SECRET: Joi.string().required(), + + // Redis + REDIS_HOST: Joi.string().required(), + REDIS_PORT: Joi.number().default(6379), + REDIS_PASSWORD: Joi.string().optional().allow(''), + REDIS_TTL: Joi.number().default(3600), +}).options({ allowUnknown: true, abortEarly: false }); diff --git a/src/config/swagger.config.ts b/src/config/swagger.config.ts new file mode 100644 index 0000000..e107f81 --- /dev/null +++ b/src/config/swagger.config.ts @@ -0,0 +1,39 @@ +import { INestApplication } from '@nestjs/common'; +import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; + +export function setupSwagger(app: INestApplication): void { + const config = new DocumentBuilder() + .setTitle('TeachLink API') + .setDescription('TeachLink backend API documentation') + .setVersion('1.0') + .addBearerAuth( + { + type: 'http', + scheme: 'bearer', + bearerFormat: 'JWT', + name: 'Authorization', + description: 'Enter JWT token', + in: 'header', + }, + 'access-token', + ) + .addTag('Auth', 'Authentication and authorization endpoints') + .addTag('Users', 'User management endpoints') + .addTag('Courses', 'Course management endpoints') + .addTag('Payments', 'Payment processing endpoints') + .addTag('Subscriptions', 'Subscription management endpoints') + .addServer('http://localhost:3000', 'Local Development') + .addServer('https://api.teachlink.com', 'Production') + .build(); + + const document = SwaggerModule.createDocument(app, config); + + SwaggerModule.setup('api/docs', app, document, { + swaggerOptions: { + persistAuthorization: true, + tagsSorter: 'alpha', + operationsSorter: 'alpha', + }, + customSiteTitle: 'TeachLink API Docs', + }); +}