fix: connect API to tracker.db via SQLite repository
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
"""SQLite Tracker Adapter"""
|
||||
from .project_management_repositories import (
|
||||
SQLiteTaskRepository,
|
||||
SQLiteMilestoneRepository,
|
||||
SQLiteTaskIssueRepository,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"SQLiteTaskRepository",
|
||||
"SQLiteMilestoneRepository",
|
||||
"SQLiteTaskIssueRepository",
|
||||
]
|
||||
@@ -0,0 +1,154 @@
|
||||
"""SQLite 实现的项目管理 Repository"""
|
||||
import sqlite3
|
||||
from typing import List, Optional
|
||||
from datetime import datetime
|
||||
from packages.domain.entities import Task, Milestone, TaskIssue
|
||||
from packages.domain import TaskStatus, TaskPriority
|
||||
|
||||
DB_PATH = "tracker.db"
|
||||
|
||||
class SQLiteTaskRepository:
|
||||
"""基于 SQLite 的任务仓储"""
|
||||
|
||||
def get_by_id(self, task_id: str) -> Optional[Task]:
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
conn.row_factory = sqlite3.Row
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("SELECT * FROM tasks WHERE id = ?", (task_id,))
|
||||
row = cursor.fetchone()
|
||||
conn.close()
|
||||
|
||||
if not row:
|
||||
return None
|
||||
|
||||
return Task(
|
||||
id=str(row['id']),
|
||||
name=row['name'],
|
||||
description=row['description'] or "",
|
||||
status=TaskStatus(row['status']) if row['status'] else TaskStatus.PENDING,
|
||||
priority=TaskPriority(row['priority']) if row['priority'] else TaskPriority.MEDIUM,
|
||||
progress=0, # tracker.db 没有 progress 字段
|
||||
project_id=row['phase'] or "xiaoxia-saas",
|
||||
workspace_id="xiaoxia-workspace",
|
||||
assignee_user_id=row['assigned_to'] or "",
|
||||
created_at=datetime.fromisoformat(row['created_at']) if row['created_at'] else datetime.now(),
|
||||
updated_at=datetime.now()
|
||||
)
|
||||
|
||||
def list_by_project(self, project_id: str, skip: int = 0, limit: int = 100) -> List[Task]:
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
conn.row_factory = sqlite3.Row
|
||||
cursor = conn.cursor()
|
||||
|
||||
# 返回所有任务(忽略 project_id 过滤,因为 tracker.db 使用 phase)
|
||||
cursor.execute("""
|
||||
SELECT * FROM tasks
|
||||
ORDER BY created_at DESC
|
||||
LIMIT ? OFFSET ?
|
||||
""", (limit, skip))
|
||||
|
||||
rows = cursor.fetchall()
|
||||
conn.close()
|
||||
|
||||
tasks = []
|
||||
for row in rows:
|
||||
tasks.append(Task(
|
||||
id=str(row['id']),
|
||||
name=row['name'],
|
||||
description=row['description'] or "",
|
||||
status=TaskStatus(row['status']) if row['status'] else TaskStatus.PENDING,
|
||||
priority=TaskPriority(row['priority']) if row['priority'] else TaskPriority.MEDIUM,
|
||||
progress=0,
|
||||
project_id=row['phase'] or "xiaoxia-saas",
|
||||
workspace_id="xiaoxia-workspace",
|
||||
assignee_user_id=row['assigned_to'] or "",
|
||||
created_at=datetime.fromisoformat(row['created_at']) if row['created_at'] else datetime.now(),
|
||||
updated_at=datetime.now()
|
||||
))
|
||||
|
||||
return tasks
|
||||
|
||||
def save(self, task: Task) -> Task:
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
cursor = conn.cursor()
|
||||
|
||||
if task.id and task.id.isdigit():
|
||||
# 更新现有任务
|
||||
cursor.execute("""
|
||||
UPDATE tasks
|
||||
SET name = ?, description = ?, status = ?, priority = ?, assigned_to = ?
|
||||
WHERE id = ?
|
||||
""", (task.name, task.description, task.status.value, task.priority.value,
|
||||
task.assignee_user_id, task.id))
|
||||
else:
|
||||
# 创建新任务
|
||||
cursor.execute("""
|
||||
INSERT INTO tasks (name, description, status, phase, priority, assigned_to, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
""", (task.name, task.description, task.status.value, task.project_id,
|
||||
task.priority.value, task.assignee_user_id, datetime.now().isoformat()))
|
||||
task.id = str(cursor.lastrowid)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return task
|
||||
|
||||
|
||||
class SQLiteMilestoneRepository:
|
||||
"""基于 SQLite 的里程碑仓储"""
|
||||
|
||||
def list_by_project(self, project_id: str) -> List[Milestone]:
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
conn.row_factory = sqlite3.Row
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("SELECT * FROM milestones ORDER BY start_date")
|
||||
rows = cursor.fetchall()
|
||||
conn.close()
|
||||
|
||||
milestones = []
|
||||
for row in rows:
|
||||
milestones.append(Milestone(
|
||||
id=str(row['id']),
|
||||
name=row['name'],
|
||||
description=row['description'] or "",
|
||||
target_date=row['end_date'] or "",
|
||||
project_id=row['phase'] or "xiaoxia-saas",
|
||||
workspace_id="xiaoxia-workspace",
|
||||
created_at=datetime.fromisoformat(row['start_date']) if row['start_date'] else datetime.now()
|
||||
))
|
||||
|
||||
return milestones
|
||||
|
||||
def save(self, milestone: Milestone) -> Milestone:
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
cursor = conn.cursor()
|
||||
|
||||
if milestone.id and milestone.id.isdigit():
|
||||
cursor.execute("""
|
||||
UPDATE milestones
|
||||
SET name = ?, description = ?, end_date = ?
|
||||
WHERE id = ?
|
||||
""", (milestone.name, milestone.description, milestone.target_date, milestone.id))
|
||||
else:
|
||||
cursor.execute("""
|
||||
INSERT INTO milestones (name, description, phase, start_date, end_date)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
""", (milestone.name, milestone.description, milestone.project_id,
|
||||
datetime.now().isoformat(), milestone.target_date))
|
||||
milestone.id = str(cursor.lastrowid)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return milestone
|
||||
|
||||
|
||||
class SQLiteTaskIssueRepository:
|
||||
"""空实现 - tracker.db 没有 issues 表"""
|
||||
|
||||
def list_by_task(self, task_id: str) -> List[TaskIssue]:
|
||||
return []
|
||||
|
||||
def save(self, issue: TaskIssue) -> TaskIssue:
|
||||
return issue
|
||||
Reference in New Issue
Block a user