Files
liqa/src/scenario/scenario.controller.ts
T
ars9 36f8b8c0ca feat(pagination): add generic typed pagination with ordering to all list endpoints
- add PaginationQueryDto<TOrderBy> generic with orderBy and orderDir fields
- add SessionOrderBy, EnvironmentOrderBy, ScenarioOrderBy type aliases
- update session, environment, scenario services and controllers to use typed pagination
- update MCP list_sessions, list_environments, list_scenarios tools to expose orderBy/orderDir
- update tests for all list endpoints to cover page, limit, ordering, and invalid param rejection
2026-04-07 17:54:23 +03:00

138 lines
4.9 KiB
TypeScript

import {
Body,
Controller,
Delete,
Get,
HttpCode,
Param,
ParseIntPipe,
Patch,
Post,
Query,
} from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { ScenarioService } from './scenario.service';
import { CreateScenarioDto } from './dto/create-scenario.dto';
import { UpdateScenarioDto } from './dto/update-scenario.dto';
import { CreateScenarioStepDto } from './dto/create-scenario-step.dto';
import { UpdateScenarioStepDto } from './dto/update-scenario-step.dto';
import { PaginationQueryDto } from './dto/pagination-query.dto';
import { ScenarioOrderBy } from './scenario.service';
import { RunsQueryDto } from './dto/runs-query.dto';
@ApiTags('scenarios')
@Controller('scenarios')
export class ScenarioController {
constructor(private readonly scenarioService: ScenarioService) {}
// ── Scenarios ─────────────────────────────────────────────────────────────
@Post()
@ApiOperation({ summary: 'Create a scenario' })
@ApiResponse({ status: 201, description: 'Scenario created' })
create(@Body() dto: CreateScenarioDto) {
return this.scenarioService.create(dto);
}
@Get()
@ApiOperation({ summary: 'List all scenarios (paginated)' })
@ApiResponse({ status: 200 })
findAll(@Query() query: PaginationQueryDto<ScenarioOrderBy>) {
return this.scenarioService.findAll(query);
}
@Get(':id')
@ApiOperation({ summary: 'Get a scenario with its steps' })
@ApiResponse({ status: 200 })
@ApiResponse({ status: 404, description: 'Scenario not found' })
findOne(@Param('id', ParseIntPipe) id: number) {
return this.scenarioService.findOne(id);
}
@Patch(':id')
@ApiOperation({ summary: 'Update a scenario' })
@ApiResponse({ status: 200 })
@ApiResponse({ status: 404, description: 'Scenario not found' })
update(@Param('id', ParseIntPipe) id: number, @Body() dto: UpdateScenarioDto) {
return this.scenarioService.update(id, dto);
}
@Delete(':id')
@HttpCode(204)
@ApiOperation({ summary: 'Delete a scenario and all its steps' })
@ApiResponse({ status: 204 })
@ApiResponse({ status: 404, description: 'Scenario not found' })
remove(@Param('id', ParseIntPipe) id: number) {
return this.scenarioService.remove(id);
}
// ── Steps ─────────────────────────────────────────────────────────────────
@Post(':id/steps')
@ApiOperation({ summary: 'Add a step to a scenario' })
@ApiResponse({ status: 201, description: 'Step created' })
@ApiResponse({ status: 404, description: 'Scenario not found' })
createStep(
@Param('id', ParseIntPipe) id: number,
@Body() dto: CreateScenarioStepDto,
) {
return this.scenarioService.createStep(id, dto);
}
@Get(':id/steps/:stepId')
@ApiOperation({ summary: 'Get a single step' })
@ApiResponse({ status: 200 })
@ApiResponse({ status: 404, description: 'Scenario or step not found' })
findStep(
@Param('id', ParseIntPipe) id: number,
@Param('stepId', ParseIntPipe) stepId: number,
) {
return this.scenarioService.findStep(id, stepId);
}
@Patch(':id/steps/:stepId')
@ApiOperation({ summary: 'Update a step' })
@ApiResponse({ status: 200 })
@ApiResponse({ status: 404, description: 'Scenario or step not found' })
updateStep(
@Param('id', ParseIntPipe) id: number,
@Param('stepId', ParseIntPipe) stepId: number,
@Body() dto: UpdateScenarioStepDto,
) {
return this.scenarioService.updateStep(id, stepId, dto);
}
@Delete(':id/steps/:stepId')
@HttpCode(204)
@ApiOperation({ summary: 'Delete a step' })
@ApiResponse({ status: 204 })
@ApiResponse({ status: 404, description: 'Scenario or step not found' })
removeStep(
@Param('id', ParseIntPipe) id: number,
@Param('stepId', ParseIntPipe) stepId: number,
) {
return this.scenarioService.removeStep(id, stepId);
}
// ── Runs ──────────────────────────────────────────────────────────────────
@Get(':id/runs')
@ApiOperation({ summary: 'List runs for a scenario (paginated, filterable by status)' })
@ApiResponse({ status: 200 })
@ApiResponse({ status: 404, description: 'Scenario not found' })
findRuns(
@Param('id', ParseIntPipe) id: number,
@Query() query: RunsQueryDto,
) {
return this.scenarioService.findRuns(id, query);
}
@Post(':id/run')
@ApiOperation({ summary: 'Create a new run for a scenario' })
@ApiResponse({ status: 201, description: 'Run created with step runs' })
@ApiResponse({ status: 404, description: 'Scenario not found' })
createRun(@Param('id', ParseIntPipe) id: number) {
return this.scenarioService.createRun(id);
}
}