//! //! 数据持久化客户端 //! //! 提供一个类型化的接口,用于与 `data-persistence-service` 进行通信。 //! use crate::error::Result; use common_contracts::{ dtos::{CompanyProfileDto, RealtimeQuoteDto, TimeSeriesFinancialBatchDto, TimeSeriesFinancialDto}, }; use tracing::info; #[derive(Clone)] pub struct PersistenceClient { client: reqwest::Client, base_url: String, } impl PersistenceClient { pub fn new(base_url: String) -> Self { Self { client: reqwest::Client::new(), base_url, } } pub async fn get_company_profile(&self, symbol: &str) -> Result { let url = format!("{}/companies/{}", self.base_url, symbol); info!("Fetching company profile for {} from {}", symbol, url); let dto = self .client .get(&url) .send() .await? .error_for_status()? .json::() .await?; Ok(dto) } pub async fn get_financial_statements( &self, symbol: &str, ) -> Result> { let url = format!("{}/market-data/financials/{}", self.base_url, symbol); info!("Fetching financials for {} from {}", symbol, url); let dtos = self .client .get(&url) .send() .await? .error_for_status()? .json::>() .await?; Ok(dtos) } pub async fn upsert_company_profile(&self, profile: CompanyProfileDto) -> Result<()> { let url = format!("{}/companies", self.base_url); info!("Upserting company profile for {} to {}", profile.symbol, url); self.client .put(&url) .json(&profile) .send() .await? .error_for_status()?; Ok(()) } pub async fn upsert_realtime_quote(&self, quote: RealtimeQuoteDto) -> Result<()> { let url = format!("{}/market-data/quotes", self.base_url); info!("Upserting realtime quote for {} to {}", quote.symbol, url); self.client .post(&url) .json("e) .send() .await? .error_for_status()?; Ok(()) } pub async fn batch_insert_financials(&self, dtos: Vec) -> Result<()> { if dtos.is_empty() { return Ok(()); } let url = format!("{}/market-data/financials/batch", self.base_url); let symbol = dtos[0].symbol.clone(); info!("Batch inserting {} financial statements for {} to {}", dtos.len(), symbol, url); let batch = TimeSeriesFinancialBatchDto { records: dtos }; self.client .post(&url) .json(&batch) .send() .await? .error_for_status()?; Ok(()) } }