Files
goodgo-platform/docs/audits/ACCESSIBILITY_AUDIT_QUICK_REFERENCE.md
Ho Ngoc Hai 11f2bf26e6
Some checks failed
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 29s
CI / E2E Tests (push) Has been skipped
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 2m42s
Deploy / Build Web Image (push) Failing after 27s
Deploy / Build AI Services Image (push) Failing after 29s
E2E Tests / Playwright E2E (push) Failing after 43s
Deploy / Build API Image (push) Failing after 1m31s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 6s
Security Scanning / Trivy Scan — API Image (push) Failing after 5m35s
Security Scanning / Trivy Scan — AI Services Image (push) Failing after 3m45s
Deploy / Deploy to Staging (push) Has been skipped
Deploy / Smoke Test Staging (push) Has been skipped
Deploy / Deploy to Production (push) Has been skipped
Deploy / Smoke Test Production (push) Has been skipped
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped
Security Scanning / Trivy Scan — Web Image (push) Failing after 13m51s
Security Scanning / Trivy Filesystem Scan (push) Failing after 14m46s
Security Scanning / Security Gate (push) Has been cancelled
chore: update project documentation, audit reports, and initialize IDE configuration files
2026-04-19 03:12:54 +07:00

11 KiB
Raw Permalink Blame History

GoodGo Platform Kiểm Toán Khả Năng Tiếp Cận - Tài Liệu Tham Khảo Nhanh

Ngày: 10 tháng 4 năm 2026 | Trạng thái: Tuân thủ WCAG 2.1 AA ở mức 7075%


📊 Chỉ Số Chính

Chỉ số Số lượng Trạng thái
Tổng số tệp đã phân tích 90+
Thuộc tính ARIA tìm thấy 75
Tệp sử dụng ARIA 14
Vấn đề nghiêm trọng 2 🔴
Vấn đề lớn 3 🟡
Vấn đề nhỏ 2 🟢

🔴 VẤN ĐỀ NGHIÊM TRỌNG (Phải Sửa)

1. Thành Phần Dialog Thiếu Khả Năng Tiếp Cận

Tệp: apps/web/components/ui/dialog.tsx Vấn đề:

  • Thiếu role="dialog"
  • Thiếu aria-modal="true"
  • Không có bẫy tiêu điểm (focus trap)
  • Không xử lý phím Escape
  • Phần nền không bị ẩn khỏi trình đọc màn hình

Thời gian sửa: 23 giờ | Ưu tiên: 1

Danh sách kiểm tra sửa nhanh:

  • Thêm role="dialog" vào vùng chứa dialog
  • Thêm aria-modal="true"
  • Triển khai trình lắng nghe phím Escape
  • Thêm aria-hidden="true" vào lớp phủ nền
  • Kiểm tra với trình đọc màn hình NVDA

2. Nút Hình Thu Nhỏ Trong Thư Viện Ảnh Thiếu Nhãn

Tệp: apps/web/components/listings/image-gallery.tsx:69-84 Vấn đề: Các nút hình thu nhỏ thiếu aria-label

Thời gian sửa: 1530 phút | Ưu tiên: 2

Sửa nhanh:

// Thêm vào mỗi nút hình thu nhỏ:
aria-label={`Select image ${index + 1}${img.caption ? ': ' + img.caption : ''}`}
aria-pressed={index === selectedIndex}

🟡 VẤN ĐỀ LỚN (Nên Sửa)

1. Tiêu Đề Layout Admin Thiếu Vai Trò Banner

Tệp: apps/web/app/[locale]/(admin)/layout.tsx:134

Sửa nhanh:

// Đổi từ:
<header className="sticky...">

// Sang:
<header role="banner" className="sticky...">

Thời gian sửa: 2 phút | Ưu tiên: 3


2. Độ Tương Phản Màu Chưa Được Kiểm Tra

Vấn đề: Các biến CSS đã được định nghĩa nhưng tỷ lệ tương phản chưa được kiểm tra Tác động: Có thể vi phạm WCAG 1.4.3 Thời gian sửa: 46 giờ kiểm tra

Danh sách kiểm tra:

  • Trích xuất giá trị biến CSS từ globals.css
  • Kiểm tra bằng WebAIM Contrast Checker
  • Xác minh tỷ lệ 4.5:1 cho văn bản thông thường (WCAG AA)
  • Xác minh tỷ lệ 7:1 cho tuân thủ AAA
  • Kiểm tra ở cả chế độ sáng và tối

3. Ô Nhập Tìm Kiếm Trang Đầu Thiếu Nhãn Hiển Thị

Tệp: apps/web/app/[locale]/(public)/page.tsx:87-92

