Các quy ước mang tính định hướng rõ ràng để xây dựng ứng dụng Next.js thực tế với App Router.
# Next.js App Router taste - Mặc định sử dụng Server Components và chỉ thêm "use client" ở các component nhánh cuối (leaf components) cần tính tương tác. Độ tin cậy: 0.95 - Truy xuất dữ liệu trực tiếp trong Server Components thay vì dùng các API route cho việc đọc dữ liệu nội bộ. Độ tin cậy: 0.90 - Sử dụng Server Actions cho các thao tác biến đổi dữ liệu (mutations) và xác thực đầu vào bằng zod. Độ tin cậy: 0.85 - Đặt các component, bộ tải dữ liệu (loaders) và tệp kiểm thử cùng chỗ theo từng tính năng thay vì phân chia theo loại tệp. Độ tin cậy: 0.80 - Sử dụng Tailwind CSS với một tập hợp nhỏ các design token được khai báo trong biến CSS. Độ tin cậy: 0.85 - Sử dụng next/image và next/font cho toàn bộ hình ảnh và phông chữ. Độ tin cậy: 0.90 - Thêm loading.tsx và error.tsx vào mọi phân đoạn đường dẫn (route segment) có truy xuất dữ liệu. Độ tin cậy: 0.85 - Sử dụng Prisma hoặc Drizzle với các truy vấn được định kiểu (typed queries) và giữ trình khách (client) trong một tệp lib/db.ts duy nhất. Độ tin cậy: 0.80 - Lưu bộ nhớ đệm (cache) bằng thẻ fetch (fetch tags) và revalidateTag thay vì tự tạo bộ nhớ đệm thủ công trong bộ nhớ (in-memory). Độ tin cậy: 0.75 - Luôn xác thực các biến môi trường ngay khi khởi động bằng một mô-đun env được định kiểu. Độ tin cậy: 0.85 - Tạo siêu dữ liệu bằng hàm generateMetadata và luôn thiết lập hình ảnh Open Graph. Độ tin cậy: 0.85 - Tránh sử dụng các tệp gom (barrel files) trong những ứng dụng lớn vì chúng làm chậm thời gian biên dịch (build). Độ tin cậy: 0.70 - Chỉ sử dụng middleware cho việc chuyển hướng xác thực (auth redirects) và định tuyến ngôn ngữ/khu vực (locale routing), tuyệt đối không đặt logic nặng ở đây. Độ tin cậy: 0.80 - Kiểm thử các luồng quan trọng bằng Playwright và kiểm thử các component bằng vitest. Độ tin cậy: 0.80 - Triển khai trên Vercel kèm theo bản triển khai xem trước (preview deployments) cho mỗi pull request. Độ tin cậy: 0.75
Kiểm toán các cặp màu tiền cảnh/hậu cảnh theo độ tương phản WCAG 2.x (mức AA và AAA cho văn bản thường và văn bản lớn), báo cáo tỷ lệ và kết quả đạt/không đạt, đồng thời lưu ý các rủi ro đối với người mù màu. Sử dụng khi kiểm tra bảng màu giao diện người dùng (UI palette), design token, hoặc hỏi "màu xám trên nền trắng này có dễ đọc không?". Bao gồm công cụ kiểm tra độ tương phản bằng thư viện chuẩn Python có hỗ trợ --self-test.
---
name: accessibility-color-contrast-auditor
description: Kiểm toán các cặp màu tiền cảnh/hậu cảnh theo độ tương phản WCAG 2.x (mức AA và AAA cho văn bản thường và văn bản lớn), báo cáo tỷ lệ và kết quả đạt/không đạt, đồng thời lưu ý các rủi ro đối với người mù màu. Sử dụng khi kiểm tra bảng màu giao diện người dùng (UI palette), design token, hoặc hỏi "màu xám trên nền trắng này có dễ đọc không?". Bao gồm công cụ kiểm tra độ tương phản bằng thư viện chuẩn Python có hỗ trợ --self-test.
---
# Công cụ Kiểm toán Độ tương phản Màu sắc cho Khả năng Tiếp cận
Bạn giúp các nhà thiết kế và kỹ sư frontend kiểm tra xem màu sắc của văn bản và giao diện người dùng (UI) có đáp ứng tỷ lệ tương phản WCAG 2.x hay không. Bạn tính toán độ tương phản độ chói tương đối (relative luminance contrast) cho các cặp màu tiền cảnh/hậu cảnh, đối chiếu kết quả với tiêu chuẩn AA/AAA cho văn bản thường và văn bản lớn, đồng thời gắn cờ cảnh báo các cặp màu chỉ dựa vào sắc độ (hue) để truyền tải ý nghĩa.
## Các tệp trong kỹ năng này
- `scripts/contrast_check.py` - tính toán tỷ lệ tương phản cho các cặp mã màu hex và in ra bảng kết quả đạt/không đạt (chỉ dùng thư viện chuẩn Python 3)
- `references/wcag-contrast.md` - các ngưỡng tiêu chuẩn và quy định thế nào được tính là văn bản lớn
- `references/color-blindness-notes.md` - lý do tại sao các màu trạng thái chỉ phân biệt bằng sắc độ lại gây lỗi với người dùng thực tế
- `templates/audit-table.md` - bảng markdown phục vụ đánh giá thiết kế
- `examples/palette.json` - các cặp token mẫu
## Quy trình làm việc
### 1. Thu thập các cặp màu
Yêu cầu cung cấp các mã màu hex (`#RGB`, `#RRGGBB`, hoặc `#RRGGBBAA` với kênh alpha được bỏ qua trên nền đục). Ghi chú rõ màu nào là văn bản/biểu tượng (fg) và màu nào là bề mặt nền (bg).
### 2. Chạy công cụ kiểm tra
```
python3 scripts/contrast_check.py --fg '#1a1a1a' --bg '#ffffff'
python3 scripts/contrast_check.py --palette examples/palette.json
python3 scripts/contrast_check.py --self-test
```
### 3. Diễn giải kết quả
- Văn bản thường mức AA cần **4.5:1**; mức AAA cần **7:1**.
- Văn bản lớn (18pt+ hoặc 14pt+ in đậm) mức AA cần **3:1**; mức AAA cần **4.5:1**.
- Các thành phần giao diện người dùng phi văn bản / đối tượng đồ họa mang ý nghĩa cần đạt **3:1** so với các màu liền kề (WCAG 2.1 SC 1.4.11).
### 4. Trả lời
Đối với mỗi cặp màu: nêu tỷ lệ (làm tròn một chữ số thập phân), kết quả AA/AAA cho văn bản thường, AA/AAA cho văn bản lớn, và gợi ý khắc phục ngắn gọn (làm tối màu fg, làm sáng màu bg, hoặc tăng độ đậm/kích thước chữ). Nhắc đến vấn đề mù màu nếu trạng thái chỉ phụ thuộc vào sự khác biệt giữa màu đỏ và màu xanh lá.
## Quy tắc
- Sử dụng công thức độ chói tương đối của WCAG; không ước lượng cảm tính bằng mắt thường ("eyeballing").
- Bỏ qua các tuyên bố tiếp thị về "chế độ hỗ trợ tiếp cận" trừ khi có hiển thị tỷ lệ tương phản cụ thể.
- Nếu có pha trộn kênh alpha (alpha blending), hãy yêu cầu mã màu hex thực tế sau khi đã làm phẳng trên nền thật.
FILE:references/wcag-contrast.md
# Các ngưỡng tương phản WCAG (WCAG 2.1 / 2.2)
| Nội dung | AA | AAA |
| --- | --- | --- |
| Văn bản thường | 4.5:1 | 7:1 |
| Văn bản lớn | 3:1 | 4.5:1 |
| Thành phần UI & đối tượng đồ họa (1.4.11) | 3:1 | — |
## Văn bản lớn
Văn bản lớn là văn bản có kích thước tối thiểu **18 CSS pt** (thường là 24px) đối với chữ thường, hoặc **14 CSS pt** (thường là 18.66px) đối với chữ in đậm.
## Độ chói tương đối (Relative luminance)
Đối với kênh màu sRGB C_srgb trong khoảng 0..1:
- nếu C_srgb <= 0.04045: C = C_srgb / 12.92
- ngược lại: C = ((C_srgb + 0.055) / 1.055) ^ 2.4
L = 0.2126 R + 0.7152 G + 0.0722 B
Tỷ lệ tương phản = (L_lighter + 0.05) / (L_darker + 0.05)
## Ghi chú
- Văn bản giữ chỗ (placeholder) / văn bản bị vô hiệu hóa (disabled) được miễn trừ khỏi các tiêu chí thành công (SC) về độ tương phản văn bản nhưng vẫn nên đảm bảo sự rõ ràng.
- Các chỉ báo tiêu điểm (focus indicators) cần đạt tỷ lệ 3:1 so với các màu liền kề (2.4.11 / 2.4.13 tùy theo cấp độ).
FILE:references/color-blindness-notes.md
# Ghi chú về chứng mù màu đối với bảng màu
Chỉ riêng tỷ lệ tương phản là không đủ khi ý nghĩa chỉ được truyền tải thông qua sắc độ (hue).
## Các lỗi thường gặp
- **Trạng thái đỏ so với xanh lá** không kèm biểu tượng hoặc nhãn văn bản: người mắc chứng mù màu lục/đỏ (deuteranomaly/protanomaly) có thể không phân biệt được chúng.
- **Các chuỗi dữ liệu biểu đồ** chỉ phân biệt bằng màu sắc: hãy thêm họa tiết, hình dạng, hoặc nhãn trực tiếp.
- **Màu liên kết (link)** có cùng độ sáng với văn bản thân bài: đường gạch chân hoặc độ đậm của chữ phải được giữ nguyên khi loại bỏ yếu tố màu sắc.
- **Viền báo lỗi** chỉ có sắc đỏ nhạt: hãy đảm bảo tỷ lệ 3:1 so với màu nền và kèm theo văn bản/biểu tượng.
## Các mẫu thiết kế an toàn hơn
1. Kết hợp màu sắc với văn bản ("Error", "Success") hoặc biểu tượng.
2. Sử dụng sự chênh lệch về độ sáng (lightness), chứ không chỉ dịch chuyển sắc độ (hue).
3. Kiểm tra bằng ảnh chụp màn hình giao diện ở chế độ thang độ xám (grayscale).
4. Tránh chỉ dùng mỗi màu đỏ để biểu thị trạng thái trường bắt buộc nhập.
## Mẹo thân thiện với người mắc chứng mù màu lục (Deuteranopia)
Ưu tiên sử dụng các cặp màu xanh dương/cam hoặc xanh dương/nâu thay vì đỏ/xanh lá cho dữ liệu phân loại khi bạn bắt buộc phải dùng hai sắc độ.
FILE:templates/audit-table.md
# Kiểm toán độ tương phản
- **Sản phẩm / màn hình**:
- **Ngày**:
- **Tiêu chuẩn**: WCAG 2.2 AA (mặc định) / AAA ở những nơi được ghi chú
| Token / mục đích sử dụng | FG | BG | Tỷ lệ | AA thường | AAA thường | AA lớn | Ghi chú / cách sửa |
| --- | --- | --- | --- | --- | --- | --- | --- |
| văn bản thân bài | `#1a1a1a` | `#ffffff` | 16.1 | pass | pass | pass | |
| chú thích mờ | `#9ca3af` | `#ffffff` | 2.5 | fail | fail | fail | Làm tối xuống khoảng ~`#6b7280` |
## Quyết định
- [ ] Cập nhật các token
- [ ] Chấp nhận chỉ sử dụng cho văn bản lớn
- [ ] Thêm dấu hiệu nhận biết phi màu sắc
FILE:examples/palette.json
{
"pairs": [
{"name": "body_on_white", "fg": "#1a1a1a", "bg": "#ffffff"},
{"name": "muted_on_white", "fg": "#9ca3af", "bg": "#ffffff"},
{"name": "link_on_white", "fg": "#2563eb", "bg": "#ffffff"},
{"name": "button_label", "fg": "#ffffff", "bg": "#2563eb"},
{"name": "error_on_white", "fg": "#dc2626", "bg": "#ffffff"},
{"name": "white_on_light_gray", "fg": "#ffffff", "bg": "#e5e7eb"}
]
}
FILE:scripts/contrast_check.py
#!/usr/bin/env python3
"""WCAG contrast ratio checker for hex fg/bg pairs.
Usage:
python3 contrast_check.py --fg '#1a1a1a' --bg '#ffffff'
python3 contrast_check.py --palette palette.json
python3 contrast_check.py --self-test
Python 3 standard library only.
"""
from __future__ import annotations
import argparse
import json
import math
import sys
from typing import Dict, List, Tuple
def parse_hex(color: str) -> Tuple[float, float, float]:
c = color.strip().lstrip("#")
if len(c) == 3:
c = "".join(ch * 2 for ch in c)
if len(c) == 8:
c = c[:6] # ignore alpha
if len(c) != 6:
raise ValueError(f"Bad hex color: {color!r}")
r = int(c[0:2], 16) / 255.0
g = int(c[2:4], 16) / 255.0
b = int(c[4:6], 16) / 255.0
return r, g, b
def channel(c: float) -> float:
if c <= 0.04045:
return c / 12.92
return ((c + 0.055) / 1.055) ** 2.4
def relative_luminance(rgb: Tuple[float, float, float]) -> float:
r, g, b = rgb
return 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b)
def contrast_ratio(fg: str, bg: str) -> float:
l1 = relative_luminance(parse_hex(fg))
l2 = relative_luminance(parse_hex(bg))
lighter, darker = max(l1, l2), min(l1, l2)
return (lighter + 0.05) / (darker + 0.05)
def evaluate(ratio: float) -> Dict[str, bool]:
return {
"aa_normal": ratio >= 4.5,
"aaa_normal": ratio >= 7.0,
"aa_large": ratio >= 3.0,
"aaa_large": ratio >= 4.5,
"ui_3_1": ratio >= 3.0,
}
def format_row(name: str, fg: str, bg: str) -> str:
ratio = contrast_ratio(fg, bg)
ev = evaluate(ratio)
flags = " ".join(
f"{k}={'PASS' if v else 'FAIL'}"
for k, v in ev.items()
if k in ("aa_normal", "aaa_normal", "aa_large")
)
return f"{name}: {fg} on {bg} -> {ratio:.2f}:1 {flags}"
def self_test() -> int:
cases = [
("black_white", contrast_ratio("#000000", "#ffffff"), 21.0),
("white_black", contrast_ratio("#ffffff", "#000000"), 21.0),
("body", contrast_ratio("#1a1a1a", "#ffffff") > 12.0, True),
("muted_fail_aa", evaluate(contrast_ratio("#9ca3af", "#ffffff"))["aa_normal"], False),
("link_aa", evaluate(contrast_ratio("#2563eb", "#ffffff"))["aa_normal"], True),
("same_color", abs(contrast_ratio("#ffffff", "#ffffff") - 1.0) < 1e-9, True),
("short_hex", abs(contrast_ratio("#000", "#fff") - 21.0) < 1e-9, True),
("parse3", parse_hex("#abc") == parse_hex("#aabbcc"), True),
("ui_pass", evaluate(3.0)["ui_3_1"], True),
("aaa_border", evaluate(7.0)["aaa_normal"], True),
("just_under_aa", evaluate(4.49)["aa_normal"], False),
]
failed = 0
for name, got, expected in cases:
if isinstance(expected, float):
ok = abs(float(got) - expected) < 0.05
else:
ok = got == expected
failed += not ok
print(f"{'PASS' if ok else 'FAIL'} {name}: got={got!r} expected={expected!r}")
print(f"\n{len(cases) - failed}/{len(cases)} passed")
return 1 if failed else 0
def main(argv=None) -> int:
p = argparse.ArgumentParser(description="Check WCAG contrast for fg/bg hex pairs.")
p.add_argument("--fg")
p.add_argument("--bg")
p.add_argument("--palette", help="JSON file with {pairs:[{name,fg,bg}]}")
p.add_argument("--json", action="store_true")
p.add_argument("--self-test", action="store_true")
a = p.parse_args(argv)
if a.self_test:
return self_test()
rows = []
if a.palette:
data = json.load(open(a.palette, encoding="utf-8"))
for pair in data.get("pairs", []):
rows.append(pair)
elif a.fg and a.bg:
rows.append({"name": "pair", "fg": a.fg, "bg": a.bg})
else:
p.error("provide --fg and --bg, or --palette, or --self-test")
out = []
any_fail = False
for row in rows:
ratio = contrast_ratio(row["fg"], row["bg"])
ev = evaluate(ratio)
if not ev["aa_normal"]:
any_fail = True
item = {"name": row.get("name", "pair"), "fg": row["fg"], "bg": row["bg"], "ratio": round(ratio, 2), **ev}
out.append(item)
if not a.json:
print(format_row(item["name"], item["fg"], item["bg"]))
if a.json:
print(json.dumps(out, indent=2))
return 1 if any_fail else 0
if __name__ == "__main__":
sys.exit(main())Những ưu tiên mang tính định hướng rõ ràng để quản lý trạng thái phía máy khách (client) và máy chủ (server) trong các ứng dụng React.
# Quản Lý Trạng Thái React taste - Bắt đầu với useState cục bộ và chỉ nâng trạng thái lên (lift state) khi hai thành phần anh em thực sự cần dùng chung nó. Độ tin cậy: 0.95 - Coi dữ liệu từ máy chủ là một bộ nhớ đệm (cache) và quản lý nó bằng TanStack Query thay vì đưa vào kho lưu trữ trạng thái toàn cục (global store). Độ tin cậy: 0.90 - Giữ các trạng thái xứng đáng nằm trên URL như bộ lọc, thẻ tab và phân trang ở trong các tham số tìm kiếm (search params). Độ tin cậy: 0.90 - Sử dụng Zustand khi trạng thái máy khách dùng chung vượt quá phạm vi của một cây thành phần (component tree) đơn lẻ. Độ tin cậy: 0.80 - Tránh dùng Redux cho các dự án mới trừ khi nhóm phát triển đã phụ thuộc sẵn vào bộ công cụ devtools và middleware của nó. Độ tin cậy: 0.70 - Sử dụng React Context cho các giá trị ít thay đổi như giao diện (theme), ngôn ngữ bản địa (locale) và người dùng hiện tại, không dùng cho dữ liệu thay đổi liên tục. Độ tin cậy: 0.90 - Tính toán các giá trị phái sinh ngay trong quá trình kết xuất (render) thay vì đồng bộ hóa chúng vào một trạng thái phụ bằng useEffect. Độ tin cậy: 0.95 - Mô hình hóa trạng thái cục bộ phức tạp bằng useReducer kết hợp với kiểu hợp phân biệt (discriminated union) của các hành động (actions). Độ tin cậy: 0.80 - Biểu diễn trạng thái bất đồng bộ dưới dạng một kiểu hợp (union) duy nhất như idle, loading, success và error thay vì dùng nhiều biến boolean rời rạc. Độ tin cậy: 0.85 - Quản lý trạng thái biểu mẫu trong React Hook Form kết hợp với lược đồ kiểm tra zod thay vì tự viết useState thủ công cho từng trường. Độ tin cậy: 0.80 - Chỉ chọn lát cắt dữ liệu (slice) nhỏ nhất từ kho lưu trữ trong mỗi thành phần để tránh việc kết xuất lại (re-render) không cần thiết. Độ tin cậy: 0.85 - Lưu trữ các mã định danh (id) trong trạng thái và tra cứu các đối tượng đầy đủ, thay vì sao chép trùng lặp dữ liệu lồng nhau. Độ tin cậy: 0.80 - Sử dụng cập nhật lạc quan (optimistic updates) cho các thao tác nhanh của người dùng và hoàn tác (roll back) khi xảy ra lỗi. Độ tin cậy: 0.75 - Không bao giờ thay đổi trực tiếp (mutate) các đối tượng trạng thái tại chỗ; hãy trả về các đối tượng mới hoặc dùng Immer cho các cập nhật nằm sâu bên trong. Độ tin cậy: 0.90 - Giữ cho trạng thái lưu trữ bền vững (persisted state) nhỏ gọn và có đánh số phiên bản khi lưu vào localStorage. Độ tin cậy: 0.75 - Đặt lại trạng thái của thành phần bằng cách thay đổi thuộc tính key của nó thay vì viết các hàm hiệu ứng (effects) để đặt lại. Độ tin cậy: 0.80 - Đặt các kho lưu trữ trạng thái (stores) nằm cạnh tính năng sở hữu chúng thay vì gom tất cả vào một thư mục store toàn cục duy nhất. Độ tin cậy: 0.75 - Định kiểu tường minh cho mọi kho lưu trữ và giá trị context, đồng thời tránh sử dụng kiểu any trong cấu trúc trạng thái. Độ tin cậy: 0.90
Các ưu tiên mang tính định hướng rõ ràng để viết CSS dễ bảo trì, hỗ trợ khả năng tiếp cận (accessible) và đáp ứng (responsive) trong các ứng dụng web hiện đại.
# Phong cách (taste) CSS của một lập trình viên frontend có tư duy thiết kế - Sử dụng các lớp tiện ích (utility classes) của Tailwind CSS để định kiểu cho component trong mã nguồn ứng dụng. Độ tin cậy: 0.80 - Định nghĩa màu sắc, khoảng cách (spacing), độ bo góc (radii) và phông chữ dưới dạng các design token trong thuộc tính tùy chỉnh CSS (CSS custom properties). Độ tin cậy: 0.90 - Không bao giờ gán cứng (hardcode) mã màu hex bên trong các component; luôn tham chiếu đến một token. Độ tin cậy: 0.85 - Xây dựng bố cục bằng flexbox và grid, sử dụng thuộc tính gap để tạo khoảng cách thay vì dùng margin giữa các phần tử anh em (siblings). Độ tin cậy: 0.90 - Thiết kế ưu tiên thiết bị di động (mobile first) và thêm các điểm ngắt (breakpoints) min-width cho màn hình lớn hơn. Độ tin cậy: 0.85 - Sử dụng container queries cho các component nằm trong những vùng chứa có chiều rộng khác nhau. Độ tin cậy: 0.75 - Sử dụng đơn vị rem cho kích thước phông chữ và khoảng cách, và chỉ dùng px cho đường viền mảnh (hairline borders). Độ tin cậy: 0.80 - Sử dụng hàm clamp() cho kiểu chữ linh hoạt (fluid typography) thay vì ghi đè tại nhiều điểm ngắt. Độ tin cậy: 0.75 - Giữ độ ưu tiên (specificity) phẳng: bộ chọn một lớp duy nhất, không dùng ID và không dùng !important bên ngoài các lớp tiện ích. Độ tin cậy: 0.90 - Sử dụng cascade layers để sắp xếp thứ tự cho reset, base, components và utilities. Độ tin cậy: 0.70 - Hỗ trợ chế độ tối (dark mode) bằng prefers-color-scheme kết hợp với các token, thay vì nhân bản các kiểu dáng của component. Độ tin cậy: 0.85 - Tôn trọng prefers-reduced-motion và tắt các hiệu ứng chuyển động không cần thiết khi tùy chọn này được bật. Độ tin cậy: 0.90 - Không bao giờ xóa đường viền tiêu điểm (focus outlines); thay vào đó hãy định kiểu cho chúng bằng :focus-visible. Độ tin cậy: 0.95 - Đạt chuẩn độ tương phản WCAG AA cho tất cả văn bản và các phần tử tương tác. Độ tin cậy: 0.90 - Chỉ tạo hiệu ứng chuyển động (animate) trên thuộc tính transform và opacity để có các chuyển cảnh mượt mà và ít tốn tài nguyên. Độ tin cậy: 0.85 - Sử dụng các thuộc tính logic như margin-inline để bố cục hoạt động tốt với cả các ngôn ngữ viết từ phải sang trái (RTL). Độ tin cậy: 0.75 - Sử dụng bộ phông chữ hệ thống (system font stack) hoặc phông chữ biến thiên (variable fonts) tự lưu trữ với thuộc tính font-display: swap. Độ tin cậy: 0.80 - Đặt thuộc tính aspect-ratio cùng với width và height trên các phần tử đa phương tiện (media) để ngăn chặn hiện tượng dịch chuyển bố cục (layout shift). Độ tin cậy: 0.85 - Sử dụng tính năng lồng nhau (nesting) nguyên bản của CSS một cách tiết chế và không bao giờ vượt quá hai cấp độ. Độ tin cậy: 0.70 - Tự động sắp xếp các lớp Tailwind bằng plugin Prettier. Độ tin cậy: 0.80 - Tách thành một component riêng khi cùng một danh sách dài các lớp lặp đi lặp lại, thay vì tạo lớp bằng @apply. Độ tin cậy: 0.75 - Đảm bảo không có phần tử nào bị cuộn ngang ở chiều rộng khung nhìn (viewport) 320px. Độ tin cậy: 0.85
Các ưu tiên mang tính định kiến nhằm giúp trang web tải nhanh và duy trì khả năng phản hồi mượt mà cho người dùng thực tế.
# Phong cách (taste) tối ưu hiệu năng Web của một kỹ sư Frontend - Đo lường các chỉ số Core Web Vitals (LCP, INP, CLS) từ người dùng thực tế, chứ không chỉ dựa vào các lần chạy Lighthouse trong môi trường thử nghiệm (lab). Độ tin cậy: 0.90 - Thiết lập ngân sách hiệu năng (performance budget) cho dung lượng JavaScript và chỉ số LCP, đồng thời cho dừng lỗi CI khi có thay đổi vượt quá giới hạn đó. Độ tin cậy: 0.80 - Kết xuất (render) khung nhìn đầu tiên trên máy chủ hoặc dưới dạng tĩnh; không phân phối một trang trắng phải chờ tải xong JavaScript. Độ tin cậy: 0.90 - Giảm lượng mã JavaScript gửi đi trước khi tối ưu hóa số JavaScript mà bạn gửi. Độ tin cậy: 0.90 - Chia nhỏ mã (code splitting) theo từng tuyến đường (route) và tải trễ (lazy-load) các thành phần nặng như trình soạn thảo, biểu đồ và bản đồ. Độ tin cậy: 0.85 - Kiểm tra bằng công cụ phân tích gói mã (bundle analyzer) trước khi thêm một thư viện phụ thuộc, và ưu tiên các thư viện nhỏ gọn, hỗ trợ loại bỏ mã thừa (tree-shakable). Độ tin cậy: 0.80 - Phân phối hình ảnh ở định dạng AVIF hoặc WebP với thuộc tính srcset đáp ứng (responsive) cùng chiều rộng (width) và chiều cao (height) tường minh. Độ tin cậy: 0.90 - Đánh dấu hình ảnh LCP bằng thuộc tính fetchpriority="high" và tuyệt đối không tải trễ (lazy-load) nó. Độ tin cậy: 0.85 - Tải trễ các hình ảnh và thẻ iframe nằm bên dưới màn hình đầu tiên (below-the-fold) bằng thuộc tính loading="lazy". Độ tin cậy: 0.85 - Tự lưu trữ (self-host) phông chữ, rút gọn bộ ký tự (subset), tải trước (preload) phông chữ chính và sử dụng thuộc tính font-display: swap. Độ tin cậy: 0.80 - Dành sẵn không gian trống cho quảng cáo, nội dung nhúng và nội dung tải muộn để bố cục trang không bị xê dịch. Độ tin cậy: 0.85 - Chia nhỏ các tác vụ kéo dài trên 50 ms và nhường quyền xử lý lại cho luồng chính (main thread) để giữ chỉ số INP ở mức thấp. Độ tin cậy: 0.80 - Tải các tập lệnh của bên thứ ba bằng thuộc tính defer hoặc sau khi có tương tác của người dùng, đồng thời kiểm tra giá trị thực sự của từng tập lệnh. Độ tin cậy: 0.85 - Lưu bộ nhớ đệm (cache) cho các tài sản tĩnh đã gắn mã băm (hashed) với tiêu đề Cache-Control: immutable trong thời hạn một năm. Độ tin cậy: 0.90 - Phân phối mọi tài nguyên qua giao thức HTTP/2 hoặc HTTP/3 từ mạng phân phối nội dung (CDN) có bật nén Brotli. Độ tin cậy: 0.85 - Chỉ khởi tạo kết nối trước (preconnect) tới một hoặc hai nguồn (origin) thực sự cần thiết cho lần kết xuất đầu tiên. Độ tin cậy: 0.70 - Nhúng trực tiếp (inline) phần CSS quan trọng (critical CSS) cho khung nhìn đầu tiên và tải phần còn lại mà không chặn quá trình kết xuất. Độ tin cậy: 0.65 - Ảo hóa (virtualize) các danh sách dài thay vì kết xuất hàng nghìn nút DOM cùng lúc. Độ tin cậy: 0.80 - Chỉ tạo hoạt ảnh (animate) trên hai thuộc tính transform và opacity, đồng thời tôn trọng tùy chọn prefers-reduced-motion của người dùng. Độ tin cậy: 0.85 - Tránh gây tính toán lại bố cục liên tục (layout thrashing): gom nhóm các thao tác đọc DOM trước khi thực hiện các thao tác ghi DOM. Độ tin cậy: 0.75 - Kiểm thử trên điện thoại Android tầm trung với mạng bị bóp băng thông (throttled), chứ không chỉ thử nghiệm trên máy tính xách tay của lập trình viên. Độ tin cậy: 0.90 - Xem sự suy giảm hiệu năng (performance regression) giống như một lỗi phần mềm (bug), cần có người chịu trách nhiệm và ngày ấn định khắc phục. Độ tin cậy: 0.80
Những ưu tiên mang tính định hướng rõ rệt để xây dựng giao diện web dễ tiếp cận, hoạt động hiệu quả cho người dùng bàn phím và trình đọc màn hình.
# Gu thiết kế Khả năng Tiếp cận Web (Web Accessibility) của một kỹ sư frontend - Ưu tiên sử dụng HTML ngữ nghĩa trước tiên (button, a, nav, main, label); chỉ thêm ARIA khi không có phần tử gốc nào phù hợp. Độ tin cậy: 0.95 - Không bao giờ gắn trình xử lý sự kiện click (click handlers) vào thẻ div hoặc span; nếu nó hoạt động như một nút bấm, nó phải là thẻ button. Độ tin cậy: 0.95 - Liên kết (links) dùng để điều hướng và nút bấm (buttons) dùng để thực hiện hành động; đừng tráo đổi chúng chỉ vì lý do tạo kiểu giao diện (styling). Độ tin cậy: 0.90 - Mọi trường nhập liệu trong biểu mẫu (form input) đều phải có nhãn (label) hiển thị rõ ràng và được liên kết về mặt lập trình; văn bản gợi ý (placeholders) không phải là nhãn. Độ tin cậy: 0.95 - Giữ một thẻ h1 duy nhất trên mỗi trang và không bao giờ nhảy cóc các cấp tiêu đề (heading levels) chỉ để chỉnh kích thước hiển thị; hãy tạo kiểu bằng CSS để thay thế. Độ tin cậy: 0.80 - Viết văn bản thay thế (alt text) mô tả đúng mục đích của hình ảnh, và sử dụng alt="" cho các hình ảnh thuần túy mang tính trang trí. Độ tin cậy: 0.90 - Giữ chỉ báo tiêu điểm (focus indicator) hiển thị rõ ràng trên mọi phần tử tương tác; sử dụng :focus-visible thay vì xóa bỏ đường viền (outlines). Độ tin cậy: 0.95 - Mọi tính năng phải hoạt động được khi chỉ dùng riêng bàn phím, theo thứ tự phím Tab hợp lý và không có bẫy bàn phím (keyboard traps). Độ tin cậy: 0.95 - Tránh các giá trị tabindex dương; hãy sửa lại thứ tự DOM để thay thế. Độ tin cậy: 0.90 - Đạt chuẩn độ tương phản WCAG AA: tỷ lệ 4.5:1 đối với văn bản nội dung và 3:1 đối với văn bản cỡ lớn cùng các thành phần giao diện người dùng (UI). Độ tin cậy: 0.90 - Không bao giờ truyền tải ý nghĩa chỉ bằng màu sắc đơn thuần; hãy kết hợp màu sắc với văn bản, biểu tượng hoặc họa tiết. Độ tin cậy: 0.90 - Sử dụng phần tử dialog gốc (hoặc một thư viện đã được kiểm thử kỹ lưỡng) cho các hộp thoại modal, giữ tiêu điểm (trap focus) bên trong khi đang mở và trả tiêu điểm về phần tử kích hoạt khi đóng lại. Độ tin cậy: 0.85 - Thông báo trạng thái bất đồng bộ và các lỗi bằng vùng aria-live hoặc role="alert", đồng thời di chuyển tiêu điểm đến phần tóm tắt lỗi sau khi gửi biểu mẫu thất bại. Độ tin cậy: 0.80 - Tôn trọng tùy chọn prefers-reduced-motion và tránh tự động phát các hiệu ứng chuyển động kéo dài quá năm giây. Độ tin cậy: 0.85 - Thiết kế các vùng chạm (touch targets) có kích thước tối thiểu 24x24 CSS pixel, lý tưởng nhất là 44x44. Độ tin cậy: 0.75 - Đặt kích thước chữ bằng đơn vị rem và đảm bảo bố cục vẫn hiển thị tốt khi phóng to 200% và ở chiều rộng 320px mà không bị cuộn ngang. Độ tin cậy: 0.85 - Thêm liên kết "Chuyển đến nội dung chính" (Skip to main content) làm phần tử có thể nhận tiêu điểm (focusable) đầu tiên. Độ tin cậy: 0.80 - Thiết lập thuộc tính lang trên thẻ html và trên bất kỳ đoạn văn bản nội dòng nào được viết bằng ngôn ngữ khác. Độ tin cậy: 0.85 - Chạy các bài kiểm tra axe hoặc Lighthouse trong quy trình CI, đồng thời hiểu rõ rằng chúng chỉ phát hiện được khoảng một phần ba số vấn đề. Độ tin cậy: 0.85 - Kiểm thử thủ công các luồng quan trọng bằng trình đọc màn hình (VoiceOver và NVDA) trước mỗi đợt phát hành lớn. Độ tin cậy: 0.80 - Kiểm tra lỗi mã nguồn JSX bằng eslint-plugin-jsx-a11y và coi các lỗi của nó là lỗi dừng quá trình build (build failures). Độ tin cậy: 0.75 - Ưu tiên các thành phần giao diện nguyên thủy hỗ trợ tiếp cận (Radix, React Aria) hơn là tự xây dựng các hộp chọn (comboboxes) và menu từ đầu. Độ tin cậy: 0.80
Các quy ước mang tính định hướng rõ ràng để xây dựng ứng dụng Vue 3 dễ bảo trì với TypeScript và Composition API.
# Ứng dụng Vue taste của một kỹ sư frontend - Bắt đầu các dự án mới bằng Vite và Vue 3, hoặc Nuxt khi cần kết xuất phía máy chủ (server rendering) hoặc định tuyến dựa trên tệp (file-based routing). Confidence: 0.90 - Viết các component bằng script setup và Composition API, không dùng Options API. Confidence: 0.90 - Sử dụng TypeScript ở mọi nơi và kiểm tra kiểu cho template bằng vue-tsc trong hệ thống CI. Confidence: 0.90 - Định nghĩa kiểu cho props và emits bằng generics của defineProps và defineEmits thay vì chỉ khai báo ở thời điểm chạy (runtime-only). Confidence: 0.85 - Sử dụng Pinia cho trạng thái phía client được chia sẻ chung và giữ cho các store nhỏ gọn, chỉ tập trung vào một miền nghiệp vụ (domain) duy nhất. Confidence: 0.85 - Tải dữ liệu từ máy chủ bằng TanStack Query cho Vue hoặc useFetch của Nuxt thay vì tự viết các cờ trạng thái đang tải (loading flags) thủ công trong store. Confidence: 0.80 - Tách logic có thể tái sử dụng thành các composable có tên theo mẫu useSomething trả về các ref và hàm. Confidence: 0.90 - Tìm đến thư viện VueUse trước khi tự viết một composable tùy chỉnh cho các API trình duyệt phổ biến. Confidence: 0.75 - Ưu tiên dùng computed hơn là watch, và chỉ sử dụng watch cho các tác vụ có hiệu ứng phụ (side effects). Confidence: 0.90 - Tuyệt đối không thay đổi trực tiếp (mutate) giá trị của props; hãy phát sự kiện (emit events) hoặc sử dụng defineModel cho ràng buộc hai chiều (two-way binding). Confidence: 0.95 - Luôn cung cấp cho các phần tử trong v-for một khóa (key) ổn định lấy từ dữ liệu, tuyệt đối không dùng chỉ số mảng (index). Confidence: 0.90 - Không bao giờ kết hợp v-if và v-for trên cùng một phần tử. Confidence: 0.90 - Giữ cho các component có độ dài dưới khoảng 200 dòng và tách nhỏ chúng ra khi phần template trở nên khó đọc lướt. Confidence: 0.70 - Sử dụng tên component gồm nhiều từ viết theo kiểu PascalCase và đặt các component cùng chỗ (colocate) theo tính năng chứ không phân chia theo loại kỹ thuật. Confidence: 0.80 - Định kiểu giao diện bằng scoped CSS hoặc Tailwind, và tránh sử dụng các kiểu toàn cục (global styles) ngoại trừ một phần reset nhỏ và các design token. Confidence: 0.75 - Tải trễ (lazy load) các component của tuyến đường (route) bằng cú pháp import động trong Vue Router. Confidence: 0.85 - Kiểm thử các component bằng Vitest và Vue Testing Library, truy vấn phần tử theo vai trò (role) và văn bản hiển thị. Confidence: 0.85 - Kiểm tra mã nguồn (lint) bằng ESLint và eslint-plugin-vue với bộ quy tắc được khuyến nghị, đồng thời định dạng mã bằng Prettier. Confidence: 0.85 - Tránh sử dụng provide và inject cho trạng thái toàn ứng dụng; chỉ dùng chúng cho phần nội bộ của thư viện component và các cấu hình truyền sâu nhiều tầng. Confidence: 0.70 - Làm sạch (sanitize) bất kỳ mã HTML nào trước khi sử dụng v-html, hoặc tốt hơn hết là tránh dùng v-html hoàn toàn. Confidence: 0.95
Các quy ước giàu tính định hướng để xây dựng ứng dụng SvelteKit full-stack với Svelte 5 runes và TypeScript.
# Gu thiết kế (taste) Ứng dụng SvelteKit của một lập trình viên web full-stack - Bắt đầu mọi dự án bằng khuôn mẫu (template) chính thức `sv create`, bật sẵn TypeScript và kích hoạt chế độ nghiêm ngặt (strict mode). Độ tin cậy: 0.90 - Sử dụng Svelte 5 runes (`$state`, `$derived`, `$effect`, `$props`) cho tất cả các component mới thay vì các câu lệnh phản ứng (reactive statements) kiểu cũ. Độ tin cậy: 0.90 - Tìm đến `$derived` trước khi nghĩ tới `$effect`, và chỉ giữ `$effect` cho việc đồng bộ hóa với những thứ nằm ngoài Svelte như DOM hoặc các thư viện bên thứ ba. Độ tin cậy: 0.90 - Tải dữ liệu trong `+page.server.ts` khi cần dùng tới thông tin bí mật (secrets) hoặc cơ sở dữ liệu, và chỉ sử dụng `+page.ts` dùng chung (universal) cho các lệnh gọi lấy dữ liệu công khai. Độ tin cậy: 0.90 - Xử lý các thao tác thay đổi dữ liệu (mutations) bằng form actions và `use:enhance` để biểu mẫu vẫn hoạt động được khi không có JavaScript và tự động hưởng lợi từ khả năng nâng cấp lũy tiến (progressive enhancement). Độ tin cậy: 0.85 - Xác thực dữ liệu đầu vào của biểu mẫu và API ở phía máy chủ bằng Zod hoặc Valibot, đồng thời trả về `fail()` kèm lỗi chi tiết từng trường thay vì ném ngoại lệ (throw). Độ tin cậy: 0.90 - Giữ mã nguồn chỉ chạy trên máy chủ trong thư mục `$lib/server` để quá trình build lập tức báo lỗi nếu mã đó vô tình bị import vào phía máy khách. Độ tin cậy: 0.95 - Đọc các thông tin bí mật từ `$env/static/private` hoặc `$env/dynamic/private`, tuyệt đối không đọc từ các module biến môi trường công khai. Độ tin cậy: 0.95 - Đặt logic xác thực và tra cứu phiên làm việc (session) trong `hooks.server.ts` và cung cấp thông tin người dùng thông qua `event.locals`. Độ tin cậy: 0.90 - Tuyệt đối không lưu trữ dữ liệu người dùng của từng yêu cầu (per-request) vào biến trạng thái ở cấp độ module, vì nó sẽ làm rò rỉ dữ liệu giữa các yêu cầu khác nhau trên máy chủ. Độ tin cậy: 0.95 - Chia sẻ trạng thái phía máy khách thông qua context hoặc các module nhỏ dựa trên rune trong các file `.svelte.ts`, thay vì dùng một store toàn cục cho mọi thứ. Độ tin cậy: 0.80 - Sử dụng các nhóm route như `(app)` và `(marketing)` để áp dụng các bố cục (layouts) khác nhau cho từng phân khu mà không làm thay đổi đường dẫn URL. Độ tin cậy: 0.80 - Kết xuất trước (prerender) các trang tĩnh như trang tài liệu và tiếp thị, đồng thời giữ các trang động được kết xuất từ phía máy chủ (server-rendered). Độ tin cậy: 0.85 - Chọn một bộ chuyển đổi (adapter) tường minh (`adapter-node`, `adapter-vercel`, `adapter-cloudflare`) thay vì phụ thuộc vào `adapter-auto` trên môi trường production. Độ tin cậy: 0.80 - Trả về dữ liệu có kiểu rõ ràng từ các hàm `load` và dựa vào `./$types` được sinh tự động thay vì tự viết kiểu cho prop bằng tay. Độ tin cậy: 0.90 - Sử dụng các trang `+error.svelte` và hàm trợ giúp `error()` cho những lỗi nằm trong dự kiến, và ghi nhật ký các lỗi bất ngờ trong `handleError`. Độ tin cậy: 0.85 - Định kiểu giao diện bằng CSS có phạm vi cục bộ theo component (scoped component CSS) làm mặc định và chỉ thêm Tailwind khi nhóm phát triển đã quen sử dụng nó. Độ tin cậy: 0.70 - Giữ cho các component nhỏ gọn và truyền các `snippets` cho phần nội dung linh hoạt thay vì dùng quá nhiều prop kiểu boolean. Độ tin cậy: 0.80 - Kiểm thử các component bằng Vitest và `@testing-library/svelte`, đồng thời bao phủ các luồng người dùng chính bằng Playwright. Độ tin cậy: 0.85 - Chạy `svelte-check`, ESLint và Prettier kèm plugin Svelte trong quy trình CI trên mọi pull request. Độ tin cậy: 0.85
Các quy ước mang tính định hướng rõ ràng để xây dựng tiện ích mở rộng (extension) đa trình duyệt bảo mật theo chuẩn Manifest V3 với TypeScript.
# Gu phát triển Tiện ích mở rộng trình duyệt (Browser Extension) của một lập trình viên tiện ích mở rộng đa trình duyệt - Xây dựng trên nền tảng Manifest V3 và lên kế hoạch xoay quanh các service worker có thể bị dừng bất cứ lúc nào. Độ tin cậy: 0.95 - Sử dụng một framework như WXT hoặc Plasmo kết hợp với TypeScript và Vite để xử lý việc đóng gói (build), tải lại (reload) và tạo tệp manifest đa trình duyệt. Độ tin cậy: 0.80 - Yêu cầu ít quyền (permissions) nhất có thể, và ưu tiên `activeTab` cùng `optional_permissions` thay vì quyền truy cập host diện rộng. Độ tin cậy: 0.95 - Không bao giờ yêu cầu quyền host `all_urls` trừ khi tính năng cốt lõi thực sự cần hoạt động trên mọi trang web. Độ tin cậy: 0.90 - Không lưu giữ trạng thái quan trọng nào trong biến toàn cục (globals) của service worker mà hãy lưu trữ bền vững bằng `chrome.storage`. Độ tin cậy: 0.95 - Sử dụng `chrome.storage.session` cho các thông tin bí mật tạm thời và `chrome.storage.local` hoặc `sync` cho cài đặt người dùng, đi kèm một lớp bọc có định kiểu (typed wrapper) và giá trị mặc định. Độ tin cậy: 0.85 - Sử dụng `chrome.alarms` cho các tác vụ định kỳ thay vì dùng `setInterval` ở chế độ chạy nền (background). Độ tin cậy: 0.90 - Đăng ký tất cả các trình lắng nghe sự kiện (event listeners) ở cấp cao nhất (top level) của service worker để chúng không bị mất khi khởi động lại. Độ tin cậy: 0.90 - Giữ cho các content script nhỏ gọn và nhúng (inject) chúng bằng mã lệnh thông qua `chrome.scripting` bất cứ khi nào có thể. Độ tin cậy: 0.85 - Cô lập giao diện người dùng (UI) được nhúng bên trong một Shadow DOM để CSS của trang web và CSS của tiện ích mở rộng không thể xung đột với nhau. Độ tin cậy: 0.90 - Coi mọi thông điệp (message) gửi từ content script và các trang web là không đáng tin cậy và phải xác thực (validate) chúng bằng một lược đồ (schema). Độ tin cậy: 0.95 - Định nghĩa các kiểu thông điệp (message types) trong một module dùng chung duy nhất và sử dụng các hàm hỗ trợ request/response có định kiểu cho việc truyền thông điệp lúc chạy (runtime messaging). Độ tin cậy: 0.85 - Không bao giờ nhúng mã nguồn từ xa (remote code) hoặc sử dụng `eval`, đồng thời duy trì Chính sách Bảo mật Nội dung (Content Security Policy - CSP) nghiêm ngặt. Độ tin cậy: 0.95 - Sử dụng `declarativeNetRequest` để chặn hoặc sửa đổi các yêu cầu mạng thay vì cố gắng chặn bắt chúng bằng mã lệnh. Độ tin cậy: 0.85 - Sử dụng `webextension-polyfill` hoặc lớp trừu tượng của framework để cùng một mã nguồn có thể chạy được trên Chrome, Firefox, Edge và Safari. Độ tin cậy: 0.80 - Thu thập ít dữ liệu người dùng nhất có thể và giải thích rõ ràng trên trang thông tin cửa hàng (store listing) về những gì được lưu trữ và lý do lưu trữ. Độ tin cậy: 0.90 - Xử lý các sự kiện cài đặt mới (`install`) và cập nhật (`update`) để di chuyển (migrate) các cài đặt đã lưu giữa các phiên bản. Độ tin cậy: 0.85 - Kiểm thử trang popup và trang tùy chọn (options) như giao diện web thông thường, và chạy kiểm thử đầu-cuối (end-to-end) bằng Playwright với tiện ích mở rộng được nạp ở dạng chưa đóng gói (unpacked). Độ tin cậy: 0.80 - Tự động hóa quá trình build, tăng số phiên bản (version bump) và tải lên cửa hàng trong CI, với một gói tệp zip đầu ra riêng cho từng trình duyệt. Độ tin cậy: 0.80 - Giữ cho cửa sổ popup phản hồi nhanh bằng cách tải trễ (lazy load) các dữ liệu nặng và hiển thị trạng thái đã lưu trong bộ nhớ đệm (cached state) trước. Độ tin cậy: 0.80 - Viết một đoạn giải trình quyền truy cập ngắn gọn cho từng quyền trước khi gửi xét duyệt lên cửa hàng. Độ tin cậy: 0.85
Các quy ước thực tế để xây dựng ứng dụng di động đa nền tảng nhanh và dễ bảo trì bằng Flutter.
# Ứng dụng Flutter taste của một lập trình viên di động đa nền tảng thực dụng - Bắt đầu trên phiên bản Flutter ổn định mới nhất với null safety, các tùy chọn phân tích nghiêm ngặt (strict analysis options) và bộ quy tắc lint chính thức hoặc very_good_analysis được kiểm tra bắt buộc trong CI. Độ tin cậy: 0.90 - Tổ chức code theo các thư mục tính năng (feature folders), mỗi thư mục có các tầng data, domain và presentation riêng, thay vì gom tất cả vào một thư mục widgets khổng lồ. Độ tin cậy: 0.85 - Sử dụng Riverpod hoặc Bloc để quản lý trạng thái và chọn một giải pháp thống nhất cho toàn bộ ứng dụng thay vì trộn lẫn nhiều thư viện. Độ tin cậy: 0.80 - Giữ các widget nhỏ gọn và có tính kết hợp (composable), tách thành một lớp widget mới thay vì dùng phương thức phụ trợ (helper method) trả về widget. Độ tin cậy: 0.85 - Đánh dấu const cho các widget và constructor ở mọi nơi có thể để giảm thiểu việc vẽ lại (rebuild) không cần thiết. Độ tin cậy: 0.90 - Tách hoàn toàn logic nghiệp vụ ra khỏi phương thức build và ra khỏi các widget. Độ tin cậy: 0.90 - Sử dụng go_router để điều hướng khai báo (declarative navigation) với các route có định kiểu (typed routes) và hỗ trợ deep link hoạt động chuẩn. Độ tin cậy: 0.80 - Mô hình hóa dữ liệu bằng các lớp bất biến (immutable classes) được sinh tự động bởi freezed và json_serializable thay vì tự viết tay copyWith và fromJson. Độ tin cậy: 0.80 - Bọc truy cập API trong các lớp repository và trả về kết quả có kiểu dữ liệu hoặc ngoại lệ rõ ràng, không bao giờ trả trực tiếp map phản hồi thô cho tầng UI. Độ tin cậy: 0.85 - Xây dựng giao diện (theme) một lần duy nhất bằng ThemeData và ColorScheme từ Material 3, và không bao giờ gán cứng (hard-code) màu sắc hoặc kiểu chữ bên trong các widget. Độ tin cậy: 0.85 - Hỗ trợ chế độ tối (dark mode), co giãn kích thước chữ động và trình đọc màn hình (screen readers) ngay từ bản phát hành đầu tiên. Độ tin cậy: 0.85 - Sử dụng flutter_localizations với các file ARB cho mọi chuỗi văn bản hiển thị tới người dùng ngay từ ngày đầu. Độ tin cậy: 0.80 - Chạy các tác vụ phân tích cú pháp nặng hoặc xử lý ảnh trong một isolate riêng bằng compute hoặc Isolate.run để luồng UI luôn mượt mà. Độ tin cậy: 0.85 - Đo đạc hiệu năng bằng DevTools ở chế độ profile trên thiết bị thật cấu hình thấp trước khi kết luận một màn hình là nhanh. Độ tin cậy: 0.85 - Sử dụng ListView.builder hoặc slivers cho các danh sách dài và không bao giờ khởi tạo sẵn hàng trăm phần tử con cùng lúc. Độ tin cậy: 0.90 - Lưu trữ token bằng flutter_secure_storage và giữ các cài đặt đơn giản trong shared_preferences. Độ tin cậy: 0.90 - Viết unit test cho phần logic, widget test cho các màn hình và một số integration test cho các luồng quan trọng. Độ tin cậy: 0.80 - Sử dụng golden test cho các widget thuộc hệ thống thiết kế (design-system) cần đảm bảo độ ổn định từng điểm ảnh. Độ tin cậy: 0.70 - Ghim cố định phiên bản các thư viện phụ thuộc, đánh giá các gói mới về mức độ bảo trì và hỗ trợ nền tảng, đồng thời giữ danh sách phụ thuộc ngắn gọn. Độ tin cậy: 0.80 - Định nghĩa các flavor cho môi trường development, staging và production với app ID và cấu hình tách biệt. Độ tin cậy: 0.85 - Đóng gói và phát hành bản dựng bằng Fastlane hoặc Codemagic từ hệ thống CI, không bao giờ phát hành thủ công từ máy tính cá nhân của lập trình viên. Độ tin cậy: 0.80 - Tích hợp Crashlytics hoặc Sentry cùng bản dựng đã làm rối mã (obfuscated builds) và tải lên các file symbol. Độ tin cậy: 0.80