feat(review): 重构项目级单方案验收协作
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""通过 Delivery Desk API 创建作品或上传作品新版本。"""
|
||||
"""通过 Delivery Desk API 创建作品或提交新的验收轮次。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -37,11 +37,10 @@ def request_json(opener, url: str, *, method: str = "GET", data: bytes | None =
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description="通过 API 创建测试作品或上传新版本")
|
||||
parser = argparse.ArgumentParser(description="通过 API 创建测试作品或提交新的验收轮次")
|
||||
parser.add_argument("--base-url", default=os.getenv("DELIVERY_DESK_BASE_URL", "http://127.0.0.1:3010"))
|
||||
parser.add_argument("--project-id", type=int, default=None, help="不传时自动选择唯一可访问的项目")
|
||||
parser.add_argument("--collection-id", type=int, default=None, help="不传时自动选择项目下唯一的作品交付集")
|
||||
parser.add_argument("--work-id", type=int, default=None, help="传入后为该作品创建新版本")
|
||||
parser.add_argument("--work-id", type=int, default=None, help="传入后为该作品提交新的验收轮次")
|
||||
parser.add_argument("--external-id", default=None, help="调用方作品唯一标识,用于幂等创建和找回作品")
|
||||
parser.add_argument("--api-key", default=os.getenv("DELIVERY_DESK_API_KEY"))
|
||||
parser.add_argument("--username", default=os.getenv("DELIVERY_DESK_USERNAME", "operator"))
|
||||
@@ -99,16 +98,6 @@ def main() -> int:
|
||||
_, projects, _ = request_json(opener, f"{base_url}/api/projects", headers=auth_headers)
|
||||
project = choose_item(projects, args.project_id, "项目")
|
||||
project_id = int(project["id"])
|
||||
_, collections, _ = request_json(
|
||||
opener,
|
||||
f"{base_url}/api/projects/{project_id}/collections",
|
||||
headers=auth_headers,
|
||||
)
|
||||
collection = choose_item(collections, args.collection_id, "作品交付集")
|
||||
collection_id = int(collection["id"])
|
||||
if int(collection["project_id"]) != project_id:
|
||||
raise ApiError(f"作品交付集 {collection_id} 不属于项目 {project_id}")
|
||||
|
||||
title = args.title or f"API 测试作品 {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
image_urls = args.image_urls or ["https://placehold.co/1200x800/png?text=Delivery+Desk+API+Test"]
|
||||
upload_headers = {**auth_headers, "Content-Type": "application/json"}
|
||||
@@ -120,28 +109,29 @@ def main() -> int:
|
||||
}
|
||||
|
||||
if args.work_id is not None:
|
||||
_, current, _ = request_json(opener, f"{base_url}/api/notes/{args.work_id}", headers=auth_headers)
|
||||
if int(current["project"]["id"]) != project_id or int(current["collection"]["id"]) != collection_id:
|
||||
raise ApiError(f"作品 {args.work_id} 不属于选定的项目和作品交付集")
|
||||
_, current, _ = request_json(opener, f"{base_url}/api/works/{args.work_id}", headers=auth_headers)
|
||||
if int(current["project"]["id"]) != project_id:
|
||||
raise ApiError(f"作品 {args.work_id} 不属于选定的项目")
|
||||
status, work, _ = request_json(
|
||||
opener,
|
||||
f"{base_url}/api/notes/{args.work_id}/versions",
|
||||
f"{base_url}/api/works/{args.work_id}/rounds",
|
||||
method="POST",
|
||||
data=json.dumps(payload).encode("utf-8"),
|
||||
headers=upload_headers,
|
||||
)
|
||||
if status != 201 or not work or int(work.get("id", 0)) != args.work_id:
|
||||
raise ApiError("新版本接口没有返回目标作品")
|
||||
action = "version_created"
|
||||
raise ApiError("新验收轮次接口没有返回目标作品")
|
||||
action = "round_created"
|
||||
external_id = work.get("external_id")
|
||||
else:
|
||||
external_id = args.external_id or f"api-smoke-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
|
||||
create_payload = {**payload, "collectionId": collection_id, "externalId": external_id}
|
||||
create_payload = {**payload, "externalId": external_id}
|
||||
body = json.dumps(create_payload).encode("utf-8")
|
||||
status, work, _ = request_json(opener, f"{base_url}/api/notes", method="POST", data=body, headers=upload_headers)
|
||||
if status not in (200, 201) or not work or int(work.get("collection_id", 0)) != collection_id:
|
||||
raise ApiError("接口未返回属于目标作品交付集的作品")
|
||||
_, repeated, _ = request_json(opener, f"{base_url}/api/notes", method="POST", data=body, headers=upload_headers)
|
||||
works_url = f"{base_url}/api/projects/{project_id}/works"
|
||||
status, work, _ = request_json(opener, works_url, method="POST", data=body, headers=upload_headers)
|
||||
if status not in (200, 201) or not work or int(work.get("project_id", 0)) != project_id:
|
||||
raise ApiError("接口未返回属于目标项目的作品")
|
||||
_, repeated, _ = request_json(opener, works_url, method="POST", data=body, headers=upload_headers)
|
||||
if int(repeated.get("id", 0)) != int(work["id"]) or not repeated.get("idempotent"):
|
||||
raise ApiError("相同 externalId 的重复请求未通过幂等校验")
|
||||
action = "work_created" if status == 201 else "existing_work_returned"
|
||||
@@ -153,7 +143,6 @@ def main() -> int:
|
||||
"action": action,
|
||||
"group": project.get("group_name"),
|
||||
"project": project.get("name"),
|
||||
"collection": collection.get("name"),
|
||||
"work_id": work.get("id"),
|
||||
"external_id": external_id,
|
||||
"version_number": work.get("version_number"),
|
||||
|
||||
Reference in New Issue
Block a user