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