diff --git a/backend/src/modules/crm/controller/admin/compliance.ts b/backend/src/modules/crm/controller/admin/compliance.ts new file mode 100644 index 0000000..c7a2c22 --- /dev/null +++ b/backend/src/modules/crm/controller/admin/compliance.ts @@ -0,0 +1,53 @@ +import { Body, Inject, Post, Provide } from '@midwayjs/core'; +import { BaseController, CoolController, CoolCommException } from '@cool-midway/core'; +import { ComplianceGdprService } from '../../service/compliance'; + +/** + * 管理后台 - 海外数据隐私与合规治理 (GDPR / CCPA) + * 路由前缀: /admin/crm/compliance + */ +@Provide() +@CoolController({ + api: [], + service: ComplianceGdprService, + serviceApis: [ + { method: 'exportPersonalDataBundle', summary: '导出个人便携数据包 (GDPR Art. 20)' }, + { method: 'executeRightToBeForgotten', summary: '签发被遗忘权销毁证书 (GDPR Art. 17)' }, + ], +}) +export class AdminCrmComplianceController extends BaseController { + @Inject() + complianceGdprService: ComplianceGdprService; + + /** + * 执行数据擦除与被遗忘权 (GDPR Article 17) + */ + @Post('/erasure', { summary: '执行被遗忘权数据抹除' }) + async erasure( + @Body() body: { email?: string; leadId?: number | string; visitorId?: string } + ) { + if (!body?.email && !body?.leadId && !body?.visitorId) { + throw new CoolCommException('缺少数据主体标识 (email / leadId / visitorId)'); + } + + const receipt = await this.complianceGdprService.purgeVisitorPersonalData(body); + return this.ok(receipt); + } + + /** + * 导出数据主体全量便携数据 (GDPR Article 20) + */ + @Post('/export', { summary: '导出数据主体便携数据包' }) + async export( + @Body() body: { subjectId: string; dataPayload: Record } + ) { + if (!body?.subjectId) { + throw new CoolCommException('缺少数据主体标识 subjectId'); + } + const bundle = await this.complianceGdprService.exportPersonalDataBundle( + body.subjectId, + body.dataPayload || {} + ); + return this.ok(bundle); + } +}