mirror of
https://github.com/hanzo-fi/payments.git
synced 2026-10-30 20:31:20 +00:00
* wip: connector workbench * wip: improve workbench * feat(workbench): improve UI with sidebar, routing, and syntax highlighting - Replace connector dropdown with Slack-style sidebar for connector selection - Add URL-based routing with react-router-dom for browser navigation support - Add JSON syntax highlighting with react-syntax-highlighter - Rework State tab layout to list/detail view with filtering - Update terminology from "create" to "instantiate" for connectors - Fix duplicate selection bug in lists (ID generation collision) - Unify data table row heights across tabs - Increase code block font sizes for readability - Hide navigation tabs on homepage when no connector selected - Make CW logo clickable to return to home view Co-authored-by: Cursor <[email protected]> * fix(workbench): use textarea for PEM/certificate config fields Fields containing 'privateKey', 'certificate', or 'pem' in their name now use a textarea instead of single-line input, preserving newlines in PEM content that would otherwise be stripped. Co-authored-by: Cursor <[email protected]> * fix(workbench): address PR review issues - Fix data race on idCounter using atomic.Int64 - Fix path traversal vulnerability in introspect.go - Fix pointer comparison for DefaultAsset in baseline.go Co-authored-by: Cursor <[email protected]> * feat(workbench): add generic connector server for integration testing Expose the generic connector REST API from the workbench so staging services can install a "generic connector" pointing to the local workbench, enabling end-to-end integration testing. - Add /generic/* routes (accounts, balances, beneficiaries, transactions) - Return cached data from storage instead of making fresh API calls - Add connector selection and optional API key authentication - Add UI panel in Debug tab for configuration Co-authored-by: Cursor <[email protected]> * fix(workbench): use internal registry to avoid pkg dependency Change imports from pkg/registry to internal/connectors/plugins/registry so the workbench can be merged before the pkg refactoring. The internal registry will automatically delegate to pkg/registry once that refactor lands. Also adds light/dark mode toggle to the UI with system preference detection. Co-authored-by: Cursor <[email protected]> * fix(workbench): address PR review feedback - Add ctx.Done() checks in fetch loops to exit early on client disconnect - Refactor generic server to get connector directly instead of via context, providing clearer data flow as suggested in review Co-authored-by: Cursor <[email protected]> * fix(workbench): include built UI files for embed directive The //go:embed ui/dist/* directive requires files to exist at build time. Add exception to .gitignore and commit the built UI distribution files. Co-authored-by: Cursor <[email protected]> * fix(workbench): address golangci-lint errors - Remove unused globalDebugTransport variable - Remove unused parseIntParam function - Fix printf format for models.TaskType (use %v instead of %s) - Add error return value handling for various function calls Co-authored-by: Cursor <[email protected]> * fix: remove .vite cache folder from git Co-authored-by: Cursor <[email protected]> * fix(workbench): fix remaining errcheck issue Co-authored-by: Cursor <[email protected]> * fix(workbench): fix all remaining lint issues - Add error handling for Body.Close() calls - Remove unnecessary fmt.Sprintf wrapper - Simplify hex character check condition Co-authored-by: Cursor <[email protected]> * fix(workbench): fix errcheck in cmd/workbench.go Co-authored-by: Cursor <[email protected]> * chore: replace ui dist build artifacts with placeholder The //go:embed directive needs at least one file to exist. Instead of committing the entire built UI, commit only a .gitkeep placeholder. The server has fallback code that displays instructions when the full UI isn't available. Co-authored-by: Cursor <[email protected]> --------- Co-authored-by: Cursor <[email protected]>
123 lines
4.2 KiB
Go
123 lines
4.2 KiB
Go
package workbench
|
|
|
|
import (
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"github.com/formancehq/payments/internal/models"
|
|
)
|
|
|
|
// Response types with proper JSON tags for the workbench UI.
|
|
// These convert from internal models.PSP* types to API-friendly formats.
|
|
|
|
// AccountResponse is the JSON-serializable account for the UI.
|
|
type AccountResponse struct {
|
|
Reference string `json:"reference"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
Name *string `json:"name,omitempty"`
|
|
DefaultAsset *string `json:"default_asset,omitempty"`
|
|
Metadata map[string]string `json:"metadata,omitempty"`
|
|
Raw json.RawMessage `json:"raw,omitempty"`
|
|
}
|
|
|
|
// PaymentResponse is the JSON-serializable payment for the UI.
|
|
type PaymentResponse struct {
|
|
Reference string `json:"reference"`
|
|
ParentReference string `json:"parent_reference,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
Type string `json:"type"`
|
|
Amount string `json:"amount"`
|
|
Asset string `json:"asset"`
|
|
Scheme string `json:"scheme,omitempty"`
|
|
Status string `json:"status"`
|
|
SourceAccountReference *string `json:"source_account_reference,omitempty"`
|
|
DestinationAccountReference *string `json:"destination_account_reference,omitempty"`
|
|
Metadata map[string]string `json:"metadata,omitempty"`
|
|
Raw json.RawMessage `json:"raw,omitempty"`
|
|
}
|
|
|
|
// BalanceResponse is the JSON-serializable balance for the UI.
|
|
type BalanceResponse struct {
|
|
AccountReference string `json:"account_reference"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
Amount string `json:"amount"`
|
|
Asset string `json:"asset"`
|
|
}
|
|
|
|
// ToAccountResponse converts a PSPAccount to an AccountResponse.
|
|
func ToAccountResponse(acc models.PSPAccount) AccountResponse {
|
|
return AccountResponse{
|
|
Reference: acc.Reference,
|
|
CreatedAt: acc.CreatedAt,
|
|
Name: acc.Name,
|
|
DefaultAsset: acc.DefaultAsset,
|
|
Metadata: acc.Metadata,
|
|
Raw: acc.Raw,
|
|
}
|
|
}
|
|
|
|
// ToAccountResponses converts a slice of PSPAccounts to AccountResponses.
|
|
func ToAccountResponses(accounts []models.PSPAccount) []AccountResponse {
|
|
result := make([]AccountResponse, len(accounts))
|
|
for i, acc := range accounts {
|
|
result[i] = ToAccountResponse(acc)
|
|
}
|
|
return result
|
|
}
|
|
|
|
// ToPaymentResponse converts a PSPPayment to a PaymentResponse.
|
|
func ToPaymentResponse(pay models.PSPPayment) PaymentResponse {
|
|
amount := "0"
|
|
if pay.Amount != nil {
|
|
amount = pay.Amount.String()
|
|
}
|
|
|
|
return PaymentResponse{
|
|
Reference: pay.Reference,
|
|
ParentReference: pay.ParentReference,
|
|
CreatedAt: pay.CreatedAt,
|
|
Type: pay.Type.String(),
|
|
Amount: amount,
|
|
Asset: pay.Asset,
|
|
Scheme: pay.Scheme.String(),
|
|
Status: pay.Status.String(),
|
|
SourceAccountReference: pay.SourceAccountReference,
|
|
DestinationAccountReference: pay.DestinationAccountReference,
|
|
Metadata: pay.Metadata,
|
|
Raw: pay.Raw,
|
|
}
|
|
}
|
|
|
|
// ToPaymentResponses converts a slice of PSPPayments to PaymentResponses.
|
|
func ToPaymentResponses(payments []models.PSPPayment) []PaymentResponse {
|
|
result := make([]PaymentResponse, len(payments))
|
|
for i, pay := range payments {
|
|
result[i] = ToPaymentResponse(pay)
|
|
}
|
|
return result
|
|
}
|
|
|
|
// ToBalanceResponse converts a PSPBalance to a BalanceResponse.
|
|
func ToBalanceResponse(bal models.PSPBalance) BalanceResponse {
|
|
amount := "0"
|
|
if bal.Amount != nil {
|
|
amount = bal.Amount.String()
|
|
}
|
|
|
|
return BalanceResponse{
|
|
AccountReference: bal.AccountReference,
|
|
CreatedAt: bal.CreatedAt,
|
|
Amount: amount,
|
|
Asset: bal.Asset,
|
|
}
|
|
}
|
|
|
|
// ToBalanceResponses converts a slice of PSPBalances to BalanceResponses.
|
|
func ToBalanceResponses(balances []models.PSPBalance) []BalanceResponse {
|
|
result := make([]BalanceResponse, len(balances))
|
|
for i, bal := range balances {
|
|
result[i] = ToBalanceResponse(bal)
|
|
}
|
|
return result
|
|
}
|