Files
aplp.frontend.web/docs/ARCHITECTURE.md
T

127 lines
4.0 KiB
Markdown
Raw Normal View History

2026-08-22 08:24:38 +07:00
# APLP Frontend — Architecture
| | |
| --- | --- |
| **Module** | `aplp.frontend.react` |
| **Status** | Phase 0 hoàn tất |
## 1. Role
Client mỏng cho `aplp.web`: gọi API của backend `aplp.backend.spring`, tập trung vào UI/UX.
**Frontend không**:
- Tính toán master/progress/adaptive (mọi quyết định từ backend).
- Chứa business rules.
- Lưu trữ dữ liệu business ngoài cache phục vụ UI.
## 2. Tech Stack (confirmed tại Phase 0)
| Lĩnh vực | Lựa chọn |
| --- | --- |
| Framework | React 19+ |
| Language | TypeScript |
| Build | Vite 8 |
| Routing | React Router 7 |
| HTTP client | Axios (abstraction) |
| Server-state | TanStack Query (React Query) |
| Client-state | Zustand |
| Styling | Tailwind CSS 4 |
| Testing | Vitest + Testing Library |
## 3. Folder Structure
```text
aplp.frontend.react/
├── docs/
├── public/
└── src/
├── app/ # app entry, router, providers, layout
├── api/ # api client, endpoints
├── features/ # feature modules (vertical per phase)
│ ├── auth/
│ ├── learner/
│ ├── course/
│ ├── learning/
│ ├── assessment/
│ ├── adaptive/
│ ├── recommendation/
│ ├── assistance/
│ └── account/
├── shared/ # shared components, hooks, utils
└── types/ # shared types / DTO contracts
```
## 4. Feature Structure
Mỗi feature module nên tự đóng gói:
```text
src/features/<feature>/
├── api/ # calls backend endpoints
├── components/
├── hooks/
├── pages/ # route-level views
└── types.ts # feature-local types
```
## 5. Data Flow
```
UI (component)
↓ hooks (React Query / Zustand)
↓ api/ axios wrapper (auth header, refresh token, error mapping)
↓ Backend REST API
```
- **Read**: React Query quản lý fetch/cache/server-state.
- **Write**: mutation qua React Query; optimistic update nếu cần.
- **Runtime UI state**: local/Zustand.
- Token: access token **in-memory** (`src/api/tokenStorage.ts`), refresh token HttpOnly cookie do backend quản lý (đã confirm Phase 0).
## 6. Auth Flow
```
Login → lưu access token → attach Authorization header
Access token hết hạn → gọi /auth/refresh → retry request
Logout → xóa token → redirect
```
- Trung tâm qua api client, không scatter trong từng page.
- Route bảo vệ qua ProtectedRoute / auth guard.
- Chi tiết (JWT/session) theo backend (OQ-010 / ARC-002).
## 7. Error Handling
- Api client chuẩn hóa lỗi (`ApiError` từ backend) → user-friendly message.
- Error boundary cho crash cấp tree.
- Loading/empty/error states component tái sử dụng.
## 8. Styling & Design
- Theme tokens dùng chung (colors, spacing, typography).
- Component pattern thống nhất (candidate: component library quyết định Phase 0).
## 9. Deployment
- Build tĩnh (Vite output) serve qua CDN/nginx hoặc tách container.
- Env qua `VITE_*` variables; không commit secret vào build config.
## 10. Guardrails
- **Không tính toán domain phía client** (adaptive, mastery, progress).
- **Không bypass auth guard**.
- **Không gọi backend API trực tiếp ngoài `src/api`** (except khi có lý do rõ).
- Loại bỏ dead code, không dùng type `any` tùy tiện (TypeScript).
- Dùng semantic versions; document trong repo.
## 11. Open Questions
| ID | Question | Impact | Status |
| --- | --- | --- | --- |
| FE-001 | Vite hay framework khác? | Setup | **Resolved: Vite** |
| FE-002 | TypeScript bắt buộc? | Quality | **Resolved: có** |
| FE-003 | Component library? | UX | **Resolved: Tailwind CSS** |
| FE-004 | Client-state tool? | Data flow | **Resolved: Zustand** |
| FE-005 | SSR/SSG? | SEO | **Resolved: không** |
| FE-008 | Cách quản lý token (memory/localStorage/refresh)? | Security | **Resolved: access token in-memory + refresh token HttpOnly cookie (backend)** |
| FE-009 | Có cần end-to-end test (Playwright)? | Testing | Open |