# Checklist deploy — public beta surface (web)

Tài liệu này mô tả cách bật **gating beta** trên app Next.js trong `web/`: chỉ mở một phần tuyến công khai; tuyến chưa sẵn sàng chuyển tới `/beta-coming-soon` trừ khi có cookie staff.

## Biến môi trường (bắt buộc / khuyến nghị)

| Biến | Phạm vi | Mô tả |
|------|---------|--------|
| `NEXT_PUBLIC_BETA_PUBLIC_SURFACE` | `NEXT_PUBLIC_*` (embed lúc build) | Đặt `1` hoặc `true` để **bật** gating. Bỏ trống / `0` = tắt (toàn bộ route như dev). |
| `BETA_PUBLIC_SURFACE` | Chỉ server (không `NEXT_PUBLIC_`) | Tuỳ chọn nhưng **khuyến nghị** trùng `1` khi bật beta: **`web/src/proxy.ts`** đọc biến này ở runtime để tránh Edge / bundle không thấy `NEXT_PUBLIC_*` đúng lúc. Client/nav vẫn dùng `NEXT_PUBLIC_BETA_PUBLIC_SURFACE`. |
| `BETA_STAFF_BYPASS_SECRET` | Chỉ server | Mật khẩu đặt cookie `ctkp_beta_staff` qua `POST /api/internal/beta-visibility/gate` và trang `/internal/beta-staff/login`. **Không** commit giá trị thật. |
| `SOFT_LAUNCH_ADMIN_SECRET` | Chỉ server | (Tuỳ chọn) Nếu dùng soft launch: cùng secret với backend; cookie `ctkp_sl_adm` cũng được proxy coi là bypass. |
| `NEXT_PUBLIC_API_BASE_URL` | Client + server | URL gốc backend (không dấu `/` cuối) — bài viết, gieo quẻ, lá số gọi API. |
| `NEXT_PUBLIC_SITE_URL` | Tuỳ chọn | Gốc site công khai cho JSON-LD / SEO. |

Chi tiết mẫu: xem `web/.env.example`.

**Smoke production & env:** [beta-production-smoke-test.md](./beta-production-smoke-test.md).  
**Smoke đăng nhập web + OTP + gate:** [beta-auth-smoke-test.md](./beta-auth-smoke-test.md).  
Kiểm tra env nhanh (không fail CI): `npm run check:beta-env`.

**Smoke Playwright beta bật:** `npm run test:e2e:beta` (config `playwright.beta.config.ts`, port 3011). Xem [beta-production-smoke-test.md](./beta-production-smoke-test.md#8-e2e--playwright).

Bước này xác nhận **proxy runtime** tại `web/src/proxy.ts` (redirect `/about`, …) dùng đúng env từ app `web/` — kết hợp `turbopack.root` + file **`web/.env.local`** khi chạy local (Vitest không thay được bước này). **Lưu ý:** không dùng shim `web/proxy.ts` re-export — dễ timeout webServer; nếu đổi layout gate, xóa **`web/.next/dev`** (script E2E làm tự động) hoặc cả **`web/.next`** thủ công rồi chạy lại dev. Trên Windows nếu cổng bận: `taskkill /PID <pid> /F`.

## Tuyến công khai khi beta bật

- `/` — trang chủ  
- `/posts`, `/posts/[slug]` — sổ bài  
- `/categories`, `/categories/[slug]` — theo mục  
- `/gieo-que` — gieo quẻ X:Y  
- `/fortune`, `/fortune/result`, `/fortune/history` — gieo ba tiền + kết quả + nhật ký local  
- `/tu-vi`, `/tu-vi/ket-qua`, `/tu-vi/da-luu` — lá số  
- `/beta-coming-soon` — thông báo “đang hoàn thiện”  
- `/internal/beta-staff/login`, `/internal/soft-launch/login` — đăng nhập nội bộ (cookie)  
- Mọi `/api/*` — không chặn ở proxy (tránh cắt API nội bộ sau này)

Danh sách trong code: `BETA_PUBLIC_PATH_PREFIXES` trong `web/src/lib/betaVisibility.ts` và logic `resolveBetaPublicSurfaceGate` trong `web/src/lib/beta-middleware-logic.ts`.

## Staff / QA — xem tuyến ẩn

1. Cấu hình `BETA_STAFF_BYPASS_SECRET` trên server chạy Next.  
2. Mở `/internal/beta-staff/login`, nhập secret → cookie HTTP-only.  
3. Truy cập lại các route như `/about`, `/contact`, `/birth-time-reconstruction`, `/internal/soft-launch/...`.

Hoặc dùng cookie soft-launch admin nếu đã cấu hình `SOFT_LAUNCH_ADMIN_SECRET` và đăng nhập `/internal/soft-launch/login`.

## Kiểm tra trước khi deploy

```bash
npm run check:beta-env
npm run lint
npm run test
npm run build
npm run test:e2e:beta
```

Trong thư mục `cms/` (nếu deploy CMS):

```bash
npm run lint
npm run build
```

## Việc còn lại (ngoài phạm vi gating)

- Xác minh backend production (`DATABASE_URL`, CORS, HTTPS).  
- CDN / cache cho static `web`.  
- Giám sát lỗi và log sau go-live.  
- Nội dung CMS (bài viết xuất bản) đã kiểm duyệt.

## Ghi chú

- Gating **không** thay thế đăng nhập người dùng cuối (USER) — chỉ ẩn tuyến web và bypass cho vận hành.  
- Mật khẩu staff phải mạnh và xoay định kỳ; coi như credential nội bộ.
