diff --git a/src/modules/ai-runtime/quiz-execution-router.spec.ts b/src/modules/ai-runtime/quiz-execution-router.spec.ts index 5027eab..4bfa00c 100644 --- a/src/modules/ai-runtime/quiz-execution-router.spec.ts +++ b/src/modules/ai-runtime/quiz-execution-router.spec.ts @@ -4,7 +4,6 @@ import { FeatureFlagService } from '../config/feature-flag.service'; import { QuizGenerationSnapshotBuilder } from '../ai-job/quiz-generation-snapshot-builder'; import { AiJobCreationService } from '../ai-job/ai-job-creation.service'; import { UserAiService } from './user-ai.service'; -import { QuotaGuardService } from '../membership/quota-guard.service'; import * as crypto from 'crypto'; function dto(overrides?: any) { @@ -42,10 +41,6 @@ describe('QuizExecutionRouter', () => { })), }; mockLegacy = { createAnalysisJob: jest.fn() }; - const mockQuotaGuard = { - check: jest.fn().mockResolvedValue({ allowed: true, quotaType: 'quiz_generation', limit: 30, used: 0, remaining: 30, resetAt: null, upgradeAvailable: false }), - buildError: jest.fn().mockReturnValue({ errorCode: 'QUOTA_EXCEEDED', message: '', quotaType: 'quiz_generation', limit: 30, used: 30, remaining: 0, resetAt: null, upgradeAvailable: true }), - }; const module: TestingModule = await Test.createTestingModule({ providers: [ @@ -54,7 +49,6 @@ describe('QuizExecutionRouter', () => { { provide: QuizGenerationSnapshotBuilder, useValue: mockSnapshot }, { provide: AiJobCreationService, useValue: mockCreation }, { provide: UserAiService, useValue: mockLegacy }, - { provide: QuotaGuardService, useValue: mockQuotaGuard }, ], }).compile(); diff --git a/src/modules/ai-runtime/quiz-execution-router.ts b/src/modules/ai-runtime/quiz-execution-router.ts index 4d87de7..ad676e4 100644 --- a/src/modules/ai-runtime/quiz-execution-router.ts +++ b/src/modules/ai-runtime/quiz-execution-router.ts @@ -1,4 +1,4 @@ -import { Injectable, Logger, BadRequestException } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; import * as crypto from 'crypto'; import { FeatureFlagService } from '../config/feature-flag.service'; import { QuizGenerationSnapshotBuilder } from '../ai-job/quiz-generation-snapshot-builder'; @@ -6,7 +6,6 @@ import type { QuizGenerationSnapshotInput } from '../ai-job/quiz-generation-snap import { AiJobCreationService } from '../ai-job/ai-job-creation.service'; import { UserAiService } from './user-ai.service'; import type { CreateAnalysisJobDto } from './user-ai.dto'; -import { QuotaGuardService } from '../membership/quota-guard.service'; /** * M-AI-07-05 / M-AI-07-CLEANUP: Quiz Execution Router @@ -35,16 +34,10 @@ export class QuizExecutionRouter { private readonly snapshotBuilder: QuizGenerationSnapshotBuilder, private readonly creationService: AiJobCreationService, private readonly legacyService: UserAiService, - private readonly quotaGuard: QuotaGuardService, ) {} async generateQuiz(userId: string, dto: CreateAnalysisJobDto) { - // M-MEMBER-01-08: quiz_generation 接入统一额度(参考集成) - const quotaOpId = dto.idempotencyKey ?? `quiz_gen:${dto.targetType}:${dto.targetId}:${Date.now()}`; - const check = await this.quotaGuard.check(userId, 'quiz_generation', quotaOpId); - if (!check.allowed) { - throw new BadRequestException(this.quotaGuard.buildError(check)); - } + // M-MEMBER-01-CLOSE-01A: 额度预占已由 UserAiController 集中处理,此处不再重复 reserve const useUnified = await this.shouldUseUnified(userId);