# Ziin Media Gateway 模块划分模板 v1

这份模板不是具体框架代码，而是给 Java / Node 团队开工时的标准分层。

## 1. 推荐服务拆分

### `file-service`

职责：

- 上传凭证签发
- 原始文件落对象存储
- MIME / 扩展名 / 文件头校验
- sha256 去重
- 文件元数据管理
- 文件归属校验

核心接口：

- `POST /media/upload-token`
- `POST /media/upload-complete`
- `GET /media/files/:fileId`

DAO：

- `MediaFileDao`

### `ai-media-gateway`

职责：

- OCR / ASR 统一入口
- 供应商路由
- 主备切换
- 重试与熔断
- 结果归一化
- 任务状态机流转

核心接口：

- `POST /media/ocr/image`
- `POST /media/ocr/document`
- `POST /media/asr/transcribe`
- `GET /media/tasks/:taskId`

DAO：

- `MediaTaskDao`
- `MediaUsageLogDao`

Provider 抽象：

- `OcrImageProvider`
- `OcrDocumentProvider`
- `AsrProvider`
- `ProviderRouter`

### `quota-billing-service`

职责：

- 用户级 / 租户级限流
- 并发控制
- 成本估算
- 预算阈值控制
- 账单汇总

核心接口：

- `GET /media/quota/current`
- `GET /media/costs/summary`

DAO：

- `MediaQuotaPolicyDao`
- `MediaUsageLogDao`

### `audit-log-service`

职责：

- 上传审计
- 调用审计
- 安全审计
- 导出和查询

核心接口：

- `GET /media/audit-logs`

DAO：

- `MediaAuditLogDao`

### `provider-config-service`

职责：

- 主供应商配置
- 备用供应商配置
- 灰度比例配置
- 成本阈值配置

核心接口：

- `GET /media/providers/config`
- `POST /media/providers/config`

DAO：

- `MediaProviderConfigDao`

## 2. Java 模块建议

```
ziin-media-parent
  ziin-media-api
  ziin-media-domain
  ziin-media-application
  ziin-media-infrastructure
  ziin-media-provider-openai
  ziin-media-provider-aliyun
  ziin-media-provider-tencent
  ziin-media-job
```

建议分层：

- `api`: Controller、DTO、OpenAPI
- `domain`: Entity、Enum、Repository Interface、Policy
- `application`: UseCase、Service、Facade
- `infrastructure`: MyBatis/JPA、对象存储、缓存、消息队列
- `provider-*`: 各供应商适配器
- `job`: 异步重试、超时补偿、成本汇总

## 3. Node 模块建议

```
src/
  modules/
    media-files/
    media-tasks/
    media-usage/
    media-quota/
    media-providers/
    media-audit/
  providers/
    ocr/
    asr/
    router/
  shared/
    storage/
    auth/
    rate-limit/
    queue/
    db/
    errors/
```

每个模块建议固定：

- `controller.ts`
- `service.ts`
- `dao.ts`
- `types.ts`
- `validator.ts`

## 4. 统一 DAO 抽象建议

至少保留这些接口：

- `MediaFileDao`
- `MediaTaskDao`
- `MediaUsageLogDao`
- `MediaQuotaPolicyDao`
- `MediaProviderConfigDao`
- `MediaAuditLogDao`

这样数据库从 MySQL 切到 PostgreSQL，或者从单库切到多租户分库，业务层都不用重写。

## 5. 最小上线顺序

第一期：

- `media_files`
- `media_tasks`
- `POST /media/upload-token`
- `POST /media/upload-complete`
- `POST /media/ocr/image`
- `POST /media/asr/transcribe`

第二期：

- `media_usage_logs`
- `media_quota_policies`
- `GET /media/quota/current`
- `GET /media/costs/summary`
- `GET /media/audit-logs`

第三期：

- `media_provider_configs`
- 主备切换
- 灰度路由
- 异步重试队列
- 预算控制

## 6. 工程边界

不要让业务问答服务直接调用具体 OCR/ASR SDK。

应该始终走：

`business-agent -> media-gateway facade -> provider router -> provider adapter`

这样后续换供应商、做成本控制、做审计与限流时，不会把上层业务一起拖进来。
