# 自标注能力<no value>
# 从外包模式到 SaaS 化：数据标注平台“自标注”功能的架构演进实践

在构建和维护 AI 数据标注平台的过程中，我们最初采用了传统的“发包-接包”模式。这种模式下，系统具有强烈的“甲方（需求方）”与“乙方（服务商）”的身份隔离。

然而，随着大模型（LLM）等 AI 技术的爆发，越来越多的小型研发团队和个人开发者需要一个轻量级的工具来完成**自主标注**，而不是将数据外包。为了满足这一需求，我们决定在不影响现有外包业务线的前提下，对系统进行一次 SaaS 化的架构升级，引入“自标注（Self-Annotation）”模式。

本文将复盘我们是如何通过最小化侵入的系统设计，分阶段完成这次核心业务逻辑重构的。

## 🎯 面临的挑战与核心需求

我们需要在同一套系统中兼容两种截然不同的业务流：
1.  **外包标注 (OUTSOURCE)**：强流程驱动，涉及竞价、多重审核、严格的数据导出限制。
2.  **自主标注 (SELF_ANNOTATION)**：敏捷 SaaS 模式，免审核，用户即插即用，数据随时导入导出。

**架构原则**：最小化对现有逻辑的影响，新增的字段和逻辑默认向下兼容现有外包行为。

---

## 🛠️ 第一阶段：数据模型与 API 层的“向下兼容”改造

为了支持新模式，我们首先对底层数据模型进行了调整。核心思路是**做减法**——将过去强绑定的实体关系解耦。

### 1. 数据库解耦设计
在原有系统中，任务（Jobs）和用户（Users）都被硬编码了身份属性。我们进行了如下改造：
* **任务表 (Jobs)**：新增了 `job_type` 枚举字段，包含 `OUTSOURCE` 和 `SELF_ANNOTATION`，并默认设为 `OUTSOURCE` 以保证老数据兼容。
* **企业关联解绑**：原有的 `party_b_enterprise_id` 字段被调整为**可选 (Nullable)**。自标注项目在创建时，不再强制需要一个“乙方”实体存在。
* **用户与企业表 (Users & Enterprises)**：将 `party`（甲/乙方）字段同样调整为**可选**。个人用户现在可以仅仅作为独立的“标注员”存在，打破了过去注册必须预设身份的限制。

### 2. API 层与业务逻辑适配
在 API 设计上，我们保持了核心查询接口（如 `GET /projects`, `GET /jobs`）的向后兼容，但重构了底层的权限拦截器。

我们引入了基于策略模式的动态权限判定：

```javascript
// 伪代码演示：基于项目类型的动态权限路由
function canExportData(user, project) {
  if (project.job_type === 'SELF_ANNOTATION') {
    // SaaS 模式：管理员拥有绝对控制权
    return isAdmin(user); 
  } else {
    // 传统外包模式：强流程校验（必须验收通过等）
    return isOutsourceWorkflowCompleted(project) && isProjectOwner(user);
  }
}