-->

Vi phạm

Danh sách vi phạm thường gặp

Stt Tên lỗi Nguyên nhân
1 ⚠️ vi phạm Clean Architecturebr /> ✅ Auditing Codebase Layout Errors
2 ⚠️ vi phạm Không tách domain logic
3 ⚠️ vi phạm Premium Coding Standards
4 ⚠️ Vi phạm Unique Constraint
5 ⚠️ Lỗi CSS cũ
✅ Auditing Legacy CSS Errors
6 ⚠️ Business logic trộn trong UI
7 ⚠️ Thiếu application layer hook
8 ⚠️ TemplateEditor UX thô sơ
9 ⚠️ Hardcode CSS
10 ⚠️ Lỗi Format (UI/Frontend)
11 ⚠️ Lỗi Naming Convention (Backend/Supabase)
✅ Auditing Backend Naming Conventions
12 ⚠️ Lỗi Tech bebt

Vi phạm Premium Coding Standards

Để ngăn chặn triệt để và an toàn các lỗi Unique Constraint Violation (vi phạm ràng buộc duy nhất) do các Edge Cases như chuỗi rỗng (""), khoảng trắng, hoặc sai sót từ Frontend, hệ thống cần được thiết lập phòng thủ qua nhiều lớp (Defense in Depth) từ Database lên đến UI.

Dưới đây là các phương pháp kiến trúc tốt nhất (Best Practices) để áp dụng:

1. Tầng Database (PostgreSQL) - Lớp phòng thủ cuối cùng & vững chắc nhất

Cơ sở dữ liệu không bao giờ được tin tưởng hoàn toàn dữ liệu từ API gửi xuống.

  • Sử dụng NULLIF để chuyển chuỗi rỗng thành NULL: Trong PostgreSQL, giá trị NULL mặc định được coi là "khác nhau" (distinct) trong các index Unique. Nếu bạn cho phép trường này bị trống, hãy ép nó thành NULL thay vì "".
    -- Trong các hàm RPC hoặc Trigger
    receipt_number = COALESCE(NULLIF(TRIM(p_header->>'receipt_number'), ''), receipt_number)
  • Ràng buộc CHECK (Check Constraints): Chặn đứng việc lưu chuỗi rỗng bằng cách ép cơ sở dữ liệu từ chối nó ngay ở cấp độ bảng.
    ALTER TABLE yarn_receipts
    ADD CONSTRAINT yarn_receipts_receipt_number_check 
    CHECK (TRIM(receipt_number) <> '');

2. Tầng API / Contract (Zod Schema) - Lớp chuẩn hóa dữ liệu

Thay vì để code Frontend tự lo liệu việc parse null hay "", hãy sử dụng thư viện validation (như Zod) để tự động làm sạch dữ liệu trước khi gọi các hàm mutation.

  • Tự động chuyển đổi String rỗng sang Null/Undefined:
    export const yarnReceiptsSchema = z.object({
      receiptNumber: z.string()
        .trim()
        .nullable()
        .transform(val => (val === '' ? null : val)), // Ép rỗng về null
    });
  • Ràng buộc chiều dài tối thiểu (Minimum Length): Nếu một trường đã được điền, nó phải có độ dài nhất định để hợp lệ.
    receiptNumber: z.string().trim().min(3, "Mã phiếu phải từ 3 ký tự trở lên").optional(),

3. Tầng Application (Mutation Hooks) - Lớp chặn logic

Lớp này gọi hàm cơ sở dữ liệu (RPC), là nơi biến đổi dữ liệu từ Contract thành Payload cho API.

  • Gán Null an toàn: Tránh dùng Nullish Coalescing (?? '') cho các trường chuỗi có Unique Constraint. Thay vào đó, hãy ưu tiên dùng toán tử OR (|| null) để đảm bảo chuỗi rỗng ("") sẽ bị Falsy và fallback về null.
    // Không an toàn: Nếu input là "" -> vẫn lấy ""
    receipt_number: input.receiptNumber ?? ''
    
    // An toàn: Nếu input là "" -> lấy null
    receipt_number: input.receiptNumber?.trim() || null

4. Tầng UI (React Hook Form) - Lớp ngăn chặn sai lầm từ phía người dùng

Giao diện (UI) là nơi định hướng hành vi.

  • Disabled vs ReadOnly: Nếu một trường (như Số Phiếu) hệ thống tự động sinh ra và không cần gửi ngầm lên khi cập nhật form, hãy dùng thuộc tính disabled thay vì readOnly. Khi dùng disabled, các thư viện (như React Hook Form) sẽ tự động bỏ qua (omit) trường đó khỏi object values gửi lên (Form Submit), giúp giảm tải băng thông và giảm triệt để rủi ro ghi đè dữ liệu.
  • Hiển thị Placeholder rõ ràng: Hướng dẫn trực quan cho thao tác của người dùng.

Tổng Kết

Kiến trúc vững vàng nhất là kết hợp Biến chuỗi rỗng thành Null tại Code logic (Tầng 2 & 3) và Sử dụng NULLIF + Ràng buộc CHECK tại DataBase (Tầng 1). Khi đã thiết lập chuẩn như vậy, ngay cả khi dữ liệu bị nhiễu, hệ thống của bạn vẫn sẽ không bao giờ vỡ vì lỗi Unique Constraint rác.

#PostgreSQL #DatabaseDesign #WebDevelopment #ReactJS #Supabase #Zod #CodingBestPractices #Architecture

Đăng nhận xét

Mới hơn Cũ hơn