diff --git a/apps/carrier-connector/internal/rateplan/interface.go b/apps/carrier-connector/internal/rateplan/interface.go new file mode 100644 index 0000000..4896d08 --- /dev/null +++ b/apps/carrier-connector/internal/rateplan/interface.go @@ -0,0 +1,36 @@ +package rateplan + +import ( + "context" +) + +// Repository defines the interface for rate plan data operations +type Repository interface { + // Rate Plan operations + CreateRatePlan(ctx context.Context, plan *RatePlan) error + GetRatePlan(ctx context.Context, id string) (*RatePlan, error) + UpdateRatePlan(ctx context.Context, plan *RatePlan) error + DeleteRatePlan(ctx context.Context, id string) error + ListRatePlans(ctx context.Context, filter *RatePlanFilter) ([]*RatePlan, error) + CountRatePlans(ctx context.Context, filter *RatePlanFilter) (int, error) + + // Subscription operations + CreateSubscription(ctx context.Context, subscription *RatePlanSubscription) error + GetSubscription(ctx context.Context, id string) (*RatePlanSubscription, error) + UpdateSubscription(ctx context.Context, subscription *RatePlanSubscription) error + DeleteSubscription(ctx context.Context, id string) error + ListSubscriptions(ctx context.Context, profileID string, filter *SubscriptionFilter) ([]*RatePlanSubscription, error) + GetActiveSubscription(ctx context.Context, profileID string) (*RatePlanSubscription, error) + + // Usage tracking operations + CreateUsage(ctx context.Context, usage *RatePlanUsage) error + GetUsage(ctx context.Context, id string) (*RatePlanUsage, error) + UpdateUsage(ctx context.Context, usage *RatePlanUsage) error + GetCurrentUsage(ctx context.Context, profileID string) (*RatePlanUsage, error) + ListUsageHistory(ctx context.Context, profileID string, limit int) ([]*RatePlanUsage, error) + + // Analytics and reporting + GetUsageAnalytics(ctx context.Context, filter *UsageAnalyticsFilter) (*UsageAnalytics, error) + GetRevenueAnalytics(ctx context.Context, filter *RevenueAnalyticsFilter) (*RevenueAnalytics, error) + GetPopularPlans(ctx context.Context, limit int) ([]*RatePlan, error) +} diff --git a/apps/carrier-connector/internal/rateplan/models.go b/apps/carrier-connector/internal/rateplan/models.go new file mode 100644 index 0000000..a2b8db2 --- /dev/null +++ b/apps/carrier-connector/internal/rateplan/models.go @@ -0,0 +1,66 @@ +package rateplan + +import ( + "time" + + "gorm.io/gorm" +) + +// TableName returns the table name for RatePlan +func (RatePlan) TableName() string { + return "rate_plans" +} + +// TableName returns the table name for RatePlanSubscription +func (RatePlanSubscription) TableName() string { + return "rate_plan_subscriptions" +} + +// TableName returns the table name for RatePlanUsage +func (RatePlanUsage) TableName() string { + return "rate_plan_usage" +} + +// BeforeCreate GORM hook for RatePlan +func (rp *RatePlan) BeforeCreate(tx *gorm.DB) error { + if rp.CreatedAt.IsZero() { + rp.CreatedAt = time.Now() + } + rp.UpdatedAt = time.Now() + return nil +} + +// BeforeUpdate GORM hook for RatePlan +func (rp *RatePlan) BeforeUpdate(tx *gorm.DB) error { + rp.UpdatedAt = time.Now() + return nil +} + +// BeforeCreate GORM hook for RatePlanSubscription +func (rps *RatePlanSubscription) BeforeCreate(tx *gorm.DB) error { + if rps.CreatedAt.IsZero() { + rps.CreatedAt = time.Now() + } + rps.UpdatedAt = time.Now() + return nil +} + +// BeforeUpdate GORM hook for RatePlanSubscription +func (rps *RatePlanSubscription) BeforeUpdate(tx *gorm.DB) error { + rps.UpdatedAt = time.Now() + return nil +} + +// BeforeCreate GORM hook for RatePlanUsage +func (rpu *RatePlanUsage) BeforeCreate(tx *gorm.DB) error { + if rpu.LastUpdated.IsZero() { + rpu.LastUpdated = time.Now() + } + return nil +} + +// BeforeUpdate GORM hook for RatePlanUsage +func (rpu *RatePlanUsage) BeforeUpdate(tx *gorm.DB) error { + rpu.LastUpdated = time.Now() + return nil +} diff --git a/apps/carrier-connector/internal/rateplan/types_extended.go b/apps/carrier-connector/internal/rateplan/types_extended.go index 6797c14..e0e8522 100644 --- a/apps/carrier-connector/internal/rateplan/types_extended.go +++ b/apps/carrier-connector/internal/rateplan/types_extended.go @@ -2,6 +2,8 @@ package rateplan import ( "time" + + "github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/smdp" ) // SubscriptionFilter defines filtering options for subscription queries @@ -62,3 +64,130 @@ type TimelineDataPoint struct { Value float64 `json:"value"` Label string `json:"label,omitempty"` } + +type SearchCriteria struct { + CarrierID string `json:"carrier_id,omitempty"` + Region string `json:"region,omitempty"` + PlanType PlanType `json:"plan_type,omitempty"` + MinPrice float64 `json:"min_price,omitempty"` + MaxPrice float64 `json:"max_price,omitempty"` + Limit int `json:"limit,omitempty"` + Offset int `json:"offset,omitempty"` + SortBy string `json:"sort_by,omitempty"` + SortOrder string `json:"sort_order,omitempty"` +} + +type SubscribeRequest struct { + ProfileID string `json:"profile_id"` + RatePlanID string `json:"rate_plan_id"` + AutoRenew bool `json:"auto_renew"` + AppliedDiscounts []string `json:"applied_discounts,omitempty"` + Metadata map[string]interface{} `json:"metadata,omitempty"` +} + +type RecordUsageRequest struct { + ProfileID string `json:"profile_id"` + DataUsed int64 `json:"data_used"` // in MB + VoiceUsed int64 `json:"voice_used"` // in minutes + SMSUsed int64 `json:"sms_used"` // count +} + +type CalculateCostRequest struct { + RatePlanID string `json:"rate_plan_id"` + DataUsed int64 `json:"data_used"` // in MB + VoiceUsed int64 `json:"voice_used"` // in minutes + SMSUsed int64 `json:"sms_used"` // count + AppliedDiscounts []string `json:"applied_discounts,omitempty"` +} + +type PriceOptimization struct { + CurrentPrice float64 `json:"current_price"` + MarketAverage float64 `json:"market_average"` + RecommendedPrice float64 `json:"recommended_price"` + PriceDifference float64 `json:"price_difference"` + CompetitorCount int `json:"competitor_count"` + OptimizedAt time.Time `json:"optimized_at"` +} + +type CostBreakdown struct { + RatePlanID string `json:"rate_plan_id"` + Currency string `json:"currency"` + TotalCost float64 `json:"total_cost"` + Subtotal float64 `json:"subtotal"` + DiscountTotal float64 `json:"discount_total"` + BreakdownItems []CostItem `json:"breakdown_items"` + CalculatedAt time.Time `json:"calculated_at"` +} + +type CostItem struct { + Type string `json:"type"` + Description string `json:"description"` + Amount float64 `json:"amount"` + Currency string `json:"currency"` +} + +type CarrierRatePlanCriteria struct { + Region string `json:"region"` + PlanType PlanType `json:"plan_type"` + MaxBudget float64 `json:"max_budget"` + Urgency string `json:"urgency"` + Preferences map[string]interface{} `json:"preferences,omitempty"` +} + +type RecommendationCriteria struct { + Region string `json:"region"` + PlanType PlanType `json:"plan_type"` + MaxBudget float64 `json:"max_budget"` + PreferredData int64 `json:"preferred_data"` + PreferredVoice int64 `json:"preferred_voice"` + PreferredSMS int64 `json:"preferred_sms"` + MaxResults int `json:"max_results"` +} + +type CarrierRatePlanResult struct { + Carrier *smdp.Carrier `json:"carrier"` + RatePlan *RatePlan `json:"rate_plan"` + TotalScore float64 `json:"total_score"` + SelectedAt time.Time `json:"selected_at"` +} + +type RatePlanRecommendation struct { + RatePlanID string `json:"rate_plan_id"` + RatePlanName string `json:"rate_plan_name"` + CarrierID string `json:"carrier_id"` + CarrierName string `json:"carrier_name"` + Price float64 `json:"price"` + Currency string `json:"currency"` + Relevance float64 `json:"relevance"` + Features []PlanFeature `json:"features"` + DataAllowance *DataAllowance `json:"data_allowance"` + VoiceAllowance *VoiceAllowance `json:"voice_allowance"` + SMSAllowance *SMSAllowance `json:"sms_allowance"` + RecommendedAt time.Time `json:"recommended_at"` +} + +type CarrierRatePlanAnalytics struct { + CarrierID string `json:"carrier_id"` + CarrierName string `json:"carrier_name"` + Region string `json:"region"` + HealthStatus string `json:"health_status"` + Priority int `json:"priority"` + TotalPlans int `json:"total_plans"` + ActivePlans int `json:"active_plans"` + GeneratedAt time.Time `json:"generated_at"` + PlanAnalytics []RatePlanAnalytics `json:"plan_analytics"` +} + +type RatePlanAnalytics struct { + RatePlanID string `json:"rate_plan_id"` + RatePlanName string `json:"rate_plan_name"` + BasePrice float64 `json:"base_price"` + Currency string `json:"currency"` + ActiveSubscriptions int `json:"active_subscriptions"` + PlanType PlanType `json:"plan_type"` + BillingCycle BillingCycle `json:"billing_cycle"` + DataAllowance *DataAllowance `json:"data_allowance"` + VoiceAllowance *VoiceAllowance `json:"voice_allowance"` + SMSAllowance *SMSAllowance `json:"sms_allowance"` + Features []PlanFeature `json:"features"` +}