mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-10-18 11:02:54 +00:00
feat: Add pricing interfaces and types for dynamic pricing rule management
- Add Repository interface with CreateRule, GetRule, UpdateRule, DeleteRule, ListRules, CountRules methods - Add GetActiveRules, GetRulesByType methods for rule evaluation - Add Service interface with rule management, pricing calculations, validation, and analytics methods - Add RuleEngine interface with EvaluateRule, ApplyRule, ValidateConditions, ExecuteActions methods - Add PricingEventHandler interface for rule lifecycle events - Add PricingValidator interface for rule and context validation - Add PricingCache interface for caching pricing data
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
package pricing
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// Repository defines the interface for pricing data access
|
||||
type Repository interface {
|
||||
// Rule operations
|
||||
CreateRule(ctx context.Context, rule *PricingRule) error
|
||||
GetRule(ctx context.Context, id string) (*PricingRule, error)
|
||||
UpdateRule(ctx context.Context, rule *PricingRule) error
|
||||
DeleteRule(ctx context.Context, id string) error
|
||||
ListRules(ctx context.Context, filter *PricingFilter) ([]*PricingRule, error)
|
||||
CountRules(ctx context.Context, filter *PricingFilter) (int, error)
|
||||
|
||||
// Rule evaluation
|
||||
GetActiveRules(ctx context.Context, tenantID string) ([]*PricingRule, error)
|
||||
GetRulesByType(ctx context.Context, tenantID string, ruleType RuleType) ([]*PricingRule, error)
|
||||
}
|
||||
|
||||
// Service defines the interface for pricing business logic
|
||||
type Service interface {
|
||||
// Rule management
|
||||
CreateRule(ctx context.Context, rule *PricingRule) (*PricingRule, error)
|
||||
GetRule(ctx context.Context, id string) (*PricingRule, error)
|
||||
UpdateRule(ctx context.Context, id string, rule *PricingRule) (*PricingRule, error)
|
||||
DeleteRule(ctx context.Context, id string) error
|
||||
ListRules(ctx context.Context, filter *PricingFilter) ([]*PricingRule, error)
|
||||
|
||||
// Pricing calculations
|
||||
CalculatePrice(ctx context.Context, context *PricingContext) (*PricingResult, error)
|
||||
ApplyRules(ctx context.Context, context *PricingContext, rules []*PricingRule) (*PricingResult, error)
|
||||
ValidateRule(ctx context.Context, rule *PricingRule) error
|
||||
|
||||
// Analytics
|
||||
GetAnalytics(ctx context.Context, tenantID string) (*PricingAnalytics, error)
|
||||
}
|
||||
|
||||
// RuleEngine defines the interface for rule evaluation
|
||||
type RuleEngine interface {
|
||||
EvaluateRule(ctx context.Context, rule *PricingRule, context *PricingContext) (bool, error)
|
||||
ApplyRule(ctx context.Context, rule *PricingRule, context *PricingContext, currentPrice float64) (float64, error)
|
||||
ValidateConditions(ctx context.Context, conditions RuleConditions, context *PricingContext) (bool, error)
|
||||
ExecuteActions(ctx context.Context, actions RuleActions, currentPrice float64) (float64, error)
|
||||
}
|
||||
|
||||
// PricingEventHandler defines the interface for pricing events
|
||||
type PricingEventHandler interface {
|
||||
OnRuleCreated(ctx context.Context, rule *PricingRule) error
|
||||
OnRuleUpdated(ctx context.Context, oldRule, newRule *PricingRule) error
|
||||
OnRuleDeleted(ctx context.Context, rule *PricingRule) error
|
||||
OnPriceCalculated(ctx context.Context, context *PricingContext, result *PricingResult) error
|
||||
}
|
||||
|
||||
// PricingValidator defines the interface for validation
|
||||
type PricingValidator interface {
|
||||
ValidateRule(ctx context.Context, rule *PricingRule) error
|
||||
ValidateContext(ctx context.Context, context *PricingContext) error
|
||||
ValidateConditions(ctx context.Context, conditions RuleConditions) error
|
||||
ValidateActions(ctx context.Context, actions RuleActions) error
|
||||
}
|
||||
|
||||
// PricingCache defines the interface for caching pricing data
|
||||
type PricingCache interface {
|
||||
GetRule(ctx context.Context, id string) (*PricingRule, error)
|
||||
SetRule(ctx context.Context, rule *PricingRule) error
|
||||
DeleteRule(ctx context.Context, id string) error
|
||||
GetActiveRules(ctx context.Context, tenantID string) ([]*PricingRule, error)
|
||||
SetActiveRules(ctx context.Context, tenantID string, rules []*PricingRule) error
|
||||
InvalidateTenant(ctx context.Context, tenantID string) error
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package pricing
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/tenant"
|
||||
)
|
||||
|
||||
// PricingRule represents a dynamic pricing rule
|
||||
type PricingRule struct {
|
||||
ID string `json:"id" gorm:"primaryKey"`
|
||||
Name string `json:"name" gorm:"not null"`
|
||||
Description string `json:"description"`
|
||||
TenantID string `json:"tenant_id" gorm:"index;not null"`
|
||||
Type RuleType `json:"type" gorm:"not null"`
|
||||
Priority int `json:"priority" gorm:"default:0"`
|
||||
IsActive bool `json:"is_active" gorm:"default:true"`
|
||||
Conditions RuleConditions `json:"conditions" gorm:"serializer:json"`
|
||||
Actions RuleActions `json:"actions" gorm:"serializer:json"`
|
||||
Metadata map[string]any `json:"metadata" gorm:"serializer:json"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// RuleType defines the type of pricing rule
|
||||
type RuleType string
|
||||
|
||||
const (
|
||||
RuleTypePercentageDiscount RuleType = "percentage_discount"
|
||||
RuleTypeFixedDiscount RuleType = "fixed_discount"
|
||||
RuleTypeMultiplier RuleType = "multiplier"
|
||||
RuleTypeTieredPricing RuleType = "tiered_pricing"
|
||||
RuleTypeDynamicPricing RuleType = "dynamic_pricing"
|
||||
RuleTypeConditionalPricing RuleType = "conditional_pricing"
|
||||
)
|
||||
|
||||
// RuleConditions defines when a rule applies
|
||||
type RuleConditions struct {
|
||||
TimeRange *TimeRange `json:"time_range,omitempty"`
|
||||
Geography []string `json:"geography,omitempty"`
|
||||
CustomerType []string `json:"customer_type,omitempty"`
|
||||
Volume *VolumeRange `json:"volume,omitempty"`
|
||||
UsagePattern *UsagePattern `json:"usage_pattern,omitempty"`
|
||||
}
|
||||
|
||||
// TimeRange defines time-based conditions
|
||||
type TimeRange struct {
|
||||
Start time.Time `json:"start"`
|
||||
End time.Time `json:"end"`
|
||||
Days []string `json:"days"` // ["monday", "tuesday", ...]
|
||||
}
|
||||
|
||||
// VolumeRange defines volume-based conditions
|
||||
type VolumeRange struct {
|
||||
Min int `json:"min"`
|
||||
Max int `json:"max"`
|
||||
}
|
||||
|
||||
// UsagePattern defines usage-based conditions
|
||||
type UsagePattern struct {
|
||||
PeakHours []string `json:"peak_hours"`
|
||||
OffPeakHours []string `json:"off_peak_hours"`
|
||||
}
|
||||
|
||||
// RuleActions defines what happens when a rule applies
|
||||
type RuleActions struct {
|
||||
AdjustmentType AdjustmentType `json:"adjustment_type"`
|
||||
Value float64 `json:"value"`
|
||||
NewPrice *float64 `json:"new_price,omitempty"`
|
||||
Limit *float64 `json:"limit,omitempty"`
|
||||
}
|
||||
|
||||
// AdjustmentType defines how pricing is adjusted
|
||||
type AdjustmentType string
|
||||
|
||||
const (
|
||||
AdjustmentTypePercentage AdjustmentType = "percentage"
|
||||
AdjustmentTypeFixed AdjustmentType = "fixed"
|
||||
AdjustmentTypeMultiply AdjustmentType = "multiply"
|
||||
AdjustmentTypeOverride AdjustmentType = "override"
|
||||
)
|
||||
|
||||
// PricingContext contains context for pricing calculations
|
||||
type PricingContext struct {
|
||||
TenantID string `json:"tenant_id"`
|
||||
CustomerID string `json:"customer_id"`
|
||||
ProductID string `json:"product_id"`
|
||||
BasePrice float64 `json:"base_price"`
|
||||
Currency string `json:"currency"`
|
||||
Quantity int `json:"quantity"`
|
||||
Location string `json:"location"`
|
||||
Time time.Time `json:"time"`
|
||||
Metadata map[string]any `json:"metadata"`
|
||||
TenantCtx *tenant.TenantContext `json:"tenant_context,omitempty"`
|
||||
}
|
||||
|
||||
// PricingResult contains the result of pricing calculations
|
||||
type PricingResult struct {
|
||||
OriginalPrice float64 `json:"original_price"`
|
||||
AdjustedPrice float64 `json:"adjusted_price"`
|
||||
FinalPrice float64 `json:"final_price"`
|
||||
Currency string `json:"currency"`
|
||||
Discount float64 `json:"discount"`
|
||||
AppliedRules []AppliedRule `json:"applied_rules"`
|
||||
Metadata map[string]any `json:"metadata"`
|
||||
}
|
||||
|
||||
// AppliedRule represents a rule that was applied
|
||||
type AppliedRule struct {
|
||||
RuleID string `json:"rule_id"`
|
||||
RuleName string `json:"rule_name"`
|
||||
Type string `json:"type"`
|
||||
Adjustment float64 `json:"adjustment"`
|
||||
}
|
||||
|
||||
// PricingFilter defines filtering options for pricing rules
|
||||
type PricingFilter struct {
|
||||
TenantID string `json:"tenant_id,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
IsActive *bool `json:"is_active,omitempty"`
|
||||
Priority *int `json:"priority,omitempty"`
|
||||
Limit int `json:"limit,omitempty"`
|
||||
Offset int `json:"offset,omitempty"`
|
||||
}
|
||||
|
||||
// PricingAnalytics contains analytics data
|
||||
type PricingAnalytics struct {
|
||||
TotalRules int `json:"total_rules"`
|
||||
ActiveRules int `json:"active_rules"`
|
||||
RulesByType map[string]int `json:"rules_by_type"`
|
||||
UsageByRule map[string]int64 `json:"usage_by_rule"`
|
||||
DiscountStats DiscountStatistics `json:"discount_stats"`
|
||||
GeneratedAt time.Time `json:"generated_at"`
|
||||
}
|
||||
|
||||
// DiscountStatistics contains discount statistics
|
||||
type DiscountStatistics struct {
|
||||
TotalDiscounts int64 `json:"total_discounts"`
|
||||
AverageDiscount float64 `json:"average_discount"`
|
||||
LargestDiscount float64 `json:"largest_discount"`
|
||||
SmallestDiscount float64 `json:"smallest_discount"`
|
||||
TotalDiscountValue float64 `json:"total_discount_value"`
|
||||
}
|
||||
Reference in New Issue
Block a user