|
@@ -0,0 +1,326 @@
|
|
|
|
|
+# API Issue Fix + Test Enhancement Plan
|
|
|
|
|
+
|
|
|
|
|
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task.
|
|
|
|
|
+
|
|
|
|
|
+**Goal:** Fix remaining API issues from v10 test report, update API test coverage for newly added features, and document E2E test deployment path.
|
|
|
|
|
+
|
|
|
|
|
+**Architecture:** Backend fixes in existing controllers (ProductSkuController, AdminGuideController) targeting NPE and 500 errors. Add API test cases for recent features to v9_test.js. Document uni-app H5 deployment config for E2E test execution.
|
|
|
|
|
+
|
|
|
|
|
+**Tech Stack:** Spring Boot 2.7.18 (backend), Node.js (API tests), Playwright (E2E tests)
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## File Changes Map
|
|
|
|
|
+
|
|
|
|
|
+| File | Action | Reason |
|
|
|
|
|
+|------|--------|--------|
|
|
|
|
|
+| `cfc-backend/src/main/java/com/etotem/cfc/controller/admin/ProductSkuController.java` | Modify | Fix NPE in listByProduct (NEW-02) |
|
|
|
|
|
+| `cfc-backend/.../controller/guide/AdminGuideController.java` | Modify | Fix 500 in activity list (INFO-GA) |
|
|
|
|
|
+| `tests/v9_test.js` | Modify | Add test cases for food/seasonal-months/nutrition endpoints |
|
|
|
|
|
+| `tests/ISSUE-TRACKING.md` | Modify | Update issue statuses |
|
|
|
|
|
+| `tests/TEST-RESULTS-v10.md` | Modify | Add v10.5 results |
|
|
|
|
|
+| `cfc-backend/src/main/resources/application.yml` | Check | Verify guide activity test config |
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### Task 1: Commit Current Uncommitted Changes
|
|
|
|
|
+
|
|
|
|
|
+**Files:**
|
|
|
|
|
+- Commit: `cfc-backend/.../controller/admin/AdminArticleController.java`
|
|
|
|
|
+- Commit: `cfc-backend/.../controller/admin/AdminFoodController.java`
|
|
|
|
|
+- Commit: `cfc-backend/.../service/ArticleService.java`
|
|
|
|
|
+- Commit: `cfc-backend/.../service/FoodService.java`
|
|
|
|
|
+- Commit: `cfc-web/src/api/admin.js`
|
|
|
|
|
+- Commit: `cfc-web/src/views/admin/Foods.vue`
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 1: Stage and commit the current session's work**
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+cd /sc-data/cfc
|
|
|
|
|
+git add cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminArticleController.java
|
|
|
|
|
+git add cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminFoodController.java
|
|
|
|
|
+git add cfc-backend/src/main/java/com/etotem/cfc/service/ArticleService.java
|
|
|
|
|
+git add cfc-backend/src/main/java/com/etotem/cfc/service/FoodService.java
|
|
|
|
|
+git add cfc-backend/src/main/java/com/etotem/cfc/service/ArticleService.java
|
|
|
|
|
+git add cfc-web/src/api/admin.js
|
|
|
|
|
+git add cfc-web/src/views/admin/Foods.vue
|
|
|
|
|
+git commit -m "feat: article AI auto-tagging + food seasonal months management"
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Expected: 7 files committed.
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### Task 2: Fix SKU List NPE (NEW-02)
|
|
|
|
|
+
|
|
|
|
|
+**Files:**
|
|
|
|
|
+- Modify: `cfc-backend/src/main/java/com/etotem/cfc/controller/admin/ProductSkuController.java`
|
|
|
|
|
+
|
|
|
|
|
+**Background:** `POST /api/admin/product/sku/list` crashes with 500 when `productIdObj` is null. The `params.get("productId")` returns null, then `.toString()` on null throws NPE before the guard.
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 1: Read and fix ProductSkuController.listByProduct()**
|
|
|
|
|
+
|
|
|
|
|
+Read the file:
|
|
|
|
|
+```
|
|
|
|
|
+cfc-backend/src/main/java/com/etotem/cfc/controller/admin/ProductSkuController.java
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Locate the `listByProduct` method. Find the problematic code:
|
|
|
|
|
+```java
|
|
|
|
|
+Object productIdObj = params.get("productId");
|
|
|
|
|
+if (productIdObj == null) return Result.error("productId不能为空");
|
|
|
|
|
+Long productId = Long.parseLong(productIdObj.toString()); // NPE if null
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Fix: The issue is that `Long.parseLong(productIdObj.toString())` can NPE because `productIdObj` is checked for null, but `toString()` could be called on a differently typed null. Actually the real NPE is likely that `productIdObj` is not null but is an Integer (not Long), so `Long.parseLong()` fails on something else. But the guard seems correct. Let me re-read the issue:
|
|
|
|
|
+
|
|
|
|
|
+From NEW-ISSUES-20260702.md:
|
|
|
|
|
+```java
|
|
|
|
|
+Object productIdObj = params.get("productId");
|
|
|
|
|
+if (productIdObj == null) return Result.error("productId不能为空");
|
|
|
|
|
+Long productId = Long.parseLong(productIdObj.toString());
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Wait, this actually looks fine for NPE (productIdObj is checked before calling toString). The issue might be that `Long.parseLong` fails because `productIdObj` might be an Integer, and Integer.toString() returns the number as a string, so `Long.parseLong("123")` works fine.
|
|
|
|
|
+
|
|
|
|
|
+Actually, let me re-read the v10 test result: "SKU list | ✅ PASS | SKU列表查询正常(NPE已修复)" - NEW-02 shows it's already fixed in the test! Let me check the git log for this fix.
|
|
|
|
|
+
|
|
|
|
|
+Wait, looking at the test results again:
|
|
|
|
|
+```
|
|
|
|
|
+| NEW-02 | SKU list | ✅ PASS | SKU列表查询正常(NPE已修复) |
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+But in NEW-ISSUES-20260702.md:
|
|
|
|
|
+```
|
|
|
|
|
+## NEW-02:SKU列表接口返回 500 ❌ 仍有Bug
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+The test result says PASS but the issue doc says FAIL. The test was from v10 (2026-07-04) and the issue doc is from 2026-07-02. So the fix was likely applied between those dates.
|
|
|
|
|
+
|
|
|
|
|
+Let me check if there's a recent fix for this.
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 2: Verify the fix exists**
|
|
|
|
|
+
|
|
|
|
|
+Search for the listByProduct method:
|
|
|
|
|
+```
|
|
|
|
|
+grep -n "listByProduct" cfc-backend/src/main/java/com/etotem/cfc/controller/admin/ProductSkuController.java
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Read the method to confirm the fix is already in place. If `Long.parseLong` is used with a try-catch or the input validation uses instanceof, the fix is done.
|
|
|
|
|
+
|
|
|
|
|
+If the fix IS already in place:
|
|
|
|
|
+- Update NEW-ISSUES-20260702.md to mark NEW-02 as fixed
|
|
|
|
|
+- Update ISSUE-TRACKING.md to move NEW-02 to "Closed"
|
|
|
|
|
+
|
|
|
|
|
+If the fix is NOT in place:
|
|
|
|
|
+- Apply the fix:
|
|
|
|
|
+```java
|
|
|
|
|
+Object productIdObj = params.get("productId");
|
|
|
|
|
+if (productIdObj == null) return Result.error("productId不能为空");
|
|
|
|
|
+Long productId;
|
|
|
|
|
+try {
|
|
|
|
|
+ productId = Long.parseLong(productIdObj.toString());
|
|
|
|
|
+} catch (NumberFormatException e) {
|
|
|
|
|
+ return Result.error("productId格式错误");
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### Task 3: Investigate Guide Activity List 500 (INFO-GA)
|
|
|
|
|
+
|
|
|
|
|
+**Files:**
|
|
|
|
|
+- Read: `cfc-backend/.../controller/guide/AdminGuideController.java` (or wherever the guide activities list endpoint lives)
|
|
|
|
|
+
|
|
|
|
|
+**Background:** `POST /api/guide/activities/list` returns 500. Test report marks it as INFO-GA ("可能是数据问题"). This might be an endpoint that requires a specific data state.
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 1: Find the guide activities list endpoint**
|
|
|
|
|
+
|
|
|
|
|
+Search:
|
|
|
|
|
+```
|
|
|
|
|
+grep -rn "activities/list" cfc-backend/src/main/java/com/etotem/cfc/controller/
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Read the controller method handling this endpoint to determine if it's a code bug or a data issue.
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 2: Analyze the root cause**
|
|
|
|
|
+
|
|
|
|
|
+Check if the method:
|
|
|
|
|
+1. Requires a non-null parameter that may be missing
|
|
|
|
|
+2. Has a null pointer or SQL exception
|
|
|
|
|
+3. Depends on specific data (guide has activities, etc.)
|
|
|
|
|
+4. Has missing @PostMapping (might be @GetMapping)
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 3: Fix or document**
|
|
|
|
|
+
|
|
|
|
|
+If code bug: Apply minimal fix (add null checks, try-catch, or default values).
|
|
|
|
|
+
|
|
|
|
|
+If data issue: Update ISSUE-TRACKING.md to note it's a data dependency, not a code bug.
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### Task 4: Investigate Vendor Login Failure (ISSUE-001)
|
|
|
|
|
+
|
|
|
|
|
+**Files:**
|
|
|
|
|
+- Read: `cfc-backend/.../controller/auth/AuthController.java`
|
|
|
|
|
+- Read: `cfc-backend/.../config/JwtInterceptor.java`
|
|
|
|
|
+
|
|
|
|
|
+**Background:** Vendor login (`POST /api/auth/phone-login`) returns non-token response. The test vendor (userId=81069) has `vendor_status=pending` in the test data.
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 1: Read AuthController.phoneLogin()**
|
|
|
|
|
+
|
|
|
|
|
+Check if the phone login method has any role-based filtering that might block pending vendors.
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 2: Read JwtInterceptor**
|
|
|
|
|
+
|
|
|
|
|
+Check if there are any JWT rules that might affect vendor token generation.
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 3: Test login manually**
|
|
|
|
|
+
|
|
|
|
|
+Try:
|
|
|
|
|
+```bash
|
|
|
|
|
+curl -X POST http://cfc.iwintrue.com/api/auth/phone-login \
|
|
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
|
|
+ -d '{"phone":"13800138001","code":"123456"}'
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Check the response. If it returns a proper token, the issue is the test data (vendor not approved). If it returns an error, it's a code bug.
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 4: Fix or document**
|
|
|
|
|
+
|
|
|
|
|
+If vendor_status=pending is blocking login → Mark as test data issue, document in ISSUE-TRACKING.md.
|
|
|
|
|
+
|
|
|
|
|
+If code bug → Fix the login flow to allow pending vendors to log in (they just can't use vendor-only features until approved).
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### Task 5: Add API Test Cases for New Features
|
|
|
|
|
+
|
|
|
|
|
+**Files:**
|
|
|
|
|
+- Modify: `tests/v9_test.js`
|
|
|
|
|
+
|
|
|
|
|
+**Background:** The current API test script doesn't cover:
|
|
|
|
|
+1. Food management CRUD (foods list/create/update/delete with seasonal months)
|
|
|
|
|
+2. Article AI auto-tagging (just verify article create still works and returns tags)
|
|
|
|
|
+3. Food recommendation endpoints (food-recommend-index, food-recommend-history)
|
|
|
|
|
+4. The new seasonal months endpoints (food detail, saveMonths)
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 1: Read existing v9_test.js structure**
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+less tests/v9_test.js
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Understand the test structure: how tests are grouped, how tokens are obtained, how results are reported.
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 2: Add food management test group**
|
|
|
|
|
+
|
|
|
|
|
+Add tests for:
|
|
|
|
|
+```
|
|
|
|
|
+NEW-FOOD-01: Food list (list all foods)
|
|
|
|
|
+NEW-FOOD-02: Food create (create a new food item)
|
|
|
|
|
+NEW-FOOD-03: Food detail with months (verify months field present)
|
|
|
|
|
+NEW-FOOD-04: Save seasonal months (set months 6,7,8 for a food)
|
|
|
|
|
+NEW-FOOD-05: Food delete (cleanup)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Each test should use the same admin token mechanism as existing tests.
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 3: Add food recommendation test group (if endpoints exist)**
|
|
|
|
|
+
|
|
|
|
|
+Check if these endpoints exist:
|
|
|
|
|
+```
|
|
|
|
|
+POST /api/health/foods/by-family
|
|
|
|
|
+POST /api/meal/recommend
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+If they exist, add basic health-check tests.
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 4: Run the updated test script**
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+node tests/v9_test.js 2>&1 | tee tests/v10.5_result.txt
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Verify all existing tests still PASS and new tests PASS.
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### Task 6: Update Test Results and Issue Tracking
|
|
|
|
|
+
|
|
|
|
|
+**Files:**
|
|
|
|
|
+- Modify: `tests/TEST-RESULTS-v10.md` (or create v11)
|
|
|
|
|
+- Modify: `tests/ISSUE-TRACKING.md`
|
|
|
|
|
+- Modify: `docs/系统测试/issue-tracking/NEW-ISSUES-20260702.md`
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 1: Update test results**
|
|
|
|
|
+
|
|
|
|
|
+Create `tests/TEST-RESULTS-v11.md` with the new test run results. Include:
|
|
|
|
|
+- Version info (date, commit hash)
|
|
|
|
|
+- Test summary (PASS/FAIL/SKIP counts)
|
|
|
|
|
+- New feature verification results
|
|
|
|
|
+- Regression test results
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 2: Update issue tracking**
|
|
|
|
|
+
|
|
|
|
|
+In `tests/ISSUE-TRACKING.md`:
|
|
|
|
|
+- If SKU list NPE is fixed → move NEW-02 to "Closed"
|
|
|
|
|
+- If vendor login is data issue → update status to "Test data needed"
|
|
|
|
|
+- If INFO-GA is data issue → update note
|
|
|
|
|
+
|
|
|
|
|
+In `docs/系统测试/issue-tracking/NEW-ISSUES-20260702.md`:
|
|
|
|
|
+- Mark NEW-02 as fixed/verified if applicable
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### Task 7: E2E Test Environment Documentation
|
|
|
|
|
+
|
|
|
|
|
+**Files:**
|
|
|
|
|
+- Create: `docs/E2E-DEPLOYMENT-GUIDE.md` (optional — only if user wants it)
|
|
|
|
|
+
|
|
|
|
|
+**Background:** All 17 Playwright E2E test files (100+ scenarios) are blocked because the uni-app H5 frontend isn't deployed to a browser-accessible URL. The tests use hash-based routing (`/#/pages/...`) which requires uni-app's H5 build.
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 1: Document the deployment requirement**
|
|
|
|
|
+
|
|
|
|
|
+Update `tests/E2E-TEST-STATUS.md` to include:
|
|
|
|
|
+1. The exact steps needed to deploy uni-app H5 build
|
|
|
|
|
+2. The required nginx/Apache config for SPA hash routing
|
|
|
|
|
+3. The baseURL that should be set in `playwright.config.js`
|
|
|
|
|
+4. Reference to the existing cfc-web deployment on 251
|
|
|
|
|
+
|
|
|
|
|
+The deployment command would be:
|
|
|
|
|
+```bash
|
|
|
|
|
+cd cfc-frontend
|
|
|
|
|
+npm install
|
|
|
|
|
+npm run build:h5 # produces dist/build/h5/
|
|
|
|
|
+# Then rsync to web server (same nginx that serves cfc-web)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+The `playwright.config.js` baseURL would need to change to wherever the H5 build is deployed.
|
|
|
|
|
+
|
|
|
|
|
+- [ ] **Step 2: Verify Playwright baseURL is configurable**
|
|
|
|
|
+
|
|
|
|
|
+Read `tests/playwright.config.js` to confirm the baseURL config, document how to switch between environments.
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## Self-Review
|
|
|
|
|
+
|
|
|
|
|
+### Spec Coverage Check
|
|
|
|
|
+| Requirement | Task | Status |
|
|
|
|
|
+|-------------|------|--------|
|
|
|
|
|
+| Commit current work | Task 1 | ✅ |
|
|
|
|
|
+| Fix SKU NPE (NEW-02) | Task 2 | ✅ — verify first, fix if needed |
|
|
|
|
|
+| Investigate INFO-GA (guide 500) | Task 3 | ✅ — analyze, fix or classify |
|
|
|
|
|
+| Investigate ISSUE-001 (vendor login) | Task 4 | ✅ — analyze, fix or classify |
|
|
|
|
|
+| Update API tests | Task 5 | ✅ — add food/seasonal coverage |
|
|
|
|
|
+| Update issue tracking | Task 6 | ✅ |
|
|
|
|
|
+| Document E2E deployment | Task 7 | ✅ |
|
|
|
|
|
+
|
|
|
|
|
+### Placeholder Check
|
|
|
|
|
+No TBD/TODO/fill-in patterns found — all steps have concrete action descriptions.
|
|
|
|
|
+
|
|
|
|
|
+### Type Consistency
|
|
|
|
|
+- All file paths use absolute paths from repo root (consistent with AGENTS.md conventions)
|
|
|
|
|
+- Controller methods follow `@PostMapping` convention (verified in codebase)
|
|
|
|
|
+- API test script uses existing `v9_test.js` structure
|