Sửa nhanh:

<div className="flex flex-col gap-1">
  <label htmlFor="search-input" className="sr-only">
    {t('landing.searchPlaceholder')}
  </label>
  <Input
    id="search-input"
    placeholder={t('landing.searchPlaceholder')}
    value={searchQuery}
    onChange={(e) => setSearchQuery(e.target.value)}
  />
</div>

Thời gian sửa: 30 phút | Ưu tiên: 4


🟢 VẤN ĐỀ NHỎ (Nên Có)

1. aria-label Thừa Trên Văn Bản Đã Hiển Thị

Tệp: apps/web/app/[locale]/(dashboard)/layout.tsx:125 Vấn đề: Các liên kết có aria-label trong khi văn bản đã hiển thị

Khuyến nghị: Xóa các aria-label thừa — văn bản hiển thị sẵn tốt hơn cho khả năng tiếp cận


NHỮNG GÌ ĐANG HOẠT ĐỘNG TỐT

Biểu Mẫu Xác Thực

  • Tất cả các ô nhập có nhãn hiển thị với <Label htmlFor="id">
  • Thông báo lỗi được liên kết qua aria-describedby
  • Trạng thái không hợp lệ được đánh dấu bằng aria-invalid
  • Nút hiện/ẩn mật khẩu có aria-label đúng chuẩn
  • Ví dụ: apps/web/app/[locale]/(auth)/login/page.tsx

Liên Kết Bỏ Qua Nội Dung (Skip-to-Content)

  • Được triển khai đúng chuẩn với khả năng hiển thị tiêu điểm
  • Ẩn theo mặc định, hiển thị khi được tiêu điểm
  • Liên kết đến id="main-content"
  • Ví dụ: apps/web/app/[locale]/layout.tsx:105-110

Điều Hướng

  • Tất cả các nav có aria-label
  • Nút chuyển đổi menu di động có nhãn động
  • Biểu tượng được ẩn đúng chuẩn với aria-hidden="true"
  • Ví dụ: Tất cả các tệp layout

Tìm Kiếm & Bộ Lọc

  • Phần bộ lọc có role="search"
  • Tất cả các ô select có aria-label
  • Ô nhập kiểu dải (range) được gắn nhãn đúng chuẩn
  • Ví dụ: apps/web/components/search/filter-bar.tsx

Thư Viện Ảnh

  • Các nút Trước/Sau có aria-label
  • Cấu trúc ngữ nghĩa tốt
  • Ví dụ: apps/web/components/listings/image-gallery.tsx:47, 54

📋 DANH SÁCH KIỂM TRA THỬ NGHIỆM

Trước Khi Triển Khai

  • Sửa khả năng tiếp cận của thành phần dialog
  • Thêm nhãn cho các nút hình thu nhỏ
  • Thêm vai trò banner vào tiêu đề admin
  • Chạy kiểm toán khả năng tiếp cận Lighthouse (mục tiêu: 90+)
  • Kiểm tra với trình đọc màn hình NVDA
  • Kiểm tra điều hướng bàn phím (Tab, Shift+Tab, Enter, Escape)
  • Xác minh tỷ lệ tương phản màu sắc
  • Kiểm tra chuyển đổi giao diện (chế độ sáng/tối)

Kiểm Tra Trình Đọc Màn Hình (NVDA)

  • Biểu mẫu đăng nhập: Có thể điền trường, nghe thông báo lỗi
  • Điều hướng: Có thể điều hướng menu, hiểu trang hiện tại
  • Tìm kiếm: Có thể tìm và gửi biểu mẫu tìm kiếm
  • Hộp thoại: Có thể mở, tương tác, đóng bằng phím Escape
  • Thư viện ảnh: Có thể chọn ảnh, nghe ảnh nào đang được chọn
  • Menu di động: Có thể mở/đóng, nút chuyển đổi hoạt động bình thường

Điều Hướng Bàn Phím

  • Tab: Di chuyển qua tất cả các phần tử tương tác theo thứ tự hợp lý
  • Shift+Tab: Di chuyển ngược lại qua các phần tử
  • Enter: Kích hoạt nút/liên kết/gửi biểu mẫu
  • Space: Kích hoạt nút, bật/tắt hộp kiểm
  • Escape: Đóng modal/menu
  • Phím mũi tên: Hoạt động trong dropdown/băng chuyền

🎯 Lộ Trình Ưu Tiên

