08 — Quy tắc FE + lộ trình Figma ↔ Ma trận ↔ App
Mục tiêu: AI/ người dựng app đầy đủ theo đúng bố cục design (Home map + 5 tab), nối dây Figma/JPG → screen → navigation → API → cập nhật ma trận. Đọc kèm: 00-DOC-MAP · 01-MATRIX · design-index · FIGMA · 05-PHASE-BACKLOG
Figma file: WELIFE - Mobile App UI · fileKey=w0SRHX3cbiWLFHjzVC0pTE
Fallback: JPG/PDF + skill image-to-ui (khi MCP View-only).
Tokens: mobile/src/theme/tokens/ · DESIGN-TOKEN-AUDIT · WP-FIGMA-TOKENS-01 DONE · FIGMA_EXACT_SYNC: DEFERRED
FE queue: figma-fe-work-queue.json → DONE_QUEUE · doc 19
1. Sơ đồ “nối dây” (bố trí như quy hoạch)
flowchart TB
subgraph Design["Design nguồn"]
FIG[Figma frame / JPG / PDF]
SCR["SCR-DOMAIN-NAME"]
IDX[design-index.md]
end
subgraph Matrix["Ma trận 01"]
DOM["D-* Domain"]
WP["WP-*-nn"]
ROW["Hàng: Design · FE · BE · PAR · DRV · ADM"]
end
subgraph AppCON["Consumer mobile/ — bố cục app"]
ROOT[RootNavigator]
AUTH[AuthStack]
TABS[MainTabs — 5 tab]
STACKS[Feature stacks]
end
subgraph BE["api/"]
TAG[Swagger tag]
EP["/api/v1/..."]
end
FIG --> SCR
SCR --> IDX
SCR --> DOM
DOM --> WP
WP --> ROW
SCR --> STACKS
ROOT --> AUTH
ROOT --> TABS
TABS --> STACKS
STACKS -->|api.ts + zod| EP
EP --> TAG
TAG --> ROW
Một màn hình = một chuỗi ID bắt buộc:
| Mắt xích | Ví dụ |
|---|---|
| Design | Figma node-id=12-34 hoặc JPG 9a111… |
| SCR | SCR-SOC-REELS-FEED |
| Domain / WP | D-SOCIAL / WP-SOC-FE-01 |
| FE path | mobile/src/features/social/screens/ReelsFeedScreen.tsx |
| Route name | ReelsFeed trong tab Social |
| BE | GET /api/v1/social/reels/feed · tag social |
| Matrix | cập nhật cột Consumer FE + Status |
Không có SCR/Domain → không code UI.
2. Bố cục app Consumer (khớp mockup Home + Navigation)
Theo KE-HOACH §6.3 và JPG Navigation / Home map:
┌─────────────────────────────────────┐
│ Status / Header │
│ (search · location · AI entry) │
├─────────────────────────────────────┤
│ │
│ NỘI DUNG TAB HIỆN TẠI │
│ Map = lưới dịch vụ + bản đồ │
│ Reels / Social / Chat / Account │
│ │
├─────────────────────────────────────┤
│ 🗺 Map │ 🎬 Reels │ 📰 Social │ 💬 Contact │ 👤 Tài khoản │
└─────────────────────────────────────┘
2.0 Hiện / ẩn tab bar và nút Back (WP-FE-NAV-01)
Tab bar (5 icon Map · Reels · Social · Contact · Tài khoản)
| Khi nào | |
|---|---|
| Hiện | Đúng 5 màn gốc tab: HomeMap · ReelsHome · SocialHome · ChatHome · AccountHome |
| Ẩn | Mọi stack push từ tab (chi tiết, checkout, ví, chat thread, cuộc gọi, matching, chỉ đường, form…) |
| Không có tab | Auth (login/OTP) · chưa vào MainTabs |
Cách hiện: thanh dưới cao 54, icon 22, tab đang chọn colors.primary, tab khác colors.muted, ẩn khi bàn phím mở. Nested → display: 'none' (không để tab đè CTA / map immersive).
Nút Back (navbar trên — không dùng native stack header)
| Khi nào | |
|---|---|
| Ẩn | 5 màn gốc tab (HomeMap dùng brand welife + search, không có ←) |
| Hiện | navigation.canGoBack() trên màn lồng |
| Hành vi | navigation.goBack() — không navigate sang tab khác |
Cách hiện: icon arrow-left 24pt, vùng chạm 44×44, mép trái header, accessibilityLabel="Quay lại". Không bật headerShown của Native Stack (tránh hai nút back). Màn immersive (Call, RouteActive, matching) ẩn tab; đóng/back theo ngữ cảnh (kết thúc cuộc gọi), không pop nhầm về tab.
2.1 Năm tab gốc + feature folders
| Tab (UI) | Route group | Feature folder | Domain chính | Entry BE |
|---|---|---|---|---|
| Map | MapTab |
features/home, places, + deep-link verticals |
D-PLACE + verticals | /places/nearby, /merchants, /parking… |
| Reels | ReelsTab |
features/social (reels) |
D-SOCIAL | /social/reels/feed |
| Social | SocialTab |
features/social (posts/feed/friends) |
D-SOCIAL | /social/posts/feed |
| Contact | ChatTab |
features/chat |
D-CHAT | /chat/conversations, /chat/calls |
| Tài khoản | AccountTab |
features/profile, wallet, settings, addresses |
D-USER · D-WALLET · D-ADDR | /users/me, /wallet |
2.2 Lưới dịch vụ trên Map (ô icon → stack)
Mỗi ô trên Home map không là tab mới — là stack push từ MapTab:
| Ô UI (design) | Domain | Stack screen | Feature path |
|---|---|---|---|
| Đặt xe | D-RIDES | RideQuote → RideTracking |
features/rides |
| Ăn uống | D-FNB | MerchantList → Menu → Cart → Order |
features/fnb |
| Đỗ xe | D-PARK | ParkingNearby → Booking |
features/parking |
| Xăng | D-FUEL | FuelNearby |
features/fuel |
| ATM | D-ATM | AtmNearby |
features/atm |
| Khách sạn | D-HOTEL | HotelSearch |
features/hotels |
| Thuê nhà | D-RENTAL | RentalSearch |
features/rentals |
| Nhà thuốc | D-PHARM | PharmacyStores |
features/pharmacy |
| Y tế | D-MED | MedicalFacilities |
features/medical |
| Trường học | D-SCHOOL | SchoolsNearby |
features/schools |
| Siêu thị | D-GROCERY | share F&B types | features/grocery (sau) |
| Ví | D-WALLET | WalletHome |
features/wallet (cũng từ Account) |
2.3 Navigation tree (code)
RootNavigator
├── AuthStack (chưa login)
│ └── Login
└── AppStack (đã login)
├── MainTabs
│ ├── MapTab → MapStack
│ │ ├── HomeMap (lưới dịch vụ)
│ │ ├── PlacesNearby
│ │ └── [Vertical stacks qua navigate]
│ ├── ReelsTab → ReelsStack
│ ├── SocialTab → SocialStack
│ ├── ChatTab → ChatStack
│ └── AccountTab → AccountStack
└── Modal / shared
├── Assistant (D-ASSIST)
├── Notifications (D-NOTIF)
└── MediaPicker
Quy tắc nối dây navigation
- Tab chỉ đổi root section — không nhảy tab khi đang deep flow thanh toán (trừ explicit “Về trang chủ”).
- Vertical từ Map:
navigation.navigate('RideQuote', { … })trong cùngMapStackhoặc nested stack đăng ký ở root. - Deep-link:
welife://rides/:id,welife://orders/:id,welife://chat/:conversationId. - Partner / Driver = app riêng (
partner/,driver/) — không nhét tab Partner vào Consumer.
3. Bộ quy tắc (bắt buộc khi code FE)
R1 — Gate trước khi viết UI
[ ] Domain D-* + WP-*-nn (từ 05-PHASE-BACKLOG / 01-MATRIX)
[ ] Surface: CON | PAR | DRV
[ ] Design: Figma node-id **hoặc** Read JPG (design-index)
[ ] BE: endpoint đã có trên /docs (IMP hoặc stub rõ)
[ ] Path: mobile|partner|driver/src/features/<domain>/
R2 — Nối Figma / ảnh
| Bước | Việc |
|---|---|
| 1 | Link 1 frame (không cả canvas 0:1) |
| 2 | Gán SCR-* trong ma trận hoặc WP |
| 3 | Skill image-to-ui / Figma MCP get_design_context |
| 4 | Tokens mobile/src/theme/tokens.ts — cấm hardcode màu |
| 5 | Tiếng Việt đúng mockup |
R3 — Nối ma trận trong app
Mỗi feature folder có file mỏng TRACE.md (optional) hoặc comment đầu screen:
/** SCR-PARK-NEARBY · D-PARK · WP-PARK-FE-01 · GET /parking/lots/nearby */
Khi Done WP FE: cập nhật cột Consumer FE + Status trong 01-MATRIX-TRACEABILITY.md.
R4 — Kiến trúc code FE (ít lỗi AI)
features/<domain>/
screens/ # 1 file ≈ 1 SCR
components/ # chỉ domain
hooks/ # data + UI state
api.ts # gọi services/api.ts
types.ts # zod + types từ Swagger
- HTTP chỉ qua
services/api.ts - Parse response quan trọng bằng zod
- Shared primitives:
shared/ui/ - Một turn AI = một WP / một SCR (không dựng cả 5 tab cùng lúc)
R5 — Surfaces
| App | Không được |
|---|---|
mobile/ |
Import api/src, logic Nest |
partner/ |
Copy-paste Consumer screens — share tokens pattern, không share business folder |
driver/ |
Lẫn tab social consumer |
R6 — Trạng thái UI theo BE
| BE | FE |
|---|---|
| IMP | Wire thật + empty/error/loading |
STUB (status: stub) |
Placeholder “Sắp ra mắt” — không fake đơn/tiền |
| PARTIAL | Chỉ wire endpoint IMP; ẩn CTA còn stub |
4. Lộ trình phát triển từng phần (FE đầy đủ)
BE nhiều domain đã IMP — lộ trình dưới là thứ tự dựng UI + nối dây, không làm lại BE trừ khi gap.
Phase F0 — Khung app (1–2 tuần) ★ ưu tiên ngay
| WP | Việc | AC | Status |
|---|---|---|---|
| WP-FE-NAV-01 | RootNavigator + AuthStack + MainTabs (5 tab shell) | Tab bar đúng 5 mục; logout → Auth | IMP |
| WP-FE-HOME-01 | HomeMap lưới dịch vụ (Read JPG 0293… / Figma) |
Ô icon → navigate stub / AllServices | IMP |
| WP-FE-SHARED-01 | Screen, Empty, Error, ListRow, TextField |
Dùng lại ≥ 3 màn | IMP |
Ma trận: cập nhật D-PLACE / home path; navigation JPG b6ccd….
Phase F1 — Account + ví + địa chỉ (song song BE đã IMP)
| WP | Domain | Screens | Status |
|---|---|---|---|
| WP-FE-USER-01 | D-USER | Profile, edit me | IMP |
| WP-FE-ADDR-01 | D-ADDR | list/add/default | IMP |
| WP-FE-WALLET-01 | D-WALLET | balance, ledger, topup → payments | IMP |
| WP-FE-WALLET-02 | D-WALLET | pixel 6183… ví + support entry |
IMP |
| WP-FE-NOTIF-01 | D-NOTIF | list + badge | IMP |
Phase F2 — Vertical Map (discovery → book)
Thứ tự theo độ sẵn sàng BE:
| # | WP | Domain | Màn tối thiểu | Status |
|---|---|---|---|---|
| 1 | WP-FE-PLACE-01 | D-PLACE | Places nearby map/list | IMP |
| 2 | WP-FE-ATM-01 | D-ATM | ATM nearby | IMP |
| 2b | WP-FE-ATM-02 | D-ATM | ATM pixel 6c9b… |
IMP |
| 3 | WP-FE-FUEL-01 | D-FUEL | Stations + prices | IMP (geo Nearby) |
| 4 | WP-FE-PARK-01 | D-PARK | Lots + booking | IMP |
| 5 | WP-FE-FNB-01 | D-FNB | Merchants → menu → cart → order → pay | IMP |
| 6 | WP-FE-RIDE-01 | D-RIDES | Quote → create → tracking (REST) | IMP |
Mỗi WP: CON UI trước → nếu có Partner mockup → WP-FE-*-PAR trên partner/.
Phase F3 — Contact + Social (BE đã IMP)
| WP | Domain | Tab | Màn | Status |
|---|---|---|---|---|
| WP-FE-CHAT-01 | D-CHAT | Contact | Conversations, Messages, Calls history | IMP |
| WP-FE-CHAT-CONTACT-01 | D-CHAT | Liên lạc | Tin nhắn / Cuộc gọi / Danh bạ + call UI | IMP |
| WP-FE-SOC-01 | D-SOCIAL | Social | Posts feed, create post/NEWS | IMP |
| WP-FE-SOC-02 | D-SOCIAL | Reels | Create post · comments sheet API · pixel 9a111… |
IMP |
| WP-FE-SOC-03 | D-SOCIAL | — | Profile social, friends, follow | IMP |
Phase F4 — Partner + Driver polish
| WP | App | Focus | | -------------- | -------- | --------------------------------------- | ------- | | WP-FE-PAR-HOME | partner/ | Dashboard overview · F&B orders · staff | IMP | | WP-FE-DRV-TRIP | driver/ | Online → accept → pickup → complete | IMP |
Phase F5 — Vertical P2 — DONE 2026-07-27
| WP | Domain | Status |
|---|---|---|
| WP-HOTEL-01 / WP-FE-HOTEL-01 | D-HOTEL | IMP |
| WP-RENT-01 / WP-FE-RENT-01 | D-RENTAL | IMP |
| WP-PHARM-01 · WP-MED-01 · WP-SCH-01 (+ FE) | D-PHARM/MED/SCHOOL | IMP |
| WP-FE-GROCERY-01 | D-GROCERY | IMP |
| WP-FE-PAR-HOTEL / WP-FE-PAR-RENT | PAR | IMP |
Audit tiếp: 11-FE-SURFACE-AUDIT.md (Partner pharm/med/school UI).
Phase F6 — AI · Favorites · Realtime
| WP | Việc |
| ------------- | ------------------------------------- | ------- |
| WP-FE-AI-01 | Assistant sheet từ header Home | IMP |
| WP-FE-FAV-01 | Favorites list + toggle | IMP |
| WP-FE-WS-01 | Chat WebSocket + WebRTC signal + push | IMP |
| WP-RIDE-WS-01 | Rides GPS /rides | IMP |
5. Bảng link nhanh Domain → Tab → Folder → Design
| Domain | Tab / Entry | FE folder | Design gợi ý |
|---|---|---|---|
| D-PLACE | Map | features/places + home |
0293…, 61a37… |
| D-RIDES | Map ô Đặt xe | features/rides |
090d… |
| D-FNB | Map ô F&B | features/fnb |
44ba…, 0beb… |
| D-PARK | Map ô Đỗ xe | features/parking |
25af… |
| D-FUEL | Map ô Xăng | features/fuel |
2905… |
| D-ATM | Map ô ATM | features/atm |
6c9b… |
| D-SOCIAL | Reels + Social | features/social |
9a111… |
| D-CHAT | Contact | features/chat |
inbox trong PDF UI |
| D-WALLET | Account + Map | features/wallet |
6183… |
| D-USER | Account | features/profile |
1eabc… |
| D-NOTIF | Modal/bell | features/notifications |
— |
| D-ASSIST | Header AI | features/assistant |
bfb028… |
Partner JPG → partner/src/features/<domain>/ (không vào mobile/).
6. Checklist một màn (DoD FE)
-
SCR-*+ Figma node hoặc JPG đã Read - Screen trong đúng
features/<domain>/screens - Route đăng ký đúng tab/stack §2
- Gọi API qua
api.ts+ zod - Loading / empty / error
- Tokens, không magic color
- AC trong WP pass
- Cập nhật 01-MATRIX cột FE
7. Prompt Cursor mẫu (copy)
Làm FE theo docs/08-FE-ROADMAP-FIGMA-MATRIX.md
Domain: D-PARK · WP-FE-PARK-01 · Surface: CON
Design: Read JPG 25af… (hoặc Figma node-id=…)
SCR: SCR-PARK-NEARBY
Path: mobile/src/features/parking/
Nav: MapStack → ParkingNearby
BE: GET /api/v1/parking/lots/nearby (IMP)
AC: list + distance + tap chi tiết; tokens; zod; empty state
Không đụng tab khác / partner.
8. Liên kết tài liệu
| File | Vai trò |
|---|---|
| 01-MATRIX | Hàng domain Status |
| 05-PHASE-BACKLOG | WP BE/platform |
| design-index | JPG → domain |
| FIGMA | fileKey + quyền MCP |
| 03-AI-WORKFLOW | Gate WP |
| Rule Cursor | .cursor/rules/fe-figma-matrix.mdc |