def test_dashboard_overview_uses_persisted_records(client, db_session): from models import ProcessingTask project_pending = client.post("/api/projects", json={ "name": "Pending Project", "status": "pending", }).json() project_ready = client.post("/api/projects", json={ "name": "Ready Project", "status": "ready", }).json() frame = client.post(f"/api/projects/{project_pending['id']}/frames", json={ "project_id": project_pending["id"], "frame_index": 0, "image_url": "frames/0.jpg", "width": 640, "height": 360, }).json() template = client.post("/api/templates", json={ "name": "Dashboard Template", "color": "#06b6d4", "z_index": 0, "classes": [], "rules": [], }).json() annotation = client.post("/api/ai/annotate", json={ "project_id": project_pending["id"], "frame_id": frame["id"], "template_id": template["id"], "mask_data": {"polygons": [[[0.1, 0.1], [0.9, 0.1], [0.9, 0.9]]]}, }) assert annotation.status_code == 201 task = ProcessingTask( task_type="parse_video", status="running", progress=35, message="正在使用 FFmpeg/OpenCV 拆帧", project_id=project_pending["id"], payload={"source_type": "video"}, ) db_session.add(task) db_session.commit() db_session.refresh(task) response = client.get("/api/dashboard/overview") assert response.status_code == 200 body = response.json() assert body["summary"]["project_count"] == 2 assert body["summary"]["frame_count"] == 1 assert body["summary"]["annotation_count"] == 1 assert body["summary"]["template_count"] == 1 assert body["summary"]["parsing_task_count"] == 1 assert body["tasks"] == [ { "id": f"task-{task.id}", "task_id": task.id, "project_id": project_pending["id"], "name": "Pending Project", "progress": 35, "status": "正在使用 FFmpeg/OpenCV 拆帧", "raw_status": "running", "frame_count": 0, "error": None, "updated_at": body["tasks"][0]["updated_at"], }, ] assert any(item["kind"] == "task" for item in body["activity"]) assert any(item["kind"] == "annotation" for item in body["activity"]) assert any(item["kind"] == "template" for item in body["activity"]) assert all(item["name"] != "Ready Project" for item in body["tasks"])