(feat) balance

This commit is contained in:
Rorik Star Platinum 2025-11-07 21:22:52 +03:00
parent 779ae4d498
commit aeb9514aa3
15 changed files with 461 additions and 26 deletions

View file

@ -1,7 +1,9 @@
// src/api/accounts.rs
// Account data retrieval
use super::{client::{BankClient, BankingError}, models::{ApiResponse, AccountData, TransactionData}};
use super::{client::{BankClient, BankingError}, models::{ApiResponse, AccountData, BalanceData, BalanceResponse}};
use tracing::{info, error, debug};
impl BankClient {
pub async fn get_accounts(
@ -9,7 +11,10 @@ impl BankClient {
client_id: &str,
consent_id: &str,
) -> Result<ApiResponse<AccountData>, BankingError> {
info!("📋 Fetching accounts for client_id: {}", client_id);
let token = self.get_token().await?;
debug!("✅ Got bank token");
let response = self.http_client
.get(self.base_url.join("/accounts")?)
@ -20,13 +25,83 @@ impl BankClient {
.send()
.await?;
let status = response.status();
debug!("📥 Response status: {}", status);
match response.status().is_success() {
true => response.json().await.map_err(Into::into),
false => Err(BankingError::ApiError {
status: response.status().as_u16(),
body: response.text().await.unwrap_or_default(),
}),
true => {
let text = response.text().await?;
info!("✅ Accounts response received");
serde_json::from_str::<ApiResponse<AccountData>>(&text)
.map_err(|e| {
error!("❌ Failed to deserialize AccountData: {}", e);
BankingError::ApiError {
status: 500,
body: format!("Deserialization error: {}", e),
}
})
},
false => {
let error_body = response.text().await.unwrap_or_default();
error!("❌ Bank API error status {}: {}", status, error_body);
Err(BankingError::ApiError {
status: status.as_u16(),
body: error_body,
})
}
}
}
pub async fn get_balances(
&self,
account_id: &str,
consent_id: &str,
) -> Result<BalanceResponse, BankingError> { // ← Changed return type!
info!("📊 Fetching balances for account: {}", account_id);
let token = self.get_token().await?;
debug!("✅ Got bank token");
let url = self.base_url.join(&format!("/accounts/{}/balances", account_id))?;
debug!("📍 Calling: {}", url);
let response = self.http_client
.get(url)
.bearer_auth(token)
.header("x-consent-id", consent_id)
.header("x-requesting-bank", self.client_id.as_str())
.send()
.await?;
let status = response.status();
debug!("📥 Response status: {}", status);
match response.status().is_success() {
true => {
let text = response.text().await?;
info!("✅ Balance response received");
serde_json::from_str::<BalanceResponse>(&text) // ← Parse as BalanceResponse
.map_err(|e| {
error!("❌ Failed to deserialize BalanceResponse: {}", e);
error!("Raw: {}", text);
BankingError::ApiError {
status: 500,
body: format!("Deserialization error: {}", e),
}
})
},
false => {
let error_body = response.text().await.unwrap_or_default();
error!("❌ Bank API error status {}: {}", status, error_body);
Err(BankingError::ApiError {
status: status.as_u16(),
body: error_body,
})
}
}
}
}

View file

@ -81,6 +81,11 @@ pub struct AccountIdentification {
pub name: String,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct BalanceResponse {
pub data: BalanceData,
}
#[derive(Debug, Deserialize, Serialize, Clone)] // Added Serialize here
pub struct BalanceData {
pub balance: Vec<Balance>,