Khóa Cơ bản · Bài 8/13 · Chặng 4 · Vẽ giao diện để AI code đúng ý

Dữ liệu và backend: khi nào cần, dùng Supabase an toàn

Trung cấp 6 phút đọc

Bài này đang khóa

Bụi Code học theo thứ tự: làm xong bài kiểm tra cuối Bài 7: Mô tả giao diện để AI làm đúng ý để mở bài này. Mỗi bài dựa trên bài trước, bỏ qua dễ hổng kiến thức.

Phân biệt khi nào web tĩnh là đủ, khi nào cần nơi lưu dữ liệu. Nắm 3 quy tắc sống còn khi cho AI làm phần dữ liệu với Supabase: bảng rõ ràng, bật RLS, không lộ khóa service_role.

Bạn sẽ làm được

  • Quyết định dự án có thật sự cần backend hay không.
  • Mô tả bảng dữ liệu cho AI bằng ngôn ngữ đời thường.
  • Hiểu RLS và hai loại khóa của Supabase để không lộ dữ liệu.
Nội dung bài học

Vấn đề thật

Bạn muốn khách để lại đơn, muốn người học lưu tiến độ, muốn có trang quản trị. AI nói “dùng Supabase nhé”, tạo bảng, viết code, chạy được. Vài tuần sau bạn phát hiện bất kỳ ai mở Console của trình duyệt cũng đọc được toàn bộ danh sách khách hàng.

Đây là lỗi phổ biến nhất khi vibe code app có dữ liệu. Bài này giúp bạn tránh nó.

Bước 0: có thật sự cần backend?

Bạn cầnCách không cần backend
Khách liên hệ, đặt hàngNút Zalo, Messenger, email
Nhận đăng ký, khảo sátNhúng Google Form, dữ liệu về Google Sheet
Hiển thị danh sách sản phẩmViết thẳng trong file nội dung, sửa rồi deploy lại
Nhớ tiến độ của một người trên một máyLưu trong trình duyệt (localStorage)

Chỉ cần backend khi: nhiều người tạo ra dữ liệu và cần thấy dữ liệu của nhau hoặc của mình trên nhiều máy, có đăng nhập, có phân quyền.

Lưu trong trình duyệt: localStorage

Với app một người dùng trên một máy (sổ chi tiêu cá nhân, danh sách việc, ghi chú), localStorage là đủ: dữ liệu nằm trong trình duyệt, tải lại trang vẫn còn, không cần máy chủ, không tốn tiền. Bụi Code lưu tiến độ học của bạn đúng bằng cách này.

Giao việc cho AI:

Làm danh sách việc cần làm, lưu bằng localStorage.
Mỗi việc: id, nội dung, đã xong (đúng/sai), ngày tạo.
Chức năng: thêm, đánh dấu xong, sửa nội dung, xóa (hỏi xác nhận trước khi xóa).
Nghiệm thu:
- Thêm 3 việc, tải lại trang, vẫn còn đủ 3 việc.
- Dữ liệu hỏng hoặc trống thì trang vẫn mở được, không trắng màn hình.
- Có nút "Xuất dữ liệu" ra file JSON để tôi sao lưu.

Biết giới hạn trước khi dùng: dữ liệu chỉ có trên trình duyệt đó. Đổi máy, đổi trình duyệt, xóa dữ liệu duyệt web hoặc dùng cửa sổ ẩn danh là mất. Không lưu thông tin nhạy cảm vào đây vì mọi đoạn code chạy trên trang đều đọc được.

Hiểu sai hay gặp: MCP không phải nơi lưu dữ liệu của app

MCP (Model Context Protocol) là cách để công cụ AI của bạn đọc, ghi vào dịch vụ khác trong lúc làm việc, ví dụ cho Claude Code xem cấu trúc bảng trên Supabase. Nó không phải cơ sở dữ liệu, và website của bạn khi chạy cho khách không dùng MCP. Dữ liệu của app vẫn nằm ở localStorage, Google Sheet hoặc một cơ sở dữ liệu như Supabase. MCP được dạy ở Khóa Claude Code.

Supabase là gì, nói ngắn

Supabase là dịch vụ cho bạn một cơ sở dữ liệu Postgres cùng đăng nhập (Auth), lưu file (Storage) và API tự sinh, quản lý qua giao diện web. Nó hợp với vibe coding vì AI biết nó khá rõ và bạn không phải tự dựng máy chủ.

Hai thứ bạn phải hiểu trước khi cho AI đụng vào:

Hai loại khóa

KhóaỞ đâuQuyền
anon / publishableĐược phép nằm trong code trình duyệtChỉ làm được những gì RLS cho phép
service_role / secretChỉ ở phía máy chủ, biến môi trườngBỏ qua mọi RLS, toàn quyền

Tên khóa có thể khác tùy thời điểm; đọc trang API keys trong tài liệu Supabase (nguồn cuối bài).

RLS: Row Level Security

RLS là luật ở cấp cơ sở dữ liệu quyết định ai được đọc, ghi dòng nào. Khi bật RLS cho một bảng mà chưa có luật (policy) nào, mọi truy cập bằng khóa anon bị chặn. Bạn mở dần bằng policy, ví dụ: “người dùng chỉ đọc được tiến độ của chính mình”.

