251128:1700 Backend to T3.1.1
This commit is contained in:
@@ -1,36 +1,172 @@
|
||||
import { Controller, Post, Body, Param, UseGuards } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
|
||||
// File: src/modules/json-schema/json-schema.controller.ts
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
HttpCode,
|
||||
HttpStatus,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
Patch,
|
||||
Post,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import {
|
||||
ApiBearerAuth,
|
||||
ApiOperation,
|
||||
ApiParam,
|
||||
ApiResponse,
|
||||
ApiTags,
|
||||
} from '@nestjs/swagger';
|
||||
|
||||
import { JsonSchemaService } from './json-schema.service';
|
||||
// ✅ FIX: Import DTO
|
||||
import { SchemaMigrationService } from './services/schema-migration.service';
|
||||
|
||||
import { CreateJsonSchemaDto } from './dto/create-json-schema.dto';
|
||||
// ✅ FIX: แก้ไข Path ของ Guards
|
||||
import { MigrateDataDto } from './dto/migrate-data.dto';
|
||||
import { SearchJsonSchemaDto } from './dto/search-json-schema.dto';
|
||||
import { UpdateJsonSchemaDto } from './dto/update-json-schema.dto';
|
||||
|
||||
import { CurrentUser } from '../../common/decorators/current-user.decorator';
|
||||
import { RequirePermission } from '../../common/decorators/require-permission.decorator';
|
||||
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
|
||||
import { RbacGuard } from '../../common/guards/rbac.guard';
|
||||
import { RequirePermission } from '../../common/decorators/require-permission.decorator';
|
||||
import { User } from '../user/entities/user.entity';
|
||||
|
||||
@ApiTags('JSON Schemas') // ✅ Add Swagger Tag
|
||||
@ApiTags('JSON Schemas Management')
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(JwtAuthGuard, RbacGuard)
|
||||
@Controller('json-schemas')
|
||||
export class JsonSchemaController {
|
||||
constructor(private readonly schemaService: JsonSchemaService) {}
|
||||
constructor(
|
||||
private readonly jsonSchemaService: JsonSchemaService,
|
||||
private readonly migrationService: SchemaMigrationService,
|
||||
) {}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Schema Management (CRUD)
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Post()
|
||||
@ApiOperation({ summary: 'Create or Update JSON Schema' })
|
||||
@ApiOperation({
|
||||
summary: 'Create a new schema or new version of existing schema',
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 201,
|
||||
description: 'The schema has been successfully created.',
|
||||
})
|
||||
@RequirePermission('system.manage_all') // Admin Only
|
||||
create(@Body() createDto: CreateJsonSchemaDto) {
|
||||
return this.schemaService.createOrUpdate(
|
||||
createDto.schemaCode,
|
||||
createDto.schemaDefinition,
|
||||
);
|
||||
return this.jsonSchemaService.create(createDto);
|
||||
}
|
||||
|
||||
@Post(':code/validate')
|
||||
@ApiOperation({ summary: 'Test validation against a schema' })
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'List all schemas with pagination and filtering' })
|
||||
@RequirePermission('document.view') // Viewer+ can see schemas
|
||||
findAll(@Query() searchDto: SearchJsonSchemaDto) {
|
||||
return this.jsonSchemaService.findAll(searchDto);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@ApiOperation({ summary: 'Get a specific schema version by ID' })
|
||||
@RequirePermission('document.view')
|
||||
findOne(@Param('id', ParseIntPipe) id: number) {
|
||||
return this.jsonSchemaService.findOne(id);
|
||||
}
|
||||
|
||||
@Get('latest/:code')
|
||||
@ApiOperation({
|
||||
summary: 'Get the latest active version of a schema by code',
|
||||
})
|
||||
@ApiParam({ name: 'code', description: 'Schema Code (e.g., RFA_DWG)' })
|
||||
@RequirePermission('document.view')
|
||||
findLatest(@Param('code') code: string) {
|
||||
return this.jsonSchemaService.findLatestByCode(code);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@ApiOperation({
|
||||
summary: 'Update a specific schema (Not recommended for active schemas)',
|
||||
})
|
||||
@RequirePermission('system.manage_all')
|
||||
update(
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@Body() updateDto: UpdateJsonSchemaDto,
|
||||
) {
|
||||
return this.jsonSchemaService.update(id, updateDto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@ApiOperation({ summary: 'Delete a schema version (Hard Delete)' })
|
||||
@RequirePermission('system.manage_all')
|
||||
remove(@Param('id', ParseIntPipe) id: number) {
|
||||
return this.jsonSchemaService.remove(id);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Validation & Security
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Post('validate/:code')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@ApiOperation({ summary: 'Validate data against the latest schema version' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'Validation result including errors and sanitized data',
|
||||
})
|
||||
@RequirePermission('document.view')
|
||||
async validate(@Param('code') code: string, @Body() data: any) {
|
||||
const isValid = await this.schemaService.validate(code, data);
|
||||
return { valid: isValid, message: 'Validation passed' };
|
||||
// Note: Validation API นี้ใช้สำหรับ Test หรือ Pre-check เท่านั้น
|
||||
// การ Save จริงจะเรียกผ่าน Service ภายใน
|
||||
return this.jsonSchemaService.validateData(code, data);
|
||||
}
|
||||
|
||||
@Post('read/:code')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@ApiOperation({
|
||||
summary: 'Process read data (Decrypt & Filter) based on user roles',
|
||||
})
|
||||
@RequirePermission('document.view')
|
||||
async processReadData(
|
||||
@Param('code') code: string,
|
||||
@Body() data: any,
|
||||
@CurrentUser() user: User,
|
||||
) {
|
||||
// แปลง User Entity เป็น Security Context
|
||||
// ใช้ as any เพื่อ bypass type checking ชั่วคราว เนื่องจาก roles มักจะถูก inject เข้ามาใน request.user
|
||||
// โดย Strategy หรือ Guard แม้จะไม่มีใน Entity หลัก
|
||||
const userWithRoles = user as any;
|
||||
const userRoles = userWithRoles.roles
|
||||
? userWithRoles.roles.map((r: any) => r.roleName || r) // รองรับทั้ง Object Role และ String Role
|
||||
: [];
|
||||
|
||||
return this.jsonSchemaService.processReadData(code, data, { userRoles });
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Data Migration
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Post('migrate/:table/:id')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@ApiOperation({
|
||||
summary: 'Migrate specific entity data to target schema version',
|
||||
})
|
||||
@ApiParam({ name: 'table', description: 'Table Name (e.g. rfa_revisions)' })
|
||||
@ApiParam({ name: 'id', description: 'Entity ID' })
|
||||
@RequirePermission('system.manage_all') // Dangerous Op -> Admin Only
|
||||
async migrateData(
|
||||
@Param('table') tableName: string,
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@Body() dto: MigrateDataDto,
|
||||
) {
|
||||
return this.migrationService.migrateData(
|
||||
tableName,
|
||||
id,
|
||||
dto.targetSchemaCode,
|
||||
dto.targetVersion,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user