Series Cloud Database Supabase #3: CI/CD Pipeline và RLS Đa tầng - "Bảo vệ Pháo đài" Dữ liệu
1. Tự động hóa Migration: Đưa CI/CD vào Database
Lỗi lớn nhất của Junior là quản lý Database thủ công. Ở chuẩn Senior, Database phải là Code. Mọi thay đổi phải đi qua Git.
Khi bạn dùng Supabase, đừng vào Dashboard để tạo bảng. Hãy dùng Supabase CLI.
Quy trình chuẩn CI/CD:
- Local Development: Bạn viết file migrate 20260714000000_create_gate_logs.sql.
- Test: Chạy supabase db reset để tái tạo database trên local, đảm bảo migration không bị lỗi.
- Git Commit: Đẩy code lên GitHub/GitLab.
- Pipeline (GitHub Actions): Tự động trigger lệnh:
supabase db push --project-ref $SUPABASE_PROJECT_ID
Với quy trình này, bạn không bao giờ sợ quên thêm cột hay sai kiểu dữ liệu giữa môi trường Dev và Production. Nếu có lỗi, bạn biết chính xác commit nào gây ra, và có thể rollback ngay lập tức.
2. RLS Đa tầng: Khi bài toán phân quyền trở nên "Căng"
Trong hệ thống Metro, bài toán phân quyền luôn là ác mộng:
- Nhân viên kỹ thuật A: Chỉ được xem lỗi của ga S01 và S02.
- Trưởng ga B: Được xem toàn bộ báo cáo doanh thu của tất cả các ga thuộc tuyến Metro số 1.
- Admin: Được xem tất cả.
Đừng viết đống if...else trong PHP nữa. Hãy để PostgreSQL xử lý bằng RLS (Row Level Security) dựa trên Metadata của user.
Kỹ thuật "User Attributes": Khi người dùng đăng nhập, Supabase cho phép bạn gán user_metadata (ví dụ: {"role": "tech", "managed_stations": ["S01", "S02"]}).
Chính sách RLS chuẩn Senior:
CREATE POLICY "Tech can only view their stations" ON gate_logs
FOR SELECT
TO authenticated
USING (
-- Kiểm tra role và ga được quản lý
auth.jwt() -> 'user_metadata' ->> 'role' = 'tech'
AND station_id = ANY( (auth.jwt() -> 'user_metadata' ->> 'managed_stations')::text[] )
);
Chỉ với vài dòng SQL, toàn bộ logic bảo mật đã được khóa chặt ngay tại tầng Database. Ngay cả khi một Developer non kinh nghiệm viết query SELECT * FROM gate_logs, thì Database cũng tự động lọc ra đúng dữ liệu của ga mà nhân viên đó được phép xem.
3. Debug SQL "Thần tốc" với View và CTE (Trạm cuối)
Trong dự án Metro, các bảng log giao dịch thường đạt con số hàng triệu dòng mỗi tháng. Để Admin xem được báo cáo, chúng ta không được phép query trực tiếp lên bảng đó.
Kỹ thuật Senior: Sử dụng Materialized Views. Chúng ta tạo ra một View "ảo" nhưng được lưu trữ dữ liệu thực tế (Materialized), nó chỉ update mỗi 1 tiếng/lần.
CREATE MATERIALIZED VIEW daily_station_report AS
SELECT station_id, date_trunc('day', created_at) as report_date, count(*) as tap_count
FROM transactions
GROUP BY station_id, report_date;
-- Admin query vào View này sẽ cực nhanh, vì dữ liệu đã được tính toán sẵn
Cách Debug: Mỗi khi thấy hệ thống chậm, hãy vào Supabase Dashboard -> Database -> Query Performance. Supabase sẽ tự động liệt kê các câu query "hung thần" đang ngốn nhiều CPU nhất. Dựa vào đó, bạn chỉ cần một lệnh:
CREATE INDEX idx_transactions_station_date ON transactions (station_id, created_at);
Câu query sẽ chạy nhanh gấp hàng trăm lần ngay lập tức.
Tổng kết Series Cloud Database Supabase
Chúng ta đã đi qua hành trình từ một "thế giới tự quản lý" (Self-hosted Docker) sang phương thức "công nghiệp" (Supabase Cloud).
Bạn đã trang bị được bộ kỹ năng mà chỉ các Senior Backend mới có:
- Database-as-Code: Quản lý cấu trúc dữ liệu bằng Migration và CI/CD.
- Zero Trust Security: Dùng RLS để bảo mật dữ liệu ngay từ gốc, tách biệt hoàn toàn khỏi logic của ứng dụng.
- Hệ thống phân tán: Sử dụng Webhooks, Edge Functions để xử lý logic "tàng hình" và Real-time.
Hệ thống của chúng ta bây giờ đã đạt tới độ chín muồi của một Enterprise Architecture. Với những kiến thức này, Hiếu hoàn toàn tự tin đảm nhận việc xây dựng, tối ưu và vận hành các dự án lớn nhất.
All rights reserved