88 lines
3.7 KiB
Markdown
88 lines
3.7 KiB
Markdown
# SuggestPrice API (AdonisJS v6)
|
|
|
|
Backend thiết kế lại cho hệ thống SuggestPrice. Lõi: **service gợi ý giá** cập nhật giá cho cả sản phẩm **sync từ ERP** và sản phẩm **nhập tay / import Excel**.
|
|
|
|
## Stack
|
|
- **AdonisJS v6** (TypeScript) + **Lucid ORM** → **MySQL 8 / MariaDB**
|
|
- **BullMQ + Redis** cho job nền (chạy `web` và `worker` riêng)
|
|
- **VineJS** validate, **access tokens** cho auth (bearer)
|
|
- Engine giá: **rule-based** (mặc định) hoặc **OpenAI** (khi cấu hình)
|
|
|
|
## Cấu trúc
|
|
```
|
|
app/
|
|
controllers/ auth, products, imports, pricing, logs, histories
|
|
models/ user, product, log, history
|
|
services/ product, import, pricing, ai, erp, ebay, sync, log, history, queue
|
|
validators/ auth, product
|
|
middleware/ auth, container_bindings
|
|
commands/ queue:work (worker), make:user
|
|
config/ database(mysql), auth, redis(queue), cors, ...
|
|
database/migrations/ users, access_tokens, products, logs, histories
|
|
start/ routes, kernel, env
|
|
```
|
|
|
|
## Database (theo schema yêu cầu)
|
|
| Bảng | Cột chính |
|
|
|---|---|
|
|
| `users` | username, password (hash), + `auth_access_tokens` (token) |
|
|
| `products` | sku, condition, qty, price, ai_price, cost, package_contain, type, erp_id |
|
|
| `logs` | username, action_name, action, product_id, meta, time |
|
|
| `histories` | username, data_sources (JSON), data_ebay (JSON), ai_result, product_id, time |
|
|
|
|
> `erp_id != null` ⇒ sản phẩm sync; `erp_id == null` ⇒ manual/import.
|
|
|
|
## Cài đặt
|
|
```bash
|
|
cd backend-adonis
|
|
npm install
|
|
cp .env.example .env
|
|
node ace generate:key # sinh APP_KEY
|
|
# cập nhật DB_* và REDIS_* trong .env, tạo database 'suggestprice' (utf8mb4)
|
|
node ace migration:run
|
|
node ace make:user admin secret123
|
|
```
|
|
|
|
## Chạy (2 process)
|
|
```bash
|
|
# Terminal 1 — HTTP API (cổng 3333)
|
|
npm run dev
|
|
|
|
# Terminal 2 — worker xử lý queue (pricing batch / sync)
|
|
npm run worker
|
|
```
|
|
|
|
## API
|
|
Tất cả (trừ register/login) cần header `Authorization: Bearer <token>`.
|
|
|
|
| Method | Endpoint | Mô tả |
|
|
|---|---|---|
|
|
| POST | `/api/auth/register` | tạo user |
|
|
| POST | `/api/auth/login` | đăng nhập → token |
|
|
| GET | `/api/auth/me` | thông tin user |
|
|
| POST | `/api/auth/logout` | hủy token |
|
|
| GET | `/api/products` | danh sách (page, search, condition, type, origin) |
|
|
| POST | `/api/products` | tạo manual |
|
|
| GET | `/api/products/:id` | chi tiết |
|
|
| PATCH| `/api/products/:id` | sửa |
|
|
| DELETE | `/api/products/:id` | xóa |
|
|
| POST | `/api/imports/products` | import Excel (field `file`: sku, condition, qty, price) |
|
|
| POST | `/api/pricing/suggest/:id` | gợi ý giá 1 SP (on-demand) |
|
|
| POST | `/api/pricing/suggest/:id/approve` | duyệt & áp giá (khi vượt ngưỡng) |
|
|
| POST | `/api/pricing/batch` | gợi ý hàng loạt (qua queue), body `{ productIds? }` |
|
|
| GET | `/api/logs` | nhật ký thao tác |
|
|
| GET | `/api/histories` | lịch sử lấy dữ liệu AI |
|
|
| GET | `/api/histories/:id` | chi tiết history |
|
|
|
|
## Cơ chế gợi ý giá (hybrid)
|
|
1. Lấy `data_sources` (ERP) + `data_ebay` (sold/sale) → lưu `histories`.
|
|
2. Engine (rule/AI) ra `suggestedPrice` → ghi `ai_price`.
|
|
3. Chênh lệch ≤ `PRICING_AUTO_APPLY_THRESHOLD_PCT` (mặc định 5%) ⇒ **tự áp** `price`; vượt ⇒ chờ **approve**.
|
|
4. Mọi bước ghi `logs`.
|
|
|
|
Chế độ: **on-demand** (`/pricing/suggest/:id`) + **batch** (`/pricing/batch` → worker).
|
|
|
|
## Còn để mở (theo yêu cầu)
|
|
- **API sync** ERP: service `sync_service.ts` đã scaffold; chỉ cần hoàn thiện `fetchProductsFromErp()` + thêm route khi có endpoint thật.
|
|
- **eBay/OpenAI thật**: điền key trong `.env` (OpenAI: `OPENAI_API_KEY`; eBay: hoàn thiện `ebay_service.ts`).
|