12 KiB
NHẬT KÝ THEO DÕI VÀ PHÒNG NGỪA LỖI TÁI CẤU TRÚC (BUG & LESSONS LEARNED LOG)
DỰ ÁN: COWORK LOCAL (COWORK-LOCAL BAMBOO)
Tài liệu này dùng để ghi nhận toàn bộ các lỗi, xung đột kiến trúc và sự cố phát sinh trong suốt quá trình refactoring của cả 3 team (Team Duy, Team Nam, Team Hoa).
Important
🛡️ NGUYÊN TẮC VÀNG VỀ QUẢN TRỊ CHẤT LƯỢNG (ZERO RECURRENCE):
- Ghi nhận ngay lập tức: Khi gặp bất kỳ lỗi nào (Syntax, Circular Import, Type Error, Test Failure, Thread Freeze, Data Corruption), kỹ sư/AI phải ghi ngay vào tài liệu này trước khi tiếp tục task.
- Phân tích nguyên nhân gốc rễ (Root Cause): Không chỉ sửa phần ngọn mà phải giải thích rõ bản chất vì sao lỗi xảy ra.
- Rút ra quy tắc phòng ngừa (Prevention Rule): Đặt ra nguyên tắc kỹ thuật để TUYỆT ĐỐI KHÔNG TÁI PHẠM ở các task tiếp theo.
- Checklist đầu vào: Trước khi bắt đầu bất kỳ task mới nào, kỹ sư/AI bắt buộc phải đọc lại toàn bộ file này.
📌 BẢNG TỔNG HỢP CÁC LỖI ĐÃ PHÁT HIỆN & KHẮC PHỤC
| Bug ID | Ngày Phát Hiện | Phân Hệ / File Bị Ảnh Hưởng | Loại Lỗi | Trạng Thái | Team Phụ Trách |
|---|---|---|---|---|---|
BUG-001 |
2026-08-20 | core/model_pricing.py ↔ core/usage_tracker.py |
Circular Dependency | 🟡 Đã có giải pháp (R09) | Team Duy & Team Nam |
BUG-002 |
2026-08-20 | core/agent_security.py ↔ core/agent_security_alert.py |
Circular Dependency | 🟡 Đã có giải pháp (R09) | Team Nam |
BUG-003 |
2026-08-20 | state.py::active_project_id & ui/workspace_tab.py |
Race Condition / Global State Leak | 🟡 Đã có giải pháp (R06) | Team Hoa |
BUG-004 |
2026-08-20 | core/task_scheduler.py ↔ PySide6.QtCore.QTimer |
Architecture Violation (Qt in Domain/App) | 🟡 Đã có giải pháp (R07) | Team Hoa |
BUG-005 |
2026-08-20 | ui/chat_panel.py#L638, ui/co4e_tab.py, ui/folder_tab.py |
Code Duplication (Copy Routing Logic) | 🟡 Đã có giải pháp (R03) | Team Duy |
BUG-006 |
2026-08-21 | scripts/check_imports.py |
UnicodeEncodeError (Windows CP932 console emoji) | 🟢 Đã khắc phục (R01) | Team Duy |
BUG-007 |
2026-08-21 | platform/ ➔ infrastructure/platform/ |
Standard Library Shadowing (import platform) |
🟢 Đã khắc phục (R01) | Team Duy |
🔍 CHI TIẾT TỪNG LỖI & QUY TẮC PHÒNG NGỪA
🔴 BUG-001: Circular Import giữa Module Định Giá (model_pricing.py) và Theo Dõi Token (usage_tracker.py)
- Phân hệ:
core/model_pricing.py&core/usage_tracker.py - Triệu chứng (Symptom): Lỗi
ImportError: cannot import name 'ModelPricing' from partially initialized modulekhi khởi động ứng dụng hoặc chạy test độc lập. - Nguyên nhân gốc rễ (Root Cause):
model_pricing.pyimportUsageTrackerđể cập nhật dữ liệu tiêu thụ.- Ngược lại,
usage_tracker.pyimportModelPricingđể tính toán chi phí theo từng model ID.
- Giải pháp khắc phục (Resolution):
- Tách Data Transfer Object (DTO)
ModelPricingsang tầng Domain thuần túydomain/models/model_pricing.py. - Cả
model_pricing.pyvàusage_tracker.pyđều import DTO từdomain/models/, chuyển quan hệ thành 1 chiều (Dependency Inversion).
- Tách Data Transfer Object (DTO)
- Quy tắc phòng ngừa (Prevention Rule - TUYỆT ĐỐI KHÔNG TÁI PHẠM):
Quy tắc: Không bao giờ để 2 service hoặc 2 module nghiệp vụ import lẫn nhau. Mọi cấu trúc dữ liệu dùng chung (DTO/Value Object/Event) phải được đặt tại tầng
domain/.
🔴 BUG-002: Circular Import giữa An Ninh Agent (agent_security.py) và Cảnh Báo (agent_security_alert.py)
- Phân hệ:
core/agent_security.py&core/agent_security_alert.py - Triệu chứng (Symptom): Lỗi khởi tạo vòng tròn khi runtime bắn ra alert sự kiện bảo mật.
- Nguyên nhân gốc rễ (Root Cause):
- Module security vừa kiểm tra policy vừa khởi tạo trực tiếp instance alert dialog, trong khi alert dialog lại import ngược lại rule security để hiển thị chi tiết mã lỗi.
- Giải pháp khắc phục (Resolution):
- Tách sự kiện cảnh báo thành Event DTO
SecurityAlertEventtạidomain/security/security_event.py. - Tầng Security chỉ phát ra Event (
emit_event), tầng Presentation/UI tự lắng nghe Event để render Dialog.
- Tách sự kiện cảnh báo thành Event DTO
- Quy tắc phòng ngừa (Prevention Rule - TUYỆT ĐỐI KHÔNG TÁI PHẠM):
Quy tắc: Logic an ninh và xử lý nghiệp vụ không bao giờ được gọi trực tiếp UI Dialog. Luôn giao tiếp thông qua cơ chế Event-Driven (
AgentEvent,SecurityEvent).
🔴 BUG-003: Xung Đột Race Condition do Sử Dụng Biến Toàn Cục active_project_id trong state.py
- Phân hệ:
state.py,ui/workspace_tab.py, Scheduled Task Runners - Triệu chứng (Symptom): Khi task scheduler chạy ngầm hoặc người dùng chuyển tab nhanh, file bị ghi nhầm vào thư mục dự án khác với dự án đang hiển thị trên màn hình.
- Nguyên nhân gốc rễ (Root Cause):
- Ứng dụng đọc và ghi trực tiếp vào biến toàn cục
AppContext.active_project_idtừ nhiều luồng khác nhau mà không có cơ chế snapshot ngữ cảnh.
- Ứng dụng đọc và ghi trực tiếp vào biến toàn cục
- Giải pháp khắc phục (Resolution):
- Xóa bỏ việc đọc biến toàn cục. Mỗi lần khởi chạy turn hoặc task, tạo một snapshot bất biến
WorkspaceSession(project_id, root_path, allowed_paths). - Luồng ngầm chỉ thao tác trên
WorkspaceSessionđược truyền vào từ lúc khởi tạo.
- Xóa bỏ việc đọc biến toàn cục. Mỗi lần khởi chạy turn hoặc task, tạo một snapshot bất biến
- Quy tắc phòng ngừa (Prevention Rule - TUYỆT ĐỐI KHÔNG TÁI PHẠM):
Quy tắc: Tuyệt đối không dùng biến toàn cục (Global State / Singletons có trạng thái thay đổi) để điều khiển luồng thực thi nền. Mọi ngữ cảnh phải được truyền tường minh qua DTO snapshot.
🔴 BUG-004: Vi Phạm Ranh Giới Kiến Trúc Khi Import PySide6.QtCore.QTimer trong Domain / Scheduling Engine
- Phân hệ:
core/task_scheduler.py#L20 - Triệu chứng (Symptom): Không thể viết Unit Test cho thuật toán tính toán lịch chạy (cron/interval) trên môi trường CI/CD (GitHub Actions / Linux Server headless) nếu thiếu driver màn hình X11/Wayland hoặc chưa cài
PySide6. - Nguyên nhân gốc rễ (Root Cause):
- Động cơ lập lịch bị gắn chặt cứng với
QTimercủa framework Qt thay vì tách riêng logic tính toán thời gian.
- Động cơ lập lịch bị gắn chặt cứng với
- Giải pháp khắc phục (Resolution):
- Tách thuật toán tính lịch sang
domain/tasks/schedule_calculator.py(Pure Python 100%). - Tạo
platform/qt/qt_scheduler_clock.pylàm adapter bọcQTimercho app chạy thật, vàtests/fakes/fake_clock.pycho unit test.
- Tách thuật toán tính lịch sang
- Quy tắc phòng ngừa (Prevention Rule - TUYỆT ĐỐI KHÔNG TÁI PHẠM):
Quy tắc: Tầng Domain và Application tuyệt đối không import thư viện GUI (
PySide6,PyQt). Luôn bọc các thành phần phụ thuộc framework bên ngoài qua Adapter Interface.
🔴 BUG-005: Nhân Bản Mã Nguồn (Code Duplication) Logic Routing Mô Hình AI tại Nhiều Màn Hình
- Phân hệ:
ui/chat_panel.py#L638,ui/co4e_tab.py,ui/folder_tab.py - Triệu chứng (Symptom): Khi cập nhật thêm model provider mới (như FPT Gateway hay Claude 3.7), phải sửa code thủ công ở 3 file UI khác nhau; phát sinh sai lệch quy tắc fallback giữa các màn hình.
- Nguyên nhân gốc rễ (Root Cause):
- Thiếu một tầng Application Service tập trung, dẫn đến việc lập trình viên copy-paste hàm chọn model từ
ChatPanelsang các tab khác.
- Thiếu một tầng Application Service tập trung, dẫn đến việc lập trình viên copy-paste hàm chọn model từ
- Giải pháp khắc phục (Resolution):
- Xây dựng
application/model_routing/routing_application_service.pyduy nhất, cung cấp APIroute_request(request) -> ModelRouteDecision. - Mọi màn hình UI chỉ gọi service này, không tự viết lại logic kiểm tra key hay fallback.
- Xây dựng
- Quy tắc phòng ngừa (Prevention Rule - TUYỆT ĐỐI KHÔNG TÁI PHẠM):
Quy tắc: Nghiệp vụ dùng chung giữa các màn hình phải được đưa vào
application/services. Không bao giờ viết logic nghiệp vụ trực tiếp trong các file Widget UI.
🟢 BUG-006: UnicodeEncodeError khi in Emojis trên Console Windows (CP932/CP1252)
- Phân hệ / File:
scripts/check_imports.py - Triệu chứng (Symptom):
Traceback (most recent call last): File "scripts/check_imports.py", line 127, in main print(f"\U0001f6e1\ufe0f Running Clean Architecture Import Guard...") UnicodeEncodeError: 'cp932' codec can't encode character '\U0001f6e1' in position 0: illegal multibyte sequence - Nguyên nhân gốc rễ (Root Cause):
- Trên hệ điều hành Windows sử dụng locale tiếng Nhật (mã trang CP932) hoặc tiếng Anh (CP1252),
sys.stdoutmặc định không hỗ trợ các ký tự Unicode/Emoji ngoài bảng mã, dẫn đến crash khi in log dòng lệnh.
- Trên hệ điều hành Windows sử dụng locale tiếng Nhật (mã trang CP932) hoặc tiếng Anh (CP1252),
- Giải pháp khắc phục (Resolution):
- Tự động bọc lại
sys.stdoutvàsys.stderrbằngio.TextIOWrappervớiencoding="utf-8"vàerrors="replace". - Thay thế các emoji phức tạp bằng các tag văn bản ASCII chuẩn hóa như
[Clean Arch Guard],[PASS],[FAIL].
- Tự động bọc lại
- Quy tắc phòng ngừa (Prevention Rule - TUYỆT ĐỐI KHÔNG TÁI PHẠM):
Quy tắc: Mọi script CLI (
scripts/*.py) phải có cơ chế cấu hìnhutf-8stream wrapper và ưu tiên sử dụng text tags ([INFO],[WARN],[ERROR]) thay vì emoji Unicode trực tiếp để đảm bảo chạy mượt mà trên mọi môi trường Windows đa ngôn ngữ.
🟢 BUG-007: Xung Đột Tên Thư Mục Trùng Với Standard Library (platform/ Shadowing import platform)
- Phân hệ / File:
platform/➔ Chuyển thànhinfrastructure/platform/ - Triệu chứng (Symptom):
INTERNALERROR> File "_pytest/terminal.py", line 853: verinfo = platform.python_version() INTERNALERROR> AttributeError: module 'platform' has no attribute 'python_version' - Nguyên nhân gốc rễ (Root Cause):
- Khi tạo một package ở thư mục gốc có tên trùng với module thư viện chuẩn của Python (
platform,email,test,asyncio,logging), Python trênsys.pathsẽ ưu tiên import thư mục local thay vì thư viện chuẩn của Python runtime, dẫn đến crash toàn bộ pytest runner và các thư viện bên thứ ba.
- Khi tạo một package ở thư mục gốc có tên trùng với module thư viện chuẩn của Python (
- Giải pháp khắc phục (Resolution):
- Xóa bỏ package
platform/ở root. - Đưa adapter Qt Scheduler Clock vào đúng vị trí hạ tầng:
infrastructure/platform/qt/.
- Xóa bỏ package
- Quy tắc phòng ngừa (Prevention Rule - TUYỆT ĐỐI KHÔNG TÁI PHẠM):
Quy tắc: Tuyệt đối không đặt tên package/thư mục ở root trùng với tên các module built-in của Python (
platform,logging,types,time,io,os,sys). Mọi platform adapter phải nằm tronginfrastructure/platform/hoặcplatform_adapters/.
📝 MẪU GHI NHẬN BUG MỚI (BUG REPORT TEMPLATE)
Khi gặp bất kỳ bug mới nào trong quá trình làm việc, hãy sao chép khối mẫu sau và điền vào cuối tài liệu:
### 🔴 `BUG-XXX`: [Tóm tắt ngắn gọn tên lỗi]
* **Phân hệ / File**: `[Đường dẫn file bị lỗi]`
* **Triệu chứng (Symptom)**: `[Mô tả hiện tượng lỗi, paste thông báo traceback hoặc kết quả test fail]`
* **Nguyên nhân gốc rễ (Root Cause)**: `[Giải thích tại sao lỗi lại xảy ra]`
* **Giải pháp khắc phục (Resolution)**: `[Mô tả cách sửa, file DTO/Service tạo mới hoặc cách refactor]`
* **Quy tắc phòng ngừa (Prevention Rule - TUYỆT ĐỐI KHÔNG TÁI PHẠM)**:
> **Quy tắc**: `[Nguyên tắc kỹ thuật cụ thể để không bao giờ tái phạm lỗi này]`