package commands import ( "bytes" "encoding/json" "fmt" "git.hangman-lab.top/zhi/HarborForge.Cli/internal/output" ) type worklogResponse struct { ID int `json:"id"` TaskID int `json:"task_id"` UserID int `json:"user_id"` Hours float64 `json:"hours"` Description *string `json:"description"` LoggedDate string `json:"logged_date"` CreatedAt string `json:"created_at"` } func RunWorklogAdd(taskCode string, hours float64, desc, date, tokenFlag string) { if taskCode == "" || hours <= 0 { output.Error("usage: hf worklog add --task --hours [--desc ] [--date ]") } c := newAuthedClient(tokenFlag) taskID := resolveTaskID(c, taskCode) me := currentUser(c) payload := map[string]interface{}{ "task_id": taskID, "user_id": me.ID, "hours": hours, } if desc != "" { payload["description"] = desc } if date != "" { payload["logged_date"] = date } body, err := json.Marshal(payload) if err != nil { output.Errorf("cannot marshal payload: %v", err) } data, err := c.Post("/worklogs", bytes.NewReader(body)) if err != nil { output.Errorf("failed to add worklog: %v", err) } if output.JSONMode { var raw json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { output.Errorf("invalid JSON response: %v", err) } output.PrintJSON(raw) return } var resp worklogResponse if err := json.Unmarshal(data, &resp); err != nil { output.Errorf("cannot parse response: %v", err) } fmt.Printf("worklog added to %s: #%d (%.2fh)\n", taskCode, resp.ID, resp.Hours) } func RunWorklogList(taskCode, username, tokenFlag string) { if taskCode == "" && username == "" { output.Error("usage: hf worklog list [--task ] [--user ]") } if taskCode != "" && username != "" { output.Error("choose only one of --task or --user ") } c := newAuthedClient(tokenFlag) path := "" if taskCode != "" { taskID := resolveTaskID(c, taskCode) path = fmt.Sprintf("/tasks/%d/worklogs", taskID) } else { path = fmt.Sprintf("/users/%s/worklogs", username) } data, err := c.Get(path) if err != nil { output.Errorf("failed to list worklogs: %v", err) } if output.JSONMode { var raw json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { output.Errorf("invalid JSON response: %v", err) } output.PrintJSON(raw) return } var logs []worklogResponse if err := json.Unmarshal(data, &logs); err != nil { output.Errorf("cannot parse worklog list: %v", err) } headers := []string{"ID", "TASK", "USER", "HOURS", "DATE", "DESCRIPTION"} var rows [][]string for _, item := range logs { desc := "" if item.Description != nil { desc = *item.Description } if len(desc) > 40 { desc = desc[:37] + "..." } rows = append(rows, []string{ fmt.Sprintf("%d", item.ID), fmt.Sprintf("%d", item.TaskID), fmt.Sprintf("%d", item.UserID), fmt.Sprintf("%.2f", item.Hours), item.LoggedDate, desc, }) } output.PrintTable(headers, rows) }