---
doc_id: "DOC-OPS-003"
title: "Hệ Thống Góp Ý & Báo Lỗi Biệt Lập (Isolated Feedback Store)"
category: "operations"
diataxis_type: "explanation"
status: "canonical"
version: "2026.1"
owner_role: "lead_documentation_architect"
last_updated: "2026-09-29"
tags: ["feedback-system", "bug-report", "sqlite-isolated", "telemetry"]
related_code:
  - "server/feedback/feedback_service.py"
  - "server/feedback/feedback_api.py"
related_docs:
  - "docs/standards/ENGINEERING_STANDARDS_2026.md"
summary: "Kiến trúc ghi nhận góp ý và telemetry lỗi của người chơi trên CSDL SQLite biệt lập tách rời hoàn toàn khỏi vòng lặp game 30Hz."
---

# HỆ THỐNG GÓP Ý & BÁO LỖI BIỆT LẬP (ISOLATED PLAYER FEEDBACK & SUGGESTIONS SYSTEM)

> **Tài liệu đặc tả kiến trúc Diátaxis 2026**  
> **Dự án**: FreeExile (MMORPG 2.5D Cổ Võ Hắc Ám)  
> **Mục tiêu**: Thiết kế kênh tiếp nhận đóng góp ý kiến, báo lỗi kỹ thuật và đề xuất tính năng trực tiếp từ bảng Cài đặt (Settings), lưu trữ vào cơ sở dữ liệu riêng biệt không ảnh hưởng nhịp tick 30Hz hay sổ cái tài chính.

---

## 1. TRIẾT LÝ THIẾT KẾ & TÍNH BIỆT LẬP DỮ LIỆU (ISOLATION PRINCIPLES)

