CI / test (push) Canceled after 0s
fix các bug theo yêu cầu https://fptsoftware362-my.sharepoint.com/❌/g/personal/nampdt_fpt_com/IQAHBJ4A9xqDTLgvt2bhukJEAdRB5LRz2hbJpTivvIiBSYM?wdExp=TEAMS-TREATMENT&web=1&isSPOFile=1&ovuser=f01e930a-b52e-42b1-b70f-a8882b5d043b%2CAnhTNM1%40fpt.com&clickparams=eyJBcHBOYW1lIjoiVGVhbXMtRGVza3RvcCIsIkFwcFZlcnNpb24iOiI0OS8yNjA4MTMxOTMxNyIsIkhhc0ZlZGVyYXRlZFVzZXIiOmZhbHNlfQ%3D%3D --------- Co-authored-by: Duy Le Huu <duylh19@fpt.com> Reviewed-on: #10 Co-authored-by: Anh Tran Nguyen Minh <anhtnm1@fpt.com>
102 lines
5.0 KiB
Markdown
102 lines
5.0 KiB
Markdown
# Project Map — Cowork Local (dành cho agent sửa bug UI/UX)
|
|
|
|
Nguồn sự thật: `README.md`, `docs/architecture/ADR-001-layered-architecture.md`,
|
|
`docs/governance/contributor-recipes.md`. File này chỉ tóm tắt phần **một người sửa bug
|
|
UI cần biết**.
|
|
|
|
---
|
|
|
|
## 1. Bốn tầng
|
|
|
|
```text
|
|
presentation/ PySide6 UI — Shell, NavRail, Chat, Scheduling, Settings, Dashboard
|
|
↓
|
|
application/ Orchestration thuần Python — Conversations, Scheduling, Workspaces, Monitoring, Routing
|
|
↓
|
|
domain/ Entity, ExecutionRequest bất biến, AgentEvent, Descriptor (thuần Python)
|
|
↑
|
|
infrastructure/ Adapter — LLM provider, persistence atomic JSON, Keyring SecretStore, MCP
|
|
```
|
|
|
|
- `domain/` và `application/` **không được** import PySide6/PyQt/`ui`/`app`
|
|
(`scripts/check_imports.py::FORBIDDEN_MODULE_PREFIXES`).
|
|
- Widget chỉ gọi xuống service của `application/`, không chạm SQLite/JSON/LLM trực tiếp.
|
|
- Mọi module production `<= 400 LOC`.
|
|
|
|
## 2. ⚠️ Hai thư mục UI cùng tồn tại — điểm dễ sửa nhầm file nhất
|
|
|
|
| Thư mục | Vai trò hiện tại | Sửa bug ở đây khi |
|
|
|---|---|---|
|
|
| `presentation/` | Kết quả refactor R08 — các màn đã tách module | Bug thuộc Chat, Co4E, Dashboard, Folder, Graph, Scheduling, Settings, Shell |
|
|
| `ui/` | **Vẫn đang chạy**, không phải code chết | Bug thuộc Monitoring, Workspace, các dialog, icon, widget dùng chung |
|
|
|
|
`presentation/` vẫn import ngược sang `ui/` cho phần dùng chung, ví dụ:
|
|
|
|
```text
|
|
presentation/shell/page_registry.py:14 from ...ui.monitoring_tab import MonitoringTab
|
|
presentation/shell/main_window.py:38 from ...ui.workspace_tab import WorkspaceTab
|
|
presentation/dashboard/dashboard_tab.py:24 from cowork_local.ui.icons import icon
|
|
```
|
|
|
|
**Luật:** trước khi sửa, `grep` tên class/hàm trên **cả hai** thư mục. Sửa bản không được
|
|
import vào runtime là lỗi "đã fix nhưng user vẫn thấy lỗi" phổ biến nhất của repo này.
|
|
|
|
```bash
|
|
grep -rn "class DashboardTab" ui/ presentation/
|
|
```
|
|
|
|
## 3. Điểm vào & trạng thái
|
|
|
|
| File | Vai trò |
|
|
|---|---|
|
|
| `app.py`, `__main__.py` | Bootstrap `QApplication`, dựng `MainWindow` |
|
|
| `presentation/shell/main_window.py` | Cửa sổ chính, `_nav_defs`, top bar, toast, help agent |
|
|
| `presentation/shell/page_registry.py` | Chuyển trang; Dashboard/Schedule/Monitoring **dựng lười** |
|
|
| `presentation/shell/nav_rail.py` | Nav rail trái, thu gọn/mở rộng, cây project & recents |
|
|
| `presentation/shell/top_bar.py` | Thanh trên: theme switch, language switch |
|
|
| `presentation/shell/toast.py` | Popup "task xong" góc trên trái |
|
|
| `state.py` | `AppContext` — cầu nối UI ↔ service |
|
|
| `config.py` | Đọc/ghi cấu hình người dùng (theme, ngôn ngữ, provider...) |
|
|
| `paths.py` | Vị trí dữ liệu runtime (`%USERPROFILE%\.cowork_local`) |
|
|
| `theme/` | Toàn bộ màu sắc & stylesheet (xem `theme_tokens.md`) |
|
|
| `i18n/` | Toàn bộ chuỗi hiển thị (xem `i18n_rules.md`) |
|
|
|
|
### Hệ quả của "dựng lười" khi debug
|
|
|
|
Dashboard, Schedule và Monitoring **chưa tồn tại** cho tới lần đầu người dùng bấm vào.
|
|
Nghĩa là:
|
|
|
|
- Bug "lần đầu mở màn X bị nhấp nháy / sai theme / sai ngôn ngữ" gần như luôn nằm ở
|
|
`_ensure_page` / `_goto` chứ không nằm trong widget của màn đó.
|
|
- Widget dựng lười **bỏ lỡ** các sự kiện đã phát trước đó (đổi theme, đổi ngôn ngữ).
|
|
Xem `qt_pitfalls.md` P07.
|
|
|
|
## 4. Bảng đối chiếu tính năng → file
|
|
|
|
| Khu vực | File chính |
|
|
|---|---|
|
|
| Chat / composer / bubble | `presentation/chat/` (`chat_panel.py`, `composer_widget.py`, `chat_bubble_style.py`) |
|
|
| Co4E canvas & node | `presentation/co4e/` (`co4e_canvas_widget.py`, `node_property_panel.py`, `canvas_geometry.py`) |
|
|
| Dashboard & biểu đồ | `presentation/dashboard/` + `ui/spline_chart.py`, `ui/widgets.py` |
|
|
| Folder / preview tài liệu | `presentation/folder/` (`folder_tab.py`, `code_editor.py`, `office_document_renderer.py`) |
|
|
| GraphRAG | `presentation/graph/` |
|
|
| Lịch / Kanban | `presentation/scheduling/` |
|
|
| Settings | `presentation/settings/` + `ui/settings_dialog.py` |
|
|
| Monitoring (8 sub-view) | `ui/monitoring_tab.py` + `presentation/monitoring/` |
|
|
| Workspace + sub-tab | `ui/workspace_tab.py`, `ui/cowork_tab.py`, `ui/co4e_tab.py` |
|
|
| Dialog (login, permission, skill, task...) | `ui/*_dialog.py` |
|
|
| Icon | `ui/icons.py` |
|
|
| Widget dùng chung (StatCard, BudgetCard...) | `ui/widgets.py` |
|
|
|
|
## 5. Test
|
|
|
|
| Đường dẫn | Nội dung |
|
|
|---|---|
|
|
| `tests/ui/` | Test widget, có `conftest.py` riêng |
|
|
| `tests/integration/` | Test ghép nhiều thành phần |
|
|
| `tests/e2e/test_smoke.py` | Smoke test bản release |
|
|
| `tests/characterization/` | Chốt hành vi hiện tại trước khi refactor |
|
|
|
|
Chạy headless: `QT_QPA_PLATFORM=offscreen pytest tests/ui -q`.
|
|
64/108 module test dựng widget thật, nên môi trường phải có PySide6.
|