import { type ApplyCustomerFieldInput, applyCustomerFieldInputSchema, type ApproveCustomerFieldInput, approveCustomerFieldInputSchema, type CustomerField, type CustomerFieldListItem, type CustomerFieldListQuery, customerFieldListQuerySchema, ErrorCode, type ListResponse, Permission, } from '@lingxi/shared'; import { Body, Controller, Get, HttpCode, Inject, Param, Post, Query } from '@nestjs/common'; import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger'; import { AppException } from '../../common/errors/app-exception'; import { ZodValidationPipe } from '../../common/pipes/zod-validation.pipe'; import type { AuthContext } from '../../common/security/auth.types'; import { Audit, CurrentScope, CurrentUser, RequirePermissions, } from '../../common/security/decorators'; import type { ScopeContext } from '../../common/security/scope/scope-context'; import { CustomerFieldsService } from './customer-fields.service'; function requireAuth(auth: AuthContext | null): AuthContext { if (auth === null) throw new AppException({ code: ErrorCode.UNAUTHENTICATED }); return auth; } @ApiTags('client-customer-fields') @ApiBearerAuth() @Controller('customer-fields') export class CustomerFieldsController { constructor(@Inject(CustomerFieldsService) private readonly fields: CustomerFieldsService) {} @Get() @RequirePermissions(Permission.CUSTOMER_FIELD_APPROVE, Permission.CUSTOMER_READ) @ApiOperation({ summary: '字段审批队列(待审批 / 已生效 / 已驳回)' }) list( @Query(new ZodValidationPipe(customerFieldListQuerySchema)) query: CustomerFieldListQuery, @CurrentScope() scope: ScopeContext | null, ): Promise> { return this.fields.list(query, scope); } @Post(':id/approve') @HttpCode(200) @RequirePermissions(Permission.CUSTOMER_FIELD_APPROVE) @Audit('client.customer_field.approve') @ApiOperation({ summary: '审批客户级字段(通过 / 驳回;驳回原因必填)' }) approve( @Param('id') id: string, @Body(new ZodValidationPipe(approveCustomerFieldInputSchema)) input: ApproveCustomerFieldInput, @CurrentUser() auth: AuthContext | null, @CurrentScope() scope: ScopeContext | null, ): Promise { return this.fields.approve(id, input, requireAuth(auth).userId, scope); } } @ApiTags('client-customer-fields') @ApiBearerAuth() @Controller('customers') export class CustomerFieldsOfCustomerController { constructor(@Inject(CustomerFieldsService) private readonly fields: CustomerFieldsService) {} @Get(':id/fields') @RequirePermissions(Permission.CUSTOMER_READ) @ApiOperation({ summary: '客户级字段列表(基础字段在 customers.custom_fields)' }) list( @Param('id') id: string, @CurrentScope() scope: ScopeContext | null, ): Promise { return this.fields.listByCustomer(id, scope); } @Post(':id/fields') @RequirePermissions(Permission.CUSTOMER_FIELD_APPLY) @Audit('client.customer_field.apply') @ApiOperation({ summary: '申请客户级字段(进入生成字段需审批;每客户 ≤ 5)' }) apply( @Param('id') id: string, @Body(new ZodValidationPipe(applyCustomerFieldInputSchema)) input: ApplyCustomerFieldInput, @CurrentUser() auth: AuthContext | null, @CurrentScope() scope: ScopeContext | null, ): Promise { return this.fields.apply(id, input, requireAuth(auth).userId, scope); } }