Files
trade-assistant/AGENTS.md
T
TradeMate Dev 5d2bced39f docs: update project docs and clean up redundant files
- PROGRESS.md: update to 2026-05-29 with security hardening (T-005),
  4-frontend architecture, AI provider refactoring, discovery features,
  landing page/referral/quota, desktop layout, admin AI management
- AGENTS.md: add AI provider list (Alibaba/NVIDIA, removed Claude/DeepL/Local),
  DB-driven config, CSRF/rate-limit/CORS notes, admin_ai reload quirk
- .env.example: sync with actual config, replace deprecated providers
  with current Sensenova/OpencodeGo/NVIDIA/Spark/Alibaba
- docs/PROJECT_STATUS.md: archive (fully superseded by PROGRESS.md)
- Remove generated JS files (_bing_search.js, _batch_search.js)
- Remove empty directories (data/corpus, data/models)
- Remove backend/.coverage (test artifact)
- Fix services/.gitignore to cover _bing_search.js
- Include pending AI provider DB admin feature (admin_ai, AIProvider model,
  AIProviders.vue, migration) and T-008 test report
2026-05-29 11:15:33 +08:00

5.2 KiB

TradeMate (外贸小助手) — Agent Guide

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
  • 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
  • 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

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

# Backend (from project root — .env is there)
cd backend && source venv/bin/activate && uvicorn app.main:app --reload --port 8000

# 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

# 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:8002

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.

Project Conventions

  • No README.md — key context is in PROGRESS.md and docs/
  • 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)
  • 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