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:
nutcas3
2026-05-02 00:08:01 +03:00
parent 49a8eba384
commit 9cf82c5f21
3 changed files with 231 additions and 0 deletions
@@ -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"`
}