Shivanshu Raj Shrivastava 9a96817a88
chore: fix naming convention
Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com>
2025-06-02 12:14:03 +05:30

125 lines
3.2 KiB
Go

package tracefunnel
import (
"fmt"
"net/http"
"sort"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/types/authtypes"
tracefunnel "github.com/SigNoz/signoz/pkg/types/tracefunnel"
"github.com/SigNoz/signoz/pkg/valuer"
)
// ValidateTimestamp validates a timestamp
func ValidateTimestamp(timestamp int64, fieldName string) error {
if timestamp == 0 {
return fmt.Errorf("%s is required", fieldName)
}
if timestamp < 0 {
return fmt.Errorf("%s must be positive", fieldName)
}
return nil
}
// ValidateTimestampIsMilliseconds validates that a timestamp is in milliseconds
func ValidateTimestampIsMilliseconds(timestamp int64) bool {
return timestamp >= 1000000000000 && timestamp <= 9999999999999
}
func ValidateFunnelSteps(steps []tracefunnel.FunnelStep) error {
if len(steps) < 2 {
return fmt.Errorf("funnel must have at least 2 steps")
}
for i, step := range steps {
if step.ServiceName == "" {
return fmt.Errorf("step %d: service name is required", i+1)
}
if step.SpanName == "" {
return fmt.Errorf("step %d: span name is required", i+1)
}
if step.Order < 0 {
return fmt.Errorf("step %d: order must be non-negative", i+1)
}
}
return nil
}
// NormalizeFunnelSteps normalizes step orders to be sequential
func NormalizeFunnelSteps(steps []tracefunnel.FunnelStep) []tracefunnel.FunnelStep {
sort.Slice(steps, func(i, j int) bool {
return steps[i].Order < steps[j].Order
})
for i := range steps {
steps[i].Order = int64(i + 1)
}
return steps
}
func GetClaims(r *http.Request) (*authtypes.Claims, error) {
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
return nil, errors.Newf(errors.TypeInvalidInput,
errors.CodeInvalidInput,
"unauthenticated")
}
return &claims, nil
}
func ValidateAndConvertTimestamp(timestamp int64) (time.Time, error) {
if err := ValidateTimestamp(timestamp, "timestamp"); err != nil {
return time.Time{}, errors.Newf(errors.TypeInvalidInput,
errors.CodeInvalidInput,
"timestamp is invalid: %v", err)
}
return time.Unix(0, timestamp*1000000), nil // Convert to nanoseconds
}
func ConstructFunnelResponse(funnel *tracefunnel.Funnel, claims *authtypes.Claims) tracefunnel.FunnelResponse {
resp := tracefunnel.FunnelResponse{
FunnelName: funnel.Name,
FunnelID: funnel.ID.String(),
Steps: funnel.Steps,
CreatedAt: funnel.CreatedAt.UnixNano() / 1000000,
CreatedBy: funnel.CreatedBy,
OrgID: funnel.OrgID.String(),
UpdatedBy: funnel.UpdatedBy,
UpdatedAt: funnel.UpdatedAt.UnixNano() / 1000000,
Description: funnel.Description,
}
if funnel.CreatedByUser != nil {
resp.UserEmail = funnel.CreatedByUser.Email
} else if claims != nil {
resp.UserEmail = claims.Email
}
return resp
}
func ProcessFunnelSteps(steps []tracefunnel.FunnelStep) ([]tracefunnel.FunnelStep, error) {
// First validate the steps
if err := ValidateFunnelSteps(steps); err != nil {
return nil, errors.Newf(errors.TypeInvalidInput,
errors.CodeInvalidInput,
"invalid funnel steps: %v", err)
}
// Then process the steps
for i := range steps {
if steps[i].Order < 1 {
steps[i].Order = int64(i + 1)
}
if steps[i].ID.IsZero() {
steps[i].ID = valuer.GenerateUUID()
}
}
return NormalizeFunnelSteps(steps), nil
}