mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-10-19 19:34:25 +00:00
feat: Add rate plan repository interface with GORM models and extended types for carrier integration
- Add Repository interface with rate plan CRUD, subscription management, usage tracking, and analytics operations - Add GORM table name methods for RatePlan, RatePlanSubscription, and RatePlanUsage models - Add GORM hooks with automatic timestamp handling for BeforeCreate and BeforeUpdate operations - Add SearchCriteria with carrier, region, plan type, price range, pagination, and sorting fields
This commit is contained in:
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user