# Hướng dẫn deploy GroupVault lên Vercel

## 1. Yêu cầu

- Tài khoản GitHub hoặc GitLab.
- Tài khoản Vercel.
- Tài khoản Supabase.
- Tài khoản Cloudflare có R2.
- Node.js 20.9 trở lên nếu chạy thử trên máy.

## 2. Tạo Supabase

1. Mở Supabase Dashboard và tạo project mới.
2. Vào **SQL Editor**.
3. Mở file `supabase/schema.sql`, sao chép toàn bộ và bấm **Run**.
4. Vào **Project Settings → API** và lấy:
   - Project URL → `NEXT_PUBLIC_SUPABASE_URL`
   - anon/public key → `NEXT_PUBLIC_SUPABASE_ANON_KEY`
   - service_role key → `SUPABASE_SERVICE_ROLE_KEY`
5. Vào **Authentication → URL Configuration**:
   - Site URL lúc đầu có thể đặt `http://localhost:3000`.
   - Sau khi có domain Vercel, đổi thành `https://ten-du-an.vercel.app`.
   - Thêm redirect URL `https://ten-du-an.vercel.app/**`.
6. Trong **Authentication → Providers → Email**, quyết định có bật xác nhận email hay không. Khi thử nhanh có thể tắt; khi vận hành thật nên bật.

`service_role` là khóa bí mật cấp cao. Không đưa khóa này vào frontend hoặc commit lên Git.

## 3. Tạo Cloudflare R2

1. Mở Cloudflare Dashboard → **R2 Object Storage**.
2. Tạo bucket, ví dụ `groupvault`.
3. Giữ bucket ở chế độ private; không cần bật public URL.
4. Tạo **R2 API Token** có quyền Object Read & Write cho riêng bucket này.
5. Lưu lại:
   - Account ID → `R2_ACCOUNT_ID`
   - Access Key ID → `R2_ACCESS_KEY_ID`
   - Secret Access Key → `R2_SECRET_ACCESS_KEY`
   - Tên bucket → `R2_BUCKET`
6. Vào phần CORS của bucket và dán nội dung từ `cloudflare-r2-cors.json`.
7. Thay `https://YOUR-DOMAIN.vercel.app` bằng domain deploy thật.

CORS phải có `PUT`, `GET`, `HEAD` và phải expose header `ETag`. Multipart upload sẽ không hoàn tất nếu trình duyệt không đọc được ETag.

CORS gợi ý:

```json
[
  {
    "AllowedOrigins": [
      "http://localhost:3000",
      "https://ten-du-an.vercel.app"
    ],
    "AllowedMethods": ["GET", "PUT", "HEAD"],
    "AllowedHeaders": ["Content-Type", "Content-Length", "ETag", "x-amz-*"],
    "ExposeHeaders": ["ETag"],
    "MaxAgeSeconds": 3600
  }
]
```

Nên tạo lifecycle rule tự dọn multipart upload chưa hoàn thành sau 1 ngày.

## 4. Chạy thử trên máy

Trong thư mục source:

```bash
copy .env.example .env.local
npm install
npm run dev
```

Trên macOS/Linux dùng:

```bash
cp .env.example .env.local
```

Điền `.env.local`:

```env
NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=...
SUPABASE_SERVICE_ROLE_KEY=...
R2_ACCOUNT_ID=...
R2_ACCESS_KEY_ID=...
R2_SECRET_ACCESS_KEY=...
R2_BUCKET=groupvault
NEXT_PUBLIC_APP_URL=http://localhost:3000
MAX_FILE_SIZE_BYTES=5497558138880
SIMPLE_UPLOAD_LIMIT_BYTES=104857600
SIGNED_URL_TTL_SECONDS=900
```

Sau đó mở `http://localhost:3000`, đăng ký và tạo nhóm đầu tiên.

## 5. Đưa source lên GitHub

```bash
git init
git add .
git commit -m "Initial GroupVault"
git branch -M main
git remote add origin https://github.com/TAI-KHOAN/groupvault.git
git push -u origin main
```

Không commit `.env.local`.

## 6. Import vào Vercel

1. Vào Vercel → **Add New → Project**.
2. Import repository `groupvault`.
3. Framework sẽ được nhận tự động là Next.js.
4. Thêm toàn bộ biến môi trường trong `.env.example`.
5. Đối với `NEXT_PUBLIC_APP_URL`, nhập domain dự kiến, ví dụ `https://groupvault-tenban.vercel.app`.
6. Bấm **Deploy**.

Sau khi deploy lần đầu:

1. Sao chép domain thật của Vercel.
2. Sửa `NEXT_PUBLIC_APP_URL` nếu khác.
3. Sửa Supabase Site URL/Redirect URLs.
4. Sửa AllowedOrigins trong R2 CORS.
5. Redeploy Vercel vì thay đổi biến môi trường chỉ áp dụng vào deployment mới.

## 7. Kiểm tra sau deploy

- Mở `/api/health`; phải thấy `ok: true`.
- Đăng ký tài khoản.
- Tạo nhóm.
- Upload một file nhỏ dưới 100 MB.
- Upload một file lớn hơn 100 MB để kiểm tra multipart.
- Tải file về và so sánh kích thước/hash với file gốc nếu cần.
- Tạo link chia sẻ có mật khẩu và thử ở trình duyệt ẩn danh.
- Tạo link mời thành viên và thử bằng tài khoản thứ hai.

## 8. Lỗi thường gặp

### R2 trả 403 SignatureDoesNotMatch

- `Content-Type` lúc upload khác với lúc ký URL.
- Clock máy chủ sai rất nhiều.
- Account ID, Access Key hoặc Secret Key sai.
- Presigned URL đã hết hạn.

### Trình duyệt báo CORS

- Chưa thêm domain Vercel vào AllowedOrigins.
- Thiếu PUT trong AllowedMethods.
- Thiếu `ETag` trong ExposeHeaders; lỗi này thường xuất hiện ở multipart.
- Sau khi đổi CORS, tải lại trang hoặc chờ cache CORS hết hạn.

### API báo chưa đăng nhập

- Kiểm tra `NEXT_PUBLIC_SUPABASE_URL` và anon key.
- Xóa local storage/cookie của site rồi đăng nhập lại.
- Kiểm tra Site URL và Redirect URLs trong Supabase.

### Build Vercel lỗi biến môi trường

- Kiểm tra tên biến phải đúng từng ký tự.
- Không đặt dấu nháy quanh giá trị trên Vercel.
- Redeploy sau khi thêm/sửa biến.

### Upload hoàn tất nhưng báo sai kích thước

- Kiểm tra file có bị proxy/CDN trung gian can thiệp không.
- Đảm bảo upload trực tiếp đến URL `r2.cloudflarestorage.com`.
- Không cấu hình custom domain cho presigned upload.
