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 { ApiTags, ApiOperation } from '@nestjs/swagger';
|
||||||
import { DocumentImportService } from './document-import.service';
|
import { DocumentImportService } from './document-import.service';
|
||||||
import { CreateImportDto } from './dto/create-import.dto';
|
import { CreateImportDto } from './dto/create-import.dto';
|
||||||
|
import { QuotaGuardService } from '../membership/quota-guard.service';
|
||||||
import { CurrentUser } from '../../common/decorators/current-user.decorator';
|
import { CurrentUser } from '../../common/decorators/current-user.decorator';
|
||||||
import type { UserPayload } from '../../common/types';
|
import type { UserPayload } from '../../common/types';
|
||||||
|
|
||||||
@ApiTags('document-import')
|
@ApiTags('document-import')
|
||||||
@Controller('imports')
|
@Controller('imports')
|
||||||
export class DocumentImportController {
|
export class DocumentImportController {
|
||||||
constructor(private readonly service: DocumentImportService) {}
|
constructor(
|
||||||
|
private readonly service: DocumentImportService,
|
||||||
|
private readonly quotaGuard: QuotaGuardService,
|
||||||
|
) {}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@HttpCode(HttpStatus.CREATED)
|
@HttpCode(HttpStatus.CREATED)
|
||||||
@ApiOperation({ summary: '创建导入任务' })
|
@ApiOperation({ summary: '创建导入任务' })
|
||||||
async createImport(@CurrentUser() user: UserPayload, @Body() dto: CreateImportDto) {
|
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')
|
@Get(':id/status')
|
||||||
|
|||||||
@ -4,8 +4,10 @@ import { AdminImportsController } from './admin-imports.controller';
|
|||||||
import { DocumentImportService } from './document-import.service';
|
import { DocumentImportService } from './document-import.service';
|
||||||
import { DocumentImportRepository } from './document-import.repository';
|
import { DocumentImportRepository } from './document-import.repository';
|
||||||
import { PrismaService } from '../../infrastructure/database/prisma.service';
|
import { PrismaService } from '../../infrastructure/database/prisma.service';
|
||||||
|
import { MembershipModule } from '../membership/membership.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
imports: [MembershipModule],
|
||||||
controllers: [DocumentImportController, AdminImportsController],
|
controllers: [DocumentImportController, AdminImportsController],
|
||||||
providers: [DocumentImportService, DocumentImportRepository, PrismaService],
|
providers: [DocumentImportService, DocumentImportRepository, PrismaService],
|
||||||
exports: [DocumentImportService, DocumentImportRepository],
|
exports: [DocumentImportService, DocumentImportRepository],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user