138 lines
7.2 KiB
Markdown
138 lines
7.2 KiB
Markdown
|
|
# 实施计划:label_backend 知识图谱智能标注平台
|
|||
|
|
|
|||
|
|
**分支**: `001-label-backend-spec` | **日期**: 2026-04-09 | **规格说明**: [spec.md](spec.md)
|
|||
|
|
**输入**: 功能规格说明 `/specs/001-label-backend-spec/spec.md`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 摘要
|
|||
|
|
|
|||
|
|
构建面向多租户的知识图谱智能标注平台后端服务,驱动**文本线**(三元组提取 → 问答对生成 → 训练样本)和**图片线**(四元组提取 → 问答对生成 → 训练样本)两条流水线。视频作为预处理入口异步汇入两条流水线。系统基于 Spring Boot 3 + Apache Shiro + MyBatis Plus + PostgreSQL + Redis + RustFS 构建,通过 HTTP 调用 Python FastAPI AI 服务完成 AI 辅助标注和问答生成能力。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 技术上下文
|
|||
|
|
|
|||
|
|
**语言/版本**: Java 17(LTS)
|
|||
|
|
**主要依赖**: Spring Boot ≥ 3.0.x、Apache Shiro ≥ 1.13.x、MyBatis Plus ≥ 3.5.x、Spring Data Redis
|
|||
|
|
**存储**: PostgreSQL ≥ 14(主库)、Redis ≥ 6.x(会话/权限缓存/分布式锁)、RustFS(S3 兼容对象存储)
|
|||
|
|
**测试**: JUnit 5 + Testcontainers(真实 PostgreSQL + Redis 实例)、Spring Boot Test
|
|||
|
|
**目标平台**: Linux 服务器,Docker Compose 容器化部署
|
|||
|
|
**项目类型**: Web Service(REST API)
|
|||
|
|
**性能目标**: 任务领取并发下有且仅有一人成功;权限变更延迟 < 1 秒生效
|
|||
|
|
**约束**: 禁止 JWT;禁止 Spring Security;禁止文件字节流存入数据库;AI HTTP 调用禁止在 @Transactional 内同步执行;所有列表接口强制分页
|
|||
|
|
**规模**: 多租户(多公司),每公司独立数据空间;11 张核心业务表
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 宪章合规检查
|
|||
|
|
|
|||
|
|
*门控:Phase 0 研究前必须通过。Phase 1 设计后重检。*
|
|||
|
|
|
|||
|
|
| # | 宪章原则 | 状态 | 说明 |
|
|||
|
|
|---|---------|------|------|
|
|||
|
|
| 1 | 环境约束(JDK 17、SB 3、Shiro、MyBatis Plus) | ✅ 通过 | pom.xml 中版本约束与宪章完全对齐;无 Spring Security 引入 |
|
|||
|
|
| 2 | 多租户数据隔离(company_id + ThreadLocal) | ✅ 通过 | TenantLineInnerInterceptor 自动注入;CompanyContext 在 finally 块清理 |
|
|||
|
|
| 3 | BCrypt 密码 + UUID Token + 禁 JWT | ✅ 通过 | AuthService 使用 BCrypt ≥ 10;UUID v4 Token 存 Redis;无 JWT 库 |
|
|||
|
|
| 4 | 分级 RBAC + 权限注解 + 角色变更驱逐缓存 | ✅ 通过 | @RequiresRoles 声明权限;updateRole() 立即删 user:perm:{userId} |
|
|||
|
|
| 5 | 双流水线 + 级联触发 + parent_source_id 溯源 | ✅ 通过 | 仅文本线/图片线;审批通过用 @TransactionalEventListener 触发 QA |
|
|||
|
|
| 6 | 状态机完整性(StateValidator) | ✅ 通过 | 所有状态变更经 StateValidator.assertTransition();禁止绕过 Mapper 直写 |
|
|||
|
|
| 7 | 任务争抢双重保障(Redis SET NX + DB 乐观锁) | ✅ 通过 | task:claim:{taskId} TTL 30s + WHERE status='UNCLAIMED' |
|
|||
|
|
| 8 | 异步视频处理幂等 + 重试上限 + FAILED 手动重置 | ✅ 通过 | SUCCESS 回调静默忽略;retry_count ≥ max_retries → FAILED |
|
|||
|
|
| 9 | 只追加审计日志 + AOP 切面 + 审计失败不回滚业务 | ✅ 通过 | @OperationLog AOP;sys_operation_log 无 UPDATE/DELETE;异常仅 error 日志 |
|
|||
|
|
| 10 | RESTful URL + 统一响应格式 + 强制分页 | ✅ 通过 | Result<T> 包装;无动词路径;PageResult<T> 分页 |
|
|||
|
|
| 11 | YAGNI:业务在 Service,Controller 只处理 HTTP | ✅ 通过 | 分层明确;无预测性抽象层 |
|
|||
|
|
|
|||
|
|
**门控结果:全部通过,可进入 Phase 0。**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 项目结构
|
|||
|
|
|
|||
|
|
### 规格说明文档(本功能)
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
specs/001-label-backend-spec/
|
|||
|
|
├── plan.md # 本文件(/speckit.plan 输出)
|
|||
|
|
├── research.md # Phase 0 输出
|
|||
|
|
├── data-model.md # Phase 1 输出
|
|||
|
|
├── quickstart.md # Phase 1 输出
|
|||
|
|
├── contracts/ # Phase 1 输出(REST API 契约)
|
|||
|
|
│ ├── auth.md
|
|||
|
|
│ ├── source.md
|
|||
|
|
│ ├── tasks.md
|
|||
|
|
│ ├── extraction.md
|
|||
|
|
│ ├── qa.md
|
|||
|
|
│ ├── export.md
|
|||
|
|
│ ├── config.md
|
|||
|
|
│ └── video.md
|
|||
|
|
└── tasks.md # Phase 2 输出(/speckit.tasks 命令创建,非本命令)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 源代码(仓库根目录)
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
src/
|
|||
|
|
└── main/
|
|||
|
|
└── java/com/label/
|
|||
|
|
├── LabelBackendApplication.java
|
|||
|
|
├── common/
|
|||
|
|
│ ├── result/ # Result<T>、ResultCode、PageResult<T>
|
|||
|
|
│ ├── exception/ # BusinessException、GlobalExceptionHandler
|
|||
|
|
│ ├── context/ # CompanyContext(ThreadLocal)
|
|||
|
|
│ ├── shiro/ # TokenFilter、UserRealm、ShiroConfig
|
|||
|
|
│ ├── redis/ # RedisKeyManager、RedisService
|
|||
|
|
│ ├── aop/ # AuditAspect、@OperationLog 注解
|
|||
|
|
│ ├── storage/ # RustFsClient(S3 兼容封装)
|
|||
|
|
│ ├── ai/ # AiServiceClient(RestClient 封装 8 个端点)
|
|||
|
|
│ └── statemachine/ # StateValidator、各状态枚举
|
|||
|
|
└── module/
|
|||
|
|
├── user/ # AuthController、UserController、AuthService、UserService
|
|||
|
|
├── source/ # SourceController、SourceService
|
|||
|
|
├── task/ # TaskController、TaskService、TaskClaimService
|
|||
|
|
├── annotation/ # ExtractionController、QaController、ExtractionService、QaService
|
|||
|
|
├── export/ # ExportController、ExportService、FinetuneService
|
|||
|
|
├── config/ # SysConfigController、SysConfigService
|
|||
|
|
└── video/ # VideoController、VideoProcessService
|
|||
|
|
|
|||
|
|
src/
|
|||
|
|
└── test/
|
|||
|
|
└── java/com/label/
|
|||
|
|
├── integration/ # Testcontainers(真实 PG + Redis)集成测试
|
|||
|
|
│ ├── AuthIntegrationTest.java
|
|||
|
|
│ ├── TaskClaimConcurrencyTest.java
|
|||
|
|
│ ├── VideoCallbackIdempotencyTest.java
|
|||
|
|
│ ├── MultiTenantIsolationTest.java
|
|||
|
|
│ └── ShiroFilterIntegrationTest.java
|
|||
|
|
└── unit/ # 纯单元测试(状态机、业务逻辑)
|
|||
|
|
└── StateMachineTest.java
|
|||
|
|
|
|||
|
|
sql/
|
|||
|
|
└── init.sql # 全部 DDL(11 张表,按依赖顺序执行)
|
|||
|
|
|
|||
|
|
docker-compose.yml # postgres、redis、rustfs、backend、ai-service、frontend
|
|||
|
|
Dockerfile # eclipse-temurin:17-jre-alpine
|
|||
|
|
pom.xml
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**结构决策**:单一后端服务(Web Service),无前端代码。标准 Maven 项目布局,源代码在 `src/main/java/com/label/`,测试在 `src/test/java/com/label/`,按 `common/` + `module/` 两层分包。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 复杂度追踪
|
|||
|
|
|
|||
|
|
> 宪章检查无违规,本节留空。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## GSTACK REVIEW REPORT
|
|||
|
|
|
|||
|
|
| Review | Trigger | Why | Runs | Status | Findings |
|
|||
|
|
|--------|---------|-----|------|--------|----------|
|
|||
|
|
| CEO Review | `/plan-ceo-review` | Scope & strategy | 0 | — | — |
|
|||
|
|
| Codex Review | `/codex review` | Independent 2nd opinion | 0 | — | — |
|
|||
|
|
| Eng Review | `/plan-eng-review` | Architecture & tests (required) | 0 | — | — |
|
|||
|
|
| Design Review | `/plan-design-review` | UI/UX gaps | 0 | — | — |
|
|||
|
|
|
|||
|
|
**VERDICT:** NO REVIEWS YET — run `/autoplan` for full review pipeline, or individual reviews above.
|