swagger
This commit is contained in:
+11
-1
@@ -3,6 +3,16 @@
|
|||||||
"collection": "@nestjs/schematics",
|
"collection": "@nestjs/schematics",
|
||||||
"sourceRoot": "src",
|
"sourceRoot": "src",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"deleteOutDir": true
|
"deleteOutDir": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "@nestjs/swagger",
|
||||||
|
"options": {
|
||||||
|
"classValidatorShim": true,
|
||||||
|
"introspectComments": true,
|
||||||
|
"dtoFileNameSuffix": [".dto.ts", ".entity.ts"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+79
-5
@@ -16,6 +16,7 @@
|
|||||||
"@nestjs/jwt": "^11.0.2",
|
"@nestjs/jwt": "^11.0.2",
|
||||||
"@nestjs/passport": "^11.0.5",
|
"@nestjs/passport": "^11.0.5",
|
||||||
"@nestjs/platform-express": "^11.0.1",
|
"@nestjs/platform-express": "^11.0.1",
|
||||||
|
"@nestjs/swagger": "^11.4.5",
|
||||||
"@nestjs/typeorm": "^11.0.2",
|
"@nestjs/typeorm": "^11.0.2",
|
||||||
"axios": "^1.18.1",
|
"axios": "^1.18.1",
|
||||||
"bcrypt": "^6.0.0",
|
"bcrypt": "^6.0.0",
|
||||||
@@ -2071,6 +2072,12 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@microsoft/tsdoc": {
|
||||||
|
"version": "0.16.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.16.0.tgz",
|
||||||
|
"integrity": "sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@napi-rs/wasm-runtime": {
|
"node_modules/@napi-rs/wasm-runtime": {
|
||||||
"version": "1.1.6",
|
"version": "1.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz",
|
||||||
@@ -2391,6 +2398,26 @@
|
|||||||
"@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0"
|
"@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@nestjs/mapped-types": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-SCCoMEJ6jdeI5h/N+KCVF1+pmg/hmEkNA5nHTS8Gvww7T/LCl4o1gFLinw2iQ60w7slFkszHcGLKGdazVI4F8A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
||||||
|
"class-transformer": "^0.4.0 || ^0.5.0",
|
||||||
|
"class-validator": "^0.13.0 || ^0.14.0 || ^0.15.0",
|
||||||
|
"reflect-metadata": "^0.1.12 || ^0.2.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"class-transformer": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"class-validator": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@nestjs/passport": {
|
"node_modules/@nestjs/passport": {
|
||||||
"version": "11.0.5",
|
"version": "11.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-11.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-11.0.5.tgz",
|
||||||
@@ -2588,6 +2615,39 @@
|
|||||||
"tslib": "^2.1.0"
|
"tslib": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@nestjs/swagger": {
|
||||||
|
"version": "11.4.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-11.4.5.tgz",
|
||||||
|
"integrity": "sha512-lvndlJmWBVDOUT0uEtLi6sSpW1syK2/nbAlHBhiELBORMpJGe9+EiWAT9qHtB10jW91L2Jmlwkr0/lttsYZrig==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@microsoft/tsdoc": "0.16.0",
|
||||||
|
"@nestjs/mapped-types": "2.1.1",
|
||||||
|
"js-yaml": "4.3.0",
|
||||||
|
"lodash": "4.18.1",
|
||||||
|
"path-to-regexp": "8.4.2",
|
||||||
|
"swagger-ui-dist": "5.32.8"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@fastify/static": "^8.0.0 || ^9.0.0",
|
||||||
|
"@nestjs/common": "^11.0.1",
|
||||||
|
"@nestjs/core": "^11.0.1",
|
||||||
|
"class-transformer": "*",
|
||||||
|
"class-validator": "*",
|
||||||
|
"reflect-metadata": "^0.1.12 || ^0.2.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@fastify/static": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"class-transformer": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"class-validator": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@nestjs/testing": {
|
"node_modules/@nestjs/testing": {
|
||||||
"version": "11.1.27",
|
"version": "11.1.27",
|
||||||
"resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.27.tgz",
|
"resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.27.tgz",
|
||||||
@@ -2676,6 +2736,13 @@
|
|||||||
"url": "https://opencollective.com/pkgr"
|
"url": "https://opencollective.com/pkgr"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@scarf/scarf": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/@sinclair/typebox": {
|
"node_modules/@sinclair/typebox": {
|
||||||
"version": "0.34.49",
|
"version": "0.34.49",
|
||||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz",
|
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz",
|
||||||
@@ -4168,7 +4235,6 @@
|
|||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||||
"dev": true,
|
|
||||||
"license": "Python-2.0"
|
"license": "Python-2.0"
|
||||||
},
|
},
|
||||||
"node_modules/array-timsort": {
|
"node_modules/array-timsort": {
|
||||||
@@ -7447,10 +7513,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/js-yaml": {
|
"node_modules/js-yaml": {
|
||||||
"version": "4.2.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
|
||||||
"integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==",
|
"integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -9444,6 +9509,15 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/swagger-ui-dist": {
|
||||||
|
"version": "5.32.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.32.8.tgz",
|
||||||
|
"integrity": "sha512-dgMdWXIgnI4zX4OPhKEdWnlDODbgm8W3AX0Ivn/BBqcUh6xZsBxhZMnvk6DJyRz1BTrj8dPxtarmEGgkz30oyA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@scarf/scarf": "=1.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/symbol-observable": {
|
"node_modules/symbol-observable": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz",
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
"@nestjs/jwt": "^11.0.2",
|
"@nestjs/jwt": "^11.0.2",
|
||||||
"@nestjs/passport": "^11.0.5",
|
"@nestjs/passport": "^11.0.5",
|
||||||
"@nestjs/platform-express": "^11.0.1",
|
"@nestjs/platform-express": "^11.0.1",
|
||||||
|
"@nestjs/swagger": "^11.4.5",
|
||||||
"@nestjs/typeorm": "^11.0.2",
|
"@nestjs/typeorm": "^11.0.2",
|
||||||
"axios": "^1.18.1",
|
"axios": "^1.18.1",
|
||||||
"bcrypt": "^6.0.0",
|
"bcrypt": "^6.0.0",
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import { Body, Controller, Post } from '@nestjs/common';
|
import { Body, Controller, Post } from '@nestjs/common';
|
||||||
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { AllowWithoutSubscription } from '../auth/decorators/allow-without-subscription.decorator';
|
import { AllowWithoutSubscription } from '../auth/decorators/allow-without-subscription.decorator';
|
||||||
|
import {
|
||||||
|
ApiProtectedEndpoint,
|
||||||
|
ApiPublicEndpoint,
|
||||||
|
} from '../swagger/decorators/swagger-auth.decorator';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { CurrentUser } from './decorators/current-user.decorator';
|
import { CurrentUser } from './decorators/current-user.decorator';
|
||||||
import { Public } from './decorators/public.decorator';
|
import { Public } from './decorators/public.decorator';
|
||||||
@@ -8,29 +13,34 @@ import { RequestOtpDto } from './dto/request-otp.dto';
|
|||||||
import { VerifyOtpDto } from './dto/verify-otp.dto';
|
import { VerifyOtpDto } from './dto/verify-otp.dto';
|
||||||
import { AuthUser } from './interfaces/auth-user.interface';
|
import { AuthUser } from './interfaces/auth-user.interface';
|
||||||
|
|
||||||
|
@ApiTags('Auth')
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
constructor(private readonly authService: AuthService) {}
|
constructor(private readonly authService: AuthService) {}
|
||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
|
@ApiPublicEndpoint('Request OTP code via SMS')
|
||||||
@Post('otp/request')
|
@Post('otp/request')
|
||||||
requestOtp(@Body() dto: RequestOtpDto) {
|
requestOtp(@Body() dto: RequestOtpDto) {
|
||||||
return this.authService.requestOtp(dto.mobile);
|
return this.authService.requestOtp(dto.mobile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
|
@ApiPublicEndpoint('Verify OTP and receive access/refresh tokens')
|
||||||
@Post('otp/verify')
|
@Post('otp/verify')
|
||||||
verifyOtp(@Body() dto: VerifyOtpDto) {
|
verifyOtp(@Body() dto: VerifyOtpDto) {
|
||||||
return this.authService.verifyOtp(dto);
|
return this.authService.verifyOtp(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
|
@ApiPublicEndpoint('Refresh access token')
|
||||||
@Post('refresh')
|
@Post('refresh')
|
||||||
refresh(@Body() dto: RefreshTokenDto) {
|
refresh(@Body() dto: RefreshTokenDto) {
|
||||||
return this.authService.refresh(dto.refreshToken);
|
return this.authService.refresh(dto.refreshToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AllowWithoutSubscription()
|
@AllowWithoutSubscription()
|
||||||
|
@ApiProtectedEndpoint('Logout and invalidate refresh token')
|
||||||
@Post('logout')
|
@Post('logout')
|
||||||
logout(@CurrentUser() user: AuthUser, @Body() dto: RefreshTokenDto) {
|
logout(@CurrentUser() user: AuthUser, @Body() dto: RefreshTokenDto) {
|
||||||
return this.authService.logout(user.id, dto.refreshToken);
|
return this.authService.logout(user.id, dto.refreshToken);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
Patch,
|
Patch,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||||
import { PermissionCode } from '../authorization/enums/permission-code.enum';
|
import { PermissionCode } from '../authorization/enums/permission-code.enum';
|
||||||
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
||||||
import { Permissions } from '../auth/decorators/permissions.decorator';
|
import { Permissions } from '../auth/decorators/permissions.decorator';
|
||||||
@@ -18,7 +19,10 @@ import { AuthUser } from '../auth/interfaces/auth-user.interface';
|
|||||||
import { UserRole } from '../users/enums/user-role.enum';
|
import { UserRole } from '../users/enums/user-role.enum';
|
||||||
import { CustomersService } from './customers.service';
|
import { CustomersService } from './customers.service';
|
||||||
import { UpdateCustomerDto } from './dto/update-customer.dto';
|
import { UpdateCustomerDto } from './dto/update-customer.dto';
|
||||||
|
import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup';
|
||||||
|
|
||||||
|
@ApiTags('Customers')
|
||||||
|
@ApiBearerAuth(SWAGGER_JWT_AUTH)
|
||||||
@Controller('customers')
|
@Controller('customers')
|
||||||
@UseGuards(RolesGuard, PermissionsGuard)
|
@UseGuards(RolesGuard, PermissionsGuard)
|
||||||
export class CustomersController {
|
export class CustomersController {
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class FixReservesStatusEnum1720500000000 implements MigrationInterface {
|
||||||
|
name = 'FixReservesStatusEnum1720500000000';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
const oldType = await queryRunner.query(`
|
||||||
|
SELECT 1 FROM pg_type WHERE typname = 'reserves_status_enum_old'
|
||||||
|
`);
|
||||||
|
|
||||||
|
if (oldType.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
ALTER TABLE "reserve_status_history"
|
||||||
|
ALTER COLUMN "fromStatus" TYPE "reserves_status_enum"
|
||||||
|
USING "fromStatus"::text::"reserves_status_enum",
|
||||||
|
ALTER COLUMN "toStatus" TYPE "reserves_status_enum"
|
||||||
|
USING "toStatus"::text::"reserves_status_enum"
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
ALTER TABLE "reserves"
|
||||||
|
ALTER COLUMN "status" TYPE "reserves_status_enum"
|
||||||
|
USING "status"::text::"reserves_status_enum"
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.query(`DROP TYPE "reserves_status_enum_old"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(): Promise<void> {
|
||||||
|
// Irreversible cleanup migration.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,9 @@ export function getTypeOrmOptions(): TypeOrmModuleOptions {
|
|||||||
autoLoadEntities: true,
|
autoLoadEntities: true,
|
||||||
entities: [__dirname + '/../**/*.entity.{js,ts}'],
|
entities: [__dirname + '/../**/*.entity.{js,ts}'],
|
||||||
migrations: [__dirname + '/migrations/*.{js,ts}'],
|
migrations: [__dirname + '/migrations/*.{js,ts}'],
|
||||||
synchronize: !isProduction,
|
// synchronize breaks shared PostgreSQL enums (reserves_status_enum is used
|
||||||
|
// by both reserves and reserve_status_history). Use migrations instead.
|
||||||
|
synchronize: false,
|
||||||
migrationsRun: isProduction,
|
migrationsRun: isProduction,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ValidationPipe } from '@nestjs/common';
|
import { ValidationPipe } from '@nestjs/common';
|
||||||
import { NestFactory } from '@nestjs/core';
|
import { NestFactory } from '@nestjs/core';
|
||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
|
import { setupSwagger } from './swagger/swagger.setup';
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
@@ -17,6 +18,8 @@ async function bootstrap() {
|
|||||||
// Global prefix
|
// Global prefix
|
||||||
app.setGlobalPrefix('api');
|
app.setGlobalPrefix('api');
|
||||||
|
|
||||||
|
setupSwagger(app);
|
||||||
|
|
||||||
// Cors
|
// Cors
|
||||||
const corsOrigin = process.env.CORS_ORIGIN;
|
const corsOrigin = process.env.CORS_ORIGIN;
|
||||||
if (corsOrigin) {
|
if (corsOrigin) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
Query,
|
Query,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||||
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
||||||
import { Permissions } from '../auth/decorators/permissions.decorator';
|
import { Permissions } from '../auth/decorators/permissions.decorator';
|
||||||
import { Roles } from '../auth/decorators/roles.decorator';
|
import { Roles } from '../auth/decorators/roles.decorator';
|
||||||
@@ -21,7 +22,10 @@ import { CreateReserveDto } from './dto/create-reserve.dto';
|
|||||||
import { FindReservesQueryDto } from './dto/find-reserves-query.dto';
|
import { FindReservesQueryDto } from './dto/find-reserves-query.dto';
|
||||||
import { UpdateReserveDto } from './dto/update-reserve.dto';
|
import { UpdateReserveDto } from './dto/update-reserve.dto';
|
||||||
import { ReservesService } from './reserves.service';
|
import { ReservesService } from './reserves.service';
|
||||||
|
import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup';
|
||||||
|
|
||||||
|
@ApiTags('Reserves')
|
||||||
|
@ApiBearerAuth(SWAGGER_JWT_AUTH)
|
||||||
@Controller('reserves')
|
@Controller('reserves')
|
||||||
@UseGuards(RolesGuard, PermissionsGuard)
|
@UseGuards(RolesGuard, PermissionsGuard)
|
||||||
export class ReservesController {
|
export class ReservesController {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
Post,
|
Post,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||||
import { OptionalCurrentUser } from '../auth/decorators/optional-current-user.decorator';
|
import { OptionalCurrentUser } from '../auth/decorators/optional-current-user.decorator';
|
||||||
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
||||||
import { Public } from '../auth/decorators/public.decorator';
|
import { Public } from '../auth/decorators/public.decorator';
|
||||||
@@ -23,7 +24,11 @@ import { UserRole } from '../users/enums/user-role.enum';
|
|||||||
import { CreateSalonDto } from './dto/create-salon.dto';
|
import { CreateSalonDto } from './dto/create-salon.dto';
|
||||||
import { UpdateSalonDto } from './dto/update-salon.dto';
|
import { UpdateSalonDto } from './dto/update-salon.dto';
|
||||||
import { SalonsService } from './salons.service';
|
import { SalonsService } from './salons.service';
|
||||||
|
import { ApiPublicEndpoint } from '../swagger/decorators/swagger-auth.decorator';
|
||||||
|
import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup';
|
||||||
|
|
||||||
|
@ApiTags('Salons')
|
||||||
|
@ApiBearerAuth(SWAGGER_JWT_AUTH)
|
||||||
@Controller('salons')
|
@Controller('salons')
|
||||||
@UseGuards(RolesGuard, PermissionsGuard)
|
@UseGuards(RolesGuard, PermissionsGuard)
|
||||||
export class SalonsController {
|
export class SalonsController {
|
||||||
@@ -41,12 +46,14 @@ export class SalonsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
|
@ApiPublicEndpoint('List all salons')
|
||||||
@Get()
|
@Get()
|
||||||
findAll(@OptionalCurrentUser() user?: AuthUser) {
|
findAll(@OptionalCurrentUser() user?: AuthUser) {
|
||||||
return this.salonsService.findAll(user);
|
return this.salonsService.findAll(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
|
@ApiPublicEndpoint('Get salon by ID')
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
findOne(@Param('id', ParseUUIDPipe) id: string) {
|
findOne(@Param('id', ParseUUIDPipe) id: string) {
|
||||||
return this.salonsService.findOne(id);
|
return this.salonsService.findOne(id);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
Query,
|
Query,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||||
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
||||||
import { Roles } from '../auth/decorators/roles.decorator';
|
import { Roles } from '../auth/decorators/roles.decorator';
|
||||||
import { RolesGuard } from '../auth/guards/roles.guard';
|
import { RolesGuard } from '../auth/guards/roles.guard';
|
||||||
@@ -18,7 +19,10 @@ import { CreateSentMessageDto } from './dto/create-sent-message.dto';
|
|||||||
import { FindSentMessagesQueryDto } from './dto/find-sent-messages-query.dto';
|
import { FindSentMessagesQueryDto } from './dto/find-sent-messages-query.dto';
|
||||||
import { UpdateSentMessageDto } from './dto/update-sent-message.dto';
|
import { UpdateSentMessageDto } from './dto/update-sent-message.dto';
|
||||||
import { SentMessagesService } from './sent-messages.service';
|
import { SentMessagesService } from './sent-messages.service';
|
||||||
|
import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup';
|
||||||
|
|
||||||
|
@ApiTags('Sent Messages')
|
||||||
|
@ApiBearerAuth(SWAGGER_JWT_AUTH)
|
||||||
@Controller('sent-messages')
|
@Controller('sent-messages')
|
||||||
@UseGuards(RolesGuard)
|
@UseGuards(RolesGuard)
|
||||||
export class SentMessagesController {
|
export class SentMessagesController {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
Post,
|
Post,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||||
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
||||||
import { Public } from '../auth/decorators/public.decorator';
|
import { Public } from '../auth/decorators/public.decorator';
|
||||||
import { Permissions } from '../auth/decorators/permissions.decorator';
|
import { Permissions } from '../auth/decorators/permissions.decorator';
|
||||||
@@ -23,7 +24,11 @@ import { CreateServiceDto } from './dto/create-service.dto';
|
|||||||
import { UpdateServiceSkillDto } from './dto/update-service-skill.dto';
|
import { UpdateServiceSkillDto } from './dto/update-service-skill.dto';
|
||||||
import { UpdateServiceDto } from './dto/update-service.dto';
|
import { UpdateServiceDto } from './dto/update-service.dto';
|
||||||
import { ServicesService } from './services.service';
|
import { ServicesService } from './services.service';
|
||||||
|
import { ApiPublicEndpoint } from '../swagger/decorators/swagger-auth.decorator';
|
||||||
|
import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup';
|
||||||
|
|
||||||
|
@ApiTags('Services')
|
||||||
|
@ApiBearerAuth(SWAGGER_JWT_AUTH)
|
||||||
@Controller('services')
|
@Controller('services')
|
||||||
@UseGuards(RolesGuard, PermissionsGuard)
|
@UseGuards(RolesGuard, PermissionsGuard)
|
||||||
export class ServicesController {
|
export class ServicesController {
|
||||||
@@ -40,12 +45,14 @@ export class ServicesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
|
@ApiPublicEndpoint('List all services')
|
||||||
@Get()
|
@Get()
|
||||||
findAll() {
|
findAll() {
|
||||||
return this.servicesService.findAll();
|
return this.servicesService.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
|
@ApiPublicEndpoint('Get service by ID')
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
findOne(@Param('id', ParseUUIDPipe) id: string) {
|
findOne(@Param('id', ParseUUIDPipe) id: string) {
|
||||||
return this.servicesService.findOne(id);
|
return this.servicesService.findOne(id);
|
||||||
@@ -88,12 +95,14 @@ export class ServicesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
|
@ApiPublicEndpoint('List skills for a service')
|
||||||
@Get(':serviceId/skills')
|
@Get(':serviceId/skills')
|
||||||
findSkills(@Param('serviceId', ParseUUIDPipe) serviceId: string) {
|
findSkills(@Param('serviceId', ParseUUIDPipe) serviceId: string) {
|
||||||
return this.servicesService.findSkills(serviceId);
|
return this.servicesService.findSkills(serviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
|
@ApiPublicEndpoint('Get a service skill by ID')
|
||||||
@Get(':serviceId/skills/:skillId')
|
@Get(':serviceId/skills/:skillId')
|
||||||
findSkill(
|
findSkill(
|
||||||
@Param('serviceId', ParseUUIDPipe) serviceId: string,
|
@Param('serviceId', ParseUUIDPipe) serviceId: string,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
Query,
|
Query,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||||
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
||||||
import { Permissions } from '../auth/decorators/permissions.decorator';
|
import { Permissions } from '../auth/decorators/permissions.decorator';
|
||||||
import { Roles } from '../auth/decorators/roles.decorator';
|
import { Roles } from '../auth/decorators/roles.decorator';
|
||||||
@@ -22,7 +23,10 @@ import { CreateSmsTemplateDto } from './dto/create-sms-template.dto';
|
|||||||
import { FindSmsTemplatesQueryDto } from './dto/find-sms-templates-query.dto';
|
import { FindSmsTemplatesQueryDto } from './dto/find-sms-templates-query.dto';
|
||||||
import { UpdateSmsTemplateDto } from './dto/update-sms-template.dto';
|
import { UpdateSmsTemplateDto } from './dto/update-sms-template.dto';
|
||||||
import { SmsTemplatesService } from './sms-templates.service';
|
import { SmsTemplatesService } from './sms-templates.service';
|
||||||
|
import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup';
|
||||||
|
|
||||||
|
@ApiTags('SMS Templates')
|
||||||
|
@ApiBearerAuth(SWAGGER_JWT_AUTH)
|
||||||
@Controller('sms-templates')
|
@Controller('sms-templates')
|
||||||
@UseGuards(RolesGuard, PermissionsGuard)
|
@UseGuards(RolesGuard, PermissionsGuard)
|
||||||
export class SmsTemplatesController {
|
export class SmsTemplatesController {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
Query,
|
Query,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { ApiBearerAuth, ApiQuery, ApiTags } from '@nestjs/swagger';
|
||||||
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
||||||
import { Public } from '../auth/decorators/public.decorator';
|
import { Public } from '../auth/decorators/public.decorator';
|
||||||
import { Permissions } from '../auth/decorators/permissions.decorator';
|
import { Permissions } from '../auth/decorators/permissions.decorator';
|
||||||
@@ -22,7 +23,11 @@ import { UserRole } from '../users/enums/user-role.enum';
|
|||||||
import { CreateStylistDto } from './dto/create-stylist.dto';
|
import { CreateStylistDto } from './dto/create-stylist.dto';
|
||||||
import { UpdateStylistDto } from './dto/update-stylist.dto';
|
import { UpdateStylistDto } from './dto/update-stylist.dto';
|
||||||
import { StylistsService } from './stylists.service';
|
import { StylistsService } from './stylists.service';
|
||||||
|
import { ApiPublicEndpoint } from '../swagger/decorators/swagger-auth.decorator';
|
||||||
|
import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup';
|
||||||
|
|
||||||
|
@ApiTags('Stylists')
|
||||||
|
@ApiBearerAuth(SWAGGER_JWT_AUTH)
|
||||||
@Controller('stylists')
|
@Controller('stylists')
|
||||||
@UseGuards(RolesGuard, PermissionsGuard)
|
@UseGuards(RolesGuard, PermissionsGuard)
|
||||||
export class StylistsController {
|
export class StylistsController {
|
||||||
@@ -39,12 +44,15 @@ export class StylistsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
|
@ApiPublicEndpoint('List stylists, optionally filtered by salon')
|
||||||
|
@ApiQuery({ name: 'salonId', required: false, type: String, format: 'uuid' })
|
||||||
@Get()
|
@Get()
|
||||||
findAll(@Query('salonId', new ParseUUIDPipe({ optional: true })) salonId?: string) {
|
findAll(@Query('salonId', new ParseUUIDPipe({ optional: true })) salonId?: string) {
|
||||||
return this.stylistsService.findAll(salonId);
|
return this.stylistsService.findAll(salonId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
|
@ApiPublicEndpoint('Get stylist by ID')
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
findOne(@Param('id', ParseUUIDPipe) id: string) {
|
findOne(@Param('id', ParseUUIDPipe) id: string) {
|
||||||
return this.stylistsService.findOne(id);
|
return this.stylistsService.findOne(id);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
Post,
|
Post,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||||
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
||||||
import { Permissions } from '../auth/decorators/permissions.decorator';
|
import { Permissions } from '../auth/decorators/permissions.decorator';
|
||||||
import { Roles } from '../auth/decorators/roles.decorator';
|
import { Roles } from '../auth/decorators/roles.decorator';
|
||||||
@@ -19,7 +20,10 @@ import { AllowWithoutSubscription } from '../auth/decorators/allow-without-subsc
|
|||||||
import { PurchaseSmsPackageDto } from './dto/purchase-sms-package.dto';
|
import { PurchaseSmsPackageDto } from './dto/purchase-sms-package.dto';
|
||||||
import { PurchaseSubscriptionDto } from './dto/purchase-subscription.dto';
|
import { PurchaseSubscriptionDto } from './dto/purchase-subscription.dto';
|
||||||
import { SalonSubscriptionsService } from './salon-subscriptions.service';
|
import { SalonSubscriptionsService } from './salon-subscriptions.service';
|
||||||
|
import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup';
|
||||||
|
|
||||||
|
@ApiTags('Salon Subscriptions')
|
||||||
|
@ApiBearerAuth(SWAGGER_JWT_AUTH)
|
||||||
@Controller('salon-subscriptions')
|
@Controller('salon-subscriptions')
|
||||||
@UseGuards(RolesGuard, PermissionsGuard)
|
@UseGuards(RolesGuard, PermissionsGuard)
|
||||||
export class SalonSubscriptionsController {
|
export class SalonSubscriptionsController {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
Post,
|
Post,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||||
import { Public } from '../auth/decorators/public.decorator';
|
import { Public } from '../auth/decorators/public.decorator';
|
||||||
import { Permissions } from '../auth/decorators/permissions.decorator';
|
import { Permissions } from '../auth/decorators/permissions.decorator';
|
||||||
import { Roles } from '../auth/decorators/roles.decorator';
|
import { Roles } from '../auth/decorators/roles.decorator';
|
||||||
@@ -20,7 +21,11 @@ import { AllowWithoutSubscription } from '../auth/decorators/allow-without-subsc
|
|||||||
import { CreateSmsPackageDto } from './dto/create-sms-package.dto';
|
import { CreateSmsPackageDto } from './dto/create-sms-package.dto';
|
||||||
import { UpdateSmsPackageDto } from './dto/update-sms-package.dto';
|
import { UpdateSmsPackageDto } from './dto/update-sms-package.dto';
|
||||||
import { SmsPackagesService } from './sms-packages.service';
|
import { SmsPackagesService } from './sms-packages.service';
|
||||||
|
import { ApiPublicEndpoint } from '../swagger/decorators/swagger-auth.decorator';
|
||||||
|
import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup';
|
||||||
|
|
||||||
|
@ApiTags('SMS Packages')
|
||||||
|
@ApiBearerAuth(SWAGGER_JWT_AUTH)
|
||||||
@Controller('sms-packages')
|
@Controller('sms-packages')
|
||||||
@UseGuards(RolesGuard, PermissionsGuard)
|
@UseGuards(RolesGuard, PermissionsGuard)
|
||||||
export class SmsPackagesController {
|
export class SmsPackagesController {
|
||||||
@@ -35,6 +40,7 @@ export class SmsPackagesController {
|
|||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
@AllowWithoutSubscription()
|
@AllowWithoutSubscription()
|
||||||
|
@ApiPublicEndpoint('List active SMS packages')
|
||||||
@Get()
|
@Get()
|
||||||
findAll() {
|
findAll() {
|
||||||
return this.smsPackagesService.findAll(true);
|
return this.smsPackagesService.findAll(true);
|
||||||
@@ -42,6 +48,7 @@ export class SmsPackagesController {
|
|||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
@AllowWithoutSubscription()
|
@AllowWithoutSubscription()
|
||||||
|
@ApiPublicEndpoint('Get SMS package by ID')
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
findOne(@Param('id', ParseUUIDPipe) id: string) {
|
findOne(@Param('id', ParseUUIDPipe) id: string) {
|
||||||
return this.smsPackagesService.findOne(id);
|
return this.smsPackagesService.findOne(id);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
Post,
|
Post,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||||
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
||||||
import { Public } from '../auth/decorators/public.decorator';
|
import { Public } from '../auth/decorators/public.decorator';
|
||||||
import { Permissions } from '../auth/decorators/permissions.decorator';
|
import { Permissions } from '../auth/decorators/permissions.decorator';
|
||||||
@@ -22,7 +23,11 @@ import { AllowWithoutSubscription } from '../auth/decorators/allow-without-subsc
|
|||||||
import { CreateSubscriptionPlanDto } from './dto/create-subscription-plan.dto';
|
import { CreateSubscriptionPlanDto } from './dto/create-subscription-plan.dto';
|
||||||
import { UpdateSubscriptionPlanDto } from './dto/update-subscription-plan.dto';
|
import { UpdateSubscriptionPlanDto } from './dto/update-subscription-plan.dto';
|
||||||
import { SubscriptionPlansService } from './subscription-plans.service';
|
import { SubscriptionPlansService } from './subscription-plans.service';
|
||||||
|
import { ApiPublicEndpoint } from '../swagger/decorators/swagger-auth.decorator';
|
||||||
|
import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup';
|
||||||
|
|
||||||
|
@ApiTags('Subscription Plans')
|
||||||
|
@ApiBearerAuth(SWAGGER_JWT_AUTH)
|
||||||
@Controller('subscription-plans')
|
@Controller('subscription-plans')
|
||||||
@UseGuards(RolesGuard, PermissionsGuard)
|
@UseGuards(RolesGuard, PermissionsGuard)
|
||||||
export class SubscriptionPlansController {
|
export class SubscriptionPlansController {
|
||||||
@@ -39,6 +44,7 @@ export class SubscriptionPlansController {
|
|||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
@AllowWithoutSubscription()
|
@AllowWithoutSubscription()
|
||||||
|
@ApiPublicEndpoint('List active subscription plans')
|
||||||
@Get()
|
@Get()
|
||||||
findAll() {
|
findAll() {
|
||||||
return this.subscriptionPlansService.findAll(true);
|
return this.subscriptionPlansService.findAll(true);
|
||||||
@@ -46,6 +52,7 @@ export class SubscriptionPlansController {
|
|||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
@AllowWithoutSubscription()
|
@AllowWithoutSubscription()
|
||||||
|
@ApiPublicEndpoint('Get subscription plan by ID')
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
findOne(@Param('id', ParseUUIDPipe) id: string) {
|
findOne(@Param('id', ParseUUIDPipe) id: string) {
|
||||||
return this.subscriptionPlansService.findOne(id);
|
return this.subscriptionPlansService.findOne(id);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
Query,
|
Query,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||||
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
||||||
import { Public } from '../auth/decorators/public.decorator';
|
import { Public } from '../auth/decorators/public.decorator';
|
||||||
import { Permissions } from '../auth/decorators/permissions.decorator';
|
import { Permissions } from '../auth/decorators/permissions.decorator';
|
||||||
@@ -23,7 +24,11 @@ import { CreateServiceSuggestionDto } from './dto/create-service-suggestion.dto'
|
|||||||
import { FindSuggestionsQueryDto } from './dto/find-suggestions-query.dto';
|
import { FindSuggestionsQueryDto } from './dto/find-suggestions-query.dto';
|
||||||
import { UpdateServiceSuggestionDto } from './dto/update-service-suggestion.dto';
|
import { UpdateServiceSuggestionDto } from './dto/update-service-suggestion.dto';
|
||||||
import { SuggestionsService } from './suggestions.service';
|
import { SuggestionsService } from './suggestions.service';
|
||||||
|
import { ApiPublicEndpoint } from '../swagger/decorators/swagger-auth.decorator';
|
||||||
|
import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup';
|
||||||
|
|
||||||
|
@ApiTags('Suggestions')
|
||||||
|
@ApiBearerAuth(SWAGGER_JWT_AUTH)
|
||||||
@Controller('suggestions')
|
@Controller('suggestions')
|
||||||
@UseGuards(RolesGuard, PermissionsGuard)
|
@UseGuards(RolesGuard, PermissionsGuard)
|
||||||
export class SuggestionsController {
|
export class SuggestionsController {
|
||||||
@@ -47,6 +52,7 @@ export class SuggestionsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
|
@ApiPublicEndpoint('Get suggestions for a service')
|
||||||
@Get('for-service/:serviceId')
|
@Get('for-service/:serviceId')
|
||||||
findForService(@Param('serviceId', ParseUUIDPipe) serviceId: string) {
|
findForService(@Param('serviceId', ParseUUIDPipe) serviceId: string) {
|
||||||
return this.suggestionsService.findForService(serviceId);
|
return this.suggestionsService.findForService(serviceId);
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { applyDecorators } from '@nestjs/common';
|
||||||
|
import { ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
|
||||||
|
import { SWAGGER_JWT_AUTH } from '../swagger.setup';
|
||||||
|
|
||||||
|
export function ApiPublicEndpoint(summary?: string) {
|
||||||
|
return applyDecorators(
|
||||||
|
ApiOperation({
|
||||||
|
summary,
|
||||||
|
security: [],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ApiProtectedEndpoint(summary?: string) {
|
||||||
|
return applyDecorators(
|
||||||
|
ApiBearerAuth(SWAGGER_JWT_AUTH),
|
||||||
|
...(summary ? [ApiOperation({ summary })] : []),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { INestApplication } from '@nestjs/common';
|
||||||
|
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
export const SWAGGER_JWT_AUTH = 'access-token';
|
||||||
|
|
||||||
|
export function setupSwagger(app: INestApplication): void {
|
||||||
|
const config = new DocumentBuilder()
|
||||||
|
.setTitle('Grow API')
|
||||||
|
.setDescription('BeautyBook Grow API documentation')
|
||||||
|
.setVersion('1.0')
|
||||||
|
.addBearerAuth(
|
||||||
|
{
|
||||||
|
type: 'http',
|
||||||
|
scheme: 'bearer',
|
||||||
|
bearerFormat: 'JWT',
|
||||||
|
description: 'JWT access token obtained from POST /api/auth/otp/verify',
|
||||||
|
},
|
||||||
|
SWAGGER_JWT_AUTH,
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
const document = SwaggerModule.createDocument(app, config);
|
||||||
|
|
||||||
|
SwaggerModule.setup('docs', app, document, {
|
||||||
|
jsonDocumentUrl: 'docs-json',
|
||||||
|
yamlDocumentUrl: 'docs-yaml',
|
||||||
|
swaggerOptions: {
|
||||||
|
persistAuthorization: true,
|
||||||
|
tagsSorter: 'alpha',
|
||||||
|
operationsSorter: 'alpha',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
Post,
|
Post,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||||
import { PermissionCode } from '../authorization/enums/permission-code.enum';
|
import { PermissionCode } from '../authorization/enums/permission-code.enum';
|
||||||
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
import { CurrentUser } from '../auth/decorators/current-user.decorator';
|
||||||
import { Permissions } from '../auth/decorators/permissions.decorator';
|
import { Permissions } from '../auth/decorators/permissions.decorator';
|
||||||
@@ -21,7 +22,10 @@ import { UserRole } from './enums/user-role.enum';
|
|||||||
import { CreateUserDto } from './dto/create-user.dto';
|
import { CreateUserDto } from './dto/create-user.dto';
|
||||||
import { UpdateUserDto } from './dto/update-user.dto';
|
import { UpdateUserDto } from './dto/update-user.dto';
|
||||||
import { UsersService } from './users.service';
|
import { UsersService } from './users.service';
|
||||||
|
import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup';
|
||||||
|
|
||||||
|
@ApiTags('Users')
|
||||||
|
@ApiBearerAuth(SWAGGER_JWT_AUTH)
|
||||||
@Controller('users')
|
@Controller('users')
|
||||||
@UseGuards(RolesGuard, PermissionsGuard)
|
@UseGuards(RolesGuard, PermissionsGuard)
|
||||||
export class UsersController {
|
export class UsersController {
|
||||||
|
|||||||
Reference in New Issue
Block a user