Quy tắc: Bảng nào có dữ liệu mà trang web đọc bằng khóa anon thì bắt buộc bật RLS. Không có ngoại lệ “tạm thời”.

Mô tả dữ liệu cho AI bằng ngôn ngữ đời thường

Bạn không cần biết SQL. Bạn cần mô tả rõ thứ gì, ai sở hữu, ai được làm gì:

Tôi cần lưu tiến độ học của người dùng trên Supabase.

Dữ liệu:
- Mỗi người dùng (đăng nhập bằng email) có nhiều bản ghi tiến độ.
- Mỗi bản ghi: bài học nào (mã bài dạng chữ), hoàn thành lúc nào.
- Một người chỉ có một bản ghi cho mỗi bài.

Quyền:
- Người dùng chỉ ĐỌC và THÊM tiến độ của chính mình.
- Không ai xem được tiến độ của người khác.
- Không ai xóa được qua trang web.

Yêu cầu:
1. Viết SQL tạo bảng, bật RLS, và các policy đúng quyền trên.
2. Giải thích từng policy bằng tiếng Việt đơn giản.
3. Cho tôi cách tự kiểm: đăng nhập 2 tài khoản, tài khoản B không thấy dữ liệu của A.
4. Chỉ dùng khóa anon ở trình duyệt. Không dùng service_role trong code client.
Chưa chạy gì, chờ tôi duyệt.

Kiểm tra bảo mật dữ liệu (bắt buộc trước khi công khai)

  1. Trong trang quản lý Supabase, mở mục bảng: mọi bảng có dấu hiệu RLS enabled.
  2. Tìm trong mã nguồn chữ service_role, secret: không được xuất hiện trong code chạy ở trình duyệt.
  3. Thử bằng hai tài khoản: đăng nhập A tạo dữ liệu; đăng nhập B, xem có thấy dữ liệu A không. Thấy là lỗi nghiêm trọng.
  4. Thử khi chưa đăng nhập: mở cửa sổ ẩn danh, thử gọi trang có dữ liệu.
  5. Dùng tính năng cảnh báo bảo mật trong trang quản lý Supabase (nếu có) và xử lý cảnh báo mức cao.

Lỗi hay gặp

  • AI tắt RLS “cho chạy được”. Khi gặp lỗi quyền, AI hay đề xuất tắt RLS. Không chấp nhận. Bảo nó viết policy đúng.
  • Dùng service_role ở trình duyệt vì “anon bị lỗi quyền”. Đây là cách lộ toàn bộ dữ liệu.
  • Thu thập dữ liệu thừa. Không cần số điện thoại thì đừng lưu. Dữ liệu càng ít, rủi ro càng ít.
  • Không sao lưu. Biết cách xuất dữ liệu và đã thử khôi phục ít nhất một lần.

Việc làm ngay

  1. Với ý tưởng của bạn, đi qua bảng “Bước 0”. Ghi vào brief: cần hay không cần backend, vì sao.
  2. Nếu cần: viết mô tả dữ liệu theo mẫu (thứ gì, ai sở hữu, ai làm gì), chưa cần chạy.
  3. Chép 5 bước kiểm tra bảo mật dữ liệu vào NOTES.md.

Tóm tắt

  • Chỉ thêm backend khi nhiều người tạo dữ liệu và cần đăng nhập, phân quyền.
  • Khóa anon ở trình duyệt được, nhưng chỉ an toàn khi có RLS.
  • Khóa service_role chỉ ở máy chủ.
  • Thử bằng hai tài khoản trước khi công khai.

Prompt dùng ngay cho bài này

  • Tạo dữ liệu mẫu: Có 2-3 dòng dữ liệu thật hoặc giống thật trước khi làm giao diện để AI không tự đặt tên trường rồi bắt bạn sửa cả trang.

Nguồn

  1. Supabase Docs: Row Level Security (truy cập 16/10/2026)
  2. Supabase Docs: API keys (truy cập 16/10/2026)
Kiểm tra cuối bài

Trả lời đúng 3 câu để mở Bài 9

Sai thì đọc giải thích và làm lại, không giới hạn số lần.

Câu 1. Trang giới thiệu tiệm bánh, khách đặt bánh qua Zalo. Có cần backend không?
Câu 2. Khi bật RLS cho một bảng mà chưa viết policy nào, chuyện gì xảy ra với truy cập từ trình duyệt?
Câu 3. Khóa service_role của Supabase được đặt ở đâu?

Tiến độ lưu trên trình duyệt này. Đổi máy hoặc xóa dữ liệu trình duyệt sẽ mất tiến độ cho tới khi có tài khoản.

Bài này có giúp ích cho bạn không?

Cùng ngẫm một câu

Sản phẩm của bạn có cần backend không, vì sao? Dữ liệu nào của người dùng là nhạy cảm nhất?

Tự trả lời vào NOTES.md của dự án bạn — đó là cách biến bài đọc thành việc làm thật.

Mời Bụi Code ly cà phê

Bụi Code miễn phí cho mọi người. AI viết code, còn người viết bài thì chạy bằng cà phê. Nếu bài học giúp được bạn, mời mình một ly nhé.

Kênh nhận ủng hộ đang được cập nhật. Muốn ủng hộ ngay, nhắn mình qua email phungnb@gmail.com.

Ủng hộ hoàn toàn tự nguyện. Chia sẻ Bụi Code cho một người đang cần cũng quý như một ly cà phê.