Giới thiệu
Trong thời đại mua sắm trực tuyến, đánh giá sản phẩm (review) đóng vai trò quan trọng trong việc xây dựng niềm tin và thúc đẩy quyết định mua hàng của khách hàng. Để tạo ra một hệ thống review hoàn chỉnh, chúng ta cần kết hợp giữa cơ sở dữ liệu thời gian thực, xác thực người dùng và xử lý thanh toán. Supabase cung cấp backend mạnh mẽ với PostgreSQL và Row Level Security, trong khi Stripe đảm nhận khâu thanh toán an toàn. Bài viết này sẽ hướng dẫn bạn xây dựng hệ thống review sản phẩm tích hợp cả hai công nghệ này.
Thiết kế cơ sở dữ liệu trên Supabase
Để lưu trữ reviews, chúng ta cần ít nhất hai bảng chính: một cho sản phẩm và một cho reviews. Bảng products sẽ chứa thông tin cơ bản như ID, tên, mô tả và giá. Bảng reviews sẽ lưu nội dung review, đánh giá sao, ngày tạo và liên kết với sản phẩm qua khóa ngoại. Ngoài ra, cần một bảng users để quản lý thông tin khách hàng, dù Supabase Authentication đã cung cấp sẵn user ID.
-- Bảng products
CREATE TABLE products (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
description TEXT,
price NUMERIC(10, 2) NOT NULL
);
-- Bảng reviews
CREATE TABLE reviews (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
product_id UUID REFERENCES products(id) ON DELETE CASCADE,
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
rating INTEGER NOT NULL CHECK (rating >= 1 AND rating <= 5),
comment TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
CHECK (comment IS NOT NULL OR rating IS NOT NULL)
);
Với Row Level Security, chúng ta đảm bảo chỉ chủ review mới có thể sửa hoặc xóa review của mình, và mọi người đều có thể đọc reviews công khai.
-- Chính sách cho reviews
ALTER TABLE reviews ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view reviews" ON reviews
FOR SELECT USING (true);
CREATE POLICY "Users can insert their own reviews" ON reviews
FOR INSERT WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can update their own reviews" ON reviews
FOR UPDATE USING (auth.uid() = user_id);
CREATE POLICY "Users can delete their own reviews" ON reviews
FOR DELETE USING (auth.uid() = user_id);