104 lines
4.2 KiB
Python
104 lines
4.2 KiB
Python
from __future__ import annotations
|
|
|
|
from .shared import *
|
|
|
|
from ...services.sstc.entity_lookup import _ensure_project, _ensure_release
|
|
from ...services.sstc.governance import _require_manager
|
|
from ...services.sstc.signal_core import _as_dict, _parse_node_id, _parse_project_id
|
|
|
|
router = APIRouter(tags=["sstc"])
|
|
|
|
@router.patch("/projects/{project_id}/releases/{release_node_id}/verification/items/{item_id}")
|
|
async def patch_release_verification_item(
|
|
project_id: str,
|
|
release_node_id: str,
|
|
item_id: str,
|
|
body: ReleaseVerificationItemPatchRequest,
|
|
permission_user: User = Depends(require_project_member_or_manager),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
_ = permission_user
|
|
_require_manager(current_user)
|
|
pid = _parse_project_id(project_id)
|
|
rid = _parse_node_id(release_node_id, "release_node_id")
|
|
tenant_id = int(current_user.tenant_id)
|
|
await _ensure_project(SSTCService(db, tenant_id=tenant_id), pid)
|
|
release_node = await _ensure_release(
|
|
db, tenant_id=tenant_id, project_id=pid, release_node_id=rid
|
|
)
|
|
content = _as_dict(release_node.content)
|
|
items = content.get("verification_items")
|
|
if not isinstance(items, list) or len(items) == 0:
|
|
raise HTTPException(status_code=404, detail="验证清单不存在,请先生成")
|
|
|
|
target = None
|
|
for item in items:
|
|
if str(item.get("id")) == item_id:
|
|
target = item
|
|
break
|
|
if target is None:
|
|
raise HTTPException(status_code=404, detail="验证项不存在")
|
|
|
|
target["status"] = body.status
|
|
if body.status == "done":
|
|
target["verified_by"] = str(current_user.id)
|
|
target["verified_at"] = now_cn_aware().isoformat()
|
|
else:
|
|
target["verified_by"] = None
|
|
target["verified_at"] = None
|
|
target["note"] = body.note
|
|
|
|
done_count = len([item for item in items if str(item.get("status") or "").lower() == "done"])
|
|
content["verification_items"] = items
|
|
content["verification_progress"] = {"done": done_count, "total": len(items)}
|
|
content["verification_done"] = done_count == len(items) and len(items) > 0
|
|
release_node.content = content
|
|
await db.commit()
|
|
return success_response(
|
|
{
|
|
"release_id": str(release_node.id),
|
|
"item_id": item_id,
|
|
"verification_progress": content["verification_progress"],
|
|
"verification_done": content["verification_done"],
|
|
}
|
|
)
|
|
|
|
@router.post("/projects/{project_id}/releases/{release_node_id}/verification/complete")
|
|
async def complete_release_verification(
|
|
project_id: str,
|
|
release_node_id: str,
|
|
permission_user: User = Depends(require_project_member_or_manager),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
_ = permission_user
|
|
_require_manager(current_user)
|
|
pid = _parse_project_id(project_id)
|
|
rid = _parse_node_id(release_node_id, "release_node_id")
|
|
tenant_id = int(current_user.tenant_id)
|
|
await _ensure_project(SSTCService(db, tenant_id=tenant_id), pid)
|
|
release_node = await _ensure_release(
|
|
db, tenant_id=tenant_id, project_id=pid, release_node_id=rid
|
|
)
|
|
status_raw = str(release_node.status or "").lower()
|
|
if status_raw not in {"online", "releasing"}:
|
|
raise HTTPException(status_code=409, detail="仅上线中的发布计划可完成验证")
|
|
content = _as_dict(release_node.content)
|
|
items = content.get("verification_items", [])
|
|
if not isinstance(items, list) or len(items) == 0:
|
|
raise HTTPException(status_code=409, detail="验证清单为空,请先生成并完成验证项")
|
|
incomplete = [item for item in items if str(item.get("status") or "").lower() != "done"]
|
|
if incomplete:
|
|
raise HTTPException(status_code=409, detail="仍有未完成验证项,请先逐项完成")
|
|
now_str = now_cn_aware().isoformat()
|
|
content["verification_items"] = items
|
|
content["verification_done"] = True
|
|
content["verification_progress"] = {"done": len(items), "total": len(items)}
|
|
content["verified_at"] = now_str
|
|
release_node.content = content
|
|
release_node.status = "verified"
|
|
await db.commit()
|
|
return success_response({"id": str(release_node.id), "status": release_node.status})
|
|
|