New comments section in the requests/responses

This commit is contained in:
Stephan D
2026-03-05 20:27:45 +01:00
parent 15393765b9
commit b832c2a7c4
11 changed files with 87 additions and 8 deletions

View File

@@ -1,10 +1,31 @@
# Sendico Development Environment - Makefile # Sendico Development Environment - Makefile
# Docker Compose + Makefile build system # Docker Compose + Makefile build system
.PHONY: help init build up down restart logs rebuild clean vault-init proto generate generate-api generate-frontend update update-api update-frontend test test-api test-frontend .PHONY: help init build up down restart logs rebuild clean vault-init proto generate generate-api generate-frontend update update-api update-frontend test test-api test-frontend backend-up backend-down backend-rebuild
COMPOSE := docker compose -f docker-compose.dev.yml --env-file .env.dev COMPOSE := docker compose -f docker-compose.dev.yml --env-file .env.dev
SERVICE ?= SERVICE ?=
BACKEND_SERVICES := \
dev-discovery \
dev-fx-oracle \
dev-fx-ingestor \
dev-billing-fees \
dev-billing-documents \
dev-ledger \
dev-payments-orchestrator \
dev-payments-quotation \
dev-payments-methods \
dev-chain-gateway-vault-agent \
dev-chain-gateway \
dev-tron-gateway-vault-agent \
dev-tron-gateway \
dev-aurora-gateway \
dev-tgsettle-gateway \
dev-notification \
dev-callbacks-vault-agent \
dev-callbacks \
dev-bff-vault-agent \
dev-bff
# Colors # Colors
GREEN := \033[0;32m GREEN := \033[0;32m
@@ -31,6 +52,9 @@ help:
@echo "$(YELLOW)Selective Operations:$(NC)" @echo "$(YELLOW)Selective Operations:$(NC)"
@echo " make infra-up Start infrastructure only (mongo, nats, vault)" @echo " make infra-up Start infrastructure only (mongo, nats, vault)"
@echo " make services-up Start application services only" @echo " make services-up Start application services only"
@echo " make backend-up Start backend services only (no infrastructure/frontend)"
@echo " make backend-down Stop backend services only"
@echo " make backend-rebuild Rebuild and restart backend services only"
@echo " make list-services List all available services" @echo " make list-services List all available services"
@echo "" @echo ""
@echo "$(YELLOW)Build Groups:$(NC)" @echo "$(YELLOW)Build Groups:$(NC)"
@@ -229,6 +253,21 @@ services-up:
dev-bff \ dev-bff \
dev-frontend dev-frontend
# Backend services only (no infrastructure, no frontend)
backend-up:
@echo "$(GREEN)Starting backend services only (no infra changes)...$(NC)"
@$(COMPOSE) up -d --no-deps $(BACKEND_SERVICES)
backend-down:
@echo "$(YELLOW)Stopping backend services only...$(NC)"
@$(COMPOSE) stop $(BACKEND_SERVICES)
backend-rebuild:
@echo "$(GREEN)Rebuilding backend services only (no infra changes)...$(NC)"
@$(COMPOSE) build $(BACKEND_SERVICES)
@$(COMPOSE) up -d --no-deps --force-recreate $(BACKEND_SERVICES)
@echo "$(GREEN)✅ Backend services rebuilt$(NC)"
# Status check # Status check
status: status:
@$(COMPOSE) ps @$(COMPOSE) ps

View File

@@ -24,6 +24,7 @@ Financial services platform providing payment orchestration, ledger accounting,
| FX Ingestor | `api/fx/ingestor/` | FX rate ingestion | | FX Ingestor | `api/fx/ingestor/` | FX rate ingestion |
| Gateway Chain | `api/gateway/chain/` | EVM blockchain gateway | | Gateway Chain | `api/gateway/chain/` | EVM blockchain gateway |
| Gateway TRON | `api/gateway/tron/` | TRON blockchain gateway | | Gateway TRON | `api/gateway/tron/` | TRON blockchain gateway |
| Gateway Aurora | `api/gateway/aurora/` | Card payouts simulator |
| Gateway MNTX | `api/gateway/mntx/` | Card payouts | | Gateway MNTX | `api/gateway/mntx/` | Card payouts |
| Gateway TGSettle | `api/gateway/tgsettle/` | Telegram settlements with MNTX | | Gateway TGSettle | `api/gateway/tgsettle/` | Telegram settlements with MNTX |
| Notification | `api/notification/` | Notifications | | Notification | `api/notification/` | Notifications |
@@ -31,6 +32,16 @@ Financial services platform providing payment orchestration, ledger accounting,
| Callbacks | `api/edge/callbacks/` | Webhook callbacks delivery | | Callbacks | `api/edge/callbacks/` | Webhook callbacks delivery |
| Frontend | `frontend/pweb/` | Flutter web UI | | Frontend | `frontend/pweb/` | Flutter web UI |
Gateway note: current dev compose workflows (`make services-up`, `make build-gateways`) use Aurora for card-payout flows (`chain`, `tron`, `aurora`, `tgsettle`). The MNTX gateway codebase is retained separately for Monetix-specific integration.
## Prerequisites
- Docker with Docker Compose plugin
- GNU Make
- Go toolchain
- Dart SDK
- Flutter SDK
## Development ## Development
Development uses Docker Compose via the Makefile. Run `make help` for all available commands. Development uses Docker Compose via the Makefile. Run `make help` for all available commands.
@@ -54,6 +65,8 @@ make status # Show service status
make logs # View all logs make logs # View all logs
make logs SERVICE=dev-ledger # View logs for a specific service make logs SERVICE=dev-ledger # View logs for a specific service
make rebuild SERVICE=dev-ledger # Rebuild and restart a specific service make rebuild SERVICE=dev-ledger # Rebuild and restart a specific service
make list-services # List all services and ports
make health # Check service health
make clean # Remove all containers and volumes make clean # Remove all containers and volumes
``` ```
@@ -62,6 +75,7 @@ make clean # Remove all containers and volumes
```bash ```bash
make infra-up # Start infrastructure only (MongoDB, NATS, Vault) make infra-up # Start infrastructure only (MongoDB, NATS, Vault)
make services-up # Start application services only (assumes infra is running) make services-up # Start application services only (assumes infra is running)
make list-services # Show service names, ports, and descriptions
``` ```
### Build Groups ### Build Groups
@@ -69,8 +83,8 @@ make services-up # Start application services only (assumes infra is running)
```bash ```bash
make build-core # discovery, ledger, fees, documents make build-core # discovery, ledger, fees, documents
make build-fx # oracle, ingestor make build-fx # oracle, ingestor
make build-payments # orchestrator make build-payments # orchestrator, quotation, methods
make build-gateways # chain, tron, mntx, tgsettle make build-gateways # chain, tron, aurora, tgsettle
make build-api # notification, callbacks, bff make build-api # notification, callbacks, bff
make build-frontend # Flutter web UI make build-frontend # Flutter web UI
``` ```

View File

@@ -14,6 +14,7 @@ type PaymentIntent struct {
SettlementMode SettlementMode `json:"settlement_mode,omitempty"` SettlementMode SettlementMode `json:"settlement_mode,omitempty"`
FeeTreatment FeeTreatment `json:"fee_treatment,omitempty"` FeeTreatment FeeTreatment `json:"fee_treatment,omitempty"`
Attributes map[string]string `json:"attributes,omitempty"` Attributes map[string]string `json:"attributes,omitempty"`
Comment string `json:"comment,omitempty"`
Customer *Customer `json:"customer,omitempty"` Customer *Customer `json:"customer,omitempty"`
} }

View File

@@ -70,6 +70,7 @@ type Payment struct {
PaymentRef string `json:"paymentRef,omitempty"` PaymentRef string `json:"paymentRef,omitempty"`
IdempotencyKey string `json:"idempotencyKey,omitempty"` IdempotencyKey string `json:"idempotencyKey,omitempty"`
State string `json:"state,omitempty"` State string `json:"state,omitempty"`
Comment string `json:"comment,omitempty"`
FailureCode string `json:"failureCode,omitempty"` FailureCode string `json:"failureCode,omitempty"`
FailureReason string `json:"failureReason,omitempty"` FailureReason string `json:"failureReason,omitempty"`
Operations []PaymentOperation `json:"operations,omitempty"` Operations []PaymentOperation `json:"operations,omitempty"`
@@ -294,6 +295,7 @@ func toPayment(p *orchestrationv2.Payment) *Payment {
return &Payment{ return &Payment{
PaymentRef: p.GetPaymentRef(), PaymentRef: p.GetPaymentRef(),
State: enumJSONName(p.GetState().String()), State: enumJSONName(p.GetState().String()),
Comment: strings.TrimSpace(p.GetIntentSnapshot().GetComment()),
FailureCode: failureCode, FailureCode: failureCode,
FailureReason: failureReason, FailureReason: failureReason,
Operations: operations, Operations: operations,

View File

@@ -121,6 +121,22 @@ func TestToPaymentIgnoresHiddenFailures(t *testing.T) {
} }
} }
func TestToPaymentMapsIntentComment(t *testing.T) {
dto := toPayment(&orchestrationv2.Payment{
PaymentRef: "pay-3",
State: orchestrationv2.OrchestrationState_ORCHESTRATION_STATE_CREATED,
IntentSnapshot: &quotationv2.QuoteIntent{
Comment: " invoice-7 ",
},
})
if dto == nil {
t.Fatal("expected non-nil payment dto")
}
if got, want := dto.Comment, "invoice-7"; got != want {
t.Fatalf("comment mismatch: got=%q want=%q", got, want)
}
}
func TestToPaymentQuote_MapsIntentRef(t *testing.T) { func TestToPaymentQuote_MapsIntentRef(t *testing.T) {
dto := toPaymentQuote(&quotationv2.PaymentQuote{ dto := toPaymentQuote(&quotationv2.PaymentQuote{
QuoteRef: "quote-1", QuoteRef: "quote-1",

View File

@@ -61,9 +61,7 @@ func mapQuoteIntent(intent *srequest.PaymentIntent) (*quotationv2.QuoteIntent, e
FeeTreatment: resolvedFeeTreatment, FeeTreatment: resolvedFeeTreatment,
SettlementCurrency: settlementCurrency, SettlementCurrency: settlementCurrency,
Fx: mapFXIntent(intent), Fx: mapFXIntent(intent),
} Comment: strings.TrimSpace(intent.Comment),
if comment := strings.TrimSpace(intent.Attributes["comment"]); comment != "" {
quoteIntent.Comment = comment
} }
return quoteIntent, nil return quoteIntent, nil
} }

View File

@@ -9,7 +9,6 @@ replace github.com/tech/sendico/gateway/common => ../common
require ( require (
github.com/go-chi/chi/v5 v5.2.5 github.com/go-chi/chi/v5 v5.2.5
github.com/prometheus/client_golang v1.23.2 github.com/prometheus/client_golang v1.23.2
github.com/prometheus/client_model v0.6.2
github.com/shopspring/decimal v1.4.0 github.com/shopspring/decimal v1.4.0
github.com/tech/sendico/gateway/common v0.1.0 github.com/tech/sendico/gateway/common v0.1.0
github.com/tech/sendico/pkg v0.1.0 github.com/tech/sendico/pkg v0.1.0
@@ -36,6 +35,7 @@ require (
github.com/nats-io/nats.go v1.49.0 // indirect github.com/nats-io/nats.go v1.49.0 // indirect
github.com/nats-io/nkeys v0.4.15 // indirect github.com/nats-io/nkeys v0.4.15 // indirect
github.com/nats-io/nuid v1.0.1 // indirect github.com/nats-io/nuid v1.0.1 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.1 // indirect github.com/prometheus/procfs v0.20.1 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect

View File

@@ -23,6 +23,7 @@ class PaymentIntentDTO {
final String? feeTreatment; final String? feeTreatment;
final Map<String, String>? attributes; final Map<String, String>? attributes;
final String? comment;
final CustomerDTO? customer; final CustomerDTO? customer;
const PaymentIntentDTO({ const PaymentIntentDTO({
@@ -33,10 +34,12 @@ class PaymentIntentDTO {
this.fx, this.fx,
this.settlementMode, this.settlementMode,
this.attributes, this.attributes,
this.comment,
this.customer, this.customer,
this.feeTreatment, this.feeTreatment,
}); });
factory PaymentIntentDTO.fromJson(Map<String, dynamic> json) => _$PaymentIntentDTOFromJson(json); factory PaymentIntentDTO.fromJson(Map<String, dynamic> json) =>
_$PaymentIntentDTOFromJson(json);
Map<String, dynamic> toJson() => _$PaymentIntentDTOToJson(this); Map<String, dynamic> toJson() => _$PaymentIntentDTOToJson(this);
} }

View File

@@ -16,6 +16,7 @@ extension PaymentIntentMapper on PaymentIntent {
fx: fx?.toDTO(), fx: fx?.toDTO(),
settlementMode: settlementModeToValue(settlementMode), settlementMode: settlementModeToValue(settlementMode),
attributes: attributes, attributes: attributes,
comment: comment,
customer: customer?.toDTO(), customer: customer?.toDTO(),
feeTreatment: feeTreatmentToValue(feeTreatment), feeTreatment: feeTreatmentToValue(feeTreatment),
); );
@@ -30,6 +31,7 @@ extension PaymentIntentDTOMapper on PaymentIntentDTO {
fx: fx?.toDomain(), fx: fx?.toDomain(),
settlementMode: settlementModeFromValue(settlementMode), settlementMode: settlementModeFromValue(settlementMode),
attributes: attributes, attributes: attributes,
comment: comment,
customer: customer?.toDomain(), customer: customer?.toDomain(),
feeTreatment: feeTreatmentFromValue(feeTreatment), feeTreatment: feeTreatmentFromValue(feeTreatment),
); );

View File

@@ -17,6 +17,7 @@ class PaymentIntent {
final FeeTreatment feeTreatment; final FeeTreatment feeTreatment;
final SettlementMode settlementMode; final SettlementMode settlementMode;
final Map<String, String>? attributes; final Map<String, String>? attributes;
final String? comment;
final Customer? customer; final Customer? customer;
const PaymentIntent({ const PaymentIntent({
@@ -29,6 +30,7 @@ class PaymentIntent {
this.fx, this.fx,
this.settlementMode = SettlementMode.unspecified, this.settlementMode = SettlementMode.unspecified,
this.attributes, this.attributes,
this.comment,
this.customer, this.customer,
required this.feeTreatment, required this.feeTreatment,
}); });

View File

@@ -57,6 +57,7 @@ void main() {
), ),
amount: MoneyDTO(amount: '10', currency: 'USD'), amount: MoneyDTO(amount: '10', currency: 'USD'),
settlementMode: 'fix_received', settlementMode: 'fix_received',
comment: 'invoice-7',
), ),
); );
@@ -70,6 +71,7 @@ void main() {
final intent = json['intent'] as Map<String, dynamic>; final intent = json['intent'] as Map<String, dynamic>;
expect(intent['kind'], equals('payout')); expect(intent['kind'], equals('payout'));
expect(intent['settlement_mode'], equals('fix_received')); expect(intent['settlement_mode'], equals('fix_received'));
expect(intent['comment'], equals('invoice-7'));
expect(intent.containsKey('settlement_currency'), isFalse); expect(intent.containsKey('settlement_currency'), isFalse);
final source = intent['source'] as Map<String, dynamic>; final source = intent['source'] as Map<String, dynamic>;