feat(quota): add OCR/Vision pre-check at document import controller
Document Import: EXEMPT_BY_CONTRACT (no independent import quota — constrained by file_size_bytes + storage_bytes + ocr_pages + vision_pages). OCR/Vision pre-check ensures user has quota before creating import. Per-page metering requires RAG Worker-side changes (Python). Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
1d6a04a8b3
commit
ac7a2201ab
@ -1,20 +1,33 @@
|
||||
import { Controller, Get, Post, Param, HttpCode, HttpStatus, Body } from '@nestjs/common';
|
||||
import { Controller, Get, Post, Param, HttpCode, HttpStatus, Body, BadRequestException } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation } from '@nestjs/swagger';
|
||||
import { DocumentImportService } from './document-import.service';
|
||||
import { CreateImportDto } from './dto/create-import.dto';
|
||||
import { QuotaGuardService } from '../membership/quota-guard.service';
|
||||
import { CurrentUser } from '../../common/decorators/current-user.decorator';
|
||||
import type { UserPayload } from '../../common/types';
|
||||
|
||||
@ApiTags('document-import')
|
||||
@Controller('imports')
|
||||
export class DocumentImportController {
|
||||
constructor(private readonly service: DocumentImportService) {}
|
||||
constructor(
|
||||
private readonly service: DocumentImportService,
|
||||
private readonly quotaGuard: QuotaGuardService,
|
||||
) {}
|
||||
|
||||
@Post()
|
||||
@HttpCode(HttpStatus.CREATED)
|
||||
@ApiOperation({ summary: '创建导入任务' })
|
||||
async createImport(@CurrentUser() user: UserPayload, @Body() dto: CreateImportDto) {
|
||||
return this.service.createImport({ ...dto, userId: user.id });
|
||||
const userId = user.id;
|
||||
// M-MEMBER-01-CLOSE-01D: OCR/Vision 预检——导入创建时检查可用额度
|
||||
// 实际逐页计量由 RAG Worker 侧完成
|
||||
const opId = `import:${userId}:${Date.now()}`;
|
||||
const ocrCheck = await this.quotaGuard.check(userId, 'ocr_pages', `${opId}:ocr`, 0);
|
||||
const visionCheck = await this.quotaGuard.check(userId, 'vision_pages', `${opId}:vision`, 0);
|
||||
if (!ocrCheck.allowed || !visionCheck.allowed) {
|
||||
throw new BadRequestException({ errorCode: 'QUOTA_EXCEEDED', message: 'OCR/Vision quota exceeded', quotaType: !ocrCheck.allowed ? 'ocr_pages' : 'vision_pages', limit: !ocrCheck.allowed ? ocrCheck.limit : visionCheck.limit, used: !ocrCheck.allowed ? ocrCheck.used : visionCheck.used, remaining: 0, upgradeAvailable: true });
|
||||
}
|
||||
return this.service.createImport({ ...dto, userId });
|
||||
}
|
||||
|
||||
@Get(':id/status')
|
||||
|
||||
@ -4,8 +4,10 @@ import { AdminImportsController } from './admin-imports.controller';
|
||||
import { DocumentImportService } from './document-import.service';
|
||||
import { DocumentImportRepository } from './document-import.repository';
|
||||
import { PrismaService } from '../../infrastructure/database/prisma.service';
|
||||
import { MembershipModule } from '../membership/membership.module';
|
||||
|
||||
@Module({
|
||||
imports: [MembershipModule],
|
||||
controllers: [DocumentImportController, AdminImportsController],
|
||||
providers: [DocumentImportService, DocumentImportRepository, PrismaService],
|
||||
exports: [DocumentImportService, DocumentImportRepository],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user