Files
trade-assistant/AGENTS.md
T

174 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TradeMate (外贸小助手) — Agent Guide
## Chrome 浏览器扩展 🆕
- **目录**: `browser-extension/` — 完整 Chrome 插件
- **功能**: popup 面板调用 AI 翻译/回复/提取客户信息、网页右键菜单集成、自动填写报价单
- **兼容平台**: LinkedIn / Amazon / AliExpress 等外贸平台页面
- **安装**: 打开 `chrome://extensions` → 加载已解压的扩展 → 选择 `browser-extension/` 目录
- **API 客户端**: `browser-extension/api/client.js` — 封装后端 API 调用,支持 JWT 认证
## UX Design
- **PC 工作台**: 侧边栏 5 项精简导航 (首页/客户/业务/翻译/更多) + **CommandK 命令面板** (Ctrl+K)
- **移动端 H5**: 底部 4 Tab 导航 (首页/客户/业务/我的)
- **工作区合并**: Customers/Discovery/Followup → `WorkspaceCustomer`Translate/Products/Quotations/Marketing → `WorkspaceBiz`
- **路由**: 旧页面保留隐藏路由,保证兼容性
## uni-app 移动端 H5 (改版后)
- **Tab Bar**: 4 项底部导航 — 首页 / 客户 / 业务 / 我的
- **主页** `pages/index/index.vue` — 简化仪表盘 (统计卡片 + 快捷入口矩阵 + 待办提醒)
- **客户工作台** `pages/workspace-customer/workspace-customer.vue`**NEW** 3 个内联标签 (客户列表 / 挖掘新客 / 智能跟进)
- **业务工作台** `pages/workspace-biz/workspace-biz.vue`**NEW** 4 个内联标签 (翻译 / 产品库 / 报价单 / 营销素材)
- **个人中心** `pages/profile/profile.vue` — 更新导航 (通知中心 / 数据分析 / 团队 / 升级会员 / 联系客服)
- **旧页面保留** (customers, discovery, followup, translate, product, quotation, marketing 等仍可通过 deep link 访问)
- **pages.json** — 标签栏从 5 项变为 4 项,新增 workspace-customer 和 workspace-biz 页面
- **config.js** — PAGES 配置新增 WORKSPACE_CUSTOMER / WORKSPACE_BIZ
- **部署路径**: `trade.yuzhiran.com/app/` — nginx SPA fallback `try_files $uri $uri/ /app/index.html`
## 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
## AI 数字员工 (Agent Orchestrator) 🆕
- **Dashboard**: `user-frontend/src/views/Agent.vue` — 全功能仪表盘,位于 `/agent` 路由
- **编排服务**: `backend/app/services/agent_orchestrator.py``AgentOrchestrator`
- `start_pipeline(user_id, product_name, product_description, target_market)` — 启动完整流程
- `get_pipeline(pipeline_id, user_id)` — 获取流水线详情
- `list_pipelines(user_id, page, size)` — 分页列表
- **数据模型**: `backend/app/models/agent_pipeline.py``AgentPipeline` (表: `agent_pipelines`)
- JSONB `pipeline_data` 存储 stages + leads + summary
- **API 端点**: `backend/app/api/v1/agent.py` — 3 个端点
- `POST /api/v1/agent/start` — 启动新任务 (timeout: 300s)
- `GET /api/v1/agent/pipelines` — 任务列表
- `GET /api/v1/agent/{pipeline_id}` — 任务详情
- **流程**: 用户输入产品+市场 → AgentOrchestrator 串接 DiscoveryService.search() → analyze() → outreach() → 自动保存高匹配客户
- **前端入口**: `user-frontend/src/views/Agent.vue` 已接入路由 `/workspace/agent``UserLayout.vue` 侧边栏 "AI数字员工" (MagicStick 图标)`/agent` 重定向到 `/workspace/agent`
- **迁移**: 需要运行 `alembic revision --autogenerate -m "add agent_pipelines"` 创建 `agent_pipelines`
## 收费方式(免费试用 / 私有化部署 / 买断源码)
- **页面**: `user-frontend/src/views/Upgrade.vue` + `UpgradeModal.vue``uni-app/src/pages/upgrade/upgrade.vue`、浏览器插件升级入口均改为三种方案:免费试用 / 私有化部署(年付授权)/ 买断源码(一次性)
- **企业线索**: 私有化部署与买断源码的 CTA 提交到 `POST /api/v1/leads`(模型 `EnterpriseLead`,表 `enterprise_leads`),无需登录;admin 可在 `enterprise_leads` 表查看
- **价格占位**: `Upgrade.vue``PRICING` 对象(¥39,800/年、¥98,000 一次性)为可配置展示值
- **说明**: 旧的按月订阅套餐(`/credits/subscribe`)仍存在于后端,但前端不再主推;如彻底下线订阅需同步清理 `credits.py` 订阅逻辑
## 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 + DB-driven routing rules. Routing reads `ai_routing` from `system_configs` table.
- **Database**: PostgreSQL via `asyncpg`, pool_size=20
## AI Providers
- **Active (seeded by `seed_from_env()`)**: Sensenova (商汤, if `SENSENOVA_API_KEY` set), NVIDIA (if `NVIDIA_API_KEY` set), 阿里翻译 alibaba-mt (always inserted) — at most 3 rows. Do NOT assume 5 providers exist.
- **Removed**: Claude, DeepL, Local, OpencodeGo, 讯飞 Spark — provider implementations were git rm'd; don't re-add them.
- **DB-driven**: `AIProvider` model + `admin_ai.py` API — manage providers at runtime. `router.seed_from_env()` loads from `.env` on startup
- **ECS RAM role**: 阿里翻译使用 ECS 实例 RAM 角色 `trademate-translate` 获取 STS 临时凭证
- **Provider type mapping** in `router.py._build_provider()`: sensenova, nvidia, alibaba-mt
## Security
- **CORS**: `middleware.py` — whitelist origins, restricted methods/headers
- **Rate Limit**: endpoint-specific — login 5/min, register 3/h, password 3/5min, payment 20/min, admin 30/min
- **CSRF**: `core/csrf.py` — double-submit cookie pattern. Required on auth/payment/profile. Webhooks skipped.
- **Login**: JSON `LoginRequest` model, not `OAuth2PasswordRequestForm`
## Customer Discovery
- `discovery.py` + `discovery_record.py` — Google Custom Search integration
- Contact extraction from company websites (email/phone/WhatsApp/WeChat)
## Dev Commands
```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
# Admin frontend (PC management)
cd admin-frontend && npm run dev # port 5173, base: /admin/
# User workspace (PC workbench)
cd user-frontend && npm run dev # port 5174, base: /workspace/
# Tests (backend — needs PostgreSQL running with foreign_trade_test DB)
cd backend && venv/bin/pytest # all
venv/bin/pytest tests/test_auth_api.py # single file
venv/bin/pytest tests/ -k "test_login" # keyword filter
# pytest.ini: asyncio_mode=auto (no @pytest.mark.asyncio needed) and
# addopts adds --cov=app coverage automatically on every run.
# Builds
cd uni-app && npm run build:h5 # uni-app (mobile H5)
cd admin-frontend && npm run build # admin => /www/wwwroot/trade.yuzhiran.com/admin/
cd user-frontend && npm run build # workspace => /www/wwwroot/trade.yuzhiran.com/workspace/
# Alembic migrations
cd backend && alembic upgrade head
alembic revision --autogenerate -m "desc"
```
## Deployment
- **Landing page**: `trade.yuzhiran.com/` — static marketing HTML
- **SPA**: `trade.yuzhiran.com/app/` — uni-app build (mobile)
- **Admin**: `trade.yuzhiran.com/admin/` — Vue 3 + Element Plus (standalone)
- **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:8000`
- **Makefile `make deploy`** references `docker-compose.prod.yml` / `docker-compose.staging.yml`, which do **not** exist (only `docker-compose.yml` is present). Those targets are currently broken.
## Critical Quirks
- **Route ordering**: FastAPI matches top-down. Specific routes (`/{customer_id}/health`) must be registered **before** wildcard `/{customer_id}`.
- **AI `extract_info`**: Some models (e.g. deepseek-v4-flash) don't support `response_format={"type": "json_object"}`. `openai.py` catches the failure and retries without it.
- **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`.
- **Stripe**: `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET` in `.env`. `StripePaymentService` via Checkout Sessions. Selected when `pay_type` is `card`/`stripe`. Webhook `POST /api/v1/payment/stripe-webhook`.
- **PayPal**: `PAYPAL_CLIENT_ID`, `PAYPAL_CLIENT_SECRET`, `PAYPAL_WEBHOOK_ID`, `PAYPAL_SANDBOX=True` in `.env`. `PayPalPaymentService` via Orders v2 API. Selected when `pay_type` is `paypal`. Webhook `POST /api/v1/payment/paypal-webhook`.
- **Credit purchase**: `POST /api/v1/credits/stripe-purchase` with `gateway: "stripe"|"paypal"` for overseas payments (USD), returns `session_url` for redirect. Gateway-agnostic: `gateway` param selects the provider.
- **Agent Pipeline timeout**: `POST /api/v1/agent/start` may take 2-3 minutes to complete (it chains search → analyze → outreach synchronously). Frontend timeout set to 300s.
- **Agent auto-save**: High-scoring leads (>=70 match_score) are auto-saved as Customer records with `source='ai_agent:{pipeline_id}'`. Duplicate check by name+user_id.
- **Agent pipeline_data JSONB**: Contains stages progress, leads array (with outreach content), and summary stats. This is the source of truth for the frontend dashboard rendering.
## Project Conventions
- **Docs**: `README.md` (overview), `PROGRESS.md` (task status), `docs/` (API/schema/architecture). README references this file for dev norms.
- **Chinese UI** — mobile-first, for foreign-trade SOHOs/small teams
- **No comments in code** unless explicitly asked
- **Commit messages** focus on "why" not "what", in English
- **Services** instantiate `MarketingService()` (no db needed). For customer health: `CustomerHealthService(db)`. For agent: `AgentOrchestrator(db)`.
- **AI providers** in `backend/app/ai/providers/` — inherit from `OpenAIProvider` if compatible with OpenAI API format
- **Static assets** go in `uni-app/src/static/`
- **Test DB**: `foreign_trade_test` (uses credentials from `conftest.py`, not `.env`)
## Remember
- Write tests for new features
- Run `cd backend && venv/bin/pytest` before committing
- Keep context compact — avoid bloating the session with unnecessary file reads