package cmd import ( "fmt" "strconv" "strings" "github.com/spf13/cobra" ) var addCmd = &cobra.Command{ Use: "add", Short: "Add a new part", RunE: func(cmd *cobra.Command, args []string) error { title, _ := cmd.Flags().GetString("title") if title == "" { return fmt.Errorf("--title is required") } payload := map[string]interface{}{ "title": title, } if v, _ := cmd.Flags().GetString("type"); v != "" { payload["type"] = v } if v, _ := cmd.Flags().GetString("category"); v != "" { payload["category"] = v } if v, _ := cmd.Flags().GetString("manufacturer"); v != "" { payload["manufacturer"] = v } if cmd.Flags().Changed("quantity") { v, _ := cmd.Flags().GetInt("quantity") payload["quantity"] = v } if v, _ := cmd.Flags().GetString("location"); v != "" { payload["location"] = v } if v, _ := cmd.Flags().GetString("notes"); v != "" { payload["notes"] = v } if v, _ := cmd.Flags().GetString("tags"); v != "" { payload["tags"] = strings.Split(v, ",") } properties := parseProperties(cmd) if len(properties) > 0 { payload["properties"] = properties } part, err := GetClient().CreatePart(payload) if err != nil { return fmt.Errorf("failed to create part: %w", err) } fmt.Printf("Created part: %s\n", part.ID) return nil }, } func init() { addCmd.Flags().String("title", "", "Part title (required)") addCmd.Flags().String("type", "", "Part type") addCmd.Flags().String("category", "", "Part category") addCmd.Flags().String("manufacturer", "", "Manufacturer") addCmd.Flags().Int("quantity", 1, "Quantity") addCmd.Flags().String("location", "", "Storage location") addCmd.Flags().String("notes", "", "Notes") addCmd.Flags().String("tags", "", "Comma-separated tags") addCmd.Flags().StringArray("property", []string{}, "Property in key=value format (repeatable)") rootCmd.AddCommand(addCmd) } // parseProperties extracts --property key=value flags into a map. func parseProperties(cmd *cobra.Command) map[string]interface{} { props := map[string]interface{}{} pairs, _ := cmd.Flags().GetStringArray("property") for _, pair := range pairs { parts := strings.SplitN(pair, "=", 2) if len(parts) != 2 { continue } k, v := strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]) if i, err := strconv.ParseInt(v, 10, 64); err == nil { props[k] = i } else if f, err := strconv.ParseFloat(v, 64); err == nil { props[k] = f } else if b, err := strconv.ParseBool(v); err == nil { props[k] = b } else { props[k] = v } } return props }