- Transaction, Budget, and Saving Goal calendar dates are sent unchanged as `YYYY-MM-DD`, without parsing through the device timezone.
- Datetime-local inputs such as transfers and contributions represent Vietnamese wall time and are converted to offset-aware UTC ISO strings before sending.
- Timestamp display uses `Intl` with `Asia/Ho_Chi_Minh`; report requests never send the device offset.
- Vietnamese date display, including date and datetime-local controls, uses `DD/MM/YYYY` and
`DD/MM/YYYY HH:mm`; control values and API payloads remain in their existing ISO formats.
File này lưu trữ các quyết định thiết kế dài hạn và trạng thái hiện tại của dự án để đảm bảo tính nhất quán qua các phiên làm việc của Agent.
...
...
@@ -25,7 +27,7 @@ File này lưu trữ các quyết định thiết kế dài hạn và trạng th
-**Hiển thị Category**: Trang quản lý danh mục tại `/categories` dùng `GET /categories/tree` làm nguồn hiển thị chính, giữ cấu trúc cha/con và sắp xếp đệ quy ở client vì tree endpoint không nhận tham số sort. Danh mục hệ thống là chỉ đọc và tên hiển thị được ánh xạ theo locale mà không thay đổi payload API; danh mục cá nhân giữ nguyên tên người dùng nhập và hỗ trợ tạo/sửa, archive cả nhánh, restore. Parent picker chỉ cho chọn danh mục đang hoạt động, cùng loại giao dịch và loại trừ chính node cùng toàn bộ hậu duệ để tránh chu trình.
-**Quản lý Budget**: Trang `/budgets` và `/budgets/:id` dùng trực tiếp usage do Budget API tính (`spentAmount`, `remainingAmount`, `usagePercentage`, `timeStatus`, `status`) để giữ một nguồn sự thật chung cho UI, báo cáo, thông báo và AI. `DELETE /budgets/:id` là archive/xóa mềm nhằm bảo toàn lịch sử; ngân sách đã archive chỉ đọc đến khi restore. Mọi mutation giao dịch phải invalidate cache `budgets` vì số tiền đã chi phụ thuộc giao dịch EXPENSE.
-**Quản lý Saving Goal**: Trang `/saving-goals` và `/saving-goals/:id` dùng trực tiếp progress do Saving Goal API tính (`savedAmount`, `remainingAmount`, `progressPercentage`, `daysRemaining`, `isOverdue`) để giữ một nguồn sự thật chung cho UI, báo cáo và AI. `DELETE /saving-goals/:id` là archive/xóa mềm nhằm bảo toàn lịch sử; mục tiêu archive chỉ đọc đến khi restore. Contribution được quản lý riêng và mọi mutation contribution phải làm mới cả detail, list goal và lịch sử contribution.
-**Báo cáo tài chính**: Trang `/reports` dùng trực tiếp bốn Report API (`overview`, `cash-flow`, `spending-by-category`, `budget-performance`) qua TanStack Query và luôn giữ số liệu tách theo tiền tệ; không cộng gộp các loại tiền tệ khác nhau. Bộ lọc khoảng ngày tùy chọn gửi mốc kết thúc dạng exclusive sang Backend nhưng hiển thị ngày kết thúc dạng inclusive cho người dùng. Biểu đồ dùng SVG/CSS với semantic Clay tokens, không phụ thuộc thư viện chart, và context `period`/`currency`/`walletId` được chuẩn bị tại khối AI Financial Insights cho giai đoạn tích hợp tiếp theo.
-**Báo cáo tài chính**: Trang `/reports` dùng trực tiếp bốn Report API (`overview`, `cash-flow`, `spending-by-category`, `budget-performance`) qua TanStack Query và luôn giữ số liệu tách theo tiền tệ; không cộng gộp các loại tiền tệ khác nhau. Bộ lọc khoảng ngày tùy chọn gửi mốc kết thúc dạng exclusive sang Backend nhưng hiển thị ngày kết thúc dạng inclusive cho người dùng. Biểu đồ dùng SVG/CSS với semantic Clay tokens, không phụ thuộc thư viện chart. Thẻ Tổng quan ngân sách phải thể hiện số liệu tổng hợp (đã chi, còn lại, hạn mức và số lượng theo trạng thái), còn Hiệu suất ngân sách trình bày từng ngân sách; tổng quan chỉ ưu tiên summary `OVERALL` khi `budgetCount > 0`, nếu không fallback sang `CATEGORY`, và hiển thị `—` thay vì `0%` khi không có ngân sách hợp lệ. Khối AI tại báo cáo phải hiển thị trọn bản tóm tắt cùng tối đa ba điểm đáng chú ý, sau đó mới dẫn sang Trợ lý AI để phân tích sâu; khi điều hướng phải giữ `dateFrom`/`dateTo`/`currency` của kỳ báo cáo và nút quay lại phải trở về báo cáo.
-**Thông báo & nhắc nhở**: Trang `/notifications` là trung tâm chung cho inbox thông báo, lịch nhắc và tùy chọn cảnh báo. Unread count dùng query key riêng và được hiển thị bằng badge chuông toàn cục sau đăng nhập; danh sách/count/reminder polling mỗi 30 giây khi đang hoạt động, refetch khi focus và mọi mutation invalidate namespace liên quan. Reminder datetime luôn dùng Vietnamese wall time rồi chuyển sang UTC ISO bằng helper business-time. Với cảnh báo tự động do Backend hiện tạo bằng tiếng Anh, frontend nhận diện đúng mẫu theo `type`, dùng metadata để dựng title/message theo locale; nội dung người dùng nhập, legacy không khớp mẫu và AI tương lai được giữ nguyên. Notification `data` giữ kiểu mở `Record<string, unknown>` để tiếp nhận metadata cảnh báo/AI mà UI không phụ thuộc cấu trúc riêng. Điều hướng từ nút xem chi tiết gắn `fromNotifications` trong route state; các trang đích hệ thống dùng history back khi có marker này và giữ fallback back cố định cho luồng truy cập trực tiếp.
-**Tiêu đề trang**: Mỗi route cập nhật `document.title` theo mẫu `<Tên trang> | FinWise` thông qua component dùng chung trong router; route chưa nhận diện dùng tiêu đề mô tả sản phẩm mặc định.
-**Khoảng trống và nút điều khiển trên header hệ thống**: Zalo Mini App mặc định hiển thị `zaui-header` ở phía trên. Mọi page/layout phải chừa đủ khoảng cách phía trên (tính cả safe area khi cần) để nội dung và phần tử tương tác không bị header che khuất. Cụm điều khiển riêng của app (hiện gồm theme và ngôn ngữ) phải nằm trong `.finwise-header-controls`, đặt về bên trái vùng native `right-buttons` rộng 96px; đồng thời `zaui-header` phải dành đủ `padding-right` cho cả `right-buttons` và cụm này. Không đặt từng nút bằng offset `right` rời rạc vì có thể làm switch ngôn ngữ bị che khuất.
...
...
@@ -50,14 +52,14 @@ File này lưu trữ các quyết định thiết kế dài hạn và trạng th
- Đã cấu hình React 18, Vite 5, ZMP SDK/UI, Tailwind và bộ base components Claymorphism.
- Đã có các màn hình đăng nhập, đăng ký, quên mật khẩu, đặt lại mật khẩu, trang chủ, hồ sơ và Style Guide.
- Đã kết nối frontend với API xác thực, React Query và Zustand auth store.
- Dev server đã được sửa để nội dung app tại cổng 2999 trả 200 và render đúng thay vì màn hình đen do sai Vite root.
- Dev server dùng cổng 13579 cho nội dung app và cổng 13580 cho khung mô phỏng; `index.html` tiếp tục nằm ở root để tránh iframe trả 404 hoặc màn hình đen.
- Module quản lý ví đã có frontend tại `/wallets`, kết nối đầy đủ Wallet API qua TanStack Query, gồm danh sách/chi tiết, tạo/sửa, đặt mặc định, lưu trữ/khôi phục, tìm kiếm, sắp xếp và phân trang. `DELETE /wallets/:id` được thể hiện trong UI là lưu trữ mềm, đúng quy tắc Backend bảo toàn lịch sử.
- Module quản lý danh mục đã có frontend tại `/categories`, kết nối Category API qua TanStack Query, gồm cây cha/con, tạo/sửa, tìm kiếm, lọc loại/nguồn/trạng thái, sắp xếp, lưu trữ và khôi phục; toàn bộ nội dung có bản dịch Việt/Anh.
- Module quản lý giao dịch đã có frontend tại `/transactions`, kết nối Transaction API qua TanStack Query, gồm danh sách lịch sử theo ngày, xem/tạo/sửa/xóa giao dịch, lọc nâng cao, sắp xếp, phân trang và đính kèm hóa đơn.
- Module quản lý chuyển tiền đã có frontend tại `/transfers`, dùng contract `GET/POST /transfers` và `DELETE /transfers/:id` qua TanStack Query; gồm form chọn ví nguồn/đích, validation số dư và hai ví khác nhau, xác nhận trước khi chuyển/xóa, lịch sử có tìm kiếm/lọc/sắp xếp/phân trang và đầy đủ loading/error/empty state. Sau thao tác tạo hoặc xóa, frontend làm mới cache transfer, wallet và transaction để lấy lại số dư do Backend tính toán.
- Module quản lý ngân sách đã có frontend tại `/budgets` và `/budgets/:id`, kết nối Budget API qua TanStack Query, gồm danh sách/chi tiết, tạo/sửa, archive/restore, tìm kiếm, lọc loại/chu kỳ/danh mục/thời điểm, sắp xếp, phân trang và cảnh báo trực quan theo tỷ lệ sử dụng; đầy đủ validation, loading/error/empty/confirmation và bản dịch Việt/Anh.
- Module mục tiêu tiết kiệm đã có frontend tại `/saving-goals` và `/saving-goals/:id`, kết nối Saving Goal API qua TanStack Query, gồm danh sách/chi tiết, tạo/sửa, pause/resume, archive/restore, tìm kiếm, lọc trạng thái/thời hạn, sắp xếp, phân trang và quản lý đầy đủ tạo/sửa/xóa lịch sử đóng góp; có validation, loading/error/empty/confirmation và bản dịch Việt/Anh.
- Module báo cáo tài chính đã có frontend tại `/reports`, kết nối đầy đủ Report API qua TanStack Query, gồm lọc ngày/tuần/tháng/năm/khoảng tùy chọn, ví và tiền tệ; KPI tổng quan, dòng tiền, cơ cấu chi tiêu, hiệu suất ngân sách, mục tiêu tiết kiệm, loading/error/empty state, responsive và bản dịch Việt/Anh. AI Assistant chưa được tích hợp; trang báo cáo hiện có khối preview/context làm nền tảng cho AI Financial Insights.
- Module báo cáo tài chính đã có frontend tại `/reports`, kết nối đầy đủ Report API qua TanStack Query, gồm lọc ngày/tuần/tháng/năm/khoảng tùy chọn, ví và tiền tệ; KPI tổng quan, dòng tiền, cơ cấu chi tiêu, hiệu suất ngân sách, mục tiêu tiết kiệm, loading/error/empty state, responsive và bản dịch Việt/Anh. Khối tóm tắt AI đã tích hợp AI Insights, hiển thị nhận định cùng các điểm nổi bật và điều hướng sang phân tích chi tiết với phạm vi báo cáo được giữ nguyên.
- Module thông báo và nhắc nhở đã có frontend tại `/notifications`, kết nối Notification/Reminder API qua TanStack Query, gồm badge chưa đọc toàn cục, danh sách/lọc/phân trang, đánh dấu đọc một/tất cả, xóa, điều hướng tới nguồn, CRUD và bật/tắt lịch nhắc, tùy chọn loại cảnh báo/kênh nhận; có polling gần thời gian thực, loading/error/empty state, xác nhận thao tác và bản dịch Việt/Anh.
- Xác nhận khung mô phỏng `http://localhost:3000` và iframe app `http://localhost:2999` đều phản hồi. Cổng 2999 trả 404 thường có nghĩa `index.html` không còn ở root hoặc Vite `root` bị cấu hình sai.
- Xác nhận khung mô phỏng `http://localhost:13580` và iframe app `http://localhost:13579` đều phản hồi. Cổng 13579 trả 404 thường có nghĩa `index.html` không còn ở root hoặc Vite `root` bị cấu hình sai.
- Xác nhận build output nằm trong `www/` ở root repository; không chấp nhận output nhầm tại `src/www/`.
- Kiểm tra độ tương thích responsive trên các kích thước màn hình thiết bị di động (tối thiểu là tỷ lệ màn hình 375x812 tiêu chuẩn).