# 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.
