# Charging Station Mock API (json-server) Mock server cho feature Charging Station theo tài liệu: - `docs/charging_station_final_spec.md` ## 1. Cài dependency ```bash cd mock/charging-station bun install ``` ## 2. Chạy server ```bash bun run start ``` Mặc định chạy ở `http://localhost:3100`. Có thể đổi port: ```bash PORT=3200 bun run start ``` ## 3. Static Files (Images) Server serve static files từ folder `public/`. Cấu trúc: ``` mock/charging-station/ ├── public/ │ └── images/ │ ├── banners/ # Ảnh banner (800x400 recommended) │ │ ├── banner_summer_sale.png │ │ ├── banner_cashback.png │ │ └── banner_new_year.png │ └── vouchers/ # Ảnh voucher (300x200 recommended) │ ├── starbucks.png │ ├── kfc.png │ ├── grab.png │ └── ... ├── db.json └── server.js ``` **Cách thêm ảnh mới:** 1. Đặt file ảnh vào `public/images/banners/` hoặc `public/images/vouchers/` 2. Cập nhật `imageUrl` trong `db.json` với path tương đối: `/images/banners/ten_file.png` 3. Server sẽ tự động build full URL: `http://localhost:3100/images/banners/ten_file.png` **Access trực tiếp:** ```bash # Xem ảnh trong browser open http://localhost:3100/images/banners/banner_summer_sale.png ``` ## 4. Endpoints Tất cả endpoint dùng `POST`: | Endpoint | Mô tả | |----------|-------| | `POST /charging-station/execute` | Thực thi giao dịch nạp tiền | | `POST /charging-station/getHomeData` | Lấy dữ liệu trang Home | | `POST /charging-station/search` | Tìm kiếm với AI gợi ý | | `POST /charging-station/reward/getList` | Danh sách ưu đãi/voucher | ## 5. Validation Rules ### `POST /charging-station/execute` **Input validation:** | Field | Rule | Regex | |-------|------|-------| | `accountNumber` | Bắt buộc, đúng **9 ký tự**, chỉ chứa số | `^[0-9]{9}$` | | `amount` | Bắt buộc, > 0, tối đa **1,000,000,000** | — | | `accountName` | Không bắt buộc, chỉ chữ cái và khoảng trắng | `^[a-zA-ZÀ-ỹ\s]*$` | **Error codes:** | Code | Điều kiện | Message | |------|-----------|---------| | `01` | Dữ liệu không hợp lệ / TK không tồn tại | Tùy context | | `02` | Số dư không đủ | "Số dư không đủ" | | `03` | Vượt hạn mức (> 1 tỷ) | "Số tiền tối đa là 1,000,000,000 VND" | **Simulate scenarios:** | Scenario | Cách test | |----------|-----------| | TK không tồn tại | `accountNumber` bắt đầu bằng `999` | | Số dư không đủ | `accountNumber` bắt đầu bằng `111` + `amount > 500000000` | | Vượt hạn mức | `amount > 1000000000` | ### `POST /charging-station/search` - `query` rỗng: trả full default data (recent + suggested + chips). - `query` có giá trị: filter `suggestions` theo `title/description`. ### `POST /charging-station/reward/getList` - Hỗ trợ `category` để filter voucher/brand. - Hỗ trợ `page` + `pageSize` để phân trang `vouchers`. - Trả thêm `paging` để client dễ test load more. ## 6. Curl samples ### Execute success ```bash curl -X POST http://localhost:3100/charging-station/execute \ -H "Content-Type: application/json" \ -d '{ "sessionId": "abc123", "deviceId": "device-001", "accountNumber": "012345678", "amount": "1000000", "accountName": "NGUYEN VAN A", "isDefaultAccount": true }' ``` ### Execute - TK không tồn tại ```bash curl -X POST http://localhost:3100/charging-station/execute \ -H "Content-Type: application/json" \ -d '{ "accountNumber": "999123456", "amount": "1000000" }' ``` ### Execute - Số dư không đủ ```bash curl -X POST http://localhost:3100/charging-station/execute \ -H "Content-Type: application/json" \ -d '{ "accountNumber": "111234567", "amount": "600000000" }' ``` ### Execute - Vượt hạn mức ```bash curl -X POST http://localhost:3100/charging-station/execute \ -H "Content-Type: application/json" \ -d '{ "accountNumber": "012345678", "amount": "1500000000" }' ``` ### Execute - accountNumber sai format ```bash curl -X POST http://localhost:3100/charging-station/execute \ -H "Content-Type: application/json" \ -d '{ "accountNumber": "12345", "amount": "1000000" }' ``` ### Execute - accountName có ký tự đặc biệt ```bash curl -X POST http://localhost:3100/charging-station/execute \ -H "Content-Type: application/json" \ -d '{ "accountNumber": "012345678", "amount": "1000000", "accountName": "Nguyen Van A@123" }' ``` ### Get Home Data ```bash curl -X POST http://localhost:3100/charging-station/getHomeData \ -H "Content-Type: application/json" \ -d '{"sessionId":"abc123","deviceId":"device-001"}' ``` **Response structure:** - `accounts[]` - Danh sách tài khoản cá nhân (DEFAULT, APPLE_PAY, OVERDRAFT, SALARY) - `businessAccounts[]` - Danh sách tài khoản hộ kinh doanh - `loyaltyPoints`, `cashbackAmount`, `memberLevel` - Thông tin loyalty - `recentTransactions[]` - Giao dịch gần đây ### Search default ```bash curl -X POST http://localhost:3100/charging-station/search \ -H "Content-Type: application/json" \ -d '{"sessionId":"abc123","query":"","page":1,"pageSize":20}' ``` ### Search with query ```bash curl -X POST http://localhost:3100/charging-station/search \ -H "Content-Type: application/json" \ -d '{"sessionId":"abc123","query":"chuyển tiền","page":1,"pageSize":20}' ``` ### Reward - page 1 (có banners) ```bash curl -X POST http://localhost:3100/charging-station/reward/getList \ -H "Content-Type: application/json" \ -d '{"sessionId":"abc123","page":1,"pageSize":5}' ``` **Response structure:** - `banners[]` - Danh sách banner (chỉ trả về ở page 1) - `vouchers[]` - Danh sách voucher (phân trang) - `paging` - Thông tin phân trang ### Reward - load more (page 2+, không có banners) ```bash curl -X POST http://localhost:3100/charging-station/reward/getList \ -H "Content-Type: application/json" \ -d '{"sessionId":"abc123","page":2,"pageSize":5}' ``` **Voucher fields:** - `imageUrl` - URL ảnh voucher - `content` - Nội dung/mô tả ưu đãi - `expiry` - Thời hạn (rỗng = không giới hạn) - `requireCardSpending` - `true` = yêu cầu chi tiêu thẻ --- ## 7. BASE_URL Configuration | Environment | BASE_URL | |-------------|----------| | Local | `http://localhost:3100` | | VPS Production | `https://api-mock.example.com` | > **TODO:** Cập nhật VPS Production URL sau khi deploy. --- ## 8. Deploy lên VPS với PM2 ### 8.1 Cài đặt môi trường trên VPS ```bash # 1. Cài Bun (JavaScript runtime) curl -fsSL https://bun.sh/install | bash source ~/.bashrc # 2. Cài Node.js (cần cho PM2) curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt-get install -y nodejs # 3. Cài PM2 globally sudo npm install -g pm2 # 4. Verify installations bun --version node --version pm2 --version ``` ### 8.2 Clone và setup project ```bash # Clone repo (hoặc copy folder mock/charging-station) cd /var/www git clone mbbank-mock cd mbbank-mock/mock/charging-station # Cài dependencies bun install ``` ### 8.3 Chạy với PM2 ```bash # Start server với PM2 pm2 start ecosystem.config.js --env production # Hoặc start trực tiếp pm2 start server.js --name "charging-station-mock" --interpreter bun # Xem logs pm2 logs charging-station-mock # Xem status pm2 status # Restart pm2 restart charging-station-mock # Stop pm2 stop charging-station-mock # Delete pm2 delete charging-station-mock ``` ### 8.4 Auto-start khi reboot VPS ```bash # Generate startup script pm2 startup # Save current process list pm2 save ``` ### 8.5 Cấu hình Nginx (reverse proxy) ```nginx # /etc/nginx/sites-available/charging-station-mock server { listen 80; server_name api-mock.example.com; location / { proxy_pass http://127.0.0.1:3100; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; } } ``` ```bash # Enable site sudo ln -s /etc/nginx/sites-available/charging-station-mock /etc/nginx/sites-enabled/ # Test config sudo nginx -t # Reload nginx sudo systemctl reload nginx ``` ### 8.6 Cài SSL với Certbot (HTTPS) ```bash # Cài Certbot sudo apt install certbot python3-certbot-nginx # Lấy SSL certificate sudo certbot --nginx -d api-mock.example.com # Auto-renew (đã tự động setup) sudo certbot renew --dry-run ``` ### 8.7 PM2 Commands Reference | Command | Mô tả | |---------|-------| | `pm2 start ecosystem.config.js` | Start với config file | | `pm2 start server.js --name app` | Start với tên custom | | `pm2 list` | Xem danh sách processes | | `pm2 logs [name]` | Xem logs | | `pm2 monit` | Monitor realtime | | `pm2 restart [name]` | Restart process | | `pm2 reload [name]` | Zero-downtime reload | | `pm2 stop [name]` | Stop process | | `pm2 delete [name]` | Xóa process | | `pm2 save` | Lưu process list | | `pm2 startup` | Setup auto-start | ### 8.8 Đổi Port ```bash # Cách 1: Environment variable PORT=3200 pm2 start server.js --name "charging-station-mock" --interpreter bun # Cách 2: Sửa ecosystem.config.js # env_production: { PORT: 3200 } pm2 start ecosystem.config.js --env production ``` --- ## 9. Troubleshooting ### PM2 không nhận Bun ```bash # Kiểm tra path của bun which bun # Output: /home/user/.bun/bin/bun # Sử dụng full path pm2 start server.js --interpreter /home/user/.bun/bin/bun ``` ### Port đã được sử dụng ```bash # Tìm process đang dùng port sudo lsof -i :3100 # Kill process sudo kill -9 ``` ### Logs quá lớn ```bash # Rotate logs pm2 install pm2-logrotate # Config logrotate pm2 set pm2-logrotate:max_size 10M pm2 set pm2-logrotate:retain 7 ```