Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,12 @@ python app.py # http://0.0.0.0:5001 (debug + 自动重载)

启动时自动:建表 → 轻量迁移 → 写种子(默认账号 admin/admin123、tiger/123456;RBAC 菜单;示例模型)。

健康检查:`GET http://127.0.0.1:5001/api/health` → `{"code":0,"message":"ok"}`。
健康检查:`GET http://127.0.0.1:5001/api/health` → 返回 `{"status":"ok","code":0,"message":"ok"}`(HTTP 200,不加载任何重模型 / 推理库)。

```bash
curl http://127.0.0.1:5001/api/health
# {"status":"ok","code":0,"message":"ok"}
```

单独初始化种子(可选):`python seed.py`。

Expand Down
2 changes: 1 addition & 1 deletion backend/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def create_app():

@app.get("/api/health")
def health():
return jsonify(code=0, message="ok")
return jsonify(status="ok", code=0, message="ok")

# JWT 异常 -> 统一 JSON
@jwt.unauthorized_loader
Expand Down
40 changes: 40 additions & 0 deletions backend/unittests/test_health.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""GET /api/health 健康检查接口单测(不加载重模型 / 不依赖 MySQL)。

import app 会连带导入 routes(cv2/numpy/inference 等重依赖),这里在导入前
用空壳模块占位,并把数据库指向 sqlite 内存库,避免拉起 MySQL / 推理栈。
"""
import sys
import types

for _heavy in ("cv2", "numpy", "inference", "ultralytics", "torch", "pymysql"):
if _heavy not in sys.modules:
sys.modules[_heavy] = types.ModuleType(_heavy)

import config

config.Config.SQLALCHEMY_DATABASE_URI = "sqlite://"

from app import app as app # noqa: E402,F401 模块级 create_app() 已在此执行

app.config["TESTING"] = True
client = app.test_client()


def test_health_returns_200_and_status_ok():
resp = client.get("/api/health")
assert resp.status_code == 200
payload = resp.get_json()
assert payload is not None
assert payload["status"] == "ok"


def test_health_keeps_legacy_fields():
resp = client.get("/api/health")
payload = resp.get_json()
assert payload["code"] == 0
assert payload["message"] == "ok"


def test_health_content_type_json():
resp = client.get("/api/health")
assert resp.content_type.startswith("application/json")