summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrtkay123 <dev@kanjala.com>2025-07-26 10:20:06 +0200
committerrtkay123 <dev@kanjala.com>2025-07-26 10:20:06 +0200
commit9b9d94205d3e55a5e8a765674ef464e80f3e40fb (patch)
treec63a236d82694dbf7a621fafeb13c2da988bccd2
parent8398104fd50b236619a0c20b7c9b7991ea855917 (diff)
downloadsellershut-9b9d94205d3e55a5e8a765674ef464e80f3e40fb.tar.bz2
sellershut-9b9d94205d3e55a5e8a765674ef464e80f3e40fb.zip
feat(profile): create service
-rw-r--r--crates/profile-service/Cargo.toml38
-rw-r--r--crates/profile-service/src/main.rs3
-rw-r--r--lib/sellershut-core/Cargo.toml1
-rw-r--r--lib/sellershut-core/build.rs17
-rw-r--r--lib/sellershut-core/proto/profile/profile.proto59
-rw-r--r--lib/sellershut-core/src/lib.rs4
-rw-r--r--lib/sellershut-core/src/profile.rs3
7 files changed, 121 insertions, 4 deletions
diff --git a/crates/profile-service/Cargo.toml b/crates/profile-service/Cargo.toml
new file mode 100644
index 0000000..409110b
--- /dev/null
+++ b/crates/profile-service/Cargo.toml
@@ -0,0 +1,38 @@
+[package]
+name = "profile-service"
+version = "0.1.0"
+edition = "2024"
+license.workspace = true
+homepage.workspace = true
+documentation.workspace = true
+description.workspace = true
+
+[dependencies]
+anyhow.workspace = true
+axum = { workspace = true, features = ["macros"] }
+axum-extra = { version = "0.10.1", features = ["typed-header"] }
+base64.workspace = true
+clap = { workspace = true, features = ["derive"] }
+config = { workspace = true, features = ["convert-case", "toml"] }
+futures-util.workspace = true
+jsonwebtoken = "9.3.1"
+nanoid.workspace = true
+oauth2 = "5.0.0"
+reqwest = { workspace = true, features = ["json", "rustls-tls"] }
+sellershut-core = { workspace = true, features = ["profile", "serde"] }
+serde = { workspace = true, features = ["derive"] }
+serde_json.workspace = true
+sqlx = { workspace = true, features = ["macros", "migrate", "runtime-tokio", "time", "tls-rustls", "uuid"] }
+time = { workspace = true, features = ["parsing", "serde"] }
+tokio = { workspace = true, features = ["macros", "rt-multi-thread", "signal"] }
+tonic.workspace = true
+tonic-reflection = "0.13.0"
+tower = { workspace = true, features = ["steer", "util"] }
+tower-http = { workspace = true, features = ["map-request-body", "trace", "util"] }
+tower-sessions = "0.14.0"
+tower-sessions-core = { version = "0.14.0", features = ["deletion-task"] }
+tower-sessions-moka-store = "0.15.0"
+tower-sessions-sqlx-store = { version = "0.15.0", features = ["postgres"] }
+tracing.workspace = true
+url.workspace = true
+uuid = { workspace = true, features = ["serde", "v7"] }
diff --git a/crates/profile-service/src/main.rs b/crates/profile-service/src/main.rs
new file mode 100644
index 0000000..e7a11a9
--- /dev/null
+++ b/crates/profile-service/src/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!("Hello, world!");
+}
diff --git a/lib/sellershut-core/Cargo.toml b/lib/sellershut-core/Cargo.toml
index b5e1bb9..1b7d5f7 100644
--- a/lib/sellershut-core/Cargo.toml
+++ b/lib/sellershut-core/Cargo.toml
@@ -18,6 +18,7 @@ tonic-types = "0.13.0"
[features]
default = []
auth = []
+profile = []
serde = ["dep:serde", "serde/derive", "serde_json"]
time = [
"dep:time",
diff --git a/lib/sellershut-core/build.rs b/lib/sellershut-core/build.rs
index 8ff48f1..110bc22 100644
--- a/lib/sellershut-core/build.rs
+++ b/lib/sellershut-core/build.rs
@@ -1,10 +1,12 @@
-#[cfg(feature = "auth")]
+#[cfg(any(feature = "auth", feature = "profile"))]
enum Entity {
#[cfg(feature = "auth")]
Auth,
+ #[cfg(feature = "profile")]
+ Profile,
}
-#[cfg(feature = "auth")]
+#[cfg(any(feature = "auth", feature = "profile"))]
impl Entity {
fn protos(&self) -> Vec<&'static str> {
let mut res: Vec<&'static str> = vec![];
@@ -13,6 +15,10 @@ impl Entity {
#[cfg(feature = "auth")]
Entity::Auth => {
res.extend(vec!["proto/auth/auth.proto"]);
+ },
+ #[cfg(feature = "profile")]
+ Entity::Profile => {
+ res.extend(vec!["proto/profile/profile.proto"]);
}
}
res
@@ -25,10 +31,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
#[cfg(feature = "auth")]
build_proto("auth", Entity::Auth);
+ #[cfg(feature = "profile")]
+ build_proto("profile", Entity::Profile);
+
Ok(())
}
-#[cfg(feature = "auth")]
+#[cfg(any(feature = "auth", feature = "profile"))]
fn build_proto(package: &str, entity: Entity) {
let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap());
@@ -72,7 +81,7 @@ fn build_proto(package: &str, entity: Entity) {
.compile_protos(&entity.protos(), include_paths).unwrap();
}
-#[cfg(all(feature = "serde", feature = "auth",))]
+#[cfg(all(feature = "serde", any(feature = "auth",feature = "profile")))]
fn add_serde(config: tonic_build::Builder) -> tonic_build::Builder {
config.type_attribute(
".",
diff --git a/lib/sellershut-core/proto/profile/profile.proto b/lib/sellershut-core/proto/profile/profile.proto
new file mode 100644
index 0000000..742dc7b
--- /dev/null
+++ b/lib/sellershut-core/proto/profile/profile.proto
@@ -0,0 +1,59 @@
+syntax = "proto3";
+
+package profile;
+
+import "google/protobuf/timestamp.proto";
+
+// A message representing a user profile
+message User {
+ // Unique identifier for the user
+ string id = 1;
+ // Email address of the user
+ string email = 2;
+ // Unique username chosen by the user
+ string username = 3;
+ // URL to the user's avatar image
+ optional string avatar = 4;
+ // Timestamp when the user was created
+ google.protobuf.Timestamp created_at = 5;
+ // Timestamp when the user was last updated
+ google.protobuf.Timestamp updated_at = 6;
+ // User-provided description or bio
+ optional string description = 7;
+}
+
+// Request message for creating a new user profile
+message CreateUserRequest {
+ // Email address of the new user
+ string email = 1;
+ // Avatar for the new user
+ optional string avatar = 2;
+}
+
+// Response message for CreateUser RPC
+message CreateUserResponse {
+ // Temporary assigned id
+ string temp_id = 1;
+ // Timestamp when the user was created
+ google.protobuf.Timestamp created_at = 2;
+}
+
+// Message to finalise profile creation
+message CompleteUserRequest {
+ // ID of the user to finalise
+ string id = 1;
+ // Required: username to finalise the profile
+ string username = 2;
+ // Optional: user-provided description
+ optional string description = 3;
+ // Optional: update avatar
+ optional string avatar = 4;
+}
+
+// Profile gRPC service
+service Profile {
+ // Create a new user profile
+ rpc CreateUser (CreateUserRequest) returns (CreateUserResponse);
+ // Complete Profile
+ rpc CompleteProfile (CompleteUserRequest) returns (User);
+}
diff --git a/lib/sellershut-core/src/lib.rs b/lib/sellershut-core/src/lib.rs
index ee2ed9b..c300495 100644
--- a/lib/sellershut-core/src/lib.rs
+++ b/lib/sellershut-core/src/lib.rs
@@ -10,4 +10,8 @@
#[cfg(feature = "auth")]
pub mod google;
+/// Interactions with Auth server
pub mod auth;
+
+/// Interactions with Profile server
+pub mod profile;
diff --git a/lib/sellershut-core/src/profile.rs b/lib/sellershut-core/src/profile.rs
new file mode 100644
index 0000000..bf366b1
--- /dev/null
+++ b/lib/sellershut-core/src/profile.rs
@@ -0,0 +1,3 @@
+tonic::include_proto!("profile");
+/// Profile file descriptor
+pub const PROFILE_FILE_DESCRIPTOR_SET: &[u8] = tonic::include_file_descriptor_set!("profile_descriptor");