+notification from site +version bump fix
Some checks failed
ci/woodpecker/push/billing_fees Pipeline was successful
ci/woodpecker/push/bff Pipeline was successful
ci/woodpecker/push/db Pipeline was successful
ci/woodpecker/push/chain_gateway Pipeline was successful
ci/woodpecker/push/fx_ingestor Pipeline was successful
ci/woodpecker/push/fx_oracle Pipeline was successful
ci/woodpecker/push/bump_version Pipeline failed
ci/woodpecker/push/frontend Pipeline was successful
ci/woodpecker/push/nats Pipeline was successful
ci/woodpecker/push/ledger Pipeline was successful
ci/woodpecker/push/notification Pipeline was successful
ci/woodpecker/push/payments_orchestrator Pipeline was successful
Some checks failed
ci/woodpecker/push/billing_fees Pipeline was successful
ci/woodpecker/push/bff Pipeline was successful
ci/woodpecker/push/db Pipeline was successful
ci/woodpecker/push/chain_gateway Pipeline was successful
ci/woodpecker/push/fx_ingestor Pipeline was successful
ci/woodpecker/push/fx_oracle Pipeline was successful
ci/woodpecker/push/bump_version Pipeline failed
ci/woodpecker/push/frontend Pipeline was successful
ci/woodpecker/push/nats Pipeline was successful
ci/woodpecker/push/ledger Pipeline was successful
ci/woodpecker/push/notification Pipeline was successful
ci/woodpecker/push/payments_orchestrator Pipeline was successful
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
package notifications
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
gmessaging "github.com/tech/sendico/pkg/generated/gmessaging"
|
||||
messaging "github.com/tech/sendico/pkg/messaging/envelope"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
nm "github.com/tech/sendico/pkg/model/notification"
|
||||
"github.com/tech/sendico/pkg/mservice"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type DemoRequestNotification struct {
|
||||
messaging.Envelope
|
||||
request *model.DemoRequest
|
||||
}
|
||||
|
||||
func (drn *DemoRequestNotification) Serialize() ([]byte, error) {
|
||||
if drn.request == nil {
|
||||
return nil, fmt.Errorf("demo request payload is empty")
|
||||
}
|
||||
msg := gmessaging.DemoRequestEvent{
|
||||
Name: drn.request.Name,
|
||||
OrganizationName: drn.request.OrganizationName,
|
||||
Phone: drn.request.Phone,
|
||||
WorkEmail: drn.request.WorkEmail,
|
||||
PayoutVolume: drn.request.PayoutVolume,
|
||||
Comment: drn.request.Comment,
|
||||
}
|
||||
data, err := proto.Marshal(&msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return drn.Envelope.Wrap(data)
|
||||
}
|
||||
|
||||
func NewDemoRequestEvent() model.NotificationEvent {
|
||||
return model.NewNotification(mservice.Site, nm.NACreated)
|
||||
}
|
||||
|
||||
func NewDemoRequestEnvelope(sender string, request *model.DemoRequest) messaging.Envelope {
|
||||
return &DemoRequestNotification{
|
||||
Envelope: messaging.CreateEnvelope(sender, NewDemoRequestEvent()),
|
||||
request: request,
|
||||
}
|
||||
}
|
||||
11
api/pkg/messaging/notifications/site/demo_request.go
Normal file
11
api/pkg/messaging/notifications/site/demo_request.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package notifications
|
||||
|
||||
import (
|
||||
messaging "github.com/tech/sendico/pkg/messaging/envelope"
|
||||
internalsite "github.com/tech/sendico/pkg/messaging/internal/notifications/site"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
)
|
||||
|
||||
func DemoRequest(sender string, request *model.DemoRequest) messaging.Envelope {
|
||||
return internalsite.NewDemoRequestEnvelope(sender, request)
|
||||
}
|
||||
9
api/pkg/messaging/notifications/site/handler/handler.go
Normal file
9
api/pkg/messaging/notifications/site/handler/handler.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package notifications
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
)
|
||||
|
||||
type DemoRequestHandler = func(context.Context, *model.DemoRequest) error
|
||||
50
api/pkg/messaging/notifications/site/processor.go
Normal file
50
api/pkg/messaging/notifications/site/processor.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package notifications
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
gmessaging "github.com/tech/sendico/pkg/generated/gmessaging"
|
||||
me "github.com/tech/sendico/pkg/messaging/envelope"
|
||||
internalsite "github.com/tech/sendico/pkg/messaging/internal/notifications/site"
|
||||
np "github.com/tech/sendico/pkg/messaging/notifications/processor"
|
||||
handler "github.com/tech/sendico/pkg/messaging/notifications/site/handler"
|
||||
"github.com/tech/sendico/pkg/mlogger"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type DemoRequestProcessor struct {
|
||||
logger mlogger.Logger
|
||||
handler handler.DemoRequestHandler
|
||||
event model.NotificationEvent
|
||||
}
|
||||
|
||||
func (drp *DemoRequestProcessor) Process(ctx context.Context, envelope me.Envelope) error {
|
||||
var msg gmessaging.DemoRequestEvent
|
||||
if err := proto.Unmarshal(envelope.GetData(), &msg); err != nil {
|
||||
drp.logger.Warn("Failed to decode demo request envelope", zap.Error(err), zap.String("topic", drp.event.ToString()))
|
||||
return err
|
||||
}
|
||||
request := &model.DemoRequest{
|
||||
Name: msg.GetName(),
|
||||
OrganizationName: msg.GetOrganizationName(),
|
||||
Phone: msg.GetPhone(),
|
||||
WorkEmail: msg.GetWorkEmail(),
|
||||
PayoutVolume: msg.GetPayoutVolume(),
|
||||
Comment: msg.GetComment(),
|
||||
}
|
||||
return drp.handler(ctx, request)
|
||||
}
|
||||
|
||||
func (drp *DemoRequestProcessor) GetSubject() model.NotificationEvent {
|
||||
return drp.event
|
||||
}
|
||||
|
||||
func NewDemoRequestProcessor(logger mlogger.Logger, handler handler.DemoRequestHandler) np.EnvelopeProcessor {
|
||||
return &DemoRequestProcessor{
|
||||
logger: logger.Named("demo_request_processor"),
|
||||
handler: handler,
|
||||
event: internalsite.NewDemoRequestEvent(),
|
||||
}
|
||||
}
|
||||
53
api/pkg/model/demorequest.go
Normal file
53
api/pkg/model/demorequest.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/tech/sendico/pkg/merrors"
|
||||
)
|
||||
|
||||
// DemoRequest represents a request submitted from the marketing site to request a demo.
|
||||
type DemoRequest struct {
|
||||
Name string `json:"name"`
|
||||
OrganizationName string `json:"organizationName"`
|
||||
Phone string `json:"phone"`
|
||||
WorkEmail string `json:"workEmail"`
|
||||
PayoutVolume string `json:"payoutVolume"`
|
||||
Comment string `json:"comment,omitempty"`
|
||||
}
|
||||
|
||||
// Normalize trims whitespace from all string fields.
|
||||
func (dr *DemoRequest) Normalize() {
|
||||
if dr == nil {
|
||||
return
|
||||
}
|
||||
dr.Name = strings.TrimSpace(dr.Name)
|
||||
dr.OrganizationName = strings.TrimSpace(dr.OrganizationName)
|
||||
dr.Phone = strings.TrimSpace(dr.Phone)
|
||||
dr.WorkEmail = strings.TrimSpace(dr.WorkEmail)
|
||||
dr.PayoutVolume = strings.TrimSpace(dr.PayoutVolume)
|
||||
dr.Comment = strings.TrimSpace(dr.Comment)
|
||||
}
|
||||
|
||||
// Validate ensures that all required fields are present.
|
||||
func (dr *DemoRequest) Validate() error {
|
||||
if dr == nil {
|
||||
return merrors.InvalidArgument("request payload is empty")
|
||||
}
|
||||
if dr.Name == "" {
|
||||
return merrors.InvalidArgument("name must not be empty")
|
||||
}
|
||||
if dr.OrganizationName == "" {
|
||||
return merrors.InvalidArgument("organization name must not be empty")
|
||||
}
|
||||
if dr.Phone == "" {
|
||||
return merrors.InvalidArgument("phone must not be empty")
|
||||
}
|
||||
if dr.WorkEmail == "" {
|
||||
return merrors.InvalidArgument("work email must not be empty")
|
||||
}
|
||||
if dr.PayoutVolume == "" {
|
||||
return merrors.InvalidArgument("payout volume must not be empty")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
31
api/pkg/model/demorequest_test.go
Normal file
31
api/pkg/model/demorequest_test.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package model
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestDemoRequestNormalizeAndValidate(t *testing.T) {
|
||||
req := &DemoRequest{
|
||||
Name: " Alice ",
|
||||
OrganizationName: " Sendico ",
|
||||
Phone: " +1 234 ",
|
||||
WorkEmail: " demo@sendico.io ",
|
||||
PayoutVolume: " 100k ",
|
||||
Comment: " Excited ",
|
||||
}
|
||||
|
||||
req.Normalize()
|
||||
if err := req.Validate(); err != nil {
|
||||
t.Fatalf("expected request to be valid, got error: %v", err)
|
||||
}
|
||||
|
||||
if req.Name != "Alice" || req.OrganizationName != "Sendico" || req.Phone != "+1 234" || req.WorkEmail != "demo@sendico.io" || req.PayoutVolume != "100k" || req.Comment != "Excited" {
|
||||
t.Fatalf("normalize failed: %+v", req)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDemoRequestValidateMissing(t *testing.T) {
|
||||
req := &DemoRequest{}
|
||||
req.Normalize()
|
||||
if err := req.Validate(); err == nil {
|
||||
t.Fatalf("expected validation error for empty request")
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ type Type = string
|
||||
const (
|
||||
Accounts Type = "accounts" // Represents user accounts in the system
|
||||
Amplitude Type = "amplitude" // Represents analytics integration with Amplitude
|
||||
Site Type = "site" // Represents public site endpoints
|
||||
Automations Type = "automation" // Represents automation workflows
|
||||
Changes Type = "changes" // Tracks changes made to resources
|
||||
Clients Type = "clients" // Represents client information
|
||||
@@ -59,7 +60,7 @@ const (
|
||||
|
||||
func StringToSType(s string) (Type, error) {
|
||||
switch Type(s) {
|
||||
case Accounts, Amplitude, Automations, Changes, Clients, Comments, ChainGateway, ChainWallets, ChainWalletBalances,
|
||||
case Accounts, Amplitude, Site, Automations, Changes, Clients, Comments, ChainGateway, ChainWallets, ChainWalletBalances,
|
||||
ChainTransfers, ChainDeposits, FXOracle, FeePlans, FilterProjects, Invitations, Invoices, Logo, Ledger,
|
||||
LedgerAccounts, LedgerBalances, LedgerEntries, LedgerOutbox, LedgerParties, LedgerPlines, Notifications,
|
||||
Organizations, Payments, PaymentOrchestrator, Permissions, Policies, PolicyAssignements, Priorities,
|
||||
|
||||
Reference in New Issue
Block a user