feat: time tracking / work logs (create, list, summary, project summary, CLI commands)

This commit is contained in:
Zhi
2026-02-23 05:11:52 +00:00
parent 9f276464b2
commit 703103af91
4 changed files with 157 additions and 0 deletions

35
cli.py
View File

@@ -193,6 +193,30 @@ def cmd_overdue(args):
print(f" ⏰ #{i['id']} [{i['priority']}] {i['title']} (due: {due})")
def cmd_log_time(args):
from datetime import datetime
data = {
'issue_id': args.issue_id,
'user_id': args.user_id,
'hours': args.hours,
'logged_date': datetime.utcnow().isoformat(),
}
if args.desc:
data['description'] = args.desc
r = api('POST', '/worklogs', json=data)
print(f'Logged {r["hours"]}h on issue #{r["issue_id"]} (log #{r["id"]})')
def cmd_worklogs(args):
logs = api('GET', f'/issues/{args.issue_id}/worklogs')
for l in logs:
desc = f' - {l["description"]}' if l.get('description') else ''
print(f' [{l["id"]}] {l["hours"]}h by user#{l["user_id"]} on {l["logged_date"]}{desc}')
summary = api('GET', f'/issues/{args.issue_id}/worklogs/summary')
print(f' Total: {summary["total_hours"]}h ({summary["log_count"]} logs)')
def main():
parser = argparse.ArgumentParser(description="HarborForge CLI")
sub = parser.add_subparsers(dest="command")
@@ -267,6 +291,15 @@ def main():
p_overdue = sub.add_parser("overdue", help="List overdue issues")
p_overdue.add_argument("--project", "-p", type=int)
p_logtime = sub.add_parser('log-time', help='Log time on an issue')
p_logtime.add_argument('issue_id', type=int)
p_logtime.add_argument('user_id', type=int)
p_logtime.add_argument('hours', type=float)
p_logtime.add_argument('--desc', '-d', type=str)
p_worklogs = sub.add_parser('worklogs', help='List work logs for an issue')
p_worklogs.add_argument('issue_id', type=int)
args = parser.parse_args()
if not args.command:
parser.print_help()
@@ -287,6 +320,8 @@ def main():
"milestone-progress": cmd_milestone_progress,
"notifications": cmd_notifications,
"overdue": cmd_overdue,
"log-time": cmd_log_time,
"worklogs": cmd_worklogs,
}
cmds[args.command](args)