diff --git a/scripts/kanban_api.py b/scripts/kanban_api.py index c0afe8d..5ae58ca 100644 --- a/scripts/kanban_api.py +++ b/scripts/kanban_api.py @@ -17,6 +17,29 @@ def db(): return sqlite3.connect(KANBAN_DB) +def _fmt_ts(v): + """统一时间格式:epoch 或 ISO 字符串 → ISO 8601 字符串。 + DB 存储以 epoch 为主(CLI 写入),历史数据有少量 ISO 混存(半路接入), + 输出层统一成 ISO,调用方无需感知存储格式差异。""" + if v is None: + return None + if isinstance(v, (int, float)): + try: + return datetime.fromtimestamp(int(v)).strftime("%Y-%m-%dT%H:%M:%S") + except (OverflowError, OSError, ValueError): + return str(v) + s = str(v) + try: + # 已带 T 的 ISO 直接返回;纯数字字符串按 epoch 转 + if "T" in s: + return s[:19] + if s.isdigit(): + return datetime.fromtimestamp(int(s)).strftime("%Y-%m-%dT%H:%M:%S") + except (OverflowError, OSError, ValueError): + pass + return s + + class KanbanAPI(http.server.BaseHTTPRequestHandler): def _json(self, data, status=200): self.send_response(status) @@ -37,6 +60,7 @@ class KanbanAPI(http.server.BaseHTTPRequestHandler): title = body.get("title", "") assignee = body.get("assignee", "") body_text = body.get("body", "") + created_by = body.get("created_by", "") or body.get("author", "") if not title: return self._json({"error": "title required"}, 400) @@ -47,6 +71,8 @@ class KanbanAPI(http.server.BaseHTTPRequestHandler): cmd += ["--assignee", assignee] if body_text: cmd += ["--body", body_text] + if created_by: + cmd += ["--created-by", created_by] r = subprocess.run(cmd, capture_output=True, text=True, timeout=30) if r.returncode != 0: @@ -66,6 +92,7 @@ class KanbanAPI(http.server.BaseHTTPRequestHandler): title = body.get("title", "") assignee = body.get("assignee", "") body_text = body.get("body", "") + created_by = body.get("created_by", "") or body.get("author", "") if not title: return self._json({"error": "title required"}, 400) @@ -75,6 +102,8 @@ class KanbanAPI(http.server.BaseHTTPRequestHandler): cmd += ["--assignee", assignee] if body_text: cmd += ["--body", body_text] + if created_by: + cmd += ["--created-by", created_by] r = subprocess.run(cmd, capture_output=True, text=True, timeout=30) if r.returncode != 0: return self._json({"error": r.stderr.strip()}, 500) @@ -132,7 +161,7 @@ class KanbanAPI(http.server.BaseHTTPRequestHandler): for r in rows: tasks.append({ "id": r[0], "title": r[1], "body": r[2], "status": r[3], - "assignee": r[4], "created_by": r[5], "created_at": r[6] + "assignee": r[4], "created_by": r[5], "created_at": _fmt_ts(r[6]) }) return self._json({"tasks": tasks}) @@ -208,7 +237,7 @@ class KanbanAPI(http.server.BaseHTTPRequestHandler): return self._json({ "id": row[0], "title": row[1], "body": row[2], "status": row[3], "assignee": row[4], - "created_by": row[5], "created_at": row[6] + "created_by": row[5], "created_at": _fmt_ts(row[6]) }) else: