Untitled

 avatar
unknown
plain_text
2 months ago
5.2 kB
15
Indexable
Mục tiêu:
- Xây dựng dự án backend bằng NestJS để cung cấp API thể thao cho nhiều môn.
- Quản lý gói dịch vụ (Plan), cấp API Key, giới hạn request, giới hạn competition, kiểm tra thời hạn thuê (1 tháng, ...).
- Kết nối đến DB football (chỉ có quyền read) để làm ví dụ 1 endpoint: "GET /football/competitions".
- Giới hạn IP theo API Key (mỗi key chỉ cho phép tối đa X IP, và có thể sửa danh sách IP).

Cụ thể:
1. **Cấu trúc thư mục**:
   - src/
     - modules/
       - auth/
       - users/
       - plans/
       - api-keys/
       - subscriptions/ (tách riêng subscription nếu muốn)
       - competitions/
       - sports/
       - football/ (module để demo đọc DB read-only)
     - common/
       - decorators/
       - guards/
       - interceptors/
       - filters/
       - utils/
   - config/
   - main.ts
   - ...

2. **Modules chi tiết**:
   ### Module Auth
   - Xác thực (JWT-based) cho user khi đăng nhập
   - Tạo/thu hồi Access Token
   - Xác thực qua API key cho client (APIKeyAuthGuard)

   ### Module Users
   - Bảng `User`: `id`, `email`, `password`, `role`
   - Endpoint CRUD cho admin
   - Service để quản lý user

   ### Module Plans
   - Bảng `Plan`: `id`, `name`, `maxRequestsPerDay`, `allowedCompetitions`
   - Admin CRUD
   - User được gán plan (qua subscription hoặc trực tiếp)

   ### Module Subscriptions (tùy chọn)
   - Bảng `Subscription`: `id`, `userId`, `planId`, `startDate`, `endDate`, `isActive`
   - Hoặc đơn giản lưu `expiresAt` trong `ApiKey`

   ### Module API-Keys
   - Bảng `ApiKey`: `id`, `key`, `userId`, `planId`, `isActive`, `expiresAt`
   - **Thêm** cột `allowedIPs` (danh sách IP) hoặc `maxIPCount` và thực tế lưu IP ở bảng khác
   - Tạo/thu hồi key
   - Endpoint để thêm/xoá IP trong danh sách allowed IP

   ### Module Competitions
   - Bảng `Competition`: `id`, `sportId`, `name`
   - Dùng cho `Plan` để giới hạn competition
   - Admin CRUD

   ### Module Sports
   - Bảng `Sport`: `id`, `name`, `code`
   - Kết nối competition

   ### Module Football (đọc DB read-only)
   - Kết nối tới DB football (chỉ read)
   - Ví dụ: Bảng `football_competitions`, `football_teams`, ...
   - Endpoint: `GET /football/competitions`
     - Trả về danh sách competitions từ DB read-only
     - Gọi service `FootballService` -> repository/entity (nếu dùng TypeORM read-only)

3. **Giới hạn request** (Rate limiting)
   - Redis (hoặc in-memory) để track requests
   - Kiểm tra guard -> `plan.maxRequestsPerDay`
   - Nếu vượt quá -> HTTP 429

4. **Giới hạn competition** theo gói
   - Khi gọi: ví dụ `GET /matches?competitionId=xxx`
   - Check `competitionId` có trong `plan.allowedCompetitions`?

5. **Thời hạn thuê (tháng, ...)**
   - Lưu `expiresAt` trong `ApiKey` HOẶC
   - Tạo `Subscription`: `endDate`
   - Guard kiểm tra còn hạn không

6. **Giới hạn IP theo key**
   - Bổ sung cột `allowedIPs: string[]` (hoặc quan hệ 1-n sang bảng con) trong `ApiKey`
     - `maxIPCount` => Số IP tối đa
     - Endpoint để user thêm IP -> Nếu chưa vượt `maxIPCount`, thì push
   - Guard: Lấy IP từ request (`request.ip`), kiểm tra có trong `allowedIPs` của key
   - Nếu không => HTTP 403

7. **Cấu hình DB Read-Only**:
   - Tạo một **connection** riêng (hoặc config read replica) cho module Football
   - Service `FootballService` chỉ thực hiện `SELECT`.
   - Ví dụ entity `FootballCompetition` -> Bảng `football_competitions`.
   - Endpoint `GET /football/competitions` -> gọi service -> trả data

8. **Yêu cầu code**:
   - **Entities** (hoặc Schemas) cho các bảng: User, Plan, ApiKey, Subscription (nếu có), Competition, Sport, FootballCompetition.
   - **Services** + **Controllers** cho từng module.
   - Guard `ApiKeyAuthGuard`:
     1. Kiểm tra API Key (`x-api-key`) có tồn tại, `isActive=true`.
     2. Check `expiresAt` (hoặc Subscription).
     3. Rate limit (`maxRequestsPerDay`).
     4. Kiểm tra IP `request.ip` có trong `allowedIPs`.
   - **Ví dụ** 1 endpoint `GET /football/competitions`.
     - Gọi DB read-only, trả về danh sách competitions.
   - Migrations (TypeORM hoặc Prisma).
   - Dockerfile, docker-compose (chạy NestJS, Redis, PostgreSQL).
   - Unit Test cơ bản.

9. **Hãy generate code**:
   - Tạo skeleton NestJS (cấu trúc module).
   - Tạo entity, service, controller, guard cho các tính năng trên.
   - Kết nối DB read-only cho module football.
   - Setup Docker, docker-compose.

Kết quả mong muốn:
- **Mã nguồn NestJS** có đủ module, entity, service, controller, guard.
- Quản lý user, plan, api-key, subscription (hoặc expiresAt).
- Demo endpoint đọc DB football (read-only).
- Giới hạn request, giới hạn competition, giới hạn IP, kiểm tra hạn.
- Có docker-compose (Redis, Postgres) để chạy dự án.

Hãy generate toàn bộ khung code để hệ thống hoạt động được.
Editor is loading...
Leave a Comment