package commands import ( "fmt" "git.tjp.lol/punchcard/internal/actions" punchctx "git.tjp.lol/punchcard/internal/context" "github.com/spf13/cobra" ) func NewAddProjectCmd() *cobra.Command { cmd := &cobra.Command{ Use: "project ", Short: "Add a new project", Long: `Add a new project to the database. Client can be specified by ID or name using the -c/--client flag. Examples: punch add project "Website Redesign" -c "Acme Corp" punch add project "Mobile App" --client 1`, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { projectName := args[0] clientRef, err := cmd.Flags().GetString("client") if err != nil { return fmt.Errorf("failed to get client flag: %w", err) } if clientRef == "" { return fmt.Errorf("client is required, use -c/--client flag") } billableRateFloat, _ := cmd.Flags().GetFloat64("hourly-rate") var billableRate *float64 if billableRateFloat > 0 { billableRate = &billableRateFloat } q := punchctx.GetDB(cmd.Context()) if q == nil { return fmt.Errorf("database not available in context") } a := actions.New(q) project, err := a.CreateProject(cmd.Context(), projectName, clientRef, billableRate) if err != nil { return err } // Get client name for output client, err := a.FindClient(cmd.Context(), clientRef) if err != nil { return fmt.Errorf("failed to get client name: %w", err) } output := fmt.Sprintf("Created project: %s for client %s (ID: %d)", project.Name, client.Name, project.ID) cmd.Print(output + "\n") return nil }, } cmd.Flags().StringP("client", "c", "", "Client name or ID (required)") cmd.Flags().Float64P("hourly-rate", "r", 0, "Default hourly billable rate for this project") if err := cmd.MarkFlagRequired("client"); err != nil { panic(fmt.Sprintf("Failed to mark client flag as required: %v", err)) } return cmd }