style: apply rustfmt to backend codebase
- Apply rustfmt to all Rust source files in backend/ - Fix trailing whitespace inconsistencies - Standardize formatting across handlers, models, and services - Improve code readability with consistent formatting These changes are purely stylistic and do not affect functionality. All CI checks now pass with proper formatting.
This commit is contained in:
parent
6b7e4d4016
commit
ee0feb77ef
41 changed files with 1266 additions and 819 deletions
|
|
@ -1,13 +1,13 @@
|
|||
use mongodb::{Client, Database, Collection, bson::doc, options::ClientOptions};
|
||||
use anyhow::Result;
|
||||
use mongodb::bson::oid::ObjectId;
|
||||
use mongodb::{bson::doc, options::ClientOptions, Client, Collection, Database};
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::models::{
|
||||
user::{User, UserRepository},
|
||||
share::{Share, ShareRepository},
|
||||
medication::{Medication, MedicationDose, MedicationRepository, UpdateMedicationRequest},
|
||||
permission::Permission,
|
||||
medication::{Medication, MedicationRepository, MedicationDose, UpdateMedicationRequest},
|
||||
share::{Share, ShareRepository},
|
||||
user::{User, UserRepository},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
@ -22,7 +22,7 @@ pub struct MongoDb {
|
|||
impl MongoDb {
|
||||
pub async fn new(uri: &str, db_name: &str) -> Result<Self> {
|
||||
eprintln!("[MongoDB] Starting connection to: {}", uri);
|
||||
|
||||
|
||||
// Parse the URI first
|
||||
let mut client_options = match ClientOptions::parse(uri).await {
|
||||
Ok(opts) => {
|
||||
|
|
@ -31,27 +31,35 @@ impl MongoDb {
|
|||
}
|
||||
Err(e) => {
|
||||
eprintln!("[MongoDB] ERROR: Failed to parse URI: {}", e);
|
||||
|
||||
|
||||
let error_msg = e.to_string().to_lowercase();
|
||||
if error_msg.contains("dns") || error_msg.contains("resolution") || error_msg.contains("lookup") {
|
||||
if error_msg.contains("dns")
|
||||
|| error_msg.contains("resolution")
|
||||
|| error_msg.contains("lookup")
|
||||
{
|
||||
eprintln!("[MongoDB] DNS RESOLUTION ERROR DETECTED!");
|
||||
eprintln!("[MongoDB] Cannot resolve hostname in: {}", uri);
|
||||
eprintln!("[MongoDB] Error: {}", e);
|
||||
}
|
||||
eprintln!("[MongoDB] Will continue in degraded mode (database operations will fail)");
|
||||
|
||||
eprintln!(
|
||||
"[MongoDB] Will continue in degraded mode (database operations will fail)"
|
||||
);
|
||||
|
||||
// Create a minimal configuration that will allow the server to start
|
||||
// but database operations will fail gracefully
|
||||
let mut opts = ClientOptions::parse("mongodb://localhost:27017").await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to create fallback client options: {}", e))?;
|
||||
let mut opts = ClientOptions::parse("mongodb://localhost:27017")
|
||||
.await
|
||||
.map_err(|e| {
|
||||
anyhow::anyhow!("Failed to create fallback client options: {}", e)
|
||||
})?;
|
||||
opts.server_selection_timeout = Some(Duration::from_secs(1));
|
||||
opts.connect_timeout = Some(Duration::from_secs(1));
|
||||
|
||||
|
||||
let client = Client::with_options(opts)
|
||||
.map_err(|e| anyhow::anyhow!("Failed to create MongoDB client: {}", e))?;
|
||||
|
||||
|
||||
let database = client.database(db_name);
|
||||
|
||||
|
||||
return Ok(Self {
|
||||
users: database.collection("users"),
|
||||
shares: database.collection("shares"),
|
||||
|
|
@ -61,13 +69,13 @@ impl MongoDb {
|
|||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Set connection timeout with retry logic
|
||||
client_options.server_selection_timeout = Some(Duration::from_secs(10));
|
||||
client_options.connect_timeout = Some(Duration::from_secs(10));
|
||||
|
||||
|
||||
eprintln!("[MongoDB] Connecting to server...");
|
||||
|
||||
|
||||
let client = match Client::with_options(client_options) {
|
||||
Ok(c) => {
|
||||
eprintln!("[MongoDB] Client created successfully");
|
||||
|
|
@ -76,14 +84,17 @@ impl MongoDb {
|
|||
Err(e) => {
|
||||
eprintln!("[MongoDB] ERROR: Failed to create client: {}", e);
|
||||
eprintln!("[MongoDB] Will continue in degraded mode");
|
||||
|
||||
|
||||
// Create a fallback client
|
||||
let fallback_opts = ClientOptions::parse("mongodb://localhost:27017").await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to create fallback client options: {}", e))?;
|
||||
let fallback_opts = ClientOptions::parse("mongodb://localhost:27017")
|
||||
.await
|
||||
.map_err(|e| {
|
||||
anyhow::anyhow!("Failed to create fallback client options: {}", e)
|
||||
})?;
|
||||
let fallback_client = Client::with_options(fallback_opts)
|
||||
.map_err(|e| anyhow::anyhow!("Failed to create MongoDB client: {}", e))?;
|
||||
let database = fallback_client.database(db_name);
|
||||
|
||||
|
||||
return Ok(Self {
|
||||
users: database.collection("users"),
|
||||
shares: database.collection("shares"),
|
||||
|
|
@ -93,13 +104,13 @@ impl MongoDb {
|
|||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
eprintln!("[MongoDB] Client created, selecting database...");
|
||||
|
||||
|
||||
let database = client.database(db_name);
|
||||
|
||||
|
||||
eprintln!("[MongoDB] Database selected: {}", db_name);
|
||||
|
||||
|
||||
Ok(Self {
|
||||
users: database.collection("users"),
|
||||
shares: database.collection("shares"),
|
||||
|
|
@ -108,7 +119,7 @@ impl MongoDb {
|
|||
database,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
pub async fn health_check(&self) -> Result<String> {
|
||||
eprintln!("[MongoDB] Health check: pinging database...");
|
||||
match self.database.run_command(doc! { "ping": 1 }, None).await {
|
||||
|
|
@ -124,82 +135,82 @@ impl MongoDb {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Get a reference to the underlying MongoDB Database
|
||||
/// This is needed for security services in Phase 2.6
|
||||
pub fn get_database(&self) -> Database {
|
||||
self.database.clone()
|
||||
}
|
||||
|
||||
|
||||
// ===== User Methods =====
|
||||
|
||||
|
||||
pub async fn create_user(&self, user: &User) -> Result<Option<ObjectId>> {
|
||||
let repo = UserRepository::new(self.users.clone());
|
||||
Ok(repo.create(user).await?)
|
||||
}
|
||||
|
||||
|
||||
pub async fn find_user_by_email(&self, email: &str) -> Result<Option<User>> {
|
||||
let repo = UserRepository::new(self.users.clone());
|
||||
Ok(repo.find_by_email(email).await?)
|
||||
}
|
||||
|
||||
|
||||
pub async fn find_user_by_id(&self, id: &ObjectId) -> Result<Option<User>> {
|
||||
let repo = UserRepository::new(self.users.clone());
|
||||
Ok(repo.find_by_id(id).await?)
|
||||
}
|
||||
|
||||
|
||||
pub async fn update_user(&self, user: &User) -> Result<()> {
|
||||
let repo = UserRepository::new(self.users.clone());
|
||||
repo.update(user).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub async fn update_last_active(&self, user_id: &ObjectId) -> Result<()> {
|
||||
let repo = UserRepository::new(self.users.clone());
|
||||
repo.update_last_active(user_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub async fn delete_user(&self, user_id: &ObjectId) -> Result<()> {
|
||||
let repo = UserRepository::new(self.users.clone());
|
||||
repo.delete(user_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
// ===== Share Methods =====
|
||||
|
||||
|
||||
pub async fn create_share(&self, share: &Share) -> Result<Option<ObjectId>> {
|
||||
let repo = ShareRepository::new(self.shares.clone());
|
||||
Ok(repo.create(share).await?)
|
||||
}
|
||||
|
||||
|
||||
pub async fn get_share(&self, id: &str) -> Result<Option<Share>> {
|
||||
let object_id = ObjectId::parse_str(id)?;
|
||||
let repo = ShareRepository::new(self.shares.clone());
|
||||
Ok(repo.find_by_id(&object_id).await?)
|
||||
}
|
||||
|
||||
|
||||
pub async fn list_shares_for_user(&self, user_id: &str) -> Result<Vec<Share>> {
|
||||
let object_id = ObjectId::parse_str(user_id)?;
|
||||
let repo = ShareRepository::new(self.shares.clone());
|
||||
Ok(repo.find_by_target(&object_id).await?)
|
||||
}
|
||||
|
||||
|
||||
pub async fn update_share(&self, share: &Share) -> Result<()> {
|
||||
let repo = ShareRepository::new(self.shares.clone());
|
||||
repo.update(share).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub async fn delete_share(&self, id: &str) -> Result<()> {
|
||||
let object_id = ObjectId::parse_str(id)?;
|
||||
let repo = ShareRepository::new(self.shares.clone());
|
||||
repo.delete(&object_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
// ===== Permission Methods =====
|
||||
|
||||
|
||||
pub async fn check_user_permission(
|
||||
&self,
|
||||
user_id: &str,
|
||||
|
|
@ -209,12 +220,12 @@ impl MongoDb {
|
|||
) -> Result<bool> {
|
||||
let user_oid = ObjectId::parse_str(user_id)?;
|
||||
let resource_oid = ObjectId::parse_str(resource_id)?;
|
||||
|
||||
|
||||
let repo = ShareRepository::new(self.shares.clone());
|
||||
let shares = repo.find_by_target(&user_oid).await?;
|
||||
|
||||
|
||||
for share in shares {
|
||||
if share.resource_type == resource_type
|
||||
if share.resource_type == resource_type
|
||||
&& share.resource_id.as_ref() == Some(&resource_oid)
|
||||
&& share.active
|
||||
&& !share.is_expired()
|
||||
|
|
@ -228,16 +239,16 @@ impl MongoDb {
|
|||
"admin" => Permission::Admin,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
|
||||
|
||||
if share.has_permission(&perm) {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
|
||||
/// Check permission using a simplified interface
|
||||
pub async fn check_permission(
|
||||
&self,
|
||||
|
|
@ -247,74 +258,98 @@ impl MongoDb {
|
|||
) -> Result<bool> {
|
||||
// For now, check all resource types
|
||||
let resource_types = ["profiles", "health_data", "lab_results", "medications"];
|
||||
|
||||
|
||||
for resource_type in resource_types {
|
||||
if self.check_user_permission(user_id, resource_type, resource_id, permission).await? {
|
||||
if self
|
||||
.check_user_permission(user_id, resource_type, resource_id, permission)
|
||||
.await?
|
||||
{
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
|
||||
// ===== Medication Methods (Fixed for Phase 2.8) =====
|
||||
|
||||
|
||||
pub async fn create_medication(&self, medication: &Medication) -> Result<Option<ObjectId>> {
|
||||
let repo = MedicationRepository::new(self.medications.clone());
|
||||
let created = repo.create(medication.clone())
|
||||
let created = repo
|
||||
.create(medication.clone())
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to create medication: {}", e))?;
|
||||
Ok(created.id)
|
||||
}
|
||||
|
||||
|
||||
pub async fn get_medication(&self, id: &str) -> Result<Option<Medication>> {
|
||||
let object_id = ObjectId::parse_str(id)?;
|
||||
let repo = MedicationRepository::new(self.medications.clone());
|
||||
Ok(repo.find_by_id(&object_id)
|
||||
Ok(repo
|
||||
.find_by_id(&object_id)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to get medication: {}", e))?)
|
||||
}
|
||||
|
||||
pub async fn list_medications(&self, user_id: &str, profile_id: Option<&str>) -> Result<Vec<Medication>> {
|
||||
|
||||
pub async fn list_medications(
|
||||
&self,
|
||||
user_id: &str,
|
||||
profile_id: Option<&str>,
|
||||
) -> Result<Vec<Medication>> {
|
||||
let repo = MedicationRepository::new(self.medications.clone());
|
||||
if let Some(profile_id) = profile_id {
|
||||
Ok(repo.find_by_user_and_profile(user_id, profile_id)
|
||||
Ok(repo
|
||||
.find_by_user_and_profile(user_id, profile_id)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to list medications by profile: {}", e))?)
|
||||
} else {
|
||||
Ok(repo.find_by_user(user_id)
|
||||
Ok(repo
|
||||
.find_by_user(user_id)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to list medications: {}", e))?)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update_medication(&self, id: &str, updates: UpdateMedicationRequest) -> Result<Option<Medication>> {
|
||||
|
||||
pub async fn update_medication(
|
||||
&self,
|
||||
id: &str,
|
||||
updates: UpdateMedicationRequest,
|
||||
) -> Result<Option<Medication>> {
|
||||
let object_id = ObjectId::parse_str(id)?;
|
||||
let repo = MedicationRepository::new(self.medications.clone());
|
||||
Ok(repo.update(&object_id, updates)
|
||||
Ok(repo
|
||||
.update(&object_id, updates)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to update medication: {}", e))?)
|
||||
}
|
||||
|
||||
|
||||
pub async fn delete_medication(&self, id: &str) -> Result<bool> {
|
||||
let object_id = ObjectId::parse_str(id)?;
|
||||
let repo = MedicationRepository::new(self.medications.clone());
|
||||
Ok(repo.delete(&object_id)
|
||||
Ok(repo
|
||||
.delete(&object_id)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to delete medication: {}", e))?)
|
||||
}
|
||||
|
||||
|
||||
pub async fn log_medication_dose(&self, dose: &MedicationDose) -> Result<Option<ObjectId>> {
|
||||
// Insert the dose into the medication_doses collection
|
||||
let result = self.medication_doses.insert_one(dose.clone(), None)
|
||||
let result = self
|
||||
.medication_doses
|
||||
.insert_one(dose.clone(), None)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to log dose: {}", e))?;
|
||||
Ok(result.inserted_id.as_object_id())
|
||||
}
|
||||
|
||||
pub async fn get_medication_adherence(&self, medication_id: &str, days: i64) -> Result<crate::models::medication::AdherenceStats> {
|
||||
|
||||
pub async fn get_medication_adherence(
|
||||
&self,
|
||||
medication_id: &str,
|
||||
days: i64,
|
||||
) -> Result<crate::models::medication::AdherenceStats> {
|
||||
let repo = MedicationRepository::new(self.medications.clone());
|
||||
Ok(repo.calculate_adherence(medication_id, days)
|
||||
Ok(repo
|
||||
.calculate_adherence(medication_id, days)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to calculate adherence: {}", e))?)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue