Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 60 additions & 49 deletions cmd/orchestration/instances/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
)

type InstancesDescribeStore struct {
WorkflowInstancesHistory []shared.WorkflowInstanceHistory `json:"workflowInstanceHistory"`
WorkflowInstancesHistory []shared.V2WorkflowInstanceHistory `json:"workflowInstanceHistory"`
}
type InstancesDescribeController struct {
store *InstancesDescribeStore
Expand Down Expand Up @@ -51,14 +51,14 @@ func (c *InstancesDescribeController) GetStore() *InstancesDescribeStore {
func (c *InstancesDescribeController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
store := fctl.GetStackStore(cmd.Context())

response, err := store.Client().Orchestration.V1.GetInstanceHistory(cmd.Context(), operations.GetInstanceHistoryRequest{
response, err := store.Client().Orchestration.V2.GetInstanceHistory(cmd.Context(), operations.V2GetInstanceHistoryRequest{
InstanceID: args[0],
})
if err != nil {
return nil, err
}

c.store.WorkflowInstancesHistory = response.GetWorkflowInstanceHistoryResponse.Data
c.store.WorkflowInstancesHistory = response.V2GetWorkflowInstanceHistoryResponse.Data

return c, nil
}
Expand All @@ -74,15 +74,15 @@ func (c *InstancesDescribeController) Render(cmd *cobra.Command, args []string)
return nil
}

func printHistoryBaseInfo(out io.Writer, name string, ind int, history shared.WorkflowInstanceHistory) {
func printHistoryBaseInfo(out io.Writer, name string, ind int, history shared.V2WorkflowInstanceHistory) {
fctl.Section.WithWriter(out).Printf("Stage %d : %s\n", ind, name)
fctl.BasicText.WithWriter(out).Printfln("Started at: %s", history.StartedAt.Format(time.RFC3339))
if history.Terminated {
fctl.BasicText.WithWriter(out).Printfln("Terminated at: %s", history.StartedAt.Format(time.RFC3339))
fctl.BasicText.WithWriter(out).Printfln("Terminated at: %s", history.TerminatedAt.Format(time.RFC3339))
}
}

func stageSourceName(src *shared.StageSendSource) string {
func stageSourceName(src *shared.V2StageSendSource) string {
switch {
case src.Wallet != nil:
return fmt.Sprintf("wallet '%s' (balance: %s)", src.Wallet.ID, *src.Wallet.Balance)
Expand All @@ -95,7 +95,7 @@ func stageSourceName(src *shared.StageSendSource) string {
}
}

func stageDestinationName(dst *shared.StageSendDestination) string {
func stageDestinationName(dst *shared.V2StageSendDestination) string {
switch {
case dst.Wallet != nil:
return fmt.Sprintf("wallet '%s' (balance: %s)", dst.Wallet.ID, *dst.Wallet.Balance)
Expand All @@ -108,12 +108,12 @@ func stageDestinationName(dst *shared.StageSendDestination) string {
}
}

func subjectName(src shared.Subject) string {
func subjectName(src shared.V2Subject) string {
switch {
case src.WalletSubject != nil:
return fmt.Sprintf("wallet %s (balance: %s)", src.WalletSubject.Identifier, *src.WalletSubject.Balance)
case src.LedgerAccountSubject != nil:
return fmt.Sprintf("account %s", src.LedgerAccountSubject.Identifier)
case src.V2WalletSubject != nil:
return fmt.Sprintf("wallet %s (balance: %s)", src.V2WalletSubject.Identifier, *src.V2WalletSubject.Balance)
case src.V2LedgerAccountSubject != nil:
return fmt.Sprintf("account %s", src.V2LedgerAccountSubject.Identifier)
default:
return "unknown_subject_type"
}
Expand All @@ -131,29 +131,31 @@ func printMetadata(metadata map[string]string) []pterm.BulletListItem {
return ret
}

func printStage(cmd *cobra.Command, i int, client *formance.Formance, id string, history shared.WorkflowInstanceHistory) error {
func printStage(cmd *cobra.Command, i int, client *formance.Formance, id string, history shared.V2WorkflowInstanceHistory) error {
cyanWriter := fctl.BasicTextCyan
defaultWriter := fctl.BasicText

listItems := make([]pterm.BulletListItem, 0)

switch history.Input.Type {
case shared.StageTypeStageSend:
case shared.V2StageTypeV2StageSend:
printHistoryBaseInfo(cmd.OutOrStdout(), "send", i, history)
cyanWriter.Printfln("Send %v %s from %s to %s", history.Input.StageSend.Amount.Amount,
history.Input.StageSend.Amount.Asset, stageSourceName(history.Input.StageSend.Source),
stageDestinationName(history.Input.StageSend.Destination))
if history.Input.V2StageSend != nil {
cyanWriter.Printfln("Send %v %s from %s to %s", history.Input.V2StageSend.Amount.Amount,
history.Input.V2StageSend.Amount.Asset, stageSourceName(history.Input.V2StageSend.Source),
stageDestinationName(history.Input.V2StageSend.Destination))
}
fctl.Println()

stageResponse, err := client.Orchestration.V1.GetInstanceStageHistory(cmd.Context(), operations.GetInstanceStageHistoryRequest{
stageResponse, err := client.Orchestration.V2.GetInstanceStageHistory(cmd.Context(), operations.V2GetInstanceStageHistoryRequest{
InstanceID: id,
Number: int64(i),
})
if err != nil {
return err
}

for _, historyStage := range stageResponse.GetWorkflowInstanceHistoryStageResponse.Data {
for _, historyStage := range stageResponse.V2GetWorkflowInstanceHistoryStageResponse.Data {
switch {
case historyStage.Input.StripeTransfer != nil:
listItems = append(listItems, historyItemTitle("Send %v %s to Stripe connected account: %s",
Expand All @@ -162,19 +164,26 @@ func printStage(cmd *cobra.Command, i int, client *formance.Formance, id string,
*historyStage.Input.StripeTransfer.Destination,
))
case historyStage.Input.CreateTransaction != nil:
listItems = append(listItems, historyItemTitle("Send %v %s from account %s to account %s (ledger %s)",
historyStage.Input.CreateTransaction.Data.Postings[0].Amount,
historyStage.Input.CreateTransaction.Data.Postings[0].Asset,
historyStage.Input.CreateTransaction.Data.Postings[0].Source,
historyStage.Input.CreateTransaction.Data.Postings[0].Destination,
*historyStage.Input.CreateTransaction.Ledger,
))
if historyStage.Input.CreateTransaction.Data != nil && len(historyStage.Input.CreateTransaction.Data.Postings) > 0 {
listItems = append(listItems, historyItemTitle("Send %v %s from account %s to account %s (ledger %s)",
historyStage.Input.CreateTransaction.Data.Postings[0].Amount,
historyStage.Input.CreateTransaction.Data.Postings[0].Asset,
historyStage.Input.CreateTransaction.Data.Postings[0].Source,
historyStage.Input.CreateTransaction.Data.Postings[0].Destination,
*historyStage.Input.CreateTransaction.Ledger,
))
}
if historyStage.Error == nil && historyStage.LastFailure == nil && historyStage.Terminated {
listItems = append(listItems, historyItemDetails("Created transaction: %d", historyStage.Output.CreateTransaction.Data.ID))
if historyStage.Input.CreateTransaction.Data.Reference != nil {
listItems = append(listItems, historyItemDetails("Reference: %s", *historyStage.Output.CreateTransaction.Data.Reference))
if historyStage.Output.CreateTransaction != nil && len(historyStage.Output.CreateTransaction.Data) > 0 {
txid := historyStage.Output.CreateTransaction.Data[0].Txid
if txid != nil {
listItems = append(listItems, historyItemDetails("Created transaction: %d", txid.Int64()))
}
}
if len(historyStage.Input.CreateTransaction.Data.Metadata) > 0 {
if historyStage.Input.CreateTransaction != nil && historyStage.Input.CreateTransaction.Data != nil && historyStage.Input.CreateTransaction.Data.Reference != nil {
listItems = append(listItems, historyItemDetails("Reference: %s", *historyStage.Input.CreateTransaction.Data.Reference))
}
if historyStage.Input.CreateTransaction != nil && historyStage.Input.CreateTransaction.Data != nil && len(historyStage.Input.CreateTransaction.Data.Metadata) > 0 {
listItems = append(listItems, printMetadata(historyStage.Input.CreateTransaction.Data.Metadata)...)
}
}
Expand Down Expand Up @@ -221,11 +230,7 @@ func printStage(cmd *cobra.Command, i int, client *formance.Formance, id string,
historyStage.Input.GetPayment.ID))
case historyStage.Input.GetWallet != nil:
listItems = append(listItems, historyItemTitle("Read wallet '%s'", historyStage.Input.GetWallet.ID))
case historyStage.Input.RevertTransaction != nil:
listItems = append(listItems, historyItemTitle("Revert transaction %s", historyStage.Input.RevertTransaction.ID))
if historyStage.Error == nil {
listItems = append(listItems, historyItemTitle("Created transaction: %d", historyStage.Output.RevertTransaction.Data.ID))
}
// V2 doesn't have RevertTransaction, skip it
case historyStage.Input.VoidHold != nil:
listItems = append(listItems, historyItemTitle("Cancel debit hold %s", historyStage.Input.VoidHold.ID))
case historyStage.Input.ListWallets != nil:
Expand All @@ -242,31 +247,37 @@ func printStage(cmd *cobra.Command, i int, client *formance.Formance, id string,
listItems = append(listItems, historyItemError(*historyStage.Error))
}
}
case shared.StageTypeStageDelay:
case shared.V2StageTypeV2StageDelay:
printHistoryBaseInfo(cmd.OutOrStdout(), "delay", i, history)
switch {
case history.Input.StageDelay.Duration != nil:
listItems = append(listItems, historyItemTitle("Pause workflow for a delay of %s", *history.Input.StageDelay.Duration))
case history.Input.StageDelay.Until != nil:
listItems = append(listItems, historyItemTitle("Pause workflow until %s", *history.Input.StageDelay.Until))
if history.Input.V2StageDelay != nil {
switch {
case history.Input.V2StageDelay.Duration != nil:
listItems = append(listItems, historyItemTitle("Pause workflow for a delay of %s", *history.Input.V2StageDelay.Duration))
case history.Input.V2StageDelay.Until != nil:
listItems = append(listItems, historyItemTitle("Pause workflow until %s", *history.Input.V2StageDelay.Until))
}
}
case shared.StageTypeStageWaitEvent:
case shared.V2StageTypeV2StageWaitEvent:
printHistoryBaseInfo(cmd.OutOrStdout(), "wait_event", i, history)
listItems = append(listItems, historyItemTitle("Waiting event '%s'", history.Input.StageWaitEvent.Event))
if history.Input.V2StageWaitEvent != nil {
listItems = append(listItems, historyItemTitle("Waiting event '%s'", history.Input.V2StageWaitEvent.Event))
}
if history.Error == nil {
if history.Terminated {
listItems = append(listItems, historyItemDetails("Event received!"))
} else {
listItems = append(listItems, historyItemDetails("Still waiting event..."))
}
}
case shared.StageTypeUpdate:
case shared.V2StageTypeV2Update:
printHistoryBaseInfo(cmd.OutOrStdout(), "update", i, history)
switch {
case history.Input.Update.Account != nil:
account := history.Input.Update.Account
listItems = append(listItems, historyItemTitle("Update account '%s' of ledger '%s'", account.ID, account.Ledger))
listItems = append(listItems, printMetadata(account.Metadata)...)
if history.Input.V2Update != nil {
switch {
case history.Input.V2Update.Account != nil:
account := history.Input.V2Update.Account
listItems = append(listItems, historyItemTitle("Update account '%s' of ledger '%s'", account.ID, account.Ledger))
listItems = append(listItems, printMetadata(account.Metadata)...)
}
}
default:
// Display error?
Expand Down
4 changes: 2 additions & 2 deletions cmd/orchestration/instances/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@ func (c *InstancesListController) GetStore() *InstancesListStore {
func (c *InstancesListController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
store := fctl.GetStackStore(cmd.Context())

response, err := store.Client().Orchestration.V1.ListInstances(cmd.Context(), operations.ListInstancesRequest{
response, err := store.Client().Orchestration.V2.ListInstances(cmd.Context(), operations.V2ListInstancesRequest{
Running: fctl.Ptr(fctl.GetBool(cmd, c.runningFlag)),
WorkflowID: fctl.Ptr(fctl.GetString(cmd, c.workflowFlag)),
})
Comment on lines +67 to 70
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove implicit filters when flags are unset

The new request always sends running=false and workflowId="", so a plain instances list call now hides running instances and anything whose workflow ID isn’t empty. Only set these pointers when the user actually provided the flag/value.

-	response, err := store.Client().Orchestration.V2.ListInstances(cmd.Context(), operations.V2ListInstancesRequest{
-		Running:    fctl.Ptr(fctl.GetBool(cmd, c.runningFlag)),
-		WorkflowID: fctl.Ptr(fctl.GetString(cmd, c.workflowFlag)),
-	})
+	req := operations.V2ListInstancesRequest{}
+	if cmd.Flags().Changed(c.runningFlag) {
+		req.Running = fctl.Ptr(fctl.GetBool(cmd, c.runningFlag))
+	}
+	if workflowID := fctl.GetString(cmd, c.workflowFlag); workflowID != "" {
+		req.WorkflowID = fctl.Ptr(workflowID)
+	}
+
+	response, err := store.Client().Orchestration.V2.ListInstances(cmd.Context(), req)
🤖 Prompt for AI Agents
In cmd/orchestration/instances/list.go around lines 67 to 70, the request always
sends Running=false and WorkflowID="" because the pointer fields are set
unconditionally; change the request construction to only include Running and
WorkflowID when the corresponding flag was actually provided by the user (use
cmd.Flags().Changed(c.runningFlag) and cmd.Flags().Changed(c.workflowFlag) or
equivalent) so you only set the pointers when flags are present, leaving them
nil otherwise.

if err != nil {
return nil, err
}

c.store.WorkflowInstance = fctl.Map(response.ListRunsResponse.Data, func(src shared.WorkflowInstance) WorkflowInstance {
c.store.WorkflowInstance = fctl.Map(response.V2ListRunsResponse.Cursor.Data, func(src shared.V2WorkflowInstance) WorkflowInstance {
return WorkflowInstance{
InstanceID: src.ID,
WorkflowID: src.WorkflowID,
Expand Down
4 changes: 2 additions & 2 deletions cmd/orchestration/instances/send_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ func (c *InstancesSendEventController) GetStore() *InstancesSendEventStore {

func (c *InstancesSendEventController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
store := fctl.GetStackStore(cmd.Context())
_, err := store.Client().Orchestration.V1.SendEvent(cmd.Context(), operations.SendEventRequest{
RequestBody: &operations.SendEventRequestBody{
_, err := store.Client().Orchestration.V2.SendEvent(cmd.Context(), operations.V2SendEventRequest{
RequestBody: &operations.V2SendEventRequestBody{
Name: args[1],
},
InstanceID: args[0],
Expand Down
41 changes: 33 additions & 8 deletions cmd/orchestration/instances/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
)

type InstancesShowStore struct {
WorkflowInstance shared.WorkflowInstance `json:"workflowInstance"`
Workflow shared.Workflow `json:"workflow"`
WorkflowInstance shared.V2WorkflowInstance `json:"workflowInstance"`
Workflow shared.Workflow `json:"workflow"`
}
type InstancesShowController struct {
store *InstancesShowStore
Expand Down Expand Up @@ -50,22 +50,29 @@ func (c *InstancesShowController) GetStore() *InstancesShowStore {
func (c *InstancesShowController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
store := fctl.GetStackStore(cmd.Context())

res, err := store.Client().Orchestration.V1.GetInstance(cmd.Context(), operations.GetInstanceRequest{
res, err := store.Client().Orchestration.V2.GetInstance(cmd.Context(), operations.V2GetInstanceRequest{
InstanceID: args[0],
})
if err != nil {
return nil, errors.Wrap(err, "reading instance")
}

c.store.WorkflowInstance = res.GetWorkflowInstanceResponse.Data
response, err := store.Client().Orchestration.V1.GetWorkflow(cmd.Context(), operations.GetWorkflowRequest{
FlowID: res.GetWorkflowInstanceResponse.Data.WorkflowID,
c.store.WorkflowInstance = res.V2GetWorkflowInstanceResponse.Data
response, err := store.Client().Orchestration.V2.GetWorkflow(cmd.Context(), operations.V2GetWorkflowRequest{
FlowID: res.V2GetWorkflowInstanceResponse.Data.WorkflowID,
})
if err != nil {
return nil, err
}

c.store.Workflow = response.GetWorkflowResponse.Data
// Convert V2Workflow to Workflow
v2Workflow := response.V2GetWorkflowResponse.Data
c.store.Workflow = shared.Workflow{
ID: v2Workflow.ID,
CreatedAt: v2Workflow.CreatedAt,
UpdatedAt: v2Workflow.UpdatedAt,
Config: shared.WorkflowConfig(v2Workflow.Config),
}

return c, nil
}
Expand All @@ -91,7 +98,25 @@ func (c *InstancesShowController) Render(cmd *cobra.Command, args []string) erro
return err
}

if err := internal.PrintWorkflowInstance(cmd.OutOrStdout(), c.store.Workflow, c.store.WorkflowInstance); err != nil {
// Convert V2WorkflowInstance to WorkflowInstance
v2Instance := c.store.WorkflowInstance
instance := shared.WorkflowInstance{
ID: v2Instance.ID,
WorkflowID: v2Instance.WorkflowID,
CreatedAt: v2Instance.CreatedAt,
UpdatedAt: v2Instance.UpdatedAt,
Terminated: v2Instance.Terminated,
TerminatedAt: v2Instance.TerminatedAt,
Error: v2Instance.Error,
Status: fctl.Map(v2Instance.Status, func(src shared.V2StageStatus) shared.StageStatus {
return shared.StageStatus{
StartedAt: src.StartedAt,
TerminatedAt: src.TerminatedAt,
Error: src.Error,
}
}),
}
if err := internal.PrintWorkflowInstance(cmd.OutOrStdout(), c.store.Workflow, instance); err != nil {
return err
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/orchestration/instances/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (c *InstancesStopController) GetStore() *InstancesStopStore {
func (c *InstancesStopController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
store := fctl.GetStackStore(cmd.Context())

_, err := store.Client().Orchestration.V1.CancelEvent(cmd.Context(), operations.CancelEventRequest{
_, err := store.Client().Orchestration.V2.CancelEvent(cmd.Context(), operations.V2CancelEventRequest{
InstanceID: args[0],
})
if err != nil {
Expand Down
16 changes: 13 additions & 3 deletions cmd/orchestration/triggers/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (c *TriggersCreateController) Run(cmd *cobra.Command, args []string) (fctl.
workflow = args[1]
)

data := &shared.TriggerData{
data := &shared.V2TriggerData{
Event: event,
Name: &name,
WorkflowID: workflow,
Expand All @@ -85,12 +85,22 @@ func (c *TriggersCreateController) Run(cmd *cobra.Command, args []string) (fctl.
}
}

res, err := store.Client().Orchestration.V1.CreateTrigger(cmd.Context(), data)
res, err := store.Client().Orchestration.V2.CreateTrigger(cmd.Context(), data)
if err != nil {
return nil, errors.Wrap(err, "reading trigger")
}

c.store.Trigger = res.CreateTriggerResponse.Data
// Convert V2Trigger to Trigger
v2Trigger := res.V2CreateTriggerResponse.Data
c.store.Trigger = shared.Trigger{
ID: v2Trigger.ID,
Name: v2Trigger.Name,
WorkflowID: v2Trigger.WorkflowID,
Event: v2Trigger.Event,
Filter: v2Trigger.Filter,
Vars: v2Trigger.Vars,
CreatedAt: v2Trigger.CreatedAt,
}

return c, nil
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/orchestration/triggers/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (c *TriggersDeleteController) GetStore() *TriggersDeleteStore {

func (c *TriggersDeleteController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
store := fctl.GetStackStore(cmd.Context())
_, err := store.Client().Orchestration.V1.DeleteTrigger(cmd.Context(), operations.DeleteTriggerRequest{
_, err := store.Client().Orchestration.V2.DeleteTrigger(cmd.Context(), operations.V2DeleteTriggerRequest{
TriggerID: args[0],
})
if err != nil {
Expand Down
16 changes: 14 additions & 2 deletions cmd/orchestration/triggers/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,27 @@ func (c *TriggersListController) GetStore() *TriggersListStore {
func (c *TriggersListController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
store := fctl.GetStackStore(cmd.Context())
var name = fctl.GetString(cmd, c.nameFlag)
response, err := store.Client().Orchestration.V1.ListTriggers(cmd.Context(), operations.ListTriggersRequest{
response, err := store.Client().Orchestration.V2.ListTriggers(cmd.Context(), operations.V2ListTriggersRequest{
Name: &name,
})

if err != nil {
return nil, err
}

c.store.WorkflowTrigger = response.ListTriggersResponse.Data
// Convert V2Trigger to Trigger
v2Triggers := response.V2ListTriggersResponse.Cursor.Data
c.store.WorkflowTrigger = fctl.Map(v2Triggers, func(v2Trigger shared.V2Trigger) shared.Trigger {
return shared.Trigger{
ID: v2Trigger.ID,
Name: v2Trigger.Name,
WorkflowID: v2Trigger.WorkflowID,
Event: v2Trigger.Event,
Filter: v2Trigger.Filter,
Vars: v2Trigger.Vars,
CreatedAt: v2Trigger.CreatedAt,
}
})

return c, nil
}
Expand Down
Loading