SupportHub
为印度市场构建的多租户、人工智能原生客户支持平台。提供食品配送(第一阶段),作为白标B2B2C SaaS扩展到时尚、电子和杂货。
______________________________________________________________________
目录
______________________________________________________________________
1.工程概况
SupportHub暴露了四个表面区域:
| 表面 | 描述 |
|---|---|
| 客户门户 | 移动优先React PWA——OTP登录、工单创建、FAQ自助 |
| 代理仪表板 | 桌面优先React PWA——队列管理、人工智能辅助、实时更新 |
| 管理/运营门户 | 租户配置、代理管理、SLA规则、报告 |
| API+MCP层 | 通过Spring Cloud Gateway+Spring AI MCP服务器为聊天机器人代理提供REST API |
主要用户: 终端客户、客户服务代理、运营管理员、人工智能聊天机器人代理(通过MCP)。
______________________________________________________________________
2.主要特点
- 票证生命周期 --创建、分配、状态机(打开→ 进行中→ 解决→ 关闭)、重新打开、升级
- AI情绪分析 --人类学Claude Haiku实时对每张票的情绪进行分类(支持英语、印地语、印度式英语、泰米尔语、泰卢固语等)
- AI分辨率建议 --Claude Sonnet使用RAG对常见问题+分辨率模板中的前3个可能分辨率进行排名
- 语义FAQ搜索 --pg向量余弦相似度+Elasticsearch BM25混合搜索
- MCP服务器 --暴露
create_ticket,get_ticket,list_tickets,search_faq用于任何MCP兼容AI代理的SSE工具 - 多租户技术 --通过以下方式实现完全数据隔离
tenant_id+每个表上的PostgreSQL行级安全 - 实时 --STOMP over WebSocket用于代理仪表板上的实时工单更新
- 通知 -短信(MSG91),WhatsApp(Meta Business API),电子邮件(SendGrid),应用内
- 文件附件 --MinIO/AWS S3,带有15分钟预处理URL
- CQRS报告 --Kafka消费者将票证事件投影到Elasticsearch读取模型中
______________________________________________________________________
3.建筑
系统上下文
[Customer] [Agent] [Admin] [AI Chatbot]
│ │ │ │
└──────────────────┴──────────────────┴────────────────┘
│ HTTPS / WSS
┌─────────▼──────────┐
│ API Gateway :8080 │ ← JWT auth, tenant routing,
│ Spring Cloud GW │ rate limiting, circuit breaker
└─────────┬──────────┘
┌─────────────────┼─────────────────────┐
│ │ │
┌───────▼──────┐ ┌───────▼──────┐ ┌──────────▼──────┐
│ auth :8081 │ │ ticket :8082 │ │ customer :8083 │
│ ai :8084 │ │ notif :8085 │ │ faq :8086 │
│ report :8087 │ │ tenant :8088 │ │ orders :8089 │
│ mcp :8090 │ └──────────────┘ └─────────────────┘
└──────────────┘
│ Kafka (async events)
┌───────────┴──────────────────────────────────────────┐
│ PostgreSQL MongoDB Redis Elasticsearch MinIO │
└──────────────────────────────────────────────────────┘关键模式
| 模式 | 实施 |
|---|---|
| 多租户技术 | tenant_id 每张表+PostgreSQL RLS+ TenantContextHolder 从网关传播 |
| 每个服务的数据库 | 无跨服务数据库查询;每个服务都有自己的模式 |
| 事件驱动 | Kafka用于所有跨服务状态更改——从不同步REST用于副作用 |
| CQRS | reporting-service 从Kafka事件中维护Elasticsearch读取模型 |
| AI无阻塞 | 情绪和决心是异步运行的;如果人工智能出现故障,票务操作将继续 |
| 虚拟线程 | spring.threads.virtual.enabled=true 在所有服务上(Java 21 Project Loom) |
Kafka事件流
ticket-service ──► ticket.created ──► ai-service (sentiment)
──► notification-service (customer notif)
──► reporting-service (ES projection)
ai-service ──► sentiment.completed ──► ticket-service (update fields)
──► reporting-service (ES update)
ticket-service ──► ticket.status.changed ──► notification-service
──► reporting-service
tenant-service ──► tenant.onboarded ──► notification-service (welcome comms)______________________________________________________________________
4.存储库结构
supporthub/
├── run-local.sh ← single-command local runner
├── backend/ ← Java 21 + Spring Boot 3.3 (Maven multi-module)
│ ├── pom.xml ← parent POM
│ ├── shared/ ← shared DTOs, events, exceptions, security
│ ├── api-gateway/ ← Spring Cloud Gateway — port 8080
│ ├── auth-service/ ← OTP + agent login, JWT — port 8081
│ ├── ticket-service/ ← ticket CRUD, SLA, WebSocket — port 8082
│ ├── customer-service/ ← customer profiles, addresses — port 8083
│ ├── ai-service/ ← sentiment + resolution via Anthropic — port 8084
│ ├── notification-service/ ← SMS / WhatsApp / Email / in-app — port 8085
│ ├── faq-service/ ← FAQ CRUD, pgvector search, Strapi sync — port 8086
│ ├── reporting-service/ ← Elasticsearch CQRS, CSV export — port 8087
│ ├── tenant-service/ ← tenant onboarding, config — port 8088
│ ├── order-sync-service/ ← OMS proxy, Redis order cache — port 8089
│ └── mcp-server/ ← Spring AI MCP tools over SSE — port 8090
│
├── frontend/ ← npm workspaces (Node 20)
│ ├── apps/
│ │ ├── customer-portal/ ← React 18 + Vite — port 3000
│ │ ├── agent-dashboard/ ← React 18 + Vite — port 3001
│ │ └── admin-portal/ ← React 18 + Vite — port 3002
│ └── packages/
│ ├── customer-sdk/ ← headless TypeScript SDK (@supporthub/customer-sdk)
│ └── ui-components/ ← shared shadcn/ui + Tailwind component library
│
├── infrastructure/
│ ├── docker/
│ │ ├── docker-compose.yml ← infra stack (Postgres, Mongo, Redis, Kafka, ES, MinIO, Strapi)
│ │ ├── docker-compose.services.yml ← all 11 services + 3 frontend apps
│ │ ├── .env.example ← copy to .env and fill secrets
│ │ ├── nginx/spa.conf ← nginx SPA config for frontend containers
│ │ ├── Dockerfile.template ← multi-stage Java build template
│ │ └── init-db/ ← PostgreSQL init scripts (pgvector extension)
│ ├── k8s/ ← Kubernetes Kustomize manifests
│ └── terraform/ ← AWS infrastructure (EKS, RDS, ElastiCache, MSK)
│
└── .github/workflows/
├── ci.yml ← PR validation (test, lint, build, OWASP scan)
├── deploy-staging.yml
└── deploy-prod.yml后端服务布局(每项服务)
{service}/src/main/java/in/supporthub/{service}/
├── {Service}Application.java
├── config/ ← Spring configs (Security, Kafka, Redis, etc.)
├── controller/ ← REST controllers (validate + delegate only)
├── service/ ← Business logic (@Transactional)
├── repository/ ← Spring Data interfaces (data access only)
├── domain/ ← JPA entities, enums (no service deps)
├── dto/ ← Java Records (request/response/event)
├── event/ ← Kafka producers + consumers
└── exception/ ← Typed exceptions extending AppException______________________________________________________________________
5.技术栈
后端
| 层 | 技术 |
|---|---|
| 语言 | Java 21(虚拟线程、记录、模式匹配) |
| 框架 | Spring Boot 3.3、Spring Cloud 2023.0 |
| API网关 | Spring Cloud网关(JWT、租户路由、速率限制、断路器) |
| AI | 春天AI——人物克劳德·海库(情感),克劳德·十四行诗(决议) |
| MCP | spring ai starter MCP服务器webmvc(SSE传输) |
| ORM | Spring数据JPA+Hibernate,Spring数据MongoDB |
| 迁徙 | Flyway |
| 消息传递 | Apache Kafka(Confluent) |
| 安全 | Spring Security、JJWT、RSA密钥对JWT |
| 可观测性 | 千分尺+普罗米修斯+开放遥测技术+Langfuse(LLM轨迹) |
| 构建 | Maven包装器(./mvnw) |
前端
| 层 | 技术 |
|---|---|
| 语言 | TypeScript(严格模式) |
| 框架 | React 18+Vite |
| 服务器状态 | TanStack查询 |
| 全球状态 | 状态 |
| 表单 | React钩子表单 |
| UI组件 | shadcn/UI+顺风CSS |
| 实时 | 基于WebSocket的STOMP(代理仪表板) |
| 测试 | Vitest+测试库 |
| E2E | 剧作家 |
数据存储
| 存储 | 版本 | 使用人 |
|---|---|---|
| PostgreSQL+pgvector | 16 | 身份验证、票证、客户、租户、订单同步、faq(嵌入) |
| MongoDB | 7 | ai服务(交互日志)、通知服务(历史)、faq服务(文档) |
| Redis | 7 | 所有服务——缓存、会话、速率限制、幂等性 |
| Elasticsearch | 8 | 报告服务(CQRS读取模型、全文搜索) |
| Apache Kafka | 7.6(Confluent) | 所有服务——异步事件总线 |
| MinIO/AWS S3 | 最新 | 票务服务——文件附件 |
基础设施
| 组件 | 开发 | 生产 |
|---|---|---|
| 容器运行时 | Docker Compose | Kubernetes(EKS)+Helm |
| IaC | -- | 地形图(AWS) |
| 数据库 | Docker | AWS RDS PostgreSQL多AZ |
| 缓存 | Docker | AWS ElastiCache Redis |
| 消息传递 | Docker | AWS MSK(托管Kafka) |
| 搜索 | Docker | AWS OpenSearch |
| 存储 | MinIO(Docker) | AWS S3+CloudFront |
| CMS | Docker(节点) | ECS Fargate |
| 注册表 | 本地 | AWS ECR |
______________________________________________________________________
6.本地设置
先决条件
| 工具 | 最低版本 |
|---|---|
| Docker桌面版(或Docker引擎+Compose v2) | Docker 24+,Compose v2 |
| Java(推荐使用Eclipse Temurin) | 21 |
| Node.js | 18(推荐20个) |
| Git | 任何最近 |
一个命令启动
git clone
cd supporthub
# First run: copies .env.example → infrastructure/docker/.env
# Builds all JARs + frontend, starts every service
./run-local.sh就是这样。脚本按顺序处理所有内容:
- 检查先决条件
- 副本
.env.example→infrastructure/docker/.env首次运行 - 构建所有11个Spring Boot JAR(
./mvnw clean package -DskipTests) - 构建所有3个前端应用程序(
npm run build --workspaces) - 启动基础架构堆栈(Postgres、Mongo、Redis、Kafka、Elasticsearch、MinIO、Strapi)
- 等待每个infracontainer通过其健康检查
- 启动所有11个微服务+3个nginx服务的前端应用程序
- 对每项服务进行投票
/actuator/health直到健康 - 打印访问URL表
有用的标志
./run-local.sh --skip-build # restart without rebuilding (fast after first run)
./run-local.sh --infra-only # start only Postgres/Mongo/Redis/Kafka/ES/MinIO
./run-local.sh --down # stop and remove all containers访问URL(启动后)
| 服务 | URL |
|---|---|
| 客户门户 | http://localhost:3000 |
| 代理仪表板 | http://localhost:3001 |
| 管理门户 | http://localhost:3002 |
| API网关 | http://localhost:8080 |
| 身份验证服务Swagger | http://localhost:8081/swagger-ui.html |
| 票务服务Swagger | http://localhost:8082/swagger-ui.html |
| MinIO控制台 | http://localhost:9001(用户: minioadmin /通过: minioadmin) |
| 斯特拉皮CMS | http://localhost:1337/admin |
| Elasticsearch | http://localhost:9200 |
首次配置
设置您的Anthropic API键 (AI功能需要):
# Edit the generated .env file
nano infrastructure/docker/.env
# Set this line:
ANTHROPIC_API_KEY=sk-ant-your-real-key-here在设置密钥之前,AI功能(情绪分析、解决方案建议)将显示“分析待定”。所有其他票务操作都可以在没有它的情况下工作。
创建租户 (购票前必须填写):
curl -X POST http://localhost:8080/api/v1/tenants \
-H "Content-Type: application/json" \
-d '{"name":"Demo Store","slug":"demo","planType":"TRIAL"}'在本地运行服务(不使用Docker)
使用 --infra-only 只启动后备存储,然后本机运行服务:
./run-local.sh --infra-only
# Backend (from /backend)
./mvnw spring-boot:run -pl auth-service -Dspring.profiles.active=dev
./mvnw spring-boot:run -pl ticket-service -Dspring.profiles.active=dev
# ... repeat per service
# Frontend (from /frontend)
npm run dev -w apps/customer-portal # http://localhost:3000
npm run dev -w apps/agent-dashboard # http://localhost:3001
npm run dev -w apps/admin-portal # http://localhost:3002______________________________________________________________________
7.开发命令
后端
cd backend
./mvnw clean package -DskipTests # build all services
./mvnw clean package -pl ticket-service -DskipTests # build one service
./mvnw test -pl ticket-service # unit tests
./mvnw verify -pl ticket-service # integration tests (needs Docker)
./mvnw test -pl ticket-service -Dtest=TicketServiceTest # single test class
./mvnw checkstyle:check spotbugs:check pmd:check -P analysis # static analysis
./mvnw dependency-check:check -pl ticket-service # OWASP CVE scan前端
cd frontend
npm ci # install all workspace dependencies
npm run build --workspaces # build all apps + packages
npm run test --workspaces # run all Vitest tests
npm run lint --workspaces # ESLint all packages
npm run typecheck --workspaces # TypeScript strict check
npm run dev -w apps/customer-portal # dev server on :3000
npm run dev -w apps/agent-dashboard # dev server on :3001
npm run dev -w apps/admin-portal # dev server on :3002E2E测试(剧作家)
# Requires all services running (./run-local.sh first)
cd frontend
npx playwright test
npx playwright test --ui # interactive UI modeDocker编写(手册)
# Infrastructure only
docker compose -f infrastructure/docker/docker-compose.yml \
--env-file infrastructure/docker/.env up -d
# All services + frontend
docker compose -f infrastructure/docker/docker-compose.services.yml \
--env-file infrastructure/docker/.env up -d
# View logs
docker logs -f supporthub-api-gateway
docker logs -f supporthub-ticket-service
# Stop everything
docker compose -f infrastructure/docker/docker-compose.services.yml down
docker compose -f infrastructure/docker/docker-compose.yml down______________________________________________________________________
8.生产设置
基础设施配置(Terraform)
cd infrastructure/terraform
# Initialise
terraform init
# Plan (review changes before applying)
terraform plan -var-file=environments/prod.tfvars
# Apply
terraform apply -var-file=environments/prod.tfvars地形规定:EKS集群、RDS PostgreSQL Multi-AZ、ElastiCache Redis、MSK Kafka、OpenSearch、S3 bucket、ECR存储库、VPC、ALB、IAM角色。
容器图像
通过CI/CD构建并推送到ECR(在合并到ECR时触发 main).要手动构建,请执行以下操作:
# Authenticate to ECR
aws ecr get-login-password --region ap-south-1 | \
docker login --username AWS --password-stdin .dkr.ecr.ap-south-1.amazonaws.com
# Build a service image
docker build \
-f infrastructure/docker/Dockerfile.template \
--build-arg SERVICE=ticket-service \
-t .dkr.ecr.ap-south-1.amazonaws.com/supporthub/ticket-service:v1.0.0 \
backend/
docker push .dkr.ecr.ap-south-1.amazonaws.com/supporthub/ticket-service:v1.0.0Kubernetes部署
# Apply base manifests
kubectl apply -k infrastructure/k8s/base/
# Apply environment overlay
kubectl apply -k infrastructure/k8s/overlays/prod/
# Verify rollout
kubectl rollout status deployment/ticket-service -n supporthub
kubectl get pods -n supporthub展开命令
始终遵循以下顺序以避免迁移/依赖失败:
1. Infrastructure (RDS, Redis, Kafka, ES) — must be healthy
2. DB migrations — Flyway runs automatically on service startup
3. tenant-service — must be up before any authenticated requests
4. auth-service — must be up before api-gateway validates JWTs
5. Core services — ticket, customer, faq, notification, reporting (parallel)
6. ai-service — can be delayed; ticket ops work without it
7. mcp-server — can be delayed; chatbot integrations work without it
8. api-gateway — last; routes to all services above
9. Frontend apps — after gateway is healthy秘密管理
所有秘密都存储在 AWS Secrets Manager服务在启动时通过以下方式加载它们 spring-cloud-aws-secrets-manager切勿将秘密储存于 application.yml 或Kubernetes清单。
每个服务所需的秘密(例如 ticket-service):
/supporthub/prod/ticket-service/db-password
/supporthub/prod/ticket-service/redis-password
/supporthub/prod/shared/jwt-public-key健康检查
每项服务都暴露 /actuator/health (弹簧防尘套执行器)。Kubernetes活性和就绪性探测器配置在 infrastructure/k8s/base/{service}/deployment.yaml.
# Check gateway health
curl http://localhost:8080/actuator/health
# Check all pods
kubectl get pods -n supporthub
# Tail logs for a service
kubectl logs -f deployment/ticket-service -n supporthub生产环境变量
与开发默认值不同的关键变量:
| 变量 | 开发默认值 | 生产 |
|---|---|---|
DB_URL | jdbc:postgresql://postgres:5432/supporthub | RDS端点 |
REDIS_HOST | redis | 弹性终点 |
KAFKA_SERVERS | kafka:29092 | MSK引导服务器 |
ELASTICSEARCH_URL | http://elasticsearch:9200 | OpenSearch端点 |
AWS_S3_ENDPOINT | http://minio:9000 | *(删除--使用真正的S3)* |
SPRING_PROFILES_ACTIVE | dev | prod |
ANTHROPIC_API_KEY | *(在.env中设置)* | AWS机密管理器 |
______________________________________________________________________
9.CI/CD管道
每次pull请求 develop 或 main 并行运行整个管道:
PR / Push
│
├── backend-unit-tests (./mvnw test)
│ │
│ └── backend-integration-tests (./mvnw verify, Testcontainers)
│
├── backend-security-scan (OWASP Dependency Check — fails on CVSS ≥ 8)
├── backend-code-analysis (Checkstyle + SpotBugs + PMD)
│
└── frontend-build-test (typecheck + lint + vitest + build)
│
└── build-images (Docker build → ECR push, on develop/tags only)
│
└── deploy-staging (Kubernetes rolling update)
│
└── deploy-prod (manual approval gate)工作流文件: .github/workflows/ci.yml, deploy-staging.yml, deploy-prod.yml
______________________________________________________________________
10.环境变量
完整参考资料见 infrastructure/docker/.env.example.关键变量:
# ── PostgreSQL ──────────────────────────────────────
POSTGRES_USER=supporthub
POSTGRES_PASSWORD=supporthub_dev_password
DB_URL=jdbc:postgresql://localhost:5432/supporthub
# ── MongoDB ─────────────────────────────────────────
MONGODB_URI=mongodb://supporthub:supporthub_dev_password@localhost:27017/supporthub?authSource=admin
# ── Redis ───────────────────────────────────────────
REDIS_HOST=localhost
REDIS_PASSWORD=supporthub_dev_password
# ── Kafka ───────────────────────────────────────────
KAFKA_SERVERS=localhost:9092
# ── Elasticsearch ───────────────────────────────────
ELASTICSEARCH_URI=http://localhost:9200
# ── MinIO / S3 ──────────────────────────────────────
AWS_S3_ENDPOINT=http://localhost:9000 # remove in prod (uses real S3)
AWS_S3_BUCKET=supporthub-dev
AWS_ACCESS_KEY_ID=minioadmin
AWS_SECRET_ACCESS_KEY=minioadmin
# ── AI (required for sentiment + resolution) ────────
ANTHROPIC_API_KEY=sk-ant-REPLACE_ME
ANTHROPIC_SENTIMENT_MODEL=claude-haiku-4-5-20251001
ANTHROPIC_RESOLUTION_MODEL=claude-sonnet-4-5
# ── Notifications (optional in dev) ─────────────────
MSG91_API_KEY=
SENDGRID_API_KEY=
WHATSAPP_ACCESS_TOKEN=
# ── Observability (optional) ────────────────────────
LANGFUSE_PUBLIC_KEY=
LANGFUSE_SECRET_KEY=运行前复制和编辑:
cp infrastructure/docker/.env.example infrastructure/docker/.env