187 lines
5.7 KiB
Markdown
187 lines
5.7 KiB
Markdown
# ✅ Chapter Save System - Fixed Issues Summary
|
|
|
|
**Date:** 2026-03-24
|
|
**Status:** All HIGH priority issues fixed ✅
|
|
|
|
---
|
|
|
|
## 🐛 Issues Identified & Fixed
|
|
|
|
### 1️⃣ **Ownership Check Bypass (HIGH)**
|
|
- **File:** `app/routers/mod.py`
|
|
- **Lines:** 932-936 (POST), 1000-1007 (PUT)
|
|
- **Issue:** MOD couldn't create chapters for default novels (uploaderId = NULL)
|
|
- **Fix:** Changed query from:
|
|
```python
|
|
WHERE id = :nid AND "uploaderId" = :uid
|
|
```
|
|
To:
|
|
```python
|
|
WHERE id = :nid AND ("uploaderId" = :uid OR "uploaderId" IS NULL)
|
|
```
|
|
- **Impact:** ✅ Fixed - MOD can now manage default novels
|
|
|
|
### 2️⃣ **Missing Input Validation (HIGH)**
|
|
- **File:** `app/routers/mod.py`
|
|
- **Lines:** 920-927 (POST), 997-1004 (PUT)
|
|
- **Issue:** Could save empty title/content, negative chapter numbers
|
|
- **Fix:** Added validation:
|
|
```python
|
|
if not body.title or not body.title.strip():
|
|
raise HTTPException(400, "Tiêu đề chương không được trống")
|
|
if body.number <= 0:
|
|
raise HTTPException(400, "Số chương phải > 0")
|
|
```
|
|
- **Impact:** ✅ Fixed - Invalid data rejected at API level
|
|
|
|
### 3️⃣ **Data Inconsistency on PostgreSQL Failure (HIGH)**
|
|
- **File:** `app/routers/mod.py`
|
|
- **Lines:** 956-974 (POST)
|
|
- **Issue:** If MongoDB insert succeeds but PostgreSQL sync fails → inconsistent state
|
|
- **Fix:** Added separate error handling:
|
|
```python
|
|
try:
|
|
result = await mongo_db.chapters.insert_one(doc)
|
|
except Exception as mongo_err:
|
|
raise HTTPException(500, f"Lỗi MongoDB: {str(mongo_err)}")
|
|
|
|
try:
|
|
total = await _sync_total_chapters(db, body.novelId)
|
|
except Exception as pg_err:
|
|
# Log [CRITICAL] and alert user
|
|
raise HTTPException(500, "Dữ liệu has được lưu nhưng...")
|
|
```
|
|
- **Impact:** ✅ Fixed - Clear error messages identify MongoDB vs PostgreSQL failures
|
|
|
|
### 4️⃣ **Frontend Error Display (MEDIUM)**
|
|
- **File:** `reader/app/mod/chuong/chapter-client.tsx`
|
|
- **Line:** 356
|
|
- **Issue:** Only checked `error` field, not FastAPI's `detail` field
|
|
- **Fix:** Changed:
|
|
```javascript
|
|
if (!res.ok) throw new Error(resData.error || resData.detail || "...")
|
|
```
|
|
- **Impact:** ✅ Fixed - Users see actual backend error messages
|
|
|
|
### 5️⃣ **Missing Novel Existence Check (MEDIUM)**
|
|
- **File:** `app/routers/mod.py`
|
|
- **Lines:** 948-951 (POST)
|
|
- **Issue:** Could try to save chapter for non-existent novel
|
|
- **Fix:** Added explicit check:
|
|
```python
|
|
novel_check = await db.execute(
|
|
text('SELECT id FROM "Novel" WHERE id = :nid'),
|
|
{"nid": body.novelId},
|
|
)
|
|
if not novel_check.first():
|
|
raise HTTPException(404, "Truyện không tồn tại")
|
|
```
|
|
- **Impact:** ✅ Fixed - Better error message (404 instead of 500)
|
|
|
|
---
|
|
|
|
## 📊 Testing Results
|
|
|
|
### Build Verification
|
|
```
|
|
✅ Python syntax: OK (py_compile passed)
|
|
✅ Next.js build: OK (all 11 routes successfully compiled)
|
|
✅ No type errors in modified files
|
|
```
|
|
|
|
### Modified Files
|
|
| File | Changes | Status |
|
|
|------|---------|--------|
|
|
| `app/routers/mod.py` | POST/PUT endpoints refactored with validation | ✅ Fixed |
|
|
| `reader/app/mod/chuong/chapter-client.tsx` | Error handling improved | ✅ Fixed |
|
|
| `CHAPTER_SAVE_DEBUG.md` | Debug guide created | ✅ New |
|
|
|
|
---
|
|
|
|
## 🚀 Next Steps for User
|
|
|
|
### ⚠️ IMPORTANT: Test the following scenarios
|
|
|
|
1. **Basic Save:** Create new novel → save Chapter 1 → verify appears in list
|
|
2. **Ownership:** Try saving to default novel as MOD user → should succeed now
|
|
3. **Duplicate:** Try saving same chapter twice → should show "đã tồn tại"
|
|
4. **Empty Content:** Try saving without title → should show validation error
|
|
5. **Negative Number:** Try chapter #-1 → should reject
|
|
|
|
### If Still Failing:
|
|
|
|
1. Open **DevTools Network tab** → F12 → Network
|
|
2. Try to save chapter
|
|
3. Look for **POST /api/mod/chuong** request
|
|
4. Check **Status code** and **Response body**
|
|
5. Use guide in `CHAPTER_SAVE_DEBUG.md` to troubleshoot
|
|
|
|
### Possible Remaining Issues
|
|
|
|
⚠️ **Not yet fixed (MEDIUM/LOW priority):**
|
|
- [ ] Race condition on duplicate chapter check (add MongoDB unique index)
|
|
- [ ] No MongoDB/PostgreSQL timeout configuration
|
|
- [ ] Generic exception handler logging (uses traceback.print_exc)
|
|
- [ ] Missing structured logging system
|
|
|
|
These are less critical but could cause issues under high load.
|
|
|
|
---
|
|
|
|
## 📝 Code Changes Summary
|
|
|
|
**Total lines modified:** ~150
|
|
**Files affected:** 2
|
|
**Breaking changes:** None (backward compatible)
|
|
**Rollback difficulty:** Low (simple validation additions)
|
|
|
|
---
|
|
|
|
## ✨ What Changed
|
|
|
|
```diff
|
|
# POST /mod/chuong
|
|
- Missing input validation
|
|
- Missing novel existence check
|
|
- Ownership query doesn't allow NULL uploaderId
|
|
- No separation of MongoDB vs PostgreSQL error handling
|
|
|
|
+ Full input validation (title, content, number)
|
|
+ Novel existence check with clear 404 error
|
|
+ Ownership check allows both user-owned and default novels
|
|
+ Separate error handling for MongoDB and PostgreSQL
|
|
+ Better error messages for debugging
|
|
+ Data consistency logging ([CRITICAL] alerts)
|
|
|
|
# PUT /mod/chuong
|
|
- Same issues as POST
|
|
|
|
+ Same fixes applied
|
|
|
|
# Frontend error handling
|
|
- Ignored FastAPI's 'detail' field
|
|
|
|
+ Now checks both 'error' and 'detail' fields
|
|
```
|
|
|
|
---
|
|
|
|
## 🔍 Monitoring Recommendations
|
|
|
|
1. **Set up log monitoring** for `[CRITICAL]` messages
|
|
2. **Verify MongoDB connection** on startup
|
|
3. **Verify PostgreSQL connection** on startup
|
|
4. **Add request logging** to track save operations
|
|
5. **Monitor totalChapters sync** for discrepancies
|
|
|
|
---
|
|
|
|
## 📞 Support
|
|
|
|
If issues persist after testing:
|
|
1. Follow debugging guide in `CHAPTER_SAVE_DEBUG.md`
|
|
2. Check Network tab for response codes
|
|
3. Verify MongoDB and PostgreSQL connectivity
|
|
4. Look for [CRITICAL] messages in server logs
|
|
5. Check browser console for JavaScript errors
|