chore: post-deployment cleanup and docs update
- Make AI routing rules DB-driven (read from system_configs, removed from config.py) - Add translation quota tracking to LLM translation (OpenAIProvider) - Add Alibaba MT ECS RAM role support (STS token, no AccessKey needed) - Fix admin sidebar link for AI模型配置 page - Fix Quota.vue API path (quotas → translation-quotas) - Fix login auto-redirect to dashboard - Add provider dropdown selects to AI routing config UI - Clean up stale ai_provider_* system_configs records - Remove OpencodeGo, Spark providers (code + DB) - Update deploy config: nginx port 8000, systemd cwd
This commit is contained in:
@@ -1,20 +1,31 @@
|
||||
# TradeMate (外贸小助手) — Agent Guide
|
||||
|
||||
## AI Assistant (Frontend AI Chatbot)
|
||||
|
||||
- **Components**: `user-frontend/src/components/AiAssistant.vue` + `admin-frontend/src/components/AiAssistant.vue`
|
||||
- **Backend**: `backend/app/api/v1/ai_assistant.py` — `POST /api/v1/ai/chat`, `GET /api/v1/ai/quick-questions`
|
||||
- **Action types** (configurable via `ACTION_INSTRUCTIONS`): create_customer, create_product, create_quotation, scan_followups, generate_marketing, discovery_search, navigate, search_users, update_user, update_config, review_certification, process_invoice
|
||||
- **Frontend action dispatch**: `AiAssistant.vue` switch/case calls corresponding API from `@/api`
|
||||
- **Layout integration**: `<AiAssistant />` in `UserLayout.vue` + `AdminLayout.vue`, floating button bottom-right
|
||||
- **Quick questions**: configurable via `ai_assistant_quick_questions` `SystemConfig` key
|
||||
- **System prompt**: configurable via `ai_assistant_prompt` `SystemConfig` key
|
||||
|
||||
## Architecture
|
||||
|
||||
- **Backend**: `backend/` — FastAPI + SQLAlchemy 1.4 async + asyncpg, single `app.main:app`
|
||||
- **Frontends**: `uni-app/` (mobile H5/mini-program), `admin-frontend/` (PC admin), `user-frontend/` (PC workspace)
|
||||
- **Config**: `backend/app/config.py` reads from `/.env` (project root) via pydantic BaseSettings
|
||||
- **Auth**: JWT (python-jose). Default dep `get_current_user_id` in `backend/app/api/v1/deps.py`
|
||||
- **AI Router**: `backend/app/ai/router.py` — singleton `AIRouter`, DB-driven providers. Primary = sensenova, fallbacks = alibaba-mt / opencode_go / nvidia / spark
|
||||
- **AI Router**: `backend/app/ai/router.py` — singleton `AIRouter`, DB-driven providers + DB-driven routing rules. Routing reads `ai_routing` from `system_configs` table.
|
||||
- **Database**: PostgreSQL via `asyncpg`, pool_size=20
|
||||
|
||||
## AI Providers
|
||||
|
||||
- **Active**: Sensenova (商汤), OpencodeGo, NVIDIA, 讯飞 Spark, 阿里机器翻译 (alibaba-mt)
|
||||
- **Removed (dead code)**: Claude (`claude.py`), DeepL (`deepl.py`), Local (`local.py`) — git rm'd, not yet committed
|
||||
- **Active**: Sensenova (商汤), NVIDIA, 阿里机器翻译 (alibaba-mt) — 5 providers in DB
|
||||
- **Removed**: Claude, DeepL, Local, OpencodeGo, 讯飞 Spark — all git rm'd
|
||||
- **DB-driven**: `AIProvider` model + `admin_ai.py` API — manage providers at runtime. `router.seed_from_env()` loads from `.env` on startup
|
||||
- **Provider type mapping** in `router.py._build_provider()`: sensenova, opencode_go, nvidia, spark, alibaba-mt
|
||||
- **ECS RAM role**: 阿里翻译使用 ECS 实例 RAM 角色 `trademate-translate` 获取 STS 临时凭证
|
||||
- **Provider type mapping** in `router.py._build_provider()`: sensenova, nvidia, alibaba-mt
|
||||
|
||||
## Security
|
||||
|
||||
@@ -32,7 +43,10 @@
|
||||
|
||||
```bash
|
||||
# Backend (from project root — .env is there)
|
||||
# Dev: matches Vite proxy (both frontends proxy /api → localhost:8000)
|
||||
cd backend && source venv/bin/activate && uvicorn app.main:app --reload --port 8000
|
||||
# Production: nginx proxies /api/ → localhost:8002
|
||||
cd backend && source venv/bin/activate && uvicorn app.main:app --port 8002
|
||||
|
||||
# Mobile H5
|
||||
cd uni-app && npm run dev:h5
|
||||
@@ -66,7 +80,7 @@ alembic revision --autogenerate -m "desc"
|
||||
- **Workspace**: `trade.yuzhiran.com/workspace/` — Vue 3 + Element Plus (standalone)
|
||||
- **Nginx**: SPA fallbacks for `/app/`, `/admin/`, `/workspace/`
|
||||
- **vite config**: each project has its own `base` path and dev port
|
||||
- **API**: proxied via nginx `location /api/` to `127.0.0.1:8002`
|
||||
- **API**: proxied via nginx `location /api/` to `127.0.0.1:8000`
|
||||
|
||||
## Critical Quirks
|
||||
|
||||
@@ -80,6 +94,14 @@ alembic revision --autogenerate -m "desc"
|
||||
- **AI Router reload**: After modifying AI providers via admin API, call `POST /api/v1/admin/ai/reload` to refresh in-memory providers.
|
||||
- **Payment**: Uses unified `pay-api` gateway (`UnifiedPayService`). NOT direct WeChat/Alipay integration. Credentials: `PAY_API_KEY`/`PAY_API_SECRET` from `.env`. HMAC-SHA256 auth. Webhook at `POST /api/v1/payment/webhook` skips CSRF.
|
||||
- **Payment gateway config**: `PAY_API_KEY`, `PAY_API_SECRET`, `PAY_API_BASE_URL`, `PAY_WEBHOOK_URL` in `config.py`. `pay_type` param: `"alipay"` (returns `pay_url`) or `"wechat"` (returns `code_url`). `UnifiedPayService` normalizes legacy `native`/`jsapi`/`pc` to `wechat`/`alipay`.
|
||||
- **Manual auth on some endpoints**: `keywords` and `competitor-analysis` endpoints use `authorization: str = Header(None)` instead of `Depends(get_current_user_id)`.
|
||||
- **MarketingService fallback**: When no AI providers initialized, returns template content instead of crashing.
|
||||
- **Onboarding service**: calls `mkt.generate(product_info={"name": ..., ...})`, not keyword args. Check `onboarding.py` for the exact dict shape.
|
||||
- **CustomerHealthService**: `get_health_overview` endpoint must use `CustomerHealthService(db)` not `CustomerService(db)`.
|
||||
- **CSRF**: Sensitive endpoints (auth/payment/profile) require `X-CSRF-Token` header. Token available via `csrf_token` cookie / `X-CSRF-Token` response header.
|
||||
- **AI Router reload**: After modifying AI providers via admin API, call `POST /api/v1/admin/ai/reload` to refresh in-memory providers.
|
||||
- **Payment**: Uses unified `pay-api` gateway (`UnifiedPayService`). NOT direct WeChat/Alipay integration. Credentials: `PAY_API_KEY`/`PAY_API_SECRET` from `.env`. HMAC-SHA256 auth. Webhook at `POST /api/v1/payment/webhook` skips CSRF.
|
||||
- **Payment gateway config**: `PAY_API_KEY`, `PAY_API_SECRET`, `PAY_API_BASE_URL`, `PAY_WEBHOOK_URL` in `config.py`. `pay_type` param: `"alipay"` (returns `pay_url`) or `"wechat"` (returns `code_url`). `UnifiedPayService` normalizes legacy `native`/`jsapi`/`pc` to `wechat`/`alipay`.
|
||||
|
||||
## Project Conventions
|
||||
|
||||
|
||||
Reference in New Issue
Block a user