fix: align cli routes with backend routers

This commit is contained in:
2026-04-03 13:58:15 +00:00
parent b287b1ff17
commit 84150df4d5
3 changed files with 124 additions and 53 deletions

View File

@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"io"
"net/url"
"git.hangman-lab.top/zhi/HarborForge.Cli/internal/client"
"git.hangman-lab.top/zhi/HarborForge.Cli/internal/config"
@@ -23,11 +24,35 @@ type proposeResponse struct {
CreatedAt string `json:"created_at"`
}
type projectLookup struct {
ID int `json:"id"`
ProjectCode string `json:"project_code"`
}
func resolveProposalProject(c *client.Client, proposalCode string) string {
data, err := c.Get("/projects")
if err != nil {
output.Errorf("failed to list projects for proposal lookup: %v", err)
}
var projects []projectLookup
if err := json.Unmarshal(data, &projects); err != nil {
output.Errorf("cannot parse project list for proposal lookup: %v", err)
}
for _, p := range projects {
if _, err := c.Get("/projects/" + p.ProjectCode + "/proposals/" + proposalCode); err == nil {
return p.ProjectCode
}
}
output.Errorf("proposal not found: %s", proposalCode)
return ""
}
// RunProposeList implements `hf propose list --project <project-code>`.
func RunProposeList(args []string, tokenFlag string) {
token := ResolveToken(tokenFlag)
query := ""
project := ""
query := url.Values{}
for i := 0; i < len(args); i++ {
switch args[i] {
case "--project":
@@ -35,32 +60,35 @@ func RunProposeList(args []string, tokenFlag string) {
output.Error("--project requires a value")
}
i++
query = appendQuery(query, "project", args[i])
project = args[i]
case "--status":
if i+1 >= len(args) {
output.Error("--status requires a value")
}
i++
query = appendQuery(query, "status", args[i])
query.Set("status", args[i])
case "--order-by":
if i+1 >= len(args) {
output.Error("--order-by requires a value")
}
i++
query = appendQuery(query, "order_by", args[i])
query.Set("order_by", args[i])
default:
output.Errorf("unknown flag: %s", args[i])
}
}
if project == "" {
output.Error("usage: hf propose list --project <project-code> [--status <status>] [--order-by <field>]")
}
cfg, err := config.Load()
if err != nil {
output.Errorf("config error: %v", err)
}
c := client.New(cfg.BaseURL, token)
path := "/proposes"
if query != "" {
path += "?" + query
path := "/projects/" + project + "/proposals"
if encoded := query.Encode(); encoded != "" {
path += "?" + encoded
}
data, err := c.Get(path)
if err != nil {
@@ -105,7 +133,8 @@ func RunProposeGet(proposeCode, tokenFlag string) {
output.Errorf("config error: %v", err)
}
c := client.New(cfg.BaseURL, token)
data, err := c.Get("/proposes/" + proposeCode)
project := resolveProposalProject(c, proposeCode)
data, err := c.Get("/projects/" + project + "/proposals/" + proposeCode)
if err != nil {
output.Errorf("failed to get proposal: %v", err)
}
@@ -178,9 +207,8 @@ func RunProposeCreate(args []string, tokenFlag string) {
}
payload := map[string]interface{}{
"project_code": project,
"title": title,
"description": desc,
"title": title,
"description": desc,
}
body, err := json.Marshal(payload)
@@ -193,7 +221,7 @@ func RunProposeCreate(args []string, tokenFlag string) {
output.Errorf("config error: %v", err)
}
c := client.New(cfg.BaseURL, token)
data, err := c.Post("/proposes", bytes.NewReader(body))
data, err := c.Post("/projects/"+project+"/proposals", bytes.NewReader(body))
if err != nil {
output.Errorf("failed to create proposal: %v", err)
}
@@ -253,7 +281,8 @@ func RunProposeUpdate(proposeCode string, args []string, tokenFlag string) {
output.Errorf("config error: %v", err)
}
c := client.New(cfg.BaseURL, token)
_, err = c.Patch("/proposes/"+proposeCode, bytes.NewReader(body))
project := resolveProposalProject(c, proposeCode)
_, err = c.Patch("/projects/"+project+"/proposals/"+proposeCode, bytes.NewReader(body))
if err != nil {
output.Errorf("failed to update proposal: %v", err)
}
@@ -311,7 +340,8 @@ func RunProposeAccept(proposeCode string, args []string, tokenFlag string) {
output.Errorf("config error: %v", err)
}
c := client.New(cfg.BaseURL, token)
data, err := c.Post("/proposes/"+proposeCode+"/accept", bytes.NewReader(body))
project := resolveProposalProject(c, proposeCode)
data, err := c.Post("/projects/"+project+"/proposals/"+proposeCode+"/accept", bytes.NewReader(body))
if err != nil {
output.Errorf("failed to accept proposal: %v", err)
}
@@ -380,7 +410,8 @@ func RunProposeReject(proposeCode string, args []string, tokenFlag string) {
output.Errorf("config error: %v", err)
}
c := client.New(cfg.BaseURL, token)
_, err = c.Post("/proposes/"+proposeCode+"/reject", body)
project := resolveProposalProject(c, proposeCode)
_, err = c.Post("/projects/"+project+"/proposals/"+proposeCode+"/reject", body)
if err != nil {
output.Errorf("failed to reject proposal: %v", err)
}
@@ -397,7 +428,8 @@ func RunProposeReopen(proposeCode, tokenFlag string) {
output.Errorf("config error: %v", err)
}
c := client.New(cfg.BaseURL, token)
_, err = c.Post("/proposes/"+proposeCode+"/reopen", nil)
project := resolveProposalProject(c, proposeCode)
_, err = c.Post("/projects/"+project+"/proposals/"+proposeCode+"/reopen", nil)
if err != nil {
output.Errorf("failed to reopen proposal: %v", err)
}