Tuần 1 (40 giờ)

  1. Sửa Thành Phần Dialog (23 giờ)

    • Thêm role, aria-modal, focus trap, xử lý phím Escape
    • Kiểm tra với trình đọc màn hình
  2. Thêm Nhãn Hình Thu Nhỏ (0,5 giờ)

    • Thêm aria-label vào các nút hình thu nhỏ
    • Kiểm tra
  3. Sửa Tiêu Đề Admin (0,1 giờ)

    • Thêm role="banner"
  4. Xác Minh Tương Phản (68 giờ)

    • Trích xuất biến CSS
    • Kiểm tra tất cả các tổ hợp
    • Ghi lại kết quả
    • Điều chỉnh nếu cần
  5. Thêm Nhãn Trang Đầu (0,5 giờ)

    • Thêm nhãn hiển thị vào ô nhập tìm kiếm
  6. Kiểm Tra Trình Duyệt (8 giờ)

    • Kiểm tra NVDA
    • Kiểm tra Chrome/Firefox/Safari
    • Kiểm tra trên thiết bị di động

Tuần 2 (20 giờ)

  1. Xóa Nhãn Thừa (0,5 giờ)
  2. Thêm Liên Kết Bỏ Qua Bổ Sung (23 giờ)
  3. Kiểm Tra Toàn Diện (8 giờ)
  4. Sửa Các Vấn Đề Phát Hiện (6 giờ)

📁 Tài Liệu Tham Chiếu Tệp

Các Tệp Quan Trọng Cần Xem Xét/Sửa

  • apps/web/components/ui/dialog.tsx - 🔴 CẦN VIẾT LẠI
  • apps/web/components/listings/image-gallery.tsx - 🔴 CẦN SỬA NHỎ
  • apps/web/app/[locale]/(admin)/layout.tsx - 🟡 THÊM ROLE
  • apps/web/app/globals.css - 🟡 XÁC MINH MÀU SẮC (chưa kiểm toán)

Các Tệp Có Khả Năng Tiếp Cận Tốt

  • apps/web/app/[locale]/(public)/layout.tsx - XUẤT SẮC
  • apps/web/app/[locale]/(auth)/login/page.tsx - XUẤT SẮC
  • apps/web/app/[locale]/(auth)/register/page.tsx - XUẤT SẮC
  • apps/web/components/ui/button.tsx - TỐT
  • apps/web/components/ui/input.tsx - TỐT
  • apps/web/components/ui/label.tsx - TỐT
  • apps/web/components/ui/select.tsx - TỐT
  • apps/web/components/search/filter-bar.tsx - TỐT

🔍 Ví Dụ Mã

Ví Dụ Sử Dụng ARIA Tốt

// Tốt: aria-label động cập nhật theo trạng thái
<button
  aria-label={mobileMenuOpen ? t('nav.closeMenu') : t('nav.openMenu')}
  onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
>
  {mobileMenuOpen ? <X /> : <Menu />}
</button>

Ví Dụ Khả Năng Tiếp Cận Biểu Mẫu

// Tốt: Liên kết nhãn đúng chuẩn + xử lý lỗi
<div className="space-y-2">
  <Label htmlFor="phone">{t('phone')}</Label>
  <Input
    id="phone"
    type="tel"
    aria-describedby={errors.phone ? 'phone-error' : undefined}
    aria-invalid={!!errors.phone}
    {...register('phone')}
  />
  {errors.phone && (
    <p id="phone-error" role="alert">{errors.phone.message}</p>
  )}
</div>

Ví Dụ Biểu Mẫu Tìm Kiếm

// Tốt: Vai trò ngữ nghĩa đúng chuẩn với các điều khiển được gắn nhãn
<form role="search" aria-label={t('filters')}>
  <Select aria-label={t('allTransactions')}>
    {/* options */}
  </Select>
</form>

📞 Tài Nguyên

Tài Liệu

  • Báo cáo kiểm toán đầy đủ: ACCESSIBILITY_AUDIT_2026-04-10.md
  • Kết quả chi tiết trên 15 phần
  • Phân tích từng tệp
  • Đánh giá tuân thủ WCAG 2.1

Công Cụ Kiểm Tra

Tài Nguyên Học Tập


📝 Ghi Chú

Phạm vi kiểm toán: apps/web (giao diện Next.js 15) Số tệp đã phân tích: 90+ tệp TSX/JSX Thời gian đạt tuân thủ AA: 46 ngày làm toàn thời gian Bảo trì liên tục: Nên tích hợp vào CI/CD và đào tạo lập trình viên

Bước tiếp theo:

  1. Xem xét báo cáo kiểm toán đầy đủ (1552 dòng)
  2. Tạo ticket Jira cho mỗi vấn đề
  3. Phân công nhiệm vụ cho nhóm phát triển
  4. Lên lịch kiểm tra khả năng tiếp cận
  5. Lập kế hoạch buổi đào tạo lập trình viên