# AI Generation Task Center Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Convert long-running DeepSeek generation requests into trackable asynchronous tasks with generation records, basic quota accounting, cost usage, and retry support. **Architecture:** Keep the existing synchronous `IAiGenerateService` methods as the actual generation engine and add a DB-backed task layer in front of them. A task service creates task rows, reserves quota, and a worker claims pending tasks with a short database lock before executing generation outside the claim transaction. The Vue workbench starts tasks, polls status, and applies the generated result after success. **Tech Stack:** Spring Boot, MyBatis XML mappers, MySQL tables in `sql/front_workbench.sql` and `sql/db.sql`, existing RuoYi thread pool conventions, Vue 3 + Element Plus. --- ### File Structure - Create `ruoyi-generator/src/main/java/com/ruoyi/generator/domain/front/AiGenerationTask.java`: task queue domain object. - Create `ruoyi-generator/src/main/java/com/ruoyi/generator/domain/front/AiUsageLedger.java`: usage/cost ledger domain object. - Create `ruoyi-generator/src/main/java/com/ruoyi/generator/domain/front/AiQuotaBucket.java`: per-user quota bucket domain object. - Create DTOs under `ruoyi-generator/src/main/java/com/ruoyi/generator/domain/front/dto`: `AiGenerationTaskCreateRequest`, `AiGenerationTaskStatusResponse`, `AiQuotaResponse`. - Create mapper interfaces and XML files under `ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/front` and `ruoyi-generator/src/main/resources/mapper/front`. - Create services under `ruoyi-generator/src/main/java/com/ruoyi/generator/service/front`: `IAiGenerationTaskService`, `AiGenerationTaskServiceImpl`, `AiGenerationTaskWorker`, `AiQuotaService`, `AiCostCalculator`, `AiTaskRetryPolicy`. - Modify `ruoyi-admin/src/main/java/com/ruoyi/web/controller/front/FrontProjectController.java`: add task create/status/retry/cancel/quota/history endpoints. - Modify `ruoyi-generator/src/main/java/com/ruoyi/generator/service/front/AiGenerateServiceImpl.java`: expose execution helpers or keep using the public sync methods from worker. - Modify `easycode-web/src/api/project.js`: add task APIs. - Modify `easycode-web/src/views/GenerateView.vue`: replace blocking generation calls with task start + polling. - Modify SQL scripts: add task, quota, and ledger tables. - Add focused tests in `ruoyi-generator/src/test/java/com/ruoyi/generator/service/front`. ### Task 1: Task Status and Retry Policy **Files:** - Create: `ruoyi-generator/src/main/java/com/ruoyi/generator/service/front/AiTaskRetryPolicy.java` - Test: `ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/AiTaskRetryPolicyTest.java` - [ ] **Step 1: Write failing tests** Test retryable messages: timeout, 429, 5xx, and DeepSeek unavailable retry. Test validation/permission/quota messages do not retry. Test backoff sequence returns 30 seconds, 2 minutes, 5 minutes. - [ ] **Step 2: Run test to verify it fails** Run: `mvn -pl ruoyi-generator -Dtest=AiTaskRetryPolicyTest test` Expected: compile failure because `AiTaskRetryPolicy` does not exist. - [ ] **Step 3: Implement minimal retry policy** Create constants for max attempts and retry delays. Add `boolean canRetry(String errorMessage, int attempts, int maxAttempts)` and `Date nextRetryTime(int attempts, Date now)`. - [ ] **Step 4: Run test to verify it passes** Run: `mvn -pl ruoyi-generator -Dtest=AiTaskRetryPolicyTest test` Expected: PASS. ### Task 2: Cost and Quota Services **Files:** - Create: `ruoyi-generator/src/main/java/com/ruoyi/generator/service/front/AiCostCalculator.java` - Create: `ruoyi-generator/src/main/java/com/ruoyi/generator/service/front/AiQuotaService.java` - Create: `ruoyi-generator/src/main/java/com/ruoyi/generator/domain/front/AiQuotaBucket.java` - Create: `ruoyi-generator/src/main/java/com/ruoyi/generator/domain/front/AiUsageLedger.java` - Test: `ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/AiCostCalculatorTest.java` - Test: `ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/AiQuotaServiceTest.java` - [ ] **Step 1: Write failing tests** Test default quota allows a first task, blocks when daily count reaches 20, blocks when monthly cost reaches 5000 cents, reserves one running task, and releases running count on finish. - [ ] **Step 2: Run tests to verify they fail** Run: `mvn -pl ruoyi-generator -Dtest=AiCostCalculatorTest,AiQuotaServiceTest test` Expected: compile failure for missing services/domain types. - [ ] **Step 3: Implement minimal services** Use mapper methods for load/create/update quota rows. Cost calculator returns 0 when tokens are missing and uses configurable defaults for DeepSeek estimates. - [ ] **Step 4: Run tests to verify they pass** Run: `mvn -pl ruoyi-generator -Dtest=AiCostCalculatorTest,AiQuotaServiceTest test` Expected: PASS. ### Task 3: Task Persistence **Files:** - Create: `AiGenerationTask` domain and mapper XML/interface. - Create: `AiUsageLedgerMapper` and `AiQuotaBucketMapper`. - Modify: `sql/front_workbench.sql` - Modify: `sql/db.sql` - [ ] **Step 1: Write mapper/service tests** Add tests for creating task rows, selecting task by user/project/task, selecting claimable tasks, updating lock/status, and inserting usage ledger. - [ ] **Step 2: Run tests to verify they fail** Run: `mvn -pl ruoyi-generator -Dtest=AiGenerationTaskServiceImplTest test` Expected: compile failure for missing domain/mapper/service methods. - [ ] **Step 3: Implement MyBatis domain and XML** Use status values `QUEUED`, `RUNNING`, `RETRY_WAITING`, `SUCCEEDED`, `FAILED`, `CANCELED`. Add indexes for `(status, next_retry_time)`, `(user_id, project_id)`, and `generation_id`. - [ ] **Step 4: Run tests to verify they pass** Run: `mvn -pl ruoyi-generator -Dtest=AiGenerationTaskServiceImplTest test` Expected: PASS. ### Task 4: Task Service and Worker **Files:** - Create: `IAiGenerationTaskService` - Create: `AiGenerationTaskServiceImpl` - Create: `AiGenerationTaskWorker` - Modify: `FrontProjectController` - Test: `AiGenerationTaskServiceImplTest` - [ ] **Step 1: Write failing service tests** Test task creation validates project ownership, reserves quota, creates a `front_project_generation` row, creates a queued task, returns status DTO, and deduplicates a still-running same request hash. - [ ] **Step 2: Run test to verify it fails** Run: `mvn -pl ruoyi-generator -Dtest=AiGenerationTaskServiceImplTest test` Expected: compile failure or assertion failure before implementation. - [ ] **Step 3: Implement task creation and status queries** Generate request hash from `generateType + normalized request JSON`. Store request payload as JSON. Return `taskId`, `status`, `currentStep`, `progress`, `generationId`. - [ ] **Step 4: Write failing worker tests** Test worker executes app blueprint, database, and business blueprint tasks by delegating to existing sync service methods, marks success, records elapsed time, inserts ledger, and schedules retry for retryable failures. - [ ] **Step 5: Implement worker** Claim tasks using `locked_by` and `locked_until`, run outside the claim transaction, then update status. Keep max attempts at 3. - [ ] **Step 6: Run tests to verify they pass** Run: `mvn -pl ruoyi-generator -Dtest=AiGenerationTaskServiceImplTest,AiGenerationTaskWorkerTest test` Expected: PASS. ### Task 5: REST API **Files:** - Modify: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/front/FrontProjectController.java` - Test: service tests remain the main safety net. - [ ] **Step 1: Add controller endpoints** Add `POST /front/project/{projectId}/ai-tasks`, `GET /front/project/{projectId}/ai-tasks/{taskId}`, `POST /front/project/{projectId}/ai-tasks/{taskId}/retry`, `POST /front/project/{projectId}/ai-tasks/{taskId}/cancel`, `GET /front/project/{projectId}/generations`, and `GET /front/project/ai-quota`. - [ ] **Step 2: Run compile tests** Run: `mvn -pl ruoyi-admin -DskipTests compile` Expected: SUCCESS. ### Task 6: Frontend Polling Experience **Files:** - Modify: `easycode-web/src/api/project.js` - Modify: `easycode-web/src/views/GenerateView.vue` - [ ] **Step 1: Add task API helpers** Add `createAiTask`, `getAiTask`, `retryAiTask`, `cancelAiTask`, `getAiQuota`, and `listGenerations`. - [ ] **Step 2: Update generation handlers** Replace direct calls to `generateAppBlueprint`, `generateDatabase`, and `generateBusinessBlueprint` with `createAiTask` plus polling. Keep the old direct API helpers for compatibility. - [ ] **Step 3: Show task state** Display status, progress, error message, retry button, and quota summary in the existing generate page. - [ ] **Step 4: Run frontend tests/build** Run direct `.mjs` tests with Node 20 and run Vite build. Expected: tests and build pass. ### Task 7: Final Verification **Files:** - No new files. - [ ] **Step 1: Run backend tests** Run: `mvn test` Expected: SUCCESS. - [ ] **Step 2: Run frontend tests/build** Run easycode-web direct `.mjs` tests and Vite build. Expected: SUCCESS. - [ ] **Step 3: Inspect git diff** Run: `git diff --stat` and `git status --short`. Expected: only intended AI task center files changed.