Listing_SuggestPrice/backend/README.md

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``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`).