diff --git a/apps/charging-engine/src/charging/rating_billing.rs b/apps/charging-engine/src/charging/rating_billing.rs index df9bac1..4080ce1 100644 --- a/apps/charging-engine/src/charging/rating_billing.rs +++ b/apps/charging-engine/src/charging/rating_billing.rs @@ -8,7 +8,6 @@ impl super::ChargingEngine { pub async fn calculate_usage_cost(&self, event: &UsageEvent) -> ChargingResult { // Get subscriber account to determine rating plan let account = self.get_subscriber_account(&event.imsi).await?; - let _account = account.ok_or_else(|| ChargingError::SubscriberNotFound(event.imsi.clone()))?; // Get rating plan from Postgres (simplified - defaults to basic). let plan = self diff --git a/apps/charging-engine/src/charging/rating_plans_repo.rs b/apps/charging-engine/src/charging/rating_plans_repo.rs index 1982fc2..bc67437 100644 --- a/apps/charging-engine/src/charging/rating_plans_repo.rs +++ b/apps/charging-engine/src/charging/rating_plans_repo.rs @@ -125,9 +125,13 @@ impl RatingPlansRepo { .await .map_err(|e| crate::errors::ChargingError::DatabaseError(e.to_string()))?; - let mut out = HashMap::with_capacity(rows.len()); - for row in rows { - let plan = row_to_plan(row); + let plans = rows + .into_iter() + .map(|row| row_to_plan(row)) + .collect::>(); + + let mut out = HashMap::new(); + for plan in plans { out.insert(plan.plan_id.clone(), plan); } Ok(out) @@ -236,8 +240,18 @@ fn row_to_plan(row: sqlx::postgres::PgRow) -> RatingPlan { /// Run Goose migrations by calling the goose binary. /// This ensures both Go and Rust services use the same migration system. +/// Changes to the repo root directory to find the migrations folder. async fn run_migrations(database_url: &str) -> Result<(), Box> { + use std::process::Command; + + // Change to repo root to find migrations directory + let repo_root = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .parent() + .and_then(|p| p.parent()) + .ok_or("Failed to determine repo root")?; + let output = Command::new("goose") + .current_dir(&repo_root) .args(["postgres", database_url, "up", "migrations"]) .output()?; diff --git a/apps/charging-engine/src/charging/types.rs b/apps/charging-engine/src/charging/types.rs index ab71fb4..46488ad 100644 --- a/apps/charging-engine/src/charging/types.rs +++ b/apps/charging-engine/src/charging/types.rs @@ -96,7 +96,10 @@ impl ToRedisArgs for SubscriberAccount { W: redis::RedisWrite + ?Sized, { let json = serde_json::to_string(self) - .expect("Failed to serialize SubscriberAccount"); + .unwrap_or_else(|_| { + // Fallback to empty JSON if serialization fails + r#"{"imsi":"","balance":0,"data_limit":0,"data_used":0,"voice_limit":0,"voice_used":0,"sms_limit":0,"sms_used":0,"status":"Active","last_updated":"1970-01-01T00:00:00Z"}"#.to_string() + }); json.write_redis_args(out) } } @@ -118,7 +121,10 @@ impl ToRedisArgs for UsageEvent { W: redis::RedisWrite + ?Sized, { let json = serde_json::to_string(self) - .expect("Failed to serialize UsageEvent"); + .unwrap_or_else(|_| { + // Fallback to empty JSON if serialization fails + r#"{"imsi":"","session_id":"","usage_type":"Data","volume":0,"timestamp":"1970-01-01T00:00:00Z","rate":0.0,"cost":0.0}"#.to_string() + }); json.write_redis_args(out) } }