Trong các MMORPG quy mô hàng triệu người chơi (1M+ CCU), lưu trữ dữ liệu góp ý và báo lỗi vào chung cơ sở dữ liệu trò chơi (Game State DB) hoặc sổ cái giao dịch (Financial Ledger) là một **Anti-Pattern nghiêm trọng**:
1. **Tránh tranh chấp tài nguyên (Zero Lock Contention)**: Thao tác ghi văn bản dài của người chơi (vài trăm ký tự) hoặc truy vấn báo cáo của Game Master (GM) không bao giờ được phép gây nghẽn (block) bảng vật phẩm, số dư Huyết Thạch hay nhịp tick mô phỏng vật lý 30Hz của [ZoneServer](file:///c:/Projects/FreeExile/server_cpp/include/world/ZoneServer.hpp).
2. **Cơ sở dữ liệu biệt lập (Isolated Feedback Database)**: Toàn bộ dữ liệu góp ý được lưu trữ độc lập tại [data/feedback_store.db](file:///c:/Projects/FreeExile/data/feedback_store.db) thông qua [FeedbackService](file:///c:/Projects/FreeExile/server/feedback/feedback_service.py).
3. **Thu thập dữ liệu chẩn đoán tự động (Zero-Friction Telemetry)**: Người chơi không cần gõ thủ công model máy, FPS hay tọa độ lỗi. Client tự động bắt ảnh chụp chẩn đoán phần cứng và tọa độ nhân vật ngay thời điểm bấm gửi.

---

## 2. KIẾN TRÚC LUỒNG DỮ LIỆU (DATA FLOW ARCHITECTURE)

```mermaid
sequenceDiagram
    autonumber
    actor Player as Người Chơi (Client)
    participant UI as Giao Diện Cài Đặt (Settings Modal)
    participant FM as FeedbackManager (Client TS)
    participant API as WebApp / Gateway API (/api/feedback)
    participant Service as FeedbackService (Python Engine)
    participant DB as Isolated Feedback DB (feedback_store.db)
    actor Admin as Ban Quản Trị / Lead Designer

    Player->>UI: Bấm nút Cài Đặt (⚙️) trên thanh điều hướng
    UI-->>Player: Mở Modal Thiết Lập Hệ Thống
    Player->>UI: Bấm nút "Mở Kênh Góp Ý & Báo Lỗi" (📢)
    UI->>FM: Khởi tạo Form & Thu thập Telemetry
    FM-->>UI: Hiển thị FPS (120Hz), Ping (18ms), Map, Tọa độ (wx, wy)
    Player->>UI: Chọn Phân loại, Nhập Tiêu đề & Nội dung -> Bấm "Gửi"
    UI->>FM: submitFeedback(submission)
    FM->>API: HTTP POST /api/feedback (JSON Payload)
    API->>Service: submit_feedback(player_id, category, title, content, diagnostics)
    Service->>DB: INSERT INTO player_feedback (Trạng thái: NEW)
    DB-->>Service: Ghi nhận thành công
    Service-->>API: (success=True, feedback_id="fb_...", ack_msg)
    API-->>FM: 200 OK Response
    FM->>UI: Lưu vào Local History & Hiển thị Thông Báo Thành Công
    UI-->>Player: Chuyển sang Tab "Lịch Sử Góp Ý" (Badge: Mới Tiếp Nhận)

    Note over Admin,DB: Định kỳ thẩm định & phản hồi
    Admin->>Service: update_feedback_status(feedback_id, "PLANNED", admin_note)
    Service->>DB: UPDATE player_feedback SET status='PLANNED', admin_response=...
```

---

## 3. ĐẶC TẢ SCHEMA PROTOBUF ([proto/feedback.proto](file:///c:/Projects/FreeExile/proto/feedback.proto))

Hệ thống được định nghĩa chuẩn hóa theo giao thức Protocol Buffers v3:

```protobuf
syntax = "proto3";
package freeexile.feedback;

enum FeedbackCategory {
    CATEGORY_UNSPECIFIED = 0;
    CATEGORY_BUG_REPORT = 1;          // Báo lỗi kỹ thuật / Lỗi đồ họa / Mất kết nối
    CATEGORY_GAMEPLAY_SUGGESTION = 2; // Đề xuất tính năng võ học / Phụ bản / Tiên phủ
    CATEGORY_BALANCE_ADJUSTMENT = 3;  // Cân bằng Ngũ Hành / Sát thương chiêu thức
    CATEGORY_LOCALIZATION = 4;        // Góp ý dịch thuật / Thuật ngữ cổ võ
    CATEGORY_OTHER = 5;               // Ý kiến đóng góp khác
}

enum FeedbackStatus {
    STATUS_UNSPECIFIED = 0;
    STATUS_NEW = 1;                   // Mới tiếp nhận, chờ xem xét
    STATUS_UNDER_REVIEW = 2;         // Đang được đội ngũ phát triển đánh giá
    STATUS_PLANNED = 3;              // Đã đưa vào kế hoạch phát triển (Roadmap)
    STATUS_RESOLVED = 4;             // Đã khắc phục / Đã cập nhật vào game
    STATUS_REJECTED = 5;             // Không khả thi hoặc không phù hợp định hướng
}

message SystemDiagnostics {
    string client_platform = 1;      // iOS, Android, WebApp, PC
    string os_version = 2;            // iOS 18.2, Windows 11, etc.
    string device_model = 3;          // iPhone 16 Pro Max, iPad Pro M4
    float current_fps = 4;            // 120.0 FPS
    int32 current_ping_ms = 5;        // 18 ms
    string current_zone_name = 6;     // Cổ Trấn Huyết Lân
    float player_x = 7;               // Tọa độ X thế giới
    float player_y = 8;               // Tọa độ Y thế giới
    float player_z = 9;
    string game_build_version = 10;   // v2.0-Authoritative
}
```

---

## 4. VÒNG ĐỜI TRẠNG THÁI GÓP Ý (FEEDBACK LIFECYCLE STATE MACHINE)

```mermaid
stateDiagram-v2
    [*] --> NEW: Người chơi gửi góp ý
    NEW --> UNDER_REVIEW: Đội ngũ Dev / QA mở xem xét
    UNDER_REVIEW --> PLANNED: Đề xuất hợp lý, đưa vào Roadmap
    UNDER_REVIEW --> RESOLVED: Lỗi đã sửa / Đã có trong bản cập nhật mới
    UNDER_REVIEW --> REJECTED: Ý kiến phá vỡ cân bằng hoặc sai định hướng
    PLANNED --> RESOLVED: Triển khai hoàn tất và Release
    RESOLVED --> [*]
    REJECTED --> [*]
```

### Ý nghĩa các trạng thái:
- **`NEW` (Mới Tiếp Nhận)**: Góp ý vừa được lưu vào cơ sở dữ liệu độc lập, tự động gán ID duy nhất (`fb_[timestamp]_[uuid]`).
- **`UNDER_REVIEW` (Đang Đánh Giá)**: Trưởng phòng ban liên quan (`lead_systems_designer` với gameplay, `ios_client_engineer` với client crash) đang phân tích và tái hiện.
- **`PLANNED` (Đã Lên Kế Hoạch)**: Ý kiến xuất sắc được phê duyệt đưa vào backlog tính năng hoặc bản Big Update kế tiếp.
- **`RESOLVED` (Đã Hoàn Thành)**: Tính năng đã lên sóng hoặc lỗi kỹ thuật đã được vá triệt để.
- **`REJECTED` (Chưa Thích Hợp)**: Ý kiến đi ngược lại triết lý trò chơi (ví dụ: đòi bán đồ Pay-to-Win phá vỡ kinh tế bản vị Huyết Thạch) kèm lời giải thích tôn trọng từ BQT.

---

## 5. THIẾT KẾ CƠ SỞ DỮ LIỆU ĐỘC LẬP ([server/feedback/feedback_service.py](file:///c:/Projects/FreeExile/server/feedback/feedback_service.py))

Bảng `player_feedback` trong SQLite biệt lập được đánh chỉ mục để truy vấn tức thì:

```sql
CREATE TABLE IF NOT EXISTS player_feedback (
    feedback_id TEXT PRIMARY KEY,
    player_id INTEGER NOT NULL,
    player_name TEXT NOT NULL,
    category TEXT NOT NULL,
    title TEXT NOT NULL,
    content TEXT NOT NULL,
    diagnostics_json TEXT NOT NULL,
    status TEXT NOT NULL DEFAULT 'NEW',
    admin_response TEXT DEFAULT '',
    created_at_ms INTEGER NOT NULL,
    updated_at_ms INTEGER NOT NULL
);

CREATE INDEX IF NOT EXISTS idx_feedback_status ON player_feedback(status);
CREATE INDEX IF NOT EXISTS idx_feedback_category ON player_feedback(category);
CREATE INDEX IF NOT EXISTS idx_feedback_player ON player_feedback(player_id);
```

### Tối ưu hóa Windows I/O:
Áp dụng context manager với generator bảo đảm đóng file handle ngay lập tức:
```python
@contextmanager
def _get_connection(self):
    conn = sqlite3.connect(self.db_path)
    conn.row_factory = sqlite3.Row
    try:
        yield conn
    finally:
        conn.close()
```

---

## 6. GIAO DIỆN CLIENT ([client/webapp/index.html](file:///c:/Projects/FreeExile/client/webapp/index.html))

### 6.1. Vị Trí Nút Cài Đặt (Settings Entrypoint)
Nút Cài đặt `⚙️` (`#btn-open-settings`) được đặt cố định trên thanh điều hướng góc phải màn hình, đồng bộ với phong cách Dark Martial Astral của game.

### 6.2. Banner Góp Ý Trong Bảng Cài Đặt
Bên trong modal Cài Đặt (`#modal-settings`), bên cạnh các mục tùy chỉnh Đồ họa 120Hz ProMotion, Âm thanh BGM/SFX và Cần ảo, là banner nổi bật với hiệu ứng viền vàng hoàng kim và nút:
`[ ✍️ Mở Kênh Góp Ý & Báo Lỗi ]` (`#btn-open-feedback-form`).

### 6.3. Modal Kênh Góp Ý (`#modal-feedback`)
- **Tab 1: Gửi Góp Ý Mới**:
  - Dropdown phân loại 5 danh mục.
  - Trường nhập Tiêu đề và Nội dung (kiểm tra tối thiểu 10 ký tự).
  - Khung Telemetry tự động cập nhật tọa độ nhân vật `(player.wx, player.wy)`, map hiện tại, FPS và ping.
  - Nút gửi thực thi gửi bất đồng bộ về server.
- **Tab 2: Lịch Sử Góp Ý & Phản Hồi BQT**:
  - Danh sách thẻ góp ý của người chơi kèm huy hiệu trạng thái màu sắc (`NEW`, `UNDER_REVIEW`, `PLANNED`, `RESOLVED`, `REJECTED`).
  - Khung phản hồi chính thức từ Ban Quản Trị có biểu tượng khiên hộ vệ và viền hoàng kim.

---

## 7. KIỂM THỬ TỰ HÀNH & KẾT QUẢ XÁC MINH (VERIFICATION)

Toàn bộ 114 bài kiểm thử trong hệ thống FreeExile đã vượt qua 100%:
- [test_feedback_service.py](file:///c:/Projects/FreeExile/tests/unit/test_feedback_service.py): Kiểm thử logic lưu trữ, xác thực đầu vào, đổi trạng thái và kết xuất số liệu thống kê.
- [test_feedback_api.py](file:///c:/Projects/FreeExile/tests/unit/test_feedback_api.py): Kiểm thử endpoint `POST /api/feedback`, `GET /api/feedback`, mã lỗi HTTP 400 khi thiếu thông tin.
- [test_mobile_webapp_config.py](file:///c:/Projects/FreeExile/tests/unit/test_mobile_webapp_config.py): Kiểm tra cấu trúc DOM HTML, các trường nhập liệu và 5 danh mục đóng góp.
