feat(scenario): add scenario and scenario step CRUD module

- add ScenarioEntity and ScenarioStepEntity with cascade delete
- step fields: type (login|exec), sessionName (required), execCode, validateCode
- login steps create a named session; exec steps consume it by sessionName
- full CRUD controller under /scenarios and /scenarios/:id/steps
- paginated GET /scenarios with page/limit query params returning { data, total, page, limit }
- register ScenarioModule and entities in AppModule
This commit is contained in:
2026-04-07 14:13:06 +03:00
parent 5ac26ecb3a
commit d669bf1c59
11 changed files with 396 additions and 1 deletions
@@ -0,0 +1,26 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsIn, IsNotEmpty, IsOptional, IsString } from 'class-validator';
import { StepType } from '../scenario-step.entity';
export class CreateScenarioStepDto {
@ApiProperty({ enum: ['login', 'exec'], example: 'exec' })
@IsIn(['login', 'exec'])
type: StepType;
@ApiProperty({ description: 'Session name used by this step. login steps create it; exec steps consume it.', example: 'my-session' })
@IsString()
@IsNotEmpty()
sessionName: string;
@ApiPropertyOptional({ example: 'return await page.title();' })
@IsOptional()
@IsString()
@IsNotEmpty()
execCode?: string;
@ApiPropertyOptional({ example: 'return { success: result !== null, description: "title present" };' })
@IsOptional()
@IsString()
@IsNotEmpty()
validateCode?: string;
}
+9
View File
@@ -0,0 +1,9 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsString } from 'class-validator';
export class CreateScenarioDto {
@ApiProperty({ example: 'Login and verify cabinet' })
@IsString()
@IsNotEmpty()
name: string;
}
+19
View File
@@ -0,0 +1,19 @@
import { ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IsInt, IsOptional, Min } from 'class-validator';
export class PaginationQueryDto {
@ApiPropertyOptional({ example: 1, default: 1 })
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
page?: number = 1;
@ApiPropertyOptional({ example: 20, default: 20 })
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
limit?: number = 20;
}
@@ -0,0 +1,28 @@
import { ApiPropertyOptional } from '@nestjs/swagger';
import { IsIn, IsNotEmpty, IsOptional, IsString } from 'class-validator';
import { StepType } from '../scenario-step.entity';
export class UpdateScenarioStepDto {
@ApiPropertyOptional({ enum: ['login', 'exec'] })
@IsOptional()
@IsIn(['login', 'exec'])
type?: StepType;
@ApiPropertyOptional()
@IsOptional()
@IsString()
@IsNotEmpty()
sessionName?: string;
@ApiPropertyOptional()
@IsOptional()
@IsString()
@IsNotEmpty()
execCode?: string;
@ApiPropertyOptional()
@IsOptional()
@IsString()
@IsNotEmpty()
validateCode?: string;
}
+10
View File
@@ -0,0 +1,10 @@
import { ApiPropertyOptional } from '@nestjs/swagger';
import { IsOptional, IsString, IsNotEmpty } from 'class-validator';
export class UpdateScenarioDto {
@ApiPropertyOptional({ example: 'Updated scenario name' })
@IsOptional()
@IsString()
@IsNotEmpty()
name?: string;
}