diff --git a/.gitignore b/.gitignore index 348078c..b44cd74 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,8 @@ target/ .idea/ *.swp *.swo +*# +*~ # OS .DS_Store diff --git a/backend/Cargo.lock b/backend/Cargo.lock index ea6bd36..5302f27 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -66,12 +66,6 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -258,9 +252,9 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" -version = "1.7.3" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bech32" @@ -410,9 +404,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.35" +version = "1.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "590f9024a68a8c40351881787f1934dc11afd69090f5edb6831464694d836ea3" +checksum = "5252b3d2648e5eedbc1a6f501e3c795e07025c1e93bbf8bbdd6eef7f447a6d54" dependencies = [ "find-msvc-tools", "jobserver", @@ -428,17 +422,16 @@ checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.2.0", ] [[package]] @@ -877,12 +870,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.0", ] [[package]] @@ -1248,9 +1241,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e178e4fba8a2726903f6ba98a6d221e76f9c12c650d5dc0e6afdc50677b49650" +checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d" [[package]] name = "fixed-hash" @@ -1482,7 +1475,7 @@ dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.3+wasi-0.2.4", + "wasi 0.14.4+wasi-0.2.4", ] [[package]] @@ -1972,9 +1965,9 @@ checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921" dependencies = [ "equivalent", "hashbrown 0.15.5", @@ -2176,6 +2169,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + [[package]] name = "litemap" version = "0.8.0" @@ -3068,15 +3067,16 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.8" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "9621e389a110cae094269936383d69b869492f03e5c1ed2d575a53c029d4441d" dependencies = [ "bitflags 2.9.4", "errno", "libc", - "linux-raw-sys", - "windows-sys 0.60.2", + "linux-raw-sys 0.11.0", + "linux-raw-sys 0.9.4", + "windows-sys 0.61.0", ] [[package]] @@ -4425,9 +4425,9 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.3+wasi-0.2.4" +version = "0.14.4+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95" +checksum = "88a5f4a424faf49c3c2c344f166f0662341d470ea185e939657aaff130f0ec4a" dependencies = [ "wit-bindgen", ] @@ -4554,11 +4554,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.0", ] [[package]] @@ -4575,7 +4575,7 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", - "windows-link", + "windows-link 0.1.3", "windows-result", "windows-strings", ] @@ -4608,13 +4608,19 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + [[package]] name = "windows-result" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -4623,7 +4629,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -4662,6 +4668,15 @@ dependencies = [ "windows-targets 0.53.3", ] +[[package]] +name = "windows-sys" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +dependencies = [ + "windows-link 0.2.0", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -4699,7 +4714,7 @@ version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -4869,9 +4884,9 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.45.0" +version = "0.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814" +checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" [[package]] name = "writeable" @@ -4939,18 +4954,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 6251129..e875d35 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -4,8 +4,8 @@ version = "0.1.0" edition = "2021" [[bin]] -name = "guild-backend-dev" -path = "src/main_dev.rs" +name = "guild-backend" +path = "src/main.rs" [[bin]] name = "migrate" @@ -32,7 +32,7 @@ ethers = { version = "2.0", features = ["rustls"] } sha3 = "0.10" # Pin problematic dependencies to avoid edition 2024 -base64ct = "=1.7.3" +base64ct = "1.7.3" # Utilities anyhow = "1.0" diff --git a/backend/rustfmt.toml b/backend/rustfmt.toml new file mode 100644 index 0000000..c51666e --- /dev/null +++ b/backend/rustfmt.toml @@ -0,0 +1 @@ +edition = "2018" \ No newline at end of file diff --git a/backend/src/application/commands/create_profile.rs b/backend/src/application/commands/create_profile.rs new file mode 100644 index 0000000..98a17dd --- /dev/null +++ b/backend/src/application/commands/create_profile.rs @@ -0,0 +1,55 @@ +use crate::application::dtos::profile_dtos::{ + CreateProfileRequest, ProfileListResponse, ProfileResponse, UpdateProfileRequest, +}; +use crate::domain::repositories::profile_repository::ProfileRepository; +use crate::domain::services::AuthService; +use crate::domain::value_objects::wallet_address::WalletAddress; +use std::sync::Arc; + +#[derive(Clone)] +pub struct ProfileApplicationService { + profile_repository: Arc, + auth_service: Arc, +} + +pub async fn create_profile( + &self, + request: CreateProfileRequest, +) -> Result { + let wallet_address = WalletAddress::new(request.address).map_err(|e| e.to_string())?; + let user = self + .user_repository + .find_by_wallet_address(&wallet_address.to_string()) + .await + .map_err(|e| e.to_string())? + .ok_or("User not found")?; + + // Check if profile already exists + if self + .profile_repository + .find_by_user_id(&user.id) + .await + .map_err(|e| e.to_string())? + .is_some() + { + return Err("Profile already exists for this user".to_string()); + } + + let mut profile = crate::domain::entities::profile::Profile::new(user.id); + profile.update_info(Some(request.name), request.description, request.avatar_url); + + self.profile_repository + .create(&profile) + .await + .map_err(|e| e.to_string())?; + + Ok(ProfileResponse { + id: profile.id, + user_id: profile.user_id, + name: profile.name.unwrap_or_default(), + description: profile.description, + avatar_url: profile.avatar_url, + created_at: profile.created_at, + updated_at: profile.updated_at, + }) +} diff --git a/backend/src/application/commands/get_profile.rs b/backend/src/application/commands/get_profile.rs new file mode 100644 index 0000000..f131b2c --- /dev/null +++ b/backend/src/application/commands/get_profile.rs @@ -0,0 +1,40 @@ +use crate::application::dtos::profile_dtos::{ + CreateProfileRequest, ProfileListResponse, ProfileResponse, UpdateProfileRequest, +}; +use crate::domain::repositories::profile_repository::ProfileRepository; +use crate::domain::services::AuthService; +use crate::domain::value_objects::wallet_address::WalletAddress; +use std::sync::Arc; + +#[derive(Clone)] +pub struct ProfileApplicationService { + profile_repository: Arc, + auth_service: Arc, +} + +pub async fn GetProfile(&self, address: String) -> Result { + let wallet_address = WalletAddress::new(address).map_err(|e| e.to_string())?; + let user = self + .user_repository + .find_by_wallet_address(&wallet_address.to_string()) + .await + .map_err(|e| e.to_string())? + .ok_or("User not found")?; + + let profile = self + .profile_repository + .find_by_user_id(&user.id) + .await + .map_err(|e| e.to_string())? + .ok_or("Profile not found")?; + + Ok(ProfileResponse { + id: profile.id, + user_id: profile.user_id, + name: profile.name.unwrap_or_default(), + description: profile.description, + avatar_url: profile.avatar_url, + created_at: profile.created_at, + updated_at: profile.updated_at, + }) +} diff --git a/backend/src/application/commands/mod.rs b/backend/src/application/commands/mod.rs new file mode 100644 index 0000000..aeaf30b --- /dev/null +++ b/backend/src/application/commands/mod.rs @@ -0,0 +1,3 @@ +pub mod create_profile; +pub mod get_profile; +pub mod update_profile; diff --git a/backend/src/application/commands/update_profile.rs b/backend/src/application/commands/update_profile.rs new file mode 100644 index 0000000..691dbe7 --- /dev/null +++ b/backend/src/application/commands/update_profile.rs @@ -0,0 +1,50 @@ +use crate::application::dtos::profile_dtos::{ + CreateProfileRequest, ProfileListResponse, ProfileResponse, UpdateProfileRequest, +}; +use crate::domain::repositories::profile_repository::ProfileRepository; +use crate::domain::services::AuthService; +use crate::domain::value_objects::wallet_address::WalletAddress; +use std::sync::Arc; + +#[derive(Clone)] +pub struct ProfileApplicationService { + profile_repository: Arc, + auth_service: Arc, +} + +pub async fn update_profile( + &self, + address: String, + request: UpdateProfileRequest, +) -> Result { + let wallet_address = WalletAddress::new(address).map_err(|e| e.to_string())?; + let user = self + .user_repository + .find_by_wallet_address(&wallet_address.to_string()) + .await + .map_err(|e| e.to_string())? + .ok_or("User not found")?; + + let mut profile = self + .profile_repository + .find_by_user_id(&user.id) + .await + .map_err(|e| e.to_string())? + .ok_or("Profile not found")?; + + profile.update_info(request.name, request.description, request.avatar_url); + self.profile_repository + .update(&profile) + .await + .map_err(|e| e.to_string())?; + + Ok(ProfileResponse { + id: profile.id, + user_id: profile.user_id, + name: profile.name.unwrap_or_default(), + description: profile.description, + avatar_url: profile.avatar_url, + created_at: profile.created_at, + updated_at: profile.updated_at, + }) +} diff --git a/backend/src/application/dtos/auth_dtos.rs b/backend/src/application/dtos/auth_dtos.rs index 4245913..8b38ce4 100644 --- a/backend/src/application/dtos/auth_dtos.rs +++ b/backend/src/application/dtos/auth_dtos.rs @@ -1,45 +1,9 @@ -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct AuthChallengeRequest { - pub wallet_address: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct AuthChallengeResponse { - pub nonce: String, - pub message: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct AuthVerifyRequest { - pub wallet_address: String, - pub signature: String, - pub nonce: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct AuthVerifyResponse { - pub user_id: Uuid, - pub wallet_address: String, - pub token: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct NonceResponse { - pub nonce: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] pub struct VerifyMessageRequest { pub address: String, - pub message: String, - pub signature: String, pub nonce: String, + pub message: String, } -#[derive(Debug, Clone, Serialize, Deserialize)] pub struct VerifyMessageResponse { pub success: bool, pub address: String, diff --git a/backend/src/application/dtos/badge_dtos.rs b/backend/src/application/dtos/badge_dtos.rs deleted file mode 100644 index 4ec05a0..0000000 --- a/backend/src/application/dtos/badge_dtos.rs +++ /dev/null @@ -1,40 +0,0 @@ -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -#[derive(Debug, Serialize)] -pub struct BadgeResponse { - pub id: Uuid, - pub name: String, - pub description: String, - pub issuer_address: String, - pub image_url: Option, - pub created_at: String, - pub updated_at: String, -} - -#[derive(Debug, Deserialize)] -pub struct CreateBadgeRequest { - pub name: String, - pub description: String, - pub issuer_address: String, - pub image_url: Option, -} - -#[derive(Debug, Deserialize)] -pub struct GiveBadgeRequest { - pub profile_address: String, -} - -#[derive(Debug, Serialize)] -pub struct BadgeListResponse { - pub badges: Vec, -} - -#[derive(Debug, Serialize)] -pub struct UserBadgeResponse { - pub id: Uuid, - pub badge: BadgeResponse, - pub awarded_at: String, - pub awarded_by: String, -} - diff --git a/backend/src/application/dtos/mod.rs b/backend/src/application/dtos/mod.rs index 1cacdf5..6eb6b75 100644 --- a/backend/src/application/dtos/mod.rs +++ b/backend/src/application/dtos/mod.rs @@ -1,8 +1,5 @@ pub mod auth_dtos; pub mod profile_dtos; -pub mod badge_dtos; pub use auth_dtos::*; pub use profile_dtos::*; -pub use badge_dtos::*; - diff --git a/backend/src/application/dtos/profile_dtos.rs b/backend/src/application/dtos/profile_dtos.rs index 8903b3d..396e7ee 100644 --- a/backend/src/application/dtos/profile_dtos.rs +++ b/backend/src/application/dtos/profile_dtos.rs @@ -26,8 +26,3 @@ pub struct ProfileResponse { pub created_at: chrono::DateTime, pub updated_at: chrono::DateTime, } - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ProfileListResponse { - pub profiles: Vec, -} diff --git a/backend/src/application/mod.rs b/backend/src/application/mod.rs index e7358e4..31002c8 100644 --- a/backend/src/application/mod.rs +++ b/backend/src/application/mod.rs @@ -1,3 +1,2 @@ +pub mod commands; pub mod dtos; -pub mod services; - diff --git a/backend/src/application/services/auth_service.rs b/backend/src/application/services/auth_service.rs deleted file mode 100644 index f7b17b3..0000000 --- a/backend/src/application/services/auth_service.rs +++ /dev/null @@ -1,76 +0,0 @@ -use std::sync::Arc; -use crate::domain::repositories::user_repository::UserRepository; -use crate::domain::services::auth_service::AuthService as DomainAuthService; -use crate::domain::value_objects::wallet_address::WalletAddress; -use crate::application::dtos::auth_dtos::{NonceResponse, VerifyMessageRequest, VerifyMessageResponse}; - -// Mock implementation for development -struct MockAuthService; - -#[async_trait::async_trait] -impl DomainAuthService for MockAuthService { - async fn create_challenge(&self, _wallet_address: &WalletAddress) -> Result> { - Ok(crate::domain::services::auth_service::AuthChallenge { - nonce: "mock-nonce".to_string(), - message: "mock-message".to_string(), - }) - } - - async fn verify_signature(&self, _challenge: &crate::domain::services::auth_service::AuthChallenge, _signature: &str) -> Result> { - Ok(crate::domain::services::auth_service::AuthResult { - user_id: uuid::Uuid::new_v4(), - wallet_address: WalletAddress::new("0x1234567890123456789012345678901234567890".to_string()).unwrap(), - }) - } -} - -#[derive(Clone)] -pub struct AuthApplicationService { - user_repository: Arc, - auth_service: Arc, -} - -impl AuthApplicationService { - pub fn new(user_repository: Box) -> Self { - Self { - user_repository: Arc::from(user_repository), - auth_service: Arc::new(MockAuthService), - } - } - - pub async fn generate_nonce(&self) -> Result { - let wallet_address = WalletAddress::new("0x1234567890123456789012345678901234567890".to_string()).unwrap(); - let challenge = self.auth_service.create_challenge(&wallet_address).await.map_err(|e| e.to_string())?; - Ok(NonceResponse { - nonce: challenge.nonce, - }) - } - - pub async fn verify_message(&self, request: VerifyMessageRequest) -> Result { - // Validate wallet address - let wallet_address = WalletAddress::new(request.address.clone()).map_err(|e| e.to_string())?; - - // Create challenge and verify signature - let challenge = crate::domain::services::auth_service::AuthChallenge { - nonce: request.nonce, - message: request.message, - }; - - let auth_result = self.auth_service.verify_signature(&challenge, &request.signature).await.map_err(|e| e.to_string())?; - - // Create or find user - let user = match self.user_repository.find_by_wallet_address(&wallet_address.to_string()).await.map_err(|e| e.to_string())? { - Some(user) => user, - None => { - let new_user = crate::domain::entities::user::User::new(wallet_address.to_string()); - self.user_repository.create(&new_user).await.map_err(|e| e.to_string())?; - new_user - } - }; - - Ok(VerifyMessageResponse { - success: true, - address: wallet_address.to_string(), - }) - } -} diff --git a/backend/src/application/services/badge_service.rs b/backend/src/application/services/badge_service.rs deleted file mode 100644 index e580865..0000000 --- a/backend/src/application/services/badge_service.rs +++ /dev/null @@ -1,125 +0,0 @@ -use std::sync::Arc; -use uuid::Uuid; -use crate::domain::repositories::{user_repository::UserRepository, badge_repository::BadgeRepository}; -use crate::domain::value_objects::wallet_address::WalletAddress; -use crate::application::dtos::badge_dtos::{ - BadgeResponse, CreateBadgeRequest, GiveBadgeRequest, BadgeListResponse, UserBadgeResponse -}; - -#[derive(Clone)] -pub struct BadgeApplicationService { - user_repository: Arc, - badge_repository: Arc, -} - -impl BadgeApplicationService { - pub fn new( - user_repository: Box, - badge_repository: Box, - ) -> Self { - Self { - user_repository: Arc::from(user_repository), - badge_repository: Arc::from(badge_repository), - } - } - - pub async fn get_badges(&self) -> Result { - let badges = self.badge_repository.find_all().await.map_err(|e| e.to_string())?; - let badge_responses: Vec = badges - .into_iter() - .map(|badge| BadgeResponse { - id: badge.id, - name: badge.name, - description: badge.description, - issuer_address: badge.issuer_address, - image_url: badge.image_url, - created_at: badge.created_at.to_rfc3339(), - updated_at: badge.updated_at.to_rfc3339(), - }) - .collect(); - - Ok(BadgeListResponse { - badges: badge_responses, - }) - } - - pub async fn get_badge(&self, id: Uuid) -> Result { - let badge = self.badge_repository - .find_by_id(&id) - .await.map_err(|e| e.to_string())? - .ok_or("Badge not found")?; - - Ok(BadgeResponse { - id: badge.id, - name: badge.name, - description: badge.description, - issuer_address: badge.issuer_address, - image_url: badge.image_url, - created_at: badge.created_at.to_rfc3339(), - updated_at: badge.updated_at.to_rfc3339(), - }) - } - - pub async fn create_badge(&self, request: CreateBadgeRequest) -> Result { - let mut badge = crate::domain::entities::badge::Badge::new( - request.name, - request.description, - request.issuer_address, - ); - - if let Some(image_url) = request.image_url { - badge.set_image_url(Some(image_url)); - } - - self.badge_repository.create(&badge).await.map_err(|e| e.to_string())?; - - Ok(BadgeResponse { - id: badge.id, - name: badge.name, - description: badge.description, - issuer_address: badge.issuer_address, - image_url: badge.image_url, - created_at: badge.created_at.to_rfc3339(), - updated_at: badge.updated_at.to_rfc3339(), - }) - } - - pub async fn give_badge(&self, badge_id: Uuid, request: GiveBadgeRequest) -> Result { - let wallet_address = WalletAddress::new(request.profile_address).map_err(|e| e.to_string())?; - let user = self.user_repository - .find_by_wallet_address(&wallet_address.to_string()) - .await.map_err(|e| e.to_string())? - .ok_or("User not found")?; - - // Verify badge exists - let badge = self.badge_repository - .find_by_id(&badge_id) - .await.map_err(|e| e.to_string())? - .ok_or("Badge not found")?; - - let user_badge = crate::domain::repositories::badge_repository::UserBadge { - id: uuid::Uuid::new_v4(), - user_id: user.id, - badge_id, - awarded_at: chrono::Utc::now(), - awarded_by: badge.issuer_address.clone(), - }; - - self.badge_repository.award_badge(&user_badge).await.map_err(|e| e.to_string())?; - - Ok(UserBadgeResponse { - id: user_badge.id, - badge: BadgeResponse { - id: badge.id, - name: badge.name, - description: badge.description, - issuer_address: badge.issuer_address, - image_url: badge.image_url, - created_at: badge.created_at.to_rfc3339(), - updated_at: badge.updated_at.to_rfc3339(), - }, - awarded_at: user_badge.awarded_at.to_rfc3339(), - awarded_by: user_badge.awarded_by, - }) - } -} diff --git a/backend/src/application/services/mod.rs b/backend/src/application/services/mod.rs deleted file mode 100644 index 3bf84b0..0000000 --- a/backend/src/application/services/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub mod auth_service; -pub mod profile_service; -pub mod badge_service; - -pub use auth_service::AuthApplicationService; -pub use profile_service::ProfileApplicationService; -pub use badge_service::BadgeApplicationService; - diff --git a/backend/src/application/services/profile_service.rs b/backend/src/application/services/profile_service.rs deleted file mode 100644 index 5a418b1..0000000 --- a/backend/src/application/services/profile_service.rs +++ /dev/null @@ -1,122 +0,0 @@ -use std::sync::Arc; -use uuid::Uuid; -use crate::domain::repositories::{user_repository::UserRepository, profile_repository::ProfileRepository}; -use crate::domain::value_objects::wallet_address::WalletAddress; -use crate::application::dtos::profile_dtos::{ - ProfileResponse, CreateProfileRequest, UpdateProfileRequest, ProfileListResponse -}; - -#[derive(Clone)] -pub struct ProfileApplicationService { - user_repository: Arc, - profile_repository: Arc, -} - -impl ProfileApplicationService { - pub fn new( - user_repository: Box, - profile_repository: Box, - ) -> Self { - Self { - user_repository: Arc::from(user_repository), - profile_repository: Arc::from(profile_repository), - } - } - - pub async fn get_profiles(&self) -> Result { - let profiles = self.profile_repository.find_all().await.map_err(|e| e.to_string())?; - let profile_responses: Vec = profiles - .into_iter() - .map(|profile| ProfileResponse { - id: profile.id, - user_id: profile.user_id, - name: profile.name.unwrap_or_default(), - description: profile.description, - avatar_url: profile.avatar_url, - created_at: profile.created_at, - updated_at: profile.updated_at, - }) - .collect(); - - Ok(ProfileListResponse { - profiles: profile_responses, - }) - } - - pub async fn get_profile(&self, address: String) -> Result { - let wallet_address = WalletAddress::new(address).map_err(|e| e.to_string())?; - let user = self.user_repository - .find_by_wallet_address(&wallet_address.to_string()) - .await.map_err(|e| e.to_string())? - .ok_or("User not found")?; - - let profile = self.profile_repository - .find_by_user_id(&user.id) - .await.map_err(|e| e.to_string())? - .ok_or("Profile not found")?; - - Ok(ProfileResponse { - id: profile.id, - user_id: profile.user_id, - name: profile.name.unwrap_or_default(), - description: profile.description, - avatar_url: profile.avatar_url, - created_at: profile.created_at, - updated_at: profile.updated_at, - }) - } - - pub async fn create_profile(&self, request: CreateProfileRequest) -> Result { - let wallet_address = WalletAddress::new(request.address).map_err(|e| e.to_string())?; - let user = self.user_repository - .find_by_wallet_address(&wallet_address.to_string()) - .await.map_err(|e| e.to_string())? - .ok_or("User not found")?; - - // Check if profile already exists - if self.profile_repository.find_by_user_id(&user.id).await.map_err(|e| e.to_string())?.is_some() { - return Err("Profile already exists for this user".to_string()); - } - - let mut profile = crate::domain::entities::profile::Profile::new(user.id); - profile.update_info(Some(request.name), request.description, request.avatar_url); - - self.profile_repository.create(&profile).await.map_err(|e| e.to_string())?; - - Ok(ProfileResponse { - id: profile.id, - user_id: profile.user_id, - name: profile.name.unwrap_or_default(), - description: profile.description, - avatar_url: profile.avatar_url, - created_at: profile.created_at, - updated_at: profile.updated_at, - }) - } - - pub async fn update_profile(&self, address: String, request: UpdateProfileRequest) -> Result { - let wallet_address = WalletAddress::new(address).map_err(|e| e.to_string())?; - let user = self.user_repository - .find_by_wallet_address(&wallet_address.to_string()) - .await.map_err(|e| e.to_string())? - .ok_or("User not found")?; - - let mut profile = self.profile_repository - .find_by_user_id(&user.id) - .await.map_err(|e| e.to_string())? - .ok_or("Profile not found")?; - - profile.update_info(request.name, request.description, request.avatar_url); - self.profile_repository.update(&profile).await.map_err(|e| e.to_string())?; - - Ok(ProfileResponse { - id: profile.id, - user_id: profile.user_id, - name: profile.name.unwrap_or_default(), - description: profile.description, - avatar_url: profile.avatar_url, - created_at: profile.created_at, - updated_at: profile.updated_at, - }) - } -} diff --git a/backend/src/bin/migrate.rs b/backend/src/bin/migrate.rs index e5ace55..9361c8f 100644 --- a/backend/src/bin/migrate.rs +++ b/backend/src/bin/migrate.rs @@ -5,19 +5,20 @@ use std::env; async fn main() -> Result<(), Box> { // Load environment variables dotenvy::dotenv().ok(); - - let database_url = env::var("DATABASE_URL") - .unwrap_or_else(|_| "postgresql://guild_user:guild_password@localhost:5432/guild_genesis".to_string()); - + + let database_url = env::var("DATABASE_URL").unwrap_or_else(|_| { + "postgresql://guild_user:guild_password@localhost:5432/guild_genesis".to_string() + }); + println!("🔌 Connecting to database: {}", database_url); - + let pool = PgPool::connect(&database_url).await?; - + println!("🏃‍♂️ Running migrations..."); - + // Run migrations from the migrations directory sqlx::migrate!("./migrations").run(&pool).await?; - + println!("✅ Migrations completed successfully"); Ok(()) } diff --git a/backend/src/database.rs b/backend/src/database.rs index 5ca61ad..b290d42 100644 --- a/backend/src/database.rs +++ b/backend/src/database.rs @@ -4,8 +4,8 @@ use std::env; pub async fn create_pool() -> anyhow::Result { let database_url = env::var("DATABASE_URL") .unwrap_or_else(|_| "postgres://localhost/guild_genesis".to_string()); - + let pool = PgPool::connect(&database_url).await?; - + Ok(pool) } diff --git a/backend/src/domain/entities/badge.rs b/backend/src/domain/entities/badge.rs deleted file mode 100644 index 801466b..0000000 --- a/backend/src/domain/entities/badge.rs +++ /dev/null @@ -1,56 +0,0 @@ -use chrono::{DateTime, Utc}; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Badge { - pub id: Uuid, - pub name: String, - pub description: String, - pub issuer_address: String, - pub image_url: Option, - pub created_at: DateTime, - pub updated_at: DateTime, -} - -impl Badge { - pub fn new(name: String, description: String, issuer_address: String) -> Self { - let now = Utc::now(); - Self { - id: Uuid::new_v4(), - name, - description, - issuer_address, - image_url: None, - created_at: now, - updated_at: now, - } - } - - pub fn set_image_url(&mut self, image_url: Option) { - self.image_url = image_url; - self.updated_at = Utc::now(); - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct UserBadge { - pub id: Uuid, - pub user_id: Uuid, - pub badge_id: Uuid, - pub awarded_at: DateTime, - pub awarded_by: String, // Address of the person who awarded the badge -} - -impl UserBadge { - pub fn new(user_id: Uuid, badge_id: Uuid, awarded_by: String) -> Self { - Self { - id: Uuid::new_v4(), - user_id, - badge_id, - awarded_at: Utc::now(), - awarded_by, - } - } -} - diff --git a/backend/src/domain/entities/mod.rs b/backend/src/domain/entities/mod.rs index 8910f65..1c6f56c 100644 --- a/backend/src/domain/entities/mod.rs +++ b/backend/src/domain/entities/mod.rs @@ -1,8 +1,3 @@ -pub mod user; pub mod profile; -pub mod badge; -pub use user::User; pub use profile::Profile; -pub use badge::{Badge, UserBadge}; - diff --git a/backend/src/domain/entities/profile.rs b/backend/src/domain/entities/profile.rs index 24d7ccf..7b3621e 100644 --- a/backend/src/domain/entities/profile.rs +++ b/backend/src/domain/entities/profile.rs @@ -27,11 +27,15 @@ impl Profile { } } - pub fn update_info(&mut self, name: Option, description: Option, avatar_url: Option) { + pub fn update_info( + &mut self, + name: Option, + description: Option, + avatar_url: Option, + ) { self.name = name; self.description = description; self.avatar_url = avatar_url; self.updated_at = Utc::now(); } } - diff --git a/backend/src/domain/entities/user.rs b/backend/src/domain/entities/user.rs deleted file mode 100644 index cf96403..0000000 --- a/backend/src/domain/entities/user.rs +++ /dev/null @@ -1,28 +0,0 @@ -use chrono::{DateTime, Utc}; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct User { - pub id: Uuid, - pub wallet_address: String, - pub created_at: DateTime, - pub updated_at: DateTime, -} - -impl User { - pub fn new(wallet_address: String) -> Self { - let now = Utc::now(); - Self { - id: Uuid::new_v4(), - wallet_address, - created_at: now, - updated_at: now, - } - } - - pub fn update_timestamp(&mut self) { - self.updated_at = Utc::now(); - } -} - diff --git a/backend/src/domain/mod.rs b/backend/src/domain/mod.rs index babb797..679ebe2 100644 --- a/backend/src/domain/mod.rs +++ b/backend/src/domain/mod.rs @@ -1,5 +1,4 @@ pub mod entities; -pub mod value_objects; pub mod repositories; pub mod services; - +pub mod value_objects; diff --git a/backend/src/domain/repositories/badge_repository.rs b/backend/src/domain/repositories/badge_repository.rs deleted file mode 100644 index 80b2bb6..0000000 --- a/backend/src/domain/repositories/badge_repository.rs +++ /dev/null @@ -1,27 +0,0 @@ -use async_trait::async_trait; -use uuid::Uuid; - -use crate::domain::entities::badge::Badge; - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct UserBadge { - pub id: Uuid, - pub user_id: Uuid, - pub badge_id: Uuid, - pub awarded_at: chrono::DateTime, - pub awarded_by: String, -} - -#[async_trait] -pub trait BadgeRepository: Send + Sync { - async fn create(&self, badge: &Badge) -> Result<(), Box>; - async fn find_by_id(&self, id: &Uuid) -> Result, Box>; - async fn find_all(&self) -> Result, Box>; - async fn update(&self, badge: &Badge) -> Result<(), Box>; - async fn delete(&self, id: &Uuid) -> Result<(), Box>; - - // User badge operations - async fn award_badge(&self, user_badge: &UserBadge) -> Result<(), Box>; - async fn find_user_badges(&self, user_id: &Uuid) -> Result, Box>; - async fn find_badge_users(&self, badge_id: &Uuid) -> Result, Box>; -} diff --git a/backend/src/domain/repositories/mod.rs b/backend/src/domain/repositories/mod.rs index d206233..b330a49 100644 --- a/backend/src/domain/repositories/mod.rs +++ b/backend/src/domain/repositories/mod.rs @@ -1,8 +1,3 @@ -pub mod user_repository; pub mod profile_repository; -pub mod badge_repository; -pub use user_repository::UserRepository; pub use profile_repository::ProfileRepository; -pub use badge_repository::BadgeRepository; - diff --git a/backend/src/domain/repositories/profile_repository.rs b/backend/src/domain/repositories/profile_repository.rs index 69ee377..1fa106d 100644 --- a/backend/src/domain/repositories/profile_repository.rs +++ b/backend/src/domain/repositories/profile_repository.rs @@ -6,9 +6,6 @@ use crate::domain::entities::profile::Profile; #[async_trait] pub trait ProfileRepository: Send + Sync { async fn create(&self, profile: &Profile) -> Result<(), Box>; - async fn find_by_id(&self, id: &Uuid) -> Result, Box>; - async fn find_by_user_id(&self, user_id: &Uuid) -> Result, Box>; - async fn find_all(&self) -> Result, Box>; async fn update(&self, profile: &Profile) -> Result<(), Box>; async fn delete(&self, id: &Uuid) -> Result<(), Box>; } diff --git a/backend/src/domain/repositories/user_repository.rs b/backend/src/domain/repositories/user_repository.rs deleted file mode 100644 index f052146..0000000 --- a/backend/src/domain/repositories/user_repository.rs +++ /dev/null @@ -1,13 +0,0 @@ -use async_trait::async_trait; -use uuid::Uuid; - -use crate::domain::entities::user::User; - -#[async_trait] -pub trait UserRepository: Send + Sync { - async fn create(&self, user: &User) -> Result<(), Box>; - async fn find_by_id(&self, id: &Uuid) -> Result, Box>; - async fn find_by_wallet_address(&self, address: &str) -> Result, Box>; - async fn update(&self, user: &User) -> Result<(), Box>; - async fn delete(&self, id: &Uuid) -> Result<(), Box>; -} diff --git a/backend/src/domain/services/auth_service.rs b/backend/src/domain/services/auth_service.rs index d5fe691..4953e94 100644 --- a/backend/src/domain/services/auth_service.rs +++ b/backend/src/domain/services/auth_service.rs @@ -1,5 +1,4 @@ use async_trait::async_trait; -use uuid::Uuid; use crate::domain::value_objects::wallet_address::WalletAddress; @@ -11,12 +10,14 @@ pub struct AuthChallenge { #[derive(Debug, Clone, PartialEq, Eq)] pub struct AuthResult { - pub user_id: Uuid, pub wallet_address: WalletAddress, } #[async_trait] pub trait AuthService: Send + Sync { - async fn create_challenge(&self, wallet_address: &WalletAddress) -> Result>; - async fn verify_signature(&self, challenge: &AuthChallenge, signature: &str) -> Result>; + async fn verify_signature( + &self, + challenge: &AuthChallenge, + signature: &str, + ) -> Result>; } diff --git a/backend/src/domain/services/mod.rs b/backend/src/domain/services/mod.rs index afa72f0..4b323dc 100644 --- a/backend/src/domain/services/mod.rs +++ b/backend/src/domain/services/mod.rs @@ -1,4 +1,3 @@ pub mod auth_service; -pub use auth_service::AuthService; - +pub use auth_service::*; diff --git a/backend/src/domain/value_objects/mod.rs b/backend/src/domain/value_objects/mod.rs index 32ed342..12d5f49 100644 --- a/backend/src/domain/value_objects/mod.rs +++ b/backend/src/domain/value_objects/mod.rs @@ -1,6 +1,5 @@ -pub mod wallet_address; pub mod nonce; +pub mod wallet_address; -pub use wallet_address::WalletAddress; pub use nonce::Nonce; - +pub use wallet_address::WalletAddress; diff --git a/backend/src/domain/value_objects/wallet_address.rs b/backend/src/domain/value_objects/wallet_address.rs index 903fedd..e25f37f 100644 --- a/backend/src/domain/value_objects/wallet_address.rs +++ b/backend/src/domain/value_objects/wallet_address.rs @@ -9,15 +9,15 @@ impl WalletAddress { if address.is_empty() { return Err("Wallet address cannot be empty".to_string()); } - + // Basic validation - should be a valid Ethereum address format if !address.starts_with("0x") || address.len() != 42 { return Err("Invalid wallet address format".to_string()); } - + Ok(Self(address)) } - + pub fn as_str(&self) -> &str { &self.0 } @@ -34,4 +34,3 @@ impl From for String { addr.0 } } - diff --git a/backend/src/handlers/auth.rs b/backend/src/handlers/auth.rs deleted file mode 100644 index 2e76c7b..0000000 --- a/backend/src/handlers/auth.rs +++ /dev/null @@ -1,30 +0,0 @@ -use axum::{ - extract::State, - http::StatusCode, - response::Json, -}; -use serde_json::{json, Value}; - -pub async fn get_nonce() -> Result, StatusCode> { - // Generate a random nonce for SIWE - let nonce = uuid::Uuid::new_v4().to_string(); - Ok(Json(json!({ - "nonce": nonce - }))) -} - -pub async fn verify_message( - State(_pool): State, - Json(payload): Json, -) -> Result, StatusCode> { - // TODO: Implement SIWE verification - // For now, just return success - let address = payload.get("address") - .and_then(|v| v.as_str()) - .ok_or(StatusCode::BAD_REQUEST)?; - - Ok(Json(json!({ - "success": true, - "address": address - }))) -} diff --git a/backend/src/handlers/badges.rs b/backend/src/handlers/badges.rs deleted file mode 100644 index f70e087..0000000 --- a/backend/src/handlers/badges.rs +++ /dev/null @@ -1,58 +0,0 @@ -use axum::{ - extract::{Path, State}, - http::StatusCode, - response::Json, -}; -use serde_json::{json, Value}; - -pub async fn get_badges(State(_pool): State) -> Result, StatusCode> { - // TODO: Implement database query - Ok(Json(json!({ - "badges": [] - }))) -} - -pub async fn get_badge( - State(_pool): State, - Path(id): Path, -) -> Result, StatusCode> { - // TODO: Implement database query - Ok(Json(json!({ - "id": id, - "name": "", - "description": "", - "issuer_address": "" - }))) -} - -pub async fn create_badge( - State(_pool): State, - Json(payload): Json, -) -> Result, StatusCode> { - let name = payload.get("name") - .and_then(|v| v.as_str()) - .ok_or(StatusCode::BAD_REQUEST)?; - - // TODO: Implement database insert - Ok(Json(json!({ - "success": true, - "name": name - }))) -} - -pub async fn give_badge( - State(_pool): State, - Path(id): Path, - Json(payload): Json, -) -> Result, StatusCode> { - let profile_address = payload.get("profile_address") - .and_then(|v| v.as_str()) - .ok_or(StatusCode::BAD_REQUEST)?; - - // TODO: Implement database insert - Ok(Json(json!({ - "success": true, - "badge_id": id, - "profile_address": profile_address - }))) -} diff --git a/backend/src/handlers/dev.rs b/backend/src/handlers/dev.rs deleted file mode 100644 index c4aa6f9..0000000 --- a/backend/src/handlers/dev.rs +++ /dev/null @@ -1,132 +0,0 @@ -use axum::{ - extract::Path, - http::StatusCode, - response::Json, -}; -use serde_json::{json, Value}; - -pub async fn verify_message_dev(Json(payload): Json) -> Result, StatusCode> { - let address = payload.get("address") - .and_then(|v| v.as_str()) - .ok_or(StatusCode::BAD_REQUEST)?; - - Ok(Json(json!({ - "success": true, - "address": address - }))) -} - -pub async fn get_profiles_dev() -> Result, StatusCode> { - Ok(Json(json!({ - "profiles": [ - { - "address": "0x1234567890123456789012345678901234567890", - "name": "Alice Developer", - "description": "Full-stack developer passionate about Web3 and Rust", - "avatar_url": "https://example.com/avatar.jpg", - "badges": [ - { - "id": "1", - "name": "Rust", - "description": "Rust programming", - "issuer": "0xabcd1234567890123456789012345678901234567890" - }, - { - "id": "2", - "name": "React", - "description": "React development", - "issuer": "0xefgh1234567890123456789012345678901234567890" - } - ] - } - ] - }))) -} - -pub async fn get_profile_dev(Path(address): Path) -> Result, StatusCode> { - Ok(Json(json!({ - "address": address, - "name": "Alice Developer", - "description": "Full-stack developer passionate about Web3 and Rust", - "avatar_url": "https://example.com/avatar.jpg", - "badges": [] - }))) -} - -pub async fn create_profile_dev(Json(payload): Json) -> Result, StatusCode> { - let address = payload.get("address") - .and_then(|v| v.as_str()) - .ok_or(StatusCode::BAD_REQUEST)?; - - Ok(Json(json!({ - "success": true, - "address": address - }))) -} - -pub async fn update_profile_dev( - Path(address): Path, - Json(_payload): Json, -) -> Result, StatusCode> { - Ok(Json(json!({ - "success": true, - "address": address - }))) -} - -pub async fn get_badges_dev() -> Result, StatusCode> { - Ok(Json(json!({ - "badges": [ - { - "id": "1", - "name": "Rust", - "description": "Rust programming language", - "issuer_address": "0xabcd1234567890123456789012345678901234567890" - }, - { - "id": "2", - "name": "React", - "description": "React development", - "issuer_address": "0xefgh1234567890123456789012345678901234567890" - } - ] - }))) -} - -pub async fn get_badge_dev(Path(id): Path) -> Result, StatusCode> { - Ok(Json(json!({ - "id": id, - "name": "Rust", - "description": "Rust programming language", - "issuer_address": "0xabcd1234567890123456789012345678901234567890" - }))) -} - -pub async fn create_badge_dev(Json(payload): Json) -> Result, StatusCode> { - let name = payload.get("name") - .and_then(|v| v.as_str()) - .ok_or(StatusCode::BAD_REQUEST)?; - - Ok(Json(json!({ - "success": true, - "name": name - }))) -} - -pub async fn give_badge_dev( - Path(id): Path, - Json(payload): Json, -) -> Result, StatusCode> { - let profile_address = payload.get("profile_address") - .and_then(|v| v.as_str()) - .ok_or(StatusCode::BAD_REQUEST)?; - - Ok(Json(json!({ - "success": true, - "badge_id": id, - "profile_address": profile_address - }))) -} - - - diff --git a/backend/src/handlers/mod.rs b/backend/src/handlers/mod.rs deleted file mode 100644 index fc8c82e..0000000 --- a/backend/src/handlers/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod auth; -pub mod profiles; -pub mod badges; -pub mod dev; diff --git a/backend/src/handlers/profiles.rs b/backend/src/handlers/profiles.rs deleted file mode 100644 index a4617ff..0000000 --- a/backend/src/handlers/profiles.rs +++ /dev/null @@ -1,54 +0,0 @@ -use axum::{ - extract::{Path, State}, - http::StatusCode, - response::Json, -}; -use serde_json::{json, Value}; - -pub async fn get_profiles(State(_pool): State) -> Result, StatusCode> { - // TODO: Implement database query - Ok(Json(json!({ - "profiles": [] - }))) -} - -pub async fn get_profile( - State(_pool): State, - Path(address): Path, -) -> Result, StatusCode> { - // TODO: Implement database query - Ok(Json(json!({ - "address": address, - "name": null, - "description": null, - "avatar_url": null, - "badges": [] - }))) -} - -pub async fn create_profile( - State(_pool): State, - Json(payload): Json, -) -> Result, StatusCode> { - let address = payload.get("address") - .and_then(|v| v.as_str()) - .ok_or(StatusCode::BAD_REQUEST)?; - - // TODO: Implement database insert - Ok(Json(json!({ - "success": true, - "address": address - }))) -} - -pub async fn update_profile( - State(_pool): State, - Path(address): Path, - Json(_payload): Json, -) -> Result, StatusCode> { - // TODO: Implement database update - Ok(Json(json!({ - "success": true, - "address": address - }))) -} diff --git a/backend/src/infrastructure/mod.rs b/backend/src/infrastructure/mod.rs index dbf745a..4fc67ea 100644 --- a/backend/src/infrastructure/mod.rs +++ b/backend/src/infrastructure/mod.rs @@ -1,2 +1,2 @@ pub mod repositories; - +pub mod services; diff --git a/backend/src/infrastructure/repositories/mod.rs b/backend/src/infrastructure/repositories/mod.rs index f1cca11..1955904 100644 --- a/backend/src/infrastructure/repositories/mod.rs +++ b/backend/src/infrastructure/repositories/mod.rs @@ -1,8 +1,3 @@ -pub mod postgres_user_repository; pub mod postgres_profile_repository; -pub mod postgres_badge_repository; -pub use postgres_user_repository::PostgresUserRepository; pub use postgres_profile_repository::PostgresProfileRepository; -pub use postgres_badge_repository::PostgresBadgeRepository; - diff --git a/backend/src/infrastructure/repositories/postgres_badge_repository.rs b/backend/src/infrastructure/repositories/postgres_badge_repository.rs deleted file mode 100644 index 389345e..0000000 --- a/backend/src/infrastructure/repositories/postgres_badge_repository.rs +++ /dev/null @@ -1,204 +0,0 @@ -use async_trait::async_trait; -use sqlx::PgPool; -use uuid::Uuid; - -use crate::domain::entities::badge::{Badge, UserBadge}; -use crate::domain::repositories::badge_repository::BadgeRepository; - -#[derive(Clone)] -pub struct PostgresBadgeRepository { - pool: PgPool, -} - -impl PostgresBadgeRepository { - pub fn new(pool: PgPool) -> Self { - Self { pool } - } -} - -#[async_trait] -impl BadgeRepository for PostgresBadgeRepository { - async fn create(&self, badge: &Badge) -> Result<(), Box> { - sqlx::query!( - r#" - INSERT INTO badges (id, name, description, issuer_address, image_url, created_at, updated_at) - VALUES ($1, $2, $3, $4, $5, $6, $7) - "#, - badge.id, - badge.name, - badge.description, - badge.issuer_address, - badge.image_url, - badge.created_at, - badge.updated_at - ) - .execute(&self.pool) - .await - .map_err(|e| Box::new(e) as Box)?; - - Ok(()) - } - - async fn find_by_id(&self, id: &Uuid) -> Result, Box> { - let row = sqlx::query!( - r#" - SELECT id, name, description, issuer_address, image_url, created_at, updated_at - FROM badges - WHERE id = $1 - "#, - id - ) - .fetch_optional(&self.pool) - .await - .map_err(|e| Box::new(e) as Box)?; - - Ok(row.map(|r| Badge { - id: r.id, - name: r.name, - description: r.description, - issuer_address: r.issuer_address, - image_url: r.image_url, - created_at: r.created_at, - updated_at: r.updated_at, - })) - } - - async fn find_all(&self) -> Result, Box> { - let rows = sqlx::query!( - r#" - SELECT id, name, description, issuer_address, image_url, created_at, updated_at - FROM badges - ORDER BY created_at DESC - "# - ) - .fetch_all(&self.pool) - .await - .map_err(|e| Box::new(e) as Box)?; - - let badges = rows - .into_iter() - .map(|r| Badge { - id: r.id, - name: r.name, - description: r.description, - issuer_address: r.issuer_address, - image_url: r.image_url, - created_at: r.created_at, - updated_at: r.updated_at, - }) - .collect(); - - Ok(badges) - } - - async fn update(&self, badge: &Badge) -> Result<(), Box> { - sqlx::query!( - r#" - UPDATE badges - SET name = $2, description = $3, issuer_address = $4, image_url = $5, updated_at = $6 - WHERE id = $1 - "#, - badge.id, - badge.name, - badge.description, - badge.issuer_address, - badge.image_url, - badge.updated_at - ) - .execute(&self.pool) - .await - .map_err(|e| Box::new(e) as Box)?; - - Ok(()) - } - - async fn delete(&self, id: &Uuid) -> Result<(), Box> { - sqlx::query!( - r#" - DELETE FROM badges - WHERE id = $1 - "#, - id - ) - .execute(&self.pool) - .await - .map_err(|e| Box::new(e) as Box)?; - - Ok(()) - } - - async fn find_badge_users(&self, badge_id: &Uuid) -> Result, Box> { - let rows = sqlx::query!( - r#" - SELECT ub.id, ub.user_id, ub.badge_id, ub.awarded_at, ub.awarded_by - FROM user_badges ub - WHERE ub.badge_id = $1 - ORDER BY ub.awarded_at DESC - "#, - badge_id - ) - .fetch_all(&self.pool) - .await - .map_err(|e| Box::new(e) as Box)?; - - let user_badges = rows - .into_iter() - .map(|r| crate::domain::repositories::badge_repository::UserBadge { - id: r.id, - user_id: r.user_id, - badge_id: r.badge_id, - awarded_at: r.awarded_at, - awarded_by: r.awarded_by, - }) - .collect(); - - Ok(user_badges) - } - - async fn award_badge(&self, user_badge: &crate::domain::repositories::badge_repository::UserBadge) -> Result<(), Box> { - sqlx::query!( - r#" - INSERT INTO user_badges (id, user_id, badge_id, awarded_at, awarded_by) - VALUES ($1, $2, $3, $4, $5) - "#, - user_badge.id, - user_badge.user_id, - user_badge.badge_id, - user_badge.awarded_at, - user_badge.awarded_by - ) - .execute(&self.pool) - .await - .map_err(|e| Box::new(e) as Box)?; - - Ok(()) - } - - async fn find_user_badges(&self, user_id: &Uuid) -> Result, Box> { - let rows = sqlx::query!( - r#" - SELECT ub.id, ub.user_id, ub.badge_id, ub.awarded_at, ub.awarded_by - FROM user_badges ub - WHERE ub.user_id = $1 - ORDER BY ub.awarded_at DESC - "#, - user_id - ) - .fetch_all(&self.pool) - .await - .map_err(|e| Box::new(e) as Box)?; - - let user_badges = rows - .into_iter() - .map(|r| crate::domain::repositories::badge_repository::UserBadge { - id: r.id, - user_id: r.user_id, - badge_id: r.badge_id, - awarded_at: r.awarded_at, - awarded_by: r.awarded_by, - }) - .collect(); - - Ok(user_badges) - } -} diff --git a/backend/src/infrastructure/repositories/postgres_profile_repository.rs b/backend/src/infrastructure/repositories/postgres_profile_repository.rs index 54e3941..9b4a8a9 100644 --- a/backend/src/infrastructure/repositories/postgres_profile_repository.rs +++ b/backend/src/infrastructure/repositories/postgres_profile_repository.rs @@ -35,10 +35,10 @@ impl ProfileRepository for PostgresProfileRepository { .execute(&self.pool) .await .map_err(|e| Box::new(e) as Box)?; - + Ok(()) } - + async fn find_by_id(&self, id: &Uuid) -> Result, Box> { let row = sqlx::query!( r#" @@ -51,7 +51,7 @@ impl ProfileRepository for PostgresProfileRepository { .fetch_optional(&self.pool) .await .map_err(|e| Box::new(e) as Box)?; - + Ok(row.map(|r| Profile { id: r.id, user_id: r.user_id, @@ -62,8 +62,11 @@ impl ProfileRepository for PostgresProfileRepository { updated_at: r.updated_at, })) } - - async fn find_by_user_id(&self, user_id: &Uuid) -> Result, Box> { + + async fn find_by_user_id( + &self, + user_id: &Uuid, + ) -> Result, Box> { let row = sqlx::query!( r#" SELECT id, user_id, name, description, avatar_url, created_at, updated_at @@ -75,7 +78,7 @@ impl ProfileRepository for PostgresProfileRepository { .fetch_optional(&self.pool) .await .map_err(|e| Box::new(e) as Box)?; - + Ok(row.map(|r| Profile { id: r.id, user_id: r.user_id, @@ -86,7 +89,7 @@ impl ProfileRepository for PostgresProfileRepository { updated_at: r.updated_at, })) } - + async fn find_all(&self) -> Result, Box> { let rows = sqlx::query!( r#" @@ -98,7 +101,7 @@ impl ProfileRepository for PostgresProfileRepository { .fetch_all(&self.pool) .await .map_err(|e| Box::new(e) as Box)?; - + let profiles = rows .into_iter() .map(|r| Profile { @@ -111,10 +114,10 @@ impl ProfileRepository for PostgresProfileRepository { updated_at: r.updated_at, }) .collect(); - + Ok(profiles) } - + async fn update(&self, profile: &Profile) -> Result<(), Box> { sqlx::query!( r#" @@ -131,10 +134,10 @@ impl ProfileRepository for PostgresProfileRepository { .execute(&self.pool) .await .map_err(|e| Box::new(e) as Box)?; - + Ok(()) } - + async fn delete(&self, id: &Uuid) -> Result<(), Box> { sqlx::query!( r#" @@ -146,7 +149,7 @@ impl ProfileRepository for PostgresProfileRepository { .execute(&self.pool) .await .map_err(|e| Box::new(e) as Box)?; - + Ok(()) } } diff --git a/backend/src/infrastructure/repositories/postgres_user_repository.rs b/backend/src/infrastructure/repositories/postgres_user_repository.rs deleted file mode 100644 index 4c6a71d..0000000 --- a/backend/src/infrastructure/repositories/postgres_user_repository.rs +++ /dev/null @@ -1,114 +0,0 @@ -use async_trait::async_trait; -use sqlx::PgPool; -use uuid::Uuid; - -use crate::domain::entities::user::User; -use crate::domain::repositories::user_repository::UserRepository; -use crate::domain::value_objects::wallet_address::WalletAddress; - -#[derive(Clone)] -pub struct PostgresUserRepository { - pool: PgPool, -} - -impl PostgresUserRepository { - pub fn new(pool: PgPool) -> Self { - Self { pool } - } -} - -#[async_trait] -impl UserRepository for PostgresUserRepository { - async fn create(&self, user: &User) -> Result<(), Box> { - sqlx::query( - r#" - INSERT INTO users (id, wallet_address, created_at, updated_at) - VALUES ($1, $2, $3, $4) - "# - ) - .bind(&user.id) - .bind(&user.wallet_address) - .bind(&user.created_at) - .bind(&user.updated_at) - .execute(&self.pool) - .await - .map_err(|e| Box::new(e) as Box)?; - - Ok(()) - } - - async fn find_by_id(&self, id: &Uuid) -> Result, Box> { - let row = sqlx::query!( - r#" - SELECT id, wallet_address, created_at, updated_at - FROM users - WHERE id = $1 - "#, - id - ) - .fetch_optional(&self.pool) - .await - .map_err(|e| Box::new(e) as Box)?; - - Ok(row.map(|r| User { - id: r.id, - wallet_address: r.wallet_address, - created_at: r.created_at, - updated_at: r.updated_at, - })) - } - - async fn find_by_wallet_address(&self, address: &str) -> Result, Box> { - let row = sqlx::query!( - r#" - SELECT id, wallet_address, created_at, updated_at - FROM users - WHERE wallet_address = $1 - "#, - address - ) - .fetch_optional(&self.pool) - .await - .map_err(|e| Box::new(e) as Box)?; - - Ok(row.map(|r| User { - id: r.id, - wallet_address: r.wallet_address, - created_at: r.created_at, - updated_at: r.updated_at, - })) - } - - async fn update(&self, user: &User) -> Result<(), Box> { - sqlx::query!( - r#" - UPDATE users - SET wallet_address = $2, updated_at = $3 - WHERE id = $1 - "#, - user.id, - user.wallet_address, - user.updated_at - ) - .execute(&self.pool) - .await - .map_err(|e| Box::new(e) as Box)?; - - Ok(()) - } - - async fn delete(&self, id: &Uuid) -> Result<(), Box> { - sqlx::query!( - r#" - DELETE FROM users - WHERE id = $1 - "#, - id - ) - .execute(&self.pool) - .await - .map_err(|e| Box::new(e) as Box)?; - - Ok(()) - } -} diff --git a/backend/src/infrastructure/services/ethereum_address_verification_service.rs b/backend/src/infrastructure/services/ethereum_address_verification_service.rs new file mode 100644 index 0000000..0270049 --- /dev/null +++ b/backend/src/infrastructure/services/ethereum_address_verification_service.rs @@ -0,0 +1,20 @@ +use async_trait::async_trait; + +use crate::domain::services::AuthService::{self, AuthChallenge, AuthResult}; + +pub struct EthereumAddressVerificationService {} + +impl EthereumAddressVerificationService { + pub fn new() -> Self { + Self {} + } +} + +#[async_trait] +impl AuthService for EthereumAddressVerificationService { + async fn verify_signature( + &self, + challenge: &AuthChallenge, + signature: &str, + ) -> Result>; +} diff --git a/backend/src/infrastructure/services/mod.rs b/backend/src/infrastructure/services/mod.rs new file mode 100644 index 0000000..f0cf358 --- /dev/null +++ b/backend/src/infrastructure/services/mod.rs @@ -0,0 +1 @@ +pub mod ethereum_address_verification_service; diff --git a/backend/src/lib.rs b/backend/src/lib.rs index 695bc84..5c73ee9 100644 --- a/backend/src/lib.rs +++ b/backend/src/lib.rs @@ -1,6 +1,6 @@ -pub mod domain; pub mod application; -// pub mod infrastructure; // Temporarily disabled to avoid SQLx compilation issues +pub mod domain; +pub mod infrastructure; use axum::{ extract::DefaultBodyLimit, @@ -8,44 +8,28 @@ use axum::{ routing::{get, post, put}, Router, }; +use domain::repositories::profile_repository; +use infrastructure::{ + repositories::PostgresProfileRepository, + services::ethereum_address_verification_service::EthereumAddressVerificationService, +}; use tower::ServiceBuilder; use tower_http::{ cors::{Any, CorsLayer}, trace::TraceLayer, }; -// Database repositories are temporarily disabled -// use crate::infrastructure::repositories::{ -// PostgresUserRepository, PostgresProfileRepository, PostgresBadgeRepository, -// }; -use crate::application::services::{ - AuthApplicationService, ProfileApplicationService, BadgeApplicationService, -}; +use crate::application::services::ProfileApplicationService; pub async fn create_app(_pool: sqlx::PgPool) -> Router { - // For now, create mock repositories that don't use the database - // TODO: Replace with real database implementations - let user_repository = Box::new(MockUserRepository); - let profile_repository = Box::new(MockProfileRepository); - let badge_repository = Box::new(MockBadgeRepository); - // Create application services - let auth_service = AuthApplicationService::new(user_repository.clone()); - let profile_service = ProfileApplicationService::new(user_repository.clone(), profile_repository); - let badge_service = BadgeApplicationService::new(user_repository, badge_repository); - + let auth_service = EthereumAddressVerificationService::new(); + let profile_repository = PostgresProfileRepository::new(); + Router::new() - .route("/health", get(health_check)) - .route("/siwe/nonce", get(handle_get_nonce)) - .route("/siwe/verify", post(handle_verify_message)) - .route("/profiles", get(handle_get_profiles)) - .route("/profiles", post(handle_create_profile)) + .route("/profiles/:address", post(handle_create_profile)) .route("/profiles/:address", get(handle_get_profile)) .route("/profiles/:address", put(handle_update_profile)) - .route("/badges", get(handle_get_badges)) - .route("/badges", post(handle_create_badge)) - .route("/badges/:id", get(handle_get_badge)) - .route("/badges/:id/give", post(handle_give_badge)) .layer( ServiceBuilder::new() .layer(TraceLayer::new_for_http()) @@ -57,11 +41,6 @@ pub async fn create_app(_pool: sqlx::PgPool) -> Router { ) .layer(DefaultBodyLimit::max(1024 * 1024)), // 1MB limit ) - .with_state(AppState { - auth_service, - profile_service, - badge_service, - }) } #[derive(Clone)] @@ -70,148 +49,3 @@ pub struct AppState { pub profile_service: ProfileApplicationService, pub badge_service: BadgeApplicationService, } - -async fn health_check() -> &'static str { - "OK" -} - -// Mock repository implementations for development -// use std::collections::HashMap; -use uuid::Uuid; -use crate::domain::entities::{user::User, profile::Profile, badge::Badge}; -use crate::domain::repositories::{user_repository::UserRepository, profile_repository::ProfileRepository, badge_repository::BadgeRepository}; - -#[derive(Clone)] -struct MockUserRepository; - -#[async_trait::async_trait] -impl UserRepository for MockUserRepository { - async fn create(&self, _user: &User) -> Result<(), Box> { - Ok(()) - } - - async fn find_by_id(&self, _id: &Uuid) -> Result, Box> { - Ok(None) - } - - async fn find_by_wallet_address(&self, _address: &str) -> Result, Box> { - Ok(None) - } - - async fn update(&self, _user: &User) -> Result<(), Box> { - Ok(()) - } - - async fn delete(&self, _id: &Uuid) -> Result<(), Box> { - Ok(()) - } -} - -#[derive(Clone)] -struct MockProfileRepository; - -#[async_trait::async_trait] -impl ProfileRepository for MockProfileRepository { - async fn create(&self, _profile: &Profile) -> Result<(), Box> { - Ok(()) - } - - async fn find_by_id(&self, _id: &Uuid) -> Result, Box> { - Ok(None) - } - - async fn find_by_user_id(&self, _user_id: &Uuid) -> Result, Box> { - Ok(None) - } - - async fn find_all(&self) -> Result, Box> { - Ok(vec![]) - } - - async fn update(&self, _profile: &Profile) -> Result<(), Box> { - Ok(()) - } - - async fn delete(&self, _id: &Uuid) -> Result<(), Box> { - Ok(()) - } -} - -#[derive(Clone)] -struct MockBadgeRepository; - -#[async_trait::async_trait] -impl BadgeRepository for MockBadgeRepository { - async fn create(&self, _badge: &Badge) -> Result<(), Box> { - Ok(()) - } - - async fn find_by_id(&self, _id: &Uuid) -> Result, Box> { - Ok(None) - } - - async fn find_all(&self) -> Result, Box> { - Ok(vec![]) - } - - async fn update(&self, _badge: &Badge) -> Result<(), Box> { - Ok(()) - } - - async fn delete(&self, _id: &Uuid) -> Result<(), Box> { - Ok(()) - } - - async fn award_badge(&self, _user_badge: &crate::domain::repositories::badge_repository::UserBadge) -> Result<(), Box> { - Ok(()) - } - - async fn find_user_badges(&self, _user_id: &Uuid) -> Result, Box> { - Ok(vec![]) - } - - async fn find_badge_users(&self, _badge_id: &Uuid) -> Result, Box> { - Ok(vec![]) - } -} - -// Handler functions will be implemented in separate files -async fn handle_get_nonce() -> &'static str { - "Not implemented yet" -} - -async fn handle_verify_message() -> &'static str { - "Not implemented yet" -} - -async fn handle_get_profiles() -> &'static str { - "Not implemented yet" -} - -async fn handle_create_profile() -> &'static str { - "Not implemented yet" -} - -async fn handle_get_profile() -> &'static str { - "Not implemented yet" -} - -async fn handle_update_profile() -> &'static str { - "Not implemented yet" -} - -async fn handle_get_badges() -> &'static str { - "Not implemented yet" -} - -async fn handle_create_badge() -> &'static str { - "Not implemented yet" -} - -async fn handle_get_badge() -> &'static str { - "Not implemented yet" -} - -async fn handle_give_badge() -> &'static str { - "Not implemented yet" -} \ No newline at end of file diff --git a/backend/src/main.rs b/backend/src/main.rs index d805127..d50dfad 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -1,7 +1,7 @@ +use axum::{response::Json, routing::get, Router}; +use serde_json::{json, Value}; use std::net::SocketAddr; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; -use axum::{routing::get, Router, response::Json}; -use serde_json::{json, Value}; #[tokio::main] async fn main() -> anyhow::Result<()> { @@ -19,11 +19,13 @@ async fn main() -> anyhow::Result<()> { // For development, create a mock pool // TODO: Set up real database connection - let pool = sqlx::PgPool::connect("postgresql://localhost/guild_dev").await.unwrap_or_else(|_| { - tracing::warn!("Could not connect to database, using mock pool"); - // Return a mock pool for now - panic!("Database connection required"); - }); + let pool = sqlx::PgPool::connect("postgresql://localhost/guild_dev") + .await + .unwrap_or_else(|_| { + tracing::warn!("Could not connect to database, using mock pool"); + // Return a mock pool for now + panic!("Database connection required"); + }); // Run migrations sqlx::migrate!("./migrations").run(&pool).await?; @@ -34,7 +36,7 @@ async fn main() -> anyhow::Result<()> { // Run the server let addr = SocketAddr::from(([0, 0, 0, 0], 3001)); tracing::info!("Server listening on {}", addr); - + let listener = tokio::net::TcpListener::bind(&addr).await?; axum::serve(listener, app).await?; @@ -55,4 +57,4 @@ async fn api_status() -> Json { "version": "0.1.0", "message": "API is operational" })) -} \ No newline at end of file +} diff --git a/backend/src/main_dev.rs b/backend/src/main_dev.rs deleted file mode 100644 index 236c6cc..0000000 --- a/backend/src/main_dev.rs +++ /dev/null @@ -1,77 +0,0 @@ -use axum::{ - extract::DefaultBodyLimit, - http::Method, - routing::{get, post, put}, - Router, -}; -use std::net::SocketAddr; -use tower::ServiceBuilder; -use tower_http::{ - cors::{Any, CorsLayer}, - trace::TraceLayer, -}; -use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; - -mod database; -mod handlers; -mod middleware; -mod models; - -use handlers::{auth, dev}; - -#[tokio::main] -async fn main() -> anyhow::Result<()> { - // Initialize tracing - tracing_subscriber::registry() - .with( - tracing_subscriber::EnvFilter::try_from_default_env() - .unwrap_or_else(|_| "guild_backend=debug,tower_http=debug".into()), - ) - .with(tracing_subscriber::fmt::layer()) - .init(); - - // Load environment variables - dotenvy::dotenv().ok(); - - // Create the app without database for development - let app = create_dev_app().await; - - // Run the server - let addr = SocketAddr::from(([0, 0, 0, 0], 3001)); - tracing::info!("Server listening on {}", addr); - - let listener = tokio::net::TcpListener::bind(&addr).await?; - axum::serve(listener, app).await?; - - Ok(()) -} - -pub async fn create_dev_app() -> Router { - Router::new() - .route("/health", get(health_check)) - .route("/siwe/nonce", get(auth::get_nonce)) - .route("/siwe/verify", post(dev::verify_message_dev)) - .route("/profiles", get(dev::get_profiles_dev)) - .route("/profiles", post(dev::create_profile_dev)) - .route("/profiles/:address", get(dev::get_profile_dev)) - .route("/profiles/:address", put(dev::update_profile_dev)) - .route("/badges", get(dev::get_badges_dev)) - .route("/badges", post(dev::create_badge_dev)) - .route("/badges/:id", get(dev::get_badge_dev)) - .route("/badges/:id/give", post(dev::give_badge_dev)) - .layer( - ServiceBuilder::new() - .layer(TraceLayer::new_for_http()) - .layer( - CorsLayer::new() - .allow_origin(Any) - .allow_methods([Method::GET, Method::POST, Method::PUT, Method::DELETE]) - .allow_headers(Any), - ) - .layer(DefaultBodyLimit::max(1024 * 1024)), // 1MB limit - ) -} - -async fn health_check() -> &'static str { - "OK" -} diff --git a/backend/src/middleware/mod.rs b/backend/src/middleware/mod.rs deleted file mode 100644 index f07e0a3..0000000 --- a/backend/src/middleware/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -// Middleware definitions will go here - diff --git a/backend/src/models/mod.rs b/backend/src/models/mod.rs deleted file mode 100644 index abb0667..0000000 --- a/backend/src/models/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -// Model definitions will go here - diff --git a/backend/tests/simple_tests.rs b/backend/tests/simple_tests.rs index 34a5ec4..163a318 100644 --- a/backend/tests/simple_tests.rs +++ b/backend/tests/simple_tests.rs @@ -8,38 +8,28 @@ use tower::ServiceExt; // Simple test without database #[tokio::test] async fn test_health_check() { - use axum::Router; use axum::routing::get; - + use axum::Router; + let app = Router::new().route("/health", get(|| async { "OK" })); - + let request = Request::builder() .uri("/health") .body(Body::empty()) .unwrap(); - + let response = app.oneshot(request).await.unwrap(); assert_eq!(response.status(), StatusCode::OK); } #[tokio::test] async fn test_json_response() { - use axum::{ - response::Json, - routing::get, - Router, - }; - - let app = Router::new().route("/test", get(|| async { - Json(json!({"message": "test"})) - })); - - let request = Request::builder() - .uri("/test") - .body(Body::empty()) - .unwrap(); - + use axum::{response::Json, routing::get, Router}; + + let app = Router::new().route("/test", get(|| async { Json(json!({"message": "test"})) })); + + let request = Request::builder().uri("/test").body(Body::empty()).unwrap(); + let response = app.oneshot(request).await.unwrap(); assert_eq!(response.status(), StatusCode::OK); } - diff --git a/dev.sh b/dev.sh deleted file mode 100755 index f2fd5f2..0000000 --- a/dev.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -# The Guild Genesis - Development Environment -# This script sets up the development environment using system tools - -echo "🔧 The Guild Genesis Development Environment" -echo "📦 Using system tools instead of Nix" - -# Check if required tools are installed -check_tool() { - if ! command -v "$1" &> /dev/null; then - echo "❌ $1 is not installed. Please install it with: brew install $1" - exit 1 - fi -} - -echo "🔍 Checking required tools..." -check_tool "node" -check_tool "npm" -check_tool "cargo" -check_tool "just" - -# Set environment variables -export DATABASE_URL="postgres://guild_user:guild_password@localhost:5432/guild_genesis" -export RUST_LOG="debug" - -echo "✅ All tools are available!" -echo "" -echo "📦 Available commands:" -echo " just dev - Start both frontend and backend" -echo " just dev-frontend - Start frontend only" -echo " just dev-backend - Start backend only" -echo " just db-start - Start PostgreSQL database" -echo " just db-stop - Stop PostgreSQL database" -echo " just db-setup - Set up database with migrations" -echo " just db-reset - Reset database completely" -echo " just install-all - Install all dependencies" -echo "" -echo "🚀 Run 'just ' to execute scripts" -echo "" -echo "💡 This uses system tools (Node.js, Rust, PostgreSQL) instead of Nix" -echo "💡 Install them with: brew install node rust postgresql just" - -# Start a new shell with the environment -exec "$SHELL" -i - diff --git a/flake.lock b/flake.lock deleted file mode 100644 index dc1805d..0000000 --- a/flake.lock +++ /dev/null @@ -1,61 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1688392541, - "narHash": "sha256-lHrKvEkCPTUO+7tPfjIcb7Trk6k31rz18vkyqmkeJfY=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "ea4c80b39be4c09702b0cb3b42eab59e2ba4f24b", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-22.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index 3b98b3d..0000000 --- a/flake.nix +++ /dev/null @@ -1,53 +0,0 @@ -{ - description = "The Guild Genesis - A peer-run organization for software developers"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11"; - flake-utils.url = "github:numtide/flake-utils"; - }; - - outputs = { self, nixpkgs, flake-utils }: - flake-utils.lib.eachDefaultSystem (system: - let - pkgs = nixpkgs.legacyPackages.${system}; - in - { - devShells.default = pkgs.mkShell { - buildInputs = with pkgs; [ - # Use pre-built binaries only - avoid LLVM trap - nodejs - nodePackages.npm - nodePackages.pnpm - rustc - cargo - postgresql_14 - git - curl - jq - just - ]; - - shellHook = '' - echo "🔧 The Guild Genesis Development Environment" - echo "📦 Available commands:" - echo " dev - Start both frontend and backend" - echo " dev-frontend - Start frontend only" - echo " dev-backend - Start backend only" - echo " db-start - Start PostgreSQL database" - echo " db-stop - Stop PostgreSQL database" - echo " db-setup - Set up database with migrations" - echo " db-reset - Reset database completely" - echo " install-all - Install all dependencies" - echo "" - echo "🚀 Run 'just ' to execute scripts" - echo "" - echo "💡 Database uses system PostgreSQL to avoid LLVM builds" - ''; - - # Set environment variables - DATABASE_URL = "postgres://guild_user:guild_password@localhost:5432/guild_genesis"; - RUST_LOG = "debug"; - }; - }); -} -