document generation for ops

This commit is contained in:
Stephan D
2026-03-04 15:41:28 +01:00
parent 80b25a8608
commit 92a6191014
21 changed files with 1077 additions and 255 deletions

View File

@@ -11,6 +11,9 @@ import (
connectorv1 "github.com/tech/sendico/pkg/proto/connector/v1"
chainv1 "github.com/tech/sendico/pkg/proto/gateway/chain/v1"
"go.uber.org/zap"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/structpb"
)
const tgsettleConnectorID = "tgsettle"
@@ -152,12 +155,22 @@ func (s *Service) GetOperation(ctx context.Context, req *connectorv1.GetOperatio
return nil, merrors.InvalidArgument("get_operation: operation_id is required")
}
operationID := strings.TrimSpace(req.GetOperationId())
resp, err := s.GetTransfer(ctx, &chainv1.GetTransferRequest{TransferRef: operationID})
if s.repo == nil || s.repo.Payments() == nil {
s.logger.Warn("Get operation storage unavailable", zap.String("operation_id", operationID))
return nil, merrors.Internal("get_operation: storage is not configured")
}
record, err := s.repo.Payments().FindByOperationRef(ctx, operationID)
if err != nil {
s.logger.Warn("Get operation failed", zap.String("operation_id", operationID), zap.Error(err))
s.logger.Warn("Get operation lookup by operation_ref failed", zap.String("operation_id", operationID), zap.Error(err))
return nil, err
}
return &connectorv1.GetOperationResponse{Operation: transferToOperation(resp.GetTransfer())}, nil
if record == nil {
return nil, status.Error(codes.NotFound, "operation not found")
}
return &connectorv1.GetOperationResponse{Operation: transferToOperation(transferFromPayment(record, nil))}, nil
}
func (s *Service) ListOperations(_ context.Context, _ *connectorv1.ListOperationsRequest) (*connectorv1.ListOperationsResponse, error) {
@@ -221,6 +234,19 @@ func transferToOperation(transfer *chainv1.Transfer) *connectorv1.Operation {
CreatedAt: transfer.GetCreatedAt(),
UpdatedAt: transfer.GetUpdatedAt(),
}
params := map[string]interface{}{}
if paymentRef := strings.TrimSpace(transfer.GetPaymentRef()); paymentRef != "" {
params["payment_ref"] = paymentRef
}
if organizationRef := strings.TrimSpace(transfer.GetOrganizationRef()); organizationRef != "" {
params["organization_ref"] = organizationRef
}
if failureReason := strings.TrimSpace(transfer.GetFailureReason()); failureReason != "" {
params["failure_reason"] = failureReason
}
if len(params) > 0 {
op.Params = structFromMap(params)
}
if source := strings.TrimSpace(transfer.GetSourceWalletRef()); source != "" {
op.From = &connectorv1.OperationParty{Ref: &connectorv1.OperationParty_Account{Account: &connectorv1.AccountRef{
ConnectorId: tgsettleConnectorID,
@@ -281,6 +307,17 @@ func operationAccountID(party *connectorv1.OperationParty) string {
return ""
}
func structFromMap(values map[string]interface{}) *structpb.Struct {
if len(values) == 0 {
return nil
}
result, err := structpb.NewStruct(values)
if err != nil {
return nil
}
return result
}
func operationLogFields(op *connectorv1.Operation) []zap.Field {
if op == nil {
return nil

View File

@@ -675,6 +675,9 @@ func transferFromRequest(req *chainv1.SubmitTransferRequest) *chainv1.Transfer {
SourceWalletRef: strings.TrimSpace(req.GetSourceWalletRef()),
Destination: req.GetDestination(),
RequestedAmount: req.GetAmount(),
IntentRef: strings.TrimSpace(req.GetIntentRef()),
OperationRef: strings.TrimSpace(req.GetOperationRef()),
PaymentRef: strings.TrimSpace(req.GetPaymentRef()),
Status: chainv1.TransferStatus_TRANSFER_CREATED,
}
}
@@ -714,6 +717,10 @@ func transferFromPayment(record *storagemodel.PaymentRecord, req *chainv1.Submit
IdempotencyKey: strings.TrimSpace(record.IdempotencyKey),
RequestedAmount: requested,
NetAmount: net,
IntentRef: strings.TrimSpace(record.IntentRef),
OperationRef: strings.TrimSpace(record.OperationRef),
PaymentRef: strings.TrimSpace(record.PaymentRef),
FailureReason: strings.TrimSpace(record.FailureReason),
Status: status,
}

View File

@@ -37,6 +37,20 @@ func (f *fakePaymentsStore) FindByIdempotencyKey(_ context.Context, key string)
return f.records[key], nil
}
func (f *fakePaymentsStore) FindByOperationRef(_ context.Context, key string) (*storagemodel.PaymentRecord, error) {
f.mu.Lock()
defer f.mu.Unlock()
if f.records == nil {
return nil, nil
}
for _, record := range f.records {
if record != nil && record.OperationRef == key {
return record, nil
}
}
return nil, nil
}
func (f *fakePaymentsStore) Upsert(_ context.Context, record *storagemodel.PaymentRecord) error {
f.mu.Lock()
defer f.mu.Unlock()