Files
AIclinicalresearch/backend/src/common/README.md
HaHafeng 88cc049fb3 feat(asl): Complete Day 5 - Fulltext Screening Backend API Development
- Implement 5 core API endpoints (create task, get progress, get results, update decision, export Excel)
- Add FulltextScreeningController with Zod validation (652 lines)
- Implement ExcelExporter service with 4-sheet report generation (352 lines)
- Register routes under /api/v1/asl/fulltext-screening
- Create 31 REST Client test cases
- Add automated integration test script
- Fix PDF extraction fallback mechanism in LLM12FieldsService
- Update API design documentation to v3.0
- Update development plan to v1.2
- Create Day 5 development record
- Clean up temporary test files
2025-11-23 10:52:07 +08:00

11 KiB
Raw Blame History

平台基础设施Platform Infrastructure

版本: V1.0
创建日期: 2025-11-17
状态: 实施完成


📋 概述

平台基础设施提供了一套通用的、云原生的基础能力,支持本地开发云端部署无缝切换。

核心设计原则适配器模式Adapter Pattern

所有业务模块ASL、AIA、PKB等都应该使用这些平台能力而不是重复实现。


🏗️ 模块清单

模块 路径 状态 说明
存储服务 common/storage/ 完成 文件上传下载(本地/OSS
数据库连接池 config/database.ts 完成 Prisma连接池配置
日志系统 common/logging/ 完成 结构化日志JSON
环境配置 config/env.ts 完成 统一配置管理
异步任务 common/jobs/ 完成 长时间任务异步处理
缓存服务 common/cache/ 完成 内存/Redis缓存
健康检查 common/health/ 完成 SAE健康检查端点
监控指标 common/monitoring/ 完成 关键指标监控

📦 依赖安装

在使用之前,需要安装必需的依赖:

# 进入backend目录
cd backend

# 安装winston日志库
npm install winston
npm install -D @types/winston

可选依赖(云端部署时安装):

# 阿里云OSS当STORAGE_TYPE=oss时
npm install ali-oss
npm install -D @types/ali-oss

# Redis当CACHE_TYPE=redis时
npm install ioredis
npm install -D @types/ioredis

🚀 快速开始

1. 存储服务

import { storage } from '@/common/storage'

// 上传文件
const buffer = await readFile('example.pdf')
const url = await storage.upload('literature/123.pdf', buffer)

// 下载文件
const data = await storage.download('literature/123.pdf')

// 删除文件
await storage.delete('literature/123.pdf')

环境切换:

# 本地开发
STORAGE_TYPE=local

# 云端部署
STORAGE_TYPE=oss
OSS_REGION=oss-cn-hangzhou
OSS_BUCKET=aiclinical-prod
OSS_ACCESS_KEY_ID=your-key-id
OSS_ACCESS_KEY_SECRET=your-key-secret

2. 日志系统

import { logger } from '@/common/logging'

// 基础日志
logger.info('User logged in', { userId: 123 })
logger.error('Database error', { error: err.message })

// 带上下文的日志
const aslLogger = logger.child({ module: 'ASL', projectId: 456 })
aslLogger.info('Screening started', { count: 100 })

输出格式:

  • 本地开发:彩色可读格式
  • 生产环境JSON格式便于阿里云SLS解析

3. 异步任务

import { jobQueue } from '@/common/jobs'

// 创建任务(立即返回)
const job = await jobQueue.push('asl:screening', {
  projectId: 123,
  literatureIds: [1, 2, 3]
})

// 返回任务ID给前端
res.send({ jobId: job.id })

// 注册处理函数
jobQueue.process('asl:screening', async (job) => {
  for (const id of job.data.literatureIds) {
    await processLiterature(id)
    await jobQueue.updateProgress(job.id, ...)
  }
  return { success: true }
})

// 查询任务状态
const status = await jobQueue.getJob(job.id)

4. 缓存服务

import { cache } from '@/common/cache'

// 缓存用户数据5分钟
await cache.set('user:123', userData, 60 * 5)
const user = await cache.get<User>('user:123')

// 缓存LLM响应1小时
const cacheKey = `llm:${model}:${hash(prompt)}`
const cached = await cache.get(cacheKey)
if (!cached) {
  const response = await llm.chat(prompt)
  await cache.set(cacheKey, response, 60 * 60)
}

环境切换:

# 本地开发
CACHE_TYPE=memory

# 云端部署
CACHE_TYPE=redis
REDIS_HOST=r-xxx.redis.aliyuncs.com
REDIS_PORT=6379
REDIS_PASSWORD=your-password

5. 数据库连接

import { prisma } from '@/config/database'

// 直接使用(已配置连接池)
const users = await prisma.user.findMany()

// 获取连接数(监控用)
import { getDatabaseConnectionCount } from '@/config/database'
const count = await getDatabaseConnectionCount()

云原生配置:

DATABASE_URL=postgresql://user:pass@host:5432/db
DB_MAX_CONNECTIONS=400  # RDS最大连接数
MAX_INSTANCES=20        # SAE最大实例数

6. 健康检查

import { registerHealthRoutes } from '@/common/health'

// 注册路由(在应用启动时)
await registerHealthRoutes(app)

端点:

  • GET /health/liveness - SAE存活检查
  • GET /health/readiness - SAE就绪检查
  • GET /health - 详细健康检查(开发用)

7. 监控指标

import { Metrics, requestTimingHook, responseTimingHook } from '@/common/monitoring'

// 注册中间件自动记录API响应时间
app.addHook('onRequest', requestTimingHook)
app.addHook('onResponse', responseTimingHook)

// 启动定期监控
Metrics.startPeriodicMonitoring(60000) // 每分钟

// 手动记录指标
await Metrics.recordDBConnectionCount()
Metrics.recordMemoryUsage()

// 记录LLM调用
Metrics.recordLLMCall('deepseek', 'chat', 1500, true, {
  prompt: 100,
  completion: 200,
  total: 300
})

🌍 多环境支持

本地开发(.env.development

# 应用配置
NODE_ENV=development
PORT=3001
LOG_LEVEL=debug

# 数据库
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ai_clinical

# 存储(本地)
STORAGE_TYPE=local
LOCAL_STORAGE_DIR=uploads

# 缓存(内存)
CACHE_TYPE=memory

# 任务队列(内存)
QUEUE_TYPE=memory

云端部署(.env.production

# 应用配置
NODE_ENV=production
PORT=8080
LOG_LEVEL=info

# 数据库阿里云RDS
DATABASE_URL=postgresql://user:pass@rm-xxx.pg.rds.aliyuncs.com:5432/aiclinical
DB_MAX_CONNECTIONS=400
MAX_INSTANCES=20

# 存储阿里云OSS
STORAGE_TYPE=oss
OSS_REGION=oss-cn-hangzhou
OSS_BUCKET=aiclinical-prod
OSS_ACCESS_KEY_ID=your-key-id
OSS_ACCESS_KEY_SECRET=your-key-secret

# 缓存阿里云Redis
CACHE_TYPE=redis
REDIS_HOST=r-xxx.redis.aliyuncs.com
REDIS_PORT=6379
REDIS_PASSWORD=your-password

# 任务队列(数据库)
QUEUE_TYPE=database

📊 架构示意图

┌─────────────────────────────────────────────────────────┐
│                   业务模块层                             │
│   ASL | AIA | PKB | DC | SSA | ST | UAM                │
│   只关注业务逻辑,复用平台能力                            │
└─────────────────────────────────────────────────────────┘
                    ↓ import from '@/common/'
┌─────────────────────────────────────────────────────────┐
│              平台基础设施层Adapter Pattern            │
├─────────────────────────────────────────────────────────┤
│ 存储LocalAdapter ←→ OSSAdapter                        │
│ 缓存MemoryCacheAdapter ←→ RedisCacheAdapter           │
│ 任务MemoryQueueAdapter ←→ DatabaseQueueAdapter        │
│ 日志ConsoleLogger ←→ 阿里云SLS                         │
│ 数据库本地PostgreSQL ←→ 阿里云RDS连接池            │
└─────────────────────────────────────────────────────────┘
                    ↓ 环境变量切换
┌─────────────────────────────────────────────────────────┐
│         部署环境(零代码改动)                            │
│  本地开发 | 云端SaaS | 私有化部署 | 单机版               │
└─────────────────────────────────────────────────────────┘

验收标准

功能完整性

  • 存储服务LocalAdapter实现完成OSSAdapter预留
  • 数据库:连接池配置,优雅关闭
  • 日志系统Winston配置JSON格式
  • 异步任务MemoryQueue实现完成
  • 缓存服务MemoryCacheAdapter实现完成RedisCacheAdapter预留
  • 健康检查liveness/readiness端点
  • 监控指标数据库连接数、内存、API响应时间

多环境支持

  • 本地开发LocalAdapter + MemoryCache + MemoryQueue
  • 云端部署OSSAdapter预留+ RedisCache预留+ DatabaseQueue预留
  • 零代码切换:通过环境变量切换

🚨 注意事项

1. Winston未安装

当前状态: 代码已完成但winston包未安装

安装方法:

npm install winston
npm install -D @types/winston

2. OSS/Redis待实现

当前状态: 接口和工厂类已完成,具体实现预留

实施时机: 云端部署前

实施步骤:

  1. 安装依赖:npm install ali-oss ioredis
  2. 取消注释:OSSAdapter.tsRedisCacheAdapter.ts
  3. 测试验证

3. Legacy模块兼容性

策略: Legacy模块PKB、AIA、DC保持现状新模块ASL使用平台基础设施

迁移: 可选按需迁移预计5小时


📚 相关文档


🎯 下一步

选项1安装依赖并测试推荐

cd backend
npm install winston
npm run dev

选项2开始ASL模块开发

平台基础设施已完成可以开始ASL模块开发

  • 使用 storage 上传PDF
  • 使用 logger 记录日志
  • 使用 jobQueue 处理异步筛选任务
  • 使用 cache 缓存LLM响应

平台基础设施实施完成!

总耗时: 约3小时Day 1: 2小时Day 2: 1小时
代码量: 约2000行
模块数: 8个核心模块

下一步安装winston依赖开始ASL模块开发 🚀