package client import ( "context" "errors" "net/http" "net/url" "strings" ) type Project struct { ID string `json:"id"` Name string `json:"name"` Description string `json:"description,omitempty"` Status string `json:"status"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` } func (c *Client) ListProjects(ctx context.Context) ([]Project, error) { var response struct { Projects []Project `json:"projects"` } if err := c.getJSON(ctx, "/api/v1/projects", &response); err != nil { return nil, err } return response.Projects, nil } func (c *Client) GetProject(ctx context.Context, project string) (Project, error) { project = strings.TrimSpace(project) if project == "" { return Project{}, errors.New("项目标识不能为空") } var result Project path := "/api/v1/projects/" + url.PathEscape(project) if err := c.getJSON(ctx, path, &result); err != nil { return Project{}, err } return result, nil } func (c *Client) CreateProject(ctx context.Context, project Project) (Project, error) { var result Project if err := c.postJSON(ctx, "/api/v1/projects", map[string]string{ "id": project.ID, "name": project.Name, "description": project.Description, }, &result); err != nil { return Project{}, err } return result, nil } func (c *Client) UpdateProject(ctx context.Context, project Project) (Project, error) { project.ID = strings.TrimSpace(project.ID) if err := validateProjectID(project.ID); err != nil { return Project{}, err } var result Project path := "/api/v1/projects/" + url.PathEscape(project.ID) if err := c.patchJSON(ctx, path, map[string]string{ "name": project.Name, "description": project.Description, "status": project.Status, }, &result); err != nil { return Project{}, err } return result, nil } func (c *Client) ProjectHealth(ctx context.Context) error { request, err := c.newRequest(ctx, http.MethodGet, "/healthz", nil) if err != nil { return err } response, err := c.httpClient.Do(request) if err != nil { return err } defer response.Body.Close() return checkResponse(response) }