Compare commits
2
Commits
c91682cc3e
...
8560b6a450
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8560b6a450 | ||
|
|
51e5ae9edd |
@@ -15,6 +15,9 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: '../tfsIntegration/lib', include: '*.jar')
|
||||
implementation 'com.sparkjava:spark-core:2.9.4'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.5'
|
||||
implementation 'org.slf4j:slf4j-simple:1.7.36'
|
||||
}
|
||||
|
||||
application {
|
||||
@@ -25,6 +28,13 @@ applicationDistribution.from('../tfsIntegration/lib/native') {
|
||||
into 'lib/native'
|
||||
}
|
||||
|
||||
task runServer(type: JavaExec) {
|
||||
group = 'application'
|
||||
description = 'Start the macTFS local API server.'
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
main = 'com.mydev.mactfs.server.MacTfsServer'
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
@@ -760,13 +760,17 @@ public class MacTfsCoreService {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 pending change、工作区本地版本和服务端最新版本计算目录对比状态。
|
||||
*/
|
||||
private String resolveDiffStatus(ExtendedItem item, PendingChange pendingChange, File localFile) {
|
||||
if (pendingChange != null) {
|
||||
return toPendingStatus(pendingChange);
|
||||
}
|
||||
boolean exists = localFile != null && localFile.exists();
|
||||
boolean remoteChanged = item.getLocalVersion() > 0 && item.getLatestVersion() > item.getLocalVersion();
|
||||
boolean localModified = exists && item.getCheckinDate() != null && localFile.lastModified() > item.getCheckinDate().getTimeInMillis();
|
||||
// mtime 只能作为远端版本变化时的辅助信号,避免 Get Latest 后因本地时间晚于签入时间误报本地修改。
|
||||
boolean localModified = remoteChanged && exists && item.getCheckinDate() != null && localFile.lastModified() > item.getCheckinDate().getTimeInMillis();
|
||||
if (!exists && item.getLocalVersion() > 0) {
|
||||
return "localDeleted";
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+14
-14
@@ -23,20 +23,20 @@ blocked
|
||||
| 模块 | done | total | progress |
|
||||
|---|---:|---:|---:|
|
||||
| Core | 12 | 12 | 100% |
|
||||
| Server API | 0 | 10 | 0% |
|
||||
| Server API | 10 | 10 | 100% |
|
||||
| CLI | 0 | 2 | 0% |
|
||||
| Frontend | 0 | 13 | 0% |
|
||||
| Feature E2E | 0 | 5 | 0% |
|
||||
| Release | 0 | 4 | 0% |
|
||||
| Overall | 12 | 46 | 26% |
|
||||
| Overall | 22 | 46 | 48% |
|
||||
|
||||
## 当前阶段
|
||||
|
||||
Server API
|
||||
CLI
|
||||
|
||||
## 下一步任务
|
||||
|
||||
- [SERVER-001-创建本地API服务.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-001-创建本地API服务.md)
|
||||
- [CLI-001-改造CLI调用本地API.md](/Users/fenghp/Desktop/DEV/project/mydev/task/cli/CLI-001-改造CLI调用本地API.md)
|
||||
|
||||
## Core
|
||||
|
||||
@@ -59,16 +59,16 @@ Server API
|
||||
|
||||
| 任务 | 状态 | 优先级 |
|
||||
|---|---|---|
|
||||
| [SERVER-001-创建本地API服务.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-001-创建本地API服务.md) | todo | P0 |
|
||||
| [SERVER-002-实现Token认证与健康检查.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-002-实现Token认证与健康检查.md) | todo | P0 |
|
||||
| [SERVER-003-实现配置读写API.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-003-实现配置读写API.md) | todo | P0 |
|
||||
| [SERVER-004-实现连接会话API.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-004-实现连接会话API.md) | todo | P0 |
|
||||
| [SERVER-005-实现Collection与目录API.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-005-实现Collection与目录API.md) | todo | P0 |
|
||||
| [SERVER-006-实现Workspace与MappingAPI.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-006-实现Workspace与MappingAPI.md) | todo | P0 |
|
||||
| [SERVER-007-实现文件操作API.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-007-实现文件操作API.md) | todo | P0 |
|
||||
| [SERVER-008-实现目录对比API.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-008-实现目录对比API.md) | todo | P0 |
|
||||
| [SERVER-009-实现历史与DiffAPI.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-009-实现历史与DiffAPI.md) | todo | P0 |
|
||||
| [SERVER-010-实现操作日志与超时.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-010-实现操作日志与超时.md) | todo | P1 |
|
||||
| [SERVER-001-创建本地API服务.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-001-创建本地API服务.md) | done | P0 |
|
||||
| [SERVER-002-实现Token认证与健康检查.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-002-实现Token认证与健康检查.md) | done | P0 |
|
||||
| [SERVER-003-实现配置读写API.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-003-实现配置读写API.md) | done | P0 |
|
||||
| [SERVER-004-实现连接会话API.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-004-实现连接会话API.md) | done | P0 |
|
||||
| [SERVER-005-实现Collection与目录API.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-005-实现Collection与目录API.md) | done | P0 |
|
||||
| [SERVER-006-实现Workspace与MappingAPI.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-006-实现Workspace与MappingAPI.md) | done | P0 |
|
||||
| [SERVER-007-实现文件操作API.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-007-实现文件操作API.md) | done | P0 |
|
||||
| [SERVER-008-实现目录对比API.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-008-实现目录对比API.md) | done | P0 |
|
||||
| [SERVER-009-实现历史与DiffAPI.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-009-实现历史与DiffAPI.md) | done | P0 |
|
||||
| [SERVER-010-实现操作日志与超时.md](/Users/fenghp/Desktop/DEV/project/mydev/task/server/SERVER-010-实现操作日志与超时.md) | done | P1 |
|
||||
|
||||
## CLI
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 状态
|
||||
|
||||
todo
|
||||
done
|
||||
|
||||
## 优先级
|
||||
|
||||
@@ -59,4 +59,25 @@ cd /Users/fenghp/Desktop/DEV/project/mydev/mactfs
|
||||
|
||||
## 完成记录
|
||||
|
||||
待完成后填写。
|
||||
- 实际修改文件:
|
||||
- `mactfs/build.gradle`
|
||||
- `mactfs/src/main/java/com/mydev/mactfs/server/MacTfsServer.java`
|
||||
- 实际实现内容:
|
||||
- 新增 `MacTfsServer` 本地 API 服务入口。
|
||||
- 引入 SparkJava 2.9.4、Jackson 和 slf4j-simple。
|
||||
- 服务固定监听 `127.0.0.1:38765`。
|
||||
- 新增 `runServer` Gradle 任务,不改变原 CLI 默认入口。
|
||||
- 已执行测试:
|
||||
- `JAVA_HOME=/Users/fenghp/Desktop/DEV/project/mydev/zulu8.94.0.17-ca-jdk8.0.492-macosx_x64/Contents/Home ../tfsIntegration/gradlew build`
|
||||
- `JAVA_HOME=/Users/fenghp/Desktop/DEV/project/mydev/zulu8.94.0.17-ca-jdk8.0.492-macosx_x64/Contents/Home ../tfsIntegration/gradlew runServer`
|
||||
- 测试结果:
|
||||
- build 成功。
|
||||
- Spark 启动成功,并输出监听 `127.0.0.1:38765`。
|
||||
- 未执行测试及原因:
|
||||
- 未执行真实 TFS 业务调用,本任务只要求服务骨架。
|
||||
- 是否满足验收标准:
|
||||
- 本地 API 服务可启动:满足。
|
||||
- 只监听 `127.0.0.1`:满足。
|
||||
- 构建通过:满足。
|
||||
- 遗留问题:
|
||||
- 无。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 状态
|
||||
|
||||
todo
|
||||
done
|
||||
|
||||
## 优先级
|
||||
|
||||
@@ -57,4 +57,26 @@ curl -H "Authorization: Bearer <token>" http://127.0.0.1:38765/api/health
|
||||
|
||||
## 完成记录
|
||||
|
||||
待完成后填写。
|
||||
- 实际修改文件:
|
||||
- `mactfs/src/main/java/com/mydev/mactfs/server/MacTfsServer.java`
|
||||
- 实际实现内容:
|
||||
- 启动时读取或生成 `~/.mactfs/server-token`。
|
||||
- token 文件权限设置为 `600`。
|
||||
- 所有 `/api/*` 请求校验 `Authorization: Bearer <token>`。
|
||||
- 新增 `GET /api/health`,返回 host、port、tokenFile、configFile、connected 和 durationMs。
|
||||
- 已执行测试:
|
||||
- 无 token 调用 `GET /api/health`。
|
||||
- 带正确 Bearer token 调用 `GET /api/health`。
|
||||
- 检查 `~/.mactfs/server-token` 文件权限。
|
||||
- 测试结果:
|
||||
- 无 token 返回 HTTP 401。
|
||||
- 正确 token 返回 `success=true`、`host=127.0.0.1`、`port=38765`。
|
||||
- token 文件权限为 `600`。
|
||||
- 未执行测试及原因:
|
||||
- 未打印 token 明文,符合默认日志不暴露 token 的要求。
|
||||
- 是否满足验收标准:
|
||||
- 无 token 请求被拒绝:满足。
|
||||
- 正确 token 请求通过:满足。
|
||||
- 可通过 health 检查服务状态:满足。
|
||||
- 遗留问题:
|
||||
- 无。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 状态
|
||||
|
||||
todo
|
||||
done
|
||||
|
||||
## 优先级
|
||||
|
||||
@@ -57,4 +57,26 @@ curl -H "Authorization: Bearer <token>" http://127.0.0.1:38765/api/config
|
||||
|
||||
## 完成记录
|
||||
|
||||
待完成后填写。
|
||||
- 实际修改文件:
|
||||
- `mactfs/src/main/java/com/mydev/mactfs/server/MacTfsServer.java`
|
||||
- 实际实现内容:
|
||||
- 新增 `GET /api/config`。
|
||||
- 新增 `PUT /api/config`。
|
||||
- 配置文件固定为 `~/.mactfs/config.json`。
|
||||
- 配置结构包含 serverUri、authType、domain、username、password、collection、workspace、mappings。
|
||||
- 空配置默认返回 `authType=ntlm-explicit` 和空 mappings 数组。
|
||||
- 已执行测试:
|
||||
- 带 token 调用 `GET /api/config`。
|
||||
- 执行 `../tfsIntegration/gradlew build`。
|
||||
- 测试结果:
|
||||
- `GET /api/config` 返回 `success=true`。
|
||||
- 返回配置中 `authType=ntlm-explicit`,`mappings` 为数组。
|
||||
- build 成功。
|
||||
- 未执行测试及原因:
|
||||
- 未写入真实账号密码配置,避免在本机生成不必要的明文凭据。
|
||||
- 是否满足验收标准:
|
||||
- 配置可保存并再次读取:代码已实现,未写入真实凭据验证。
|
||||
- 空配置时返回默认结构:满足。
|
||||
- JSON 结构与 PRD 一致:满足。
|
||||
- 遗留问题:
|
||||
- 后续可用测试配置补充 PUT/GET 回读验收。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 状态
|
||||
|
||||
todo
|
||||
done
|
||||
|
||||
## 优先级
|
||||
|
||||
@@ -56,4 +56,22 @@ curl -X POST -H "Authorization: Bearer <token>" -H "Content-Type: application/js
|
||||
|
||||
## 完成记录
|
||||
|
||||
待完成后填写。
|
||||
- 实际修改文件:
|
||||
- `mactfs/src/main/java/com/mydev/mactfs/server/MacTfsServer.java`
|
||||
- 实际实现内容:
|
||||
- 新增 `POST /api/session/connect`。
|
||||
- 调用 `MacTfsCoreService.testConnection` 连接 TFS。
|
||||
- 连接成功后保存当前会话配置和连接摘要。
|
||||
- 返回 serverUri、collectionCount、durationMs 和 core 日志。
|
||||
- 已执行测试:
|
||||
- 执行 `../tfsIntegration/gradlew build`。
|
||||
- 测试结果:
|
||||
- build 成功。
|
||||
- 未执行测试及原因:
|
||||
- 未执行真实 TFS 账号连接验证,当前任务输入未提供可用 TFS 地址、账号和密码。
|
||||
- 是否满足验收标准:
|
||||
- 正确账号可连接:代码调用 core 实现,待真实账号验证。
|
||||
- 错误账号返回错误:core 失败会转换为 `success=false` 响应,待真实账号验证。
|
||||
- 连接结果可被后续 API 复用:已通过 `SessionManager` 保存配置。
|
||||
- 遗留问题:
|
||||
- 需要真实 TFS 配置后补充连接成功/失败的实测记录。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 状态
|
||||
|
||||
todo
|
||||
done
|
||||
|
||||
## 优先级
|
||||
|
||||
@@ -56,4 +56,22 @@ curl -H "Authorization: Bearer <token>" "http://127.0.0.1:38765/api/collections"
|
||||
|
||||
## 完成记录
|
||||
|
||||
待完成后填写。
|
||||
- 实际修改文件:
|
||||
- `mactfs/src/main/java/com/mydev/mactfs/server/MacTfsServer.java`
|
||||
- 实际实现内容:
|
||||
- 新增 `GET /api/collections`。
|
||||
- 新增 `GET /api/server-tree`。
|
||||
- 新增 `GET /api/server-folder/items`。
|
||||
- 目录项返回 name、path、serverPath、type、folder、latestVersion、checkinDate。
|
||||
- 已执行测试:
|
||||
- 执行 `../tfsIntegration/gradlew build`。
|
||||
- 测试结果:
|
||||
- build 成功。
|
||||
- 未执行测试及原因:
|
||||
- 未执行真实 Collection 和服务端目录浏览,当前任务输入未提供 TFS 连接配置。
|
||||
- 是否满足验收标准:
|
||||
- 可查询 Collection:代码已调用 core `listCollections`。
|
||||
- 可浏览未映射服务端目录:代码已调用 core `browseServerPath`,不依赖 mapping。
|
||||
- 返回结构可供左侧树和中间列表使用:满足。
|
||||
- 遗留问题:
|
||||
- 需要真实 TFS 配置后补充目录浏览结果验收。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 状态
|
||||
|
||||
todo
|
||||
done
|
||||
|
||||
## 优先级
|
||||
|
||||
@@ -59,4 +59,26 @@ curl -H "Authorization: Bearer <token>" http://127.0.0.1:38765/api/mappings
|
||||
|
||||
## 完成记录
|
||||
|
||||
待完成后填写。
|
||||
- 实际修改文件:
|
||||
- `mactfs/src/main/java/com/mydev/mactfs/server/MacTfsServer.java`
|
||||
- 实际实现内容:
|
||||
- 新增 `GET /api/workspace`。
|
||||
- 新增 `POST /api/workspace/ensure`。
|
||||
- 新增 `GET /api/mappings`。
|
||||
- 新增 `POST /api/mappings`。
|
||||
- 新增 `DELETE /api/mappings`。
|
||||
- 创建 Mapping 后支持 `getLatest=true` 立即执行 Get Latest。
|
||||
- Workspace/Mapping 成功后同步更新 `~/.mactfs/config.json`。
|
||||
- 已执行测试:
|
||||
- 执行 `../tfsIntegration/gradlew build`。
|
||||
- 测试结果:
|
||||
- build 成功。
|
||||
- 未执行测试及原因:
|
||||
- 未执行真实 Workspace 创建和 Mapping 写入,避免在未确认 TFS 环境时修改服务端 Workspace。
|
||||
- 是否满足验收标准:
|
||||
- 可创建或复用默认 Workspace:代码已调用 core `ensureWorkspace`。
|
||||
- 可添加多条 Mapping:代码已调用 core `addMapping` 并保存 mappings。
|
||||
- 可删除 Mapping:代码已调用 core `deleteMapping`。
|
||||
- 已映射路径可被后续操作识别:配置和会话均保存 mappings。
|
||||
- 遗留问题:
|
||||
- 需要真实 TFS Workspace 环境后补充实测。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 状态
|
||||
|
||||
todo
|
||||
done
|
||||
|
||||
## 优先级
|
||||
|
||||
@@ -62,4 +62,27 @@ curl -H "Authorization: Bearer <token>" http://127.0.0.1:38765/api/pending-chang
|
||||
|
||||
## 完成记录
|
||||
|
||||
待完成后填写。
|
||||
- 实际修改文件:
|
||||
- `mactfs/src/main/java/com/mydev/mactfs/server/MacTfsServer.java`
|
||||
- 实际实现内容:
|
||||
- 新增 `POST /api/files/get-latest`。
|
||||
- 新增 `POST /api/files/checkout`。
|
||||
- 新增 `POST /api/files/add`。
|
||||
- 新增 `POST /api/files/delete`。
|
||||
- 新增 `POST /api/files/undo`。
|
||||
- 新增 `GET /api/pending-changes`。
|
||||
- 新增 `POST /api/checkin`。
|
||||
- checkin comment 通过必填校验,缺失时返回错误。
|
||||
- 已执行测试:
|
||||
- 执行 `../tfsIntegration/gradlew build`。
|
||||
- 测试结果:
|
||||
- build 成功。
|
||||
- 未执行测试及原因:
|
||||
- 未执行 get latest、checkout、add、delete、undo、checkin 的真实 TFS 操作,避免在未确认工作区和文件范围时修改本地或服务端状态。
|
||||
- 是否满足验收标准:
|
||||
- API 可操作同一 Workspace 下文件:代码已复用 core 文件操作。
|
||||
- checkin comment 必填:满足。
|
||||
- pending changes 可查询:代码已实现。
|
||||
- 操作结果包含成功、失败、耗时:统一 API 响应包含 success、errorMessage、durationMs。
|
||||
- 遗留问题:
|
||||
- 需要真实映射目录后补充文件操作实测。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 状态
|
||||
|
||||
todo
|
||||
done
|
||||
|
||||
## 优先级
|
||||
|
||||
@@ -57,4 +57,22 @@ curl -X POST -H "Authorization: Bearer <token>" -H "Content-Type: application/js
|
||||
|
||||
## 完成记录
|
||||
|
||||
待完成后填写。
|
||||
- 实际修改文件:
|
||||
- `mactfs/src/main/java/com/mydev/mactfs/server/MacTfsServer.java`
|
||||
- 实际实现内容:
|
||||
- 新增 `POST /api/compare/folder`。
|
||||
- 接收 serverPath、localPath、recursive。
|
||||
- 调用 core `compareFolder`。
|
||||
- core 已默认过滤 `upToDate`,只返回差异项。
|
||||
- 已执行测试:
|
||||
- 执行 `../tfsIntegration/gradlew build`。
|
||||
- 测试结果:
|
||||
- build 成功。
|
||||
- 未执行测试及原因:
|
||||
- 未执行真实目录对比,当前未提供可用 TFS mapping 和本地目录。
|
||||
- 是否满足验收标准:
|
||||
- 已映射目录可对比:代码已调用 core。
|
||||
- 未映射目录返回明确错误:core 会返回 `Server path is not mapped`。
|
||||
- 返回状态可供 UI 操作映射:core 返回 PRD 约定状态字段。
|
||||
- 遗留问题:
|
||||
- 需要真实映射目录后补充对比结果验收。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 状态
|
||||
|
||||
todo
|
||||
done
|
||||
|
||||
## 优先级
|
||||
|
||||
@@ -60,4 +60,24 @@ curl -H "Authorization: Bearer <token>" "http://127.0.0.1:38765/api/history?path
|
||||
|
||||
## 完成记录
|
||||
|
||||
待完成后填写。
|
||||
- 实际修改文件:
|
||||
- `mactfs/src/main/java/com/mydev/mactfs/server/MacTfsServer.java`
|
||||
- 实际实现内容:
|
||||
- 新增 `GET /api/history`。
|
||||
- 新增 `GET /api/history/changeset`。
|
||||
- 新增 `POST /api/diff/local-latest`。
|
||||
- 新增 `POST /api/diff/revisions`。
|
||||
- 历史查询复用 core 默认最近 100 条逻辑。
|
||||
- 已执行测试:
|
||||
- 执行 `../tfsIntegration/gradlew build`。
|
||||
- 测试结果:
|
||||
- build 成功。
|
||||
- 未执行测试及原因:
|
||||
- 未执行真实历史和 diff 查询,当前未提供可用 TFS 路径和 changeset。
|
||||
- 是否满足验收标准:
|
||||
- 文件历史可查询:代码已调用 core `queryHistory`。
|
||||
- 目录历史可查询:请求 `folder=true` 时调用递归历史查询。
|
||||
- changeset 文件列表可查询:代码已调用 core `queryChangesetFiles`。
|
||||
- 两个历史版本可对比:代码已调用 core `diffRevisions`。
|
||||
- 遗留问题:
|
||||
- 需要真实 TFS 路径和 changeset 后补充实测。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 状态
|
||||
|
||||
todo
|
||||
done
|
||||
|
||||
## 优先级
|
||||
|
||||
@@ -60,4 +60,24 @@ curl -H "Authorization: Bearer <token>" http://127.0.0.1:38765/api/health
|
||||
|
||||
## 完成记录
|
||||
|
||||
待完成后填写。
|
||||
- 实际修改文件:
|
||||
- `mactfs/src/main/java/com/mydev/mactfs/server/MacTfsServer.java`
|
||||
- 实际实现内容:
|
||||
- 所有 API 统一返回 durationMs、startedAt、endedAt。
|
||||
- 新增内存操作日志,记录 operation、summary、startedAt、endedAt、durationMs、success、errorMessage。
|
||||
- 新增 `GET /api/logs` 供 UI 读取最近操作日志。
|
||||
- 对连接、目录、历史、目录对比、diff、Get Latest、Checkin 等请求设置同步超时。
|
||||
- 已执行测试:
|
||||
- 带 token 调用 `GET /api/health`。
|
||||
- 执行 `../tfsIntegration/gradlew build`。
|
||||
- 测试结果:
|
||||
- health 返回 durationMs。
|
||||
- build 成功。
|
||||
- 未执行测试及原因:
|
||||
- 未通过真实长耗时 TFS 请求触发超时,当前未提供可用慢请求场景。
|
||||
- 是否满足验收标准:
|
||||
- API 等待期间可明确展示操作中:同步 API 返回前由前端展示等待状态,服务端提供 durationMs。
|
||||
- 超时返回明确错误:超时返回 `Operation timed out` 和 HTTP 504。
|
||||
- 操作日志可供 UI 展示:已提供 `GET /api/logs`。
|
||||
- 遗留问题:
|
||||
- 需要真实慢 TFS 请求后补充超时路径验收。
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
# macTFS 阶段二 Server API 测试报告
|
||||
|
||||
## 一、测试依据
|
||||
|
||||
- 任务路线图:`task/00-roadmap.md`
|
||||
- 阶段二任务:`task/server/SERVER-001` 至 `task/server/SERVER-010`
|
||||
- AI 测试流程:`TFS-AI测试流程.md`
|
||||
- PRD:`docs/mactfs-api-product-prd.md`
|
||||
- 执行时间:2026-06-06 15:13-15:20
|
||||
- 执行入口:`mactfs` 本地 Java API 服务
|
||||
|
||||
阶段二在当前任务体系中定义为 `Server API`,测试对象是本地常驻 Java HTTP 服务,不包含阶段三 CLI 改造和阶段四 Frontend UI。
|
||||
|
||||
## 二、测试环境
|
||||
|
||||
- 服务地址:`http://127.0.0.1:38765`
|
||||
- Java:项目内 x86_64 JDK 8
|
||||
- 启动命令:
|
||||
|
||||
```bash
|
||||
cd /Users/fenghp/Desktop/DEV/project/mydev/mactfs
|
||||
env JAVA_HOME=/Users/fenghp/Desktop/DEV/project/mydev/zulu8.94.0.17-ca-jdk8.0.492-macosx_x64/Contents/Home \
|
||||
arch -x86_64 ../tfsIntegration/gradlew runServer
|
||||
```
|
||||
|
||||
- 构建命令:
|
||||
|
||||
```bash
|
||||
cd /Users/fenghp/Desktop/DEV/project/mydev/mactfs
|
||||
env JAVA_HOME=/Users/fenghp/Desktop/DEV/project/mydev/zulu8.94.0.17-ca-jdk8.0.492-macosx_x64/Contents/Home \
|
||||
arch -x86_64 ../tfsIntegration/gradlew clean build installDist
|
||||
```
|
||||
|
||||
构建结果:
|
||||
|
||||
- `BUILD SUCCESSFUL`
|
||||
- `:test NO-SOURCE`
|
||||
- `installDist` 成功生成发行脚本
|
||||
|
||||
## 三、测试边界
|
||||
|
||||
写操作严格限制在测试流程指定目录:
|
||||
|
||||
- Collection:`PKUSEHR`
|
||||
- Workspace:`mactfs-ai-subapp-pm-mactfs`
|
||||
- Server Path:`$/北京排水集团人力系统/5SRC/MicroFront/subapp_pm/mactfs`
|
||||
- Local Path:`/Users/fenghp/Desktop/DEV/mactfs-ai-workspace`
|
||||
|
||||
本轮不测试:
|
||||
|
||||
- Frontend UI
|
||||
- 阶段三 CLI API 客户端改造
|
||||
- 删除 Workspace
|
||||
- WebSocket / SSE 实时日志
|
||||
- 异步 Job / 取消任务
|
||||
- 真实慢请求触发超时
|
||||
|
||||
测试前 `~/.mactfs/config.json` 不存在。测试过程中写入过配置接口,测试结束后已删除该测试配置。
|
||||
|
||||
## 四、阶段二 API 测试结果
|
||||
|
||||
| 能力域 | API / 测试项 | 结果 | 关键结果 |
|
||||
|---|---|---|---|
|
||||
| 构建 | `clean build installDist` | 通过 | Gradle `BUILD SUCCESSFUL` |
|
||||
| 服务启动 | `runServer` | 通过 | 监听 `127.0.0.1:38765` |
|
||||
| Token | 无 token 调用 `/api/health` | 通过 | HTTP 401 |
|
||||
| Token | 正确 Bearer token 调用 `/api/health` | 通过 | `success=true`,`host=127.0.0.1`,`port=38765` |
|
||||
| Token | token 文件权限 | 通过 | `~/.mactfs/server-token` 权限为 `600` |
|
||||
| 配置 | `GET /api/config` 空配置 | 通过 | 默认 `authType=ntlm-explicit`,`mappings=[]` |
|
||||
| 配置 | `PUT /api/config` 后 `GET /api/config` | 通过 | serverUri、collection、workspace、mappings 可回读 |
|
||||
| 连接 | `POST /api/session/connect` 正确账号 | 通过 | `collectionCount=2`,durationMs `2442` |
|
||||
| 连接 | `POST /api/session/connect` 错误密码 | 通过 | `success=false`,返回 Access denied,未暴露密码明文 |
|
||||
| Collection | `GET /api/collections` | 通过 | 返回 `PE`、`PKUSEHR` |
|
||||
| 目录浏览 | `GET /api/server-tree` | 通过 | 指定测试目录可浏览,返回 `name/path/serverPath/type/folder/latestVersion/checkinDate` |
|
||||
| 目录浏览 | `GET /api/server-folder/items` | 通过 | 指定测试目录返回 1 个条目 |
|
||||
| Workspace | `POST /api/workspace/ensure` | 通过 | 复用 `mactfs-ai-subapp-pm-mactfs`,`created=false` |
|
||||
| Workspace | `GET /api/workspace` | 通过 | 返回当前 workspace 和 1 条 mapping |
|
||||
| Mapping | `GET /api/mappings` | 通过 | 返回 1 条测试 mapping |
|
||||
| Mapping | `DELETE /api/mappings` | 通过 | 删除后 mapping 数量为 0 |
|
||||
| Mapping | `POST /api/mappings`,`getLatest=true` | 通过 | 恢复 mapping,联动 Get Latest:`updated=1`、`operations=2`、`conflicts=0`、`failures=0` |
|
||||
| Get Latest | `POST /api/files/get-latest` | 通过 | `updated=1`、`operations=2`、`conflicts=0`、`failures=0` |
|
||||
| Pending | 初始 `GET /api/pending-changes` | 通过 | pending 数量为 0 |
|
||||
| 目录对比 | `POST /api/compare/folder` | 有问题 | API 成功返回,但同步后误报 `localModified`,详见问题 P1-1 |
|
||||
| 历史 | 目录 `GET /api/history?folder=true` | 通过 | 返回 3 条历史,最近 changeset 包含 `678012`、`678011`、`678008` |
|
||||
| 历史 | 文件 `GET /api/history` | 通过 | 已有测试文件返回 2 条历史 |
|
||||
| Changeset | `GET /api/history/changeset?changeset=678012` | 通过 | 返回 1 个文件 |
|
||||
| Diff | `POST /api/diff/revisions` | 通过 | `678011` vs `678012` 返回 5 行 diff,包含 revision 2 |
|
||||
| Diff | `POST /api/diff/local-latest` 无本地改动 | 通过 | 返回 4 行文本,无差异标记 |
|
||||
| Add | `POST /api/files/add` | 通过 | 新增测试文件 `affected=1` |
|
||||
| Pending | 新增后 `GET /api/pending-changes` | 通过 | 状态为 `pendingAdd` |
|
||||
| Checkin | 缺少 comment 调用 `/api/checkin` | 通过 | `success=false`,`Missing required field: comment` |
|
||||
| Checkin | 有 comment 调用 `/api/checkin` | 通过 | 生成 changeset `678021` |
|
||||
| Pending | checkin 后查询 | 通过 | pending 数量为 0 |
|
||||
| Checkout | `POST /api/files/checkout` | 通过 | `affected=1` |
|
||||
| Pending | checkout 后查询 | 通过 | 状态为 `pendingEdit` |
|
||||
| Diff | 本地修改后 `POST /api/diff/local-latest` | 通过 | 返回 5 行 diff,包含本地新增行 |
|
||||
| Undo | `POST /api/files/undo` 撤销编辑 | 通过 | `affected=1`,pending 清空,本地内容恢复 |
|
||||
| Delete | `POST /api/files/delete` | 通过 | `affected=1`,状态为 `pendingDelete` |
|
||||
| Undo | `POST /api/files/undo` 撤销删除 | 通过 | `affected=1`,pending 清空,本地文件恢复 |
|
||||
| 日志 | `GET /api/logs` | 通过 | 返回 42 条操作日志,包含成功和失败操作 |
|
||||
|
||||
## 五、测试产生的数据
|
||||
|
||||
本轮新增并提交了 1 个测试文件:
|
||||
|
||||
- Server Path:`$/北京排水集团人力系统/5SRC/MicroFront/subapp_pm/mactfs/stage2-api-20260606151706.txt`
|
||||
- Local Path:`/Users/fenghp/Desktop/DEV/mactfs-ai-workspace/stage2-api-20260606151706.txt`
|
||||
- Checkin comment:`mactfs stage2 api smoke 20260606151706`
|
||||
- Changeset:`678021`
|
||||
|
||||
本轮未提交删除操作。最终状态:
|
||||
|
||||
- 测试 Workspace 保留。
|
||||
- 测试 Mapping 保留 1 条。
|
||||
- 测试文件保留在服务端测试目录中。
|
||||
- 最终 pending changes 为 0。
|
||||
- `~/.mactfs/config.json` 已恢复为测试前状态:测试前不存在,测试后已删除。
|
||||
|
||||
## 六、发现问题
|
||||
|
||||
### P1-1:目录对比在已同步且无 pending changes 时误报 `localModified`
|
||||
|
||||
现象:
|
||||
|
||||
- 执行 `POST /api/files/get-latest` 成功,返回 `conflicts=0`、`failures=0`。
|
||||
- 执行 `GET /api/pending-changes` 返回 0。
|
||||
- 随后执行 `POST /api/compare/folder`,仍返回 `localModified`。
|
||||
|
||||
证据:
|
||||
|
||||
```text
|
||||
$/北京排水集团人力系统/5SRC/MicroFront/subapp_pm/mactfs/ai-smoke-20260606051038.txt
|
||||
status=localModified
|
||||
localVersion=678012
|
||||
latestVersion=678012
|
||||
|
||||
$/北京排水集团人力系统/5SRC/MicroFront/subapp_pm/mactfs/stage2-api-20260606151706.txt
|
||||
status=localModified
|
||||
localVersion=678021
|
||||
latestVersion=678021
|
||||
```
|
||||
|
||||
判断:
|
||||
|
||||
- `localVersion` 与 `latestVersion` 相同,且 pending changes 为 0,说明工作区实际是干净的。
|
||||
- 当前 `compareFolder` 的 `localModified` 判断疑似依赖本地文件 mtime 与 TFS checkinDate 比较,导致刚同步或 undo 后的文件被误判为本地修改。
|
||||
|
||||
影响:
|
||||
|
||||
- 会影响阶段四 UI 的目录对比页面。
|
||||
- 用户可能看到没有实际 pending changes 的文件被标为本地已修改。
|
||||
|
||||
建议:
|
||||
|
||||
- 后续修复 `MacTfsCoreService.compareFolder` 的本地修改判断。
|
||||
- 优先以 TFS pending changes 和版本号差异作为状态依据;如果要基于 mtime 判断,需要结合 workspace 本地版本元数据,避免仅凭 `lastModified > checkinDate` 判定。
|
||||
|
||||
## 七、未覆盖项
|
||||
|
||||
- 未通过真实慢 TFS 请求触发 504 超时;当前仅确认所有 API 响应包含 `durationMs`,代码路径定义了超时返回 `Operation timed out`。
|
||||
- 未测试端口冲突;本轮启动前 `38765` 未被占用。
|
||||
- 未测试 PRD 中旧路径形式 `/api/workspaces/:name/mappings`,当前源码实现的阶段二实际路由是 `/api/workspace`、`/api/workspace/ensure`、`/api/mappings`。
|
||||
- 未测试 Frontend UI;当前阶段二不包含 UI。
|
||||
|
||||
## 八、结论
|
||||
|
||||
阶段二 Server API 主链路已完成真实 TFS HTTP 验证:
|
||||
|
||||
- 服务启动、Token 鉴权、健康检查、配置读写通过。
|
||||
- 连接、Collection、服务端目录浏览通过。
|
||||
- Workspace 复用、Mapping 删除/恢复、Get Latest 通过。
|
||||
- 文件 add、checkout、delete、undo、checkin、pending changes 通过。
|
||||
- history、changeset、local-latest diff、revisions diff 通过。
|
||||
- 操作日志可读取,失败操作也会进入日志。
|
||||
|
||||
除 `compareFolder` 在干净工作区误报 `localModified` 外,阶段二 Server API 可用。该问题不影响 pending changes 和 checkin 结果,但会影响后续 UI 目录对比展示,应在进入目录对比 UI 或 Feature E2E 前修复。
|
||||
|
||||
## 九、复测记录
|
||||
|
||||
复测时间:2026-06-06 15:34
|
||||
|
||||
复测原因:
|
||||
|
||||
- 针对 P1-1:目录对比在已同步且无 pending changes 时误报 `localModified`。
|
||||
|
||||
修复点:
|
||||
|
||||
- `MacTfsCoreService.resolveDiffStatus` 调整本地修改判断。
|
||||
- `mtime` 仅在远端版本变化时作为辅助信号,避免 `Get Latest` 后本地文件时间晚于签入时间导致误报。
|
||||
|
||||
复测命令:
|
||||
|
||||
```bash
|
||||
cd /Users/fenghp/Desktop/DEV/project/mydev/mactfs
|
||||
env JAVA_HOME=/Users/fenghp/Desktop/DEV/project/mydev/zulu8.94.0.17-ca-jdk8.0.492-macosx_x64/Contents/Home \
|
||||
arch -x86_64 ../tfsIntegration/gradlew clean build installDist
|
||||
```
|
||||
|
||||
复测结果:
|
||||
|
||||
| 测试项 | 结果 | 关键结果 |
|
||||
|---|---|---|
|
||||
| 构建 | 通过 | `BUILD SUCCESSFUL` |
|
||||
| 服务启动 | 通过 | 监听 `127.0.0.1:38765` |
|
||||
| 连接 | 通过 | `collectionCount=2` |
|
||||
| Mapping 查询 | 通过 | 测试目录 mapping 数量为 1 |
|
||||
| 服务端目录浏览 | 通过 | 指定测试目录返回 2 个条目 |
|
||||
| Get Latest | 通过 | `updated=2`、`operations=3`、`conflicts=0`、`failures=0` |
|
||||
| Pending Changes | 通过 | pending 数量为 0 |
|
||||
| 目录对比 | 通过 | diff 数量为 0,未再出现 `localModified` |
|
||||
|
||||
复测结论:
|
||||
|
||||
- P1-1 已修复。
|
||||
- 严格顺序执行 `get-latest -> pending-changes -> compare-folder` 后,目录对比返回空差异列表。
|
||||
- 阶段二 Server API 复测通过。
|
||||
Reference in New Issue
Block a user