diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 1dc1099..0577cb4 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1468,3 +1468,53 @@ model ReleaseChecklist { @@index([version]) } + +model PrivacyPolicy { + id String @id @default(cuid()) + version String @db.VarChar(50) + title String @db.VarChar(255) + content String @db.Text + effectiveAt DateTime + published Boolean @default(false) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@index([version]) +} + +model UserAgreement { + id String @id @default(cuid()) + version String @db.VarChar(50) + title String @db.VarChar(255) + content String @db.Text + effectiveAt DateTime + published Boolean @default(false) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@index([version]) +} + +model FilingRecord { + id String @id @default(cuid()) + type String @db.VarChar(64) + title String @db.VarChar(255) + filePath String? @db.VarChar(500) + status String @default("pending") @db.VarChar(16) + notes String? @db.Text + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model DataExportRequest { + id String @id @default(cuid()) + userId String + status String @default("pending") @db.VarChar(16) + filePath String? @db.VarChar(500) + completedAt DateTime? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@index([userId]) + @@index([status]) +} diff --git a/src/app.module.ts b/src/app.module.ts index 9a2fe55..b187fff 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -57,6 +57,7 @@ import { ReportingModule } from './modules/reporting/reporting.module'; import { ProjectCenterModule } from './modules/project-center/project-center.module'; import { HermesAgentModule } from './modules/hermes-agent/hermes-agent.module'; import { ReleaseModule } from './modules/release/release.module'; +import { ComplianceModule } from './modules/compliance/compliance.module'; import { JwtAuthGuard } from './common/guards/jwt-auth.guard'; import { RolesGuard } from './common/guards/roles.guard'; @@ -159,6 +160,7 @@ import appleConfig from './config/apple.config'; ProjectCenterModule, HermesAgentModule, ReleaseModule, + ComplianceModule, ], providers: [ { provide: APP_GUARD, useClass: RateLimitGuard }, diff --git a/src/modules/compliance/compliance.controller.ts b/src/modules/compliance/compliance.controller.ts new file mode 100644 index 0000000..7f7083a --- /dev/null +++ b/src/modules/compliance/compliance.controller.ts @@ -0,0 +1,91 @@ +import { Controller, Get, Post, Patch, Param, Body, UseGuards } from '@nestjs/common'; +import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger'; +import { PrismaService } from '../../infrastructure/database/prisma.service'; +import { AdminAuthGuard } from '../../common/guards/admin-auth.guard'; +import { AdminRolesGuard } from '../../common/guards/admin-roles.guard'; + +@ApiTags('admin-compliance') +@ApiBearerAuth() +@Controller('admin-api/compliance') +@UseGuards(AdminAuthGuard, AdminRolesGuard) +export class ComplianceController { + constructor(private readonly prisma: PrismaService) {} + + // ═══ Privacy Policy ═══ + + @Get('privacy-policies') + @ApiOperation({ summary: '隐私政策列表' }) + async listPrivacyPolicies() { + return this.prisma.privacyPolicy.findMany({ orderBy: { createdAt: 'desc' } }); + } + + @Post('privacy-policies') + @ApiOperation({ summary: '创建隐私政策版本' }) + async createPrivacyPolicy(@Body() dto: { version: string; title: string; content: string; effectiveAt: string }) { + return this.prisma.privacyPolicy.create({ data: { ...dto, effectiveAt: new Date(dto.effectiveAt) } }); + } + + @Patch('privacy-policies/:id') + @ApiOperation({ summary: '更新隐私政策' }) + async updatePrivacyPolicy(@Param('id') id: string, @Body() dto: Record) { + return this.prisma.privacyPolicy.update({ where: { id }, data: dto }); + } + + // ═══ User Agreement ═══ + + @Get('user-agreements') + @ApiOperation({ summary: '用户协议列表' }) + async listUserAgreements() { + return this.prisma.userAgreement.findMany({ orderBy: { createdAt: 'desc' } }); + } + + @Post('user-agreements') + @ApiOperation({ summary: '创建用户协议版本' }) + async createUserAgreement(@Body() dto: { version: string; title: string; content: string; effectiveAt: string }) { + return this.prisma.userAgreement.create({ data: { ...dto, effectiveAt: new Date(dto.effectiveAt) } }); + } + + // ═══ Filing Records ═══ + + @Get('filings') + @ApiOperation({ summary: '备案台账列表' }) + async listFilings() { + return this.prisma.filingRecord.findMany({ orderBy: { createdAt: 'desc' } }); + } + + @Post('filings') + @ApiOperation({ summary: '创建备案记录' }) + async createFiling(@Body() dto: { type: string; title: string; notes?: string }) { + return this.prisma.filingRecord.create({ data: dto }); + } + + // ═══ Data Deletion Requests ═══ + + @Get('deletion-requests') + @ApiOperation({ summary: '用户数据删除请求' }) + async listDeletionRequests() { + return this.prisma.accountDeletionRequest.findMany({ orderBy: { createdAt: 'desc' }, take: 100 }); + } + + @Post('deletion-requests/:id/approve') + @ApiOperation({ summary: '批准删除请求' }) + async approveDeletion(@Param('id') id: string) { + return this.prisma.accountDeletionRequest.update({ where: { id }, data: { status: 'APPROVED', reviewedAt: new Date() } }); + } + + // ═══ Data Export Requests ═══ + + @Get('export-requests') + @ApiOperation({ summary: '用户数据导出请求' }) + async listExportRequests() { + return this.prisma.dataExportRequest.findMany({ orderBy: { createdAt: 'desc' }, take: 100 }); + } + + // ═══ Security Events ═══ + + @Get('security-events') + @ApiOperation({ summary: '安全事件列表' }) + async listSecurityEvents() { + return this.prisma.securityEvent.findMany({ orderBy: { createdAt: 'desc' }, take: 100 }); + } +} diff --git a/src/modules/compliance/compliance.module.ts b/src/modules/compliance/compliance.module.ts new file mode 100644 index 0000000..8334205 --- /dev/null +++ b/src/modules/compliance/compliance.module.ts @@ -0,0 +1,7 @@ +import { Module } from '@nestjs/common'; +import { ComplianceController } from './compliance.controller'; + +@Module({ + controllers: [ComplianceController], +}) +export class ComplianceModule {}