summaryrefslogtreecommitdiffstats
path: root/crates/users-service/src/server/manager.rs
blob: 6affb4add541a84301277559f3b10091d0a6a785 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use prost::Message;
use sellershut_core::users::{
    CompleteUserRequest, CreateUserRequest, CreateUserResponse, User,
    users_service_server::UsersService,
};
use stack_up::redis::AsyncCommands;
use tonic::{Request, Response, Status, async_trait};
use tracing::{error, trace};
use uuid::Uuid;

use crate::state::AppHandle;

#[async_trait]
impl UsersService for AppHandle {
    #[doc = " Create a new user profile"]
    async fn create_user(
        &self,
        request: Request<CreateUserRequest>,
    ) -> Result<Response<CreateUserResponse>, Status> {
        trace!("creating user");
        let data = request.into_inner();
        let id = Uuid::now_v7().to_string();

        let bytes = data.encode_to_vec();
        let mut cache = self.cache().await?;
        cache
            .set_ex::<_, _, ()>(&id, &bytes, self.local_config.temp_ttl)
            .await
            .inspect_err(|e| error!("{e}"))
            .map_err(|_e| Status::internal("storage not ready"))?;

        Ok(Response::new(CreateUserResponse { temp_id: id }))
    }

    #[doc = " Complete Profile"]
    async fn complete_user(
        &self,
        request: Request<CompleteUserRequest>,
    ) -> Result<Response<User>, Status> {
        let request = request.into_inner();

        let mut cache = self.cache().await?;

        let resp = cache
            .get_del::<_, Vec<u8>>(&request.id)
            .await
            .inspect_err(|e| error!("{e}"))
            .map_err(|_e| Status::internal("storage not ready"))?;

        if resp.is_empty() {
            return Err(Status::data_loss("user unavailable"));
        }

        let create_user = CreateUserRequest::decode(resp.as_ref())
            .map_err(|_e| Status::data_loss("internal data corrupted"))?;

        let user = sqlx::query!(
            "insert 
                into
                    profile (
                        id,
                        username,
                        inbox,
                        outbox,
                        local,
                        avatar_url,
                        description,
                        user_type,
                        public_key
                    )
                values ($1, $2, $3, $4, $5, $6, $7, $8, $9)
            ",
            request.id,
            request.username,
            request.inbox,
            request.outbox,
            request.local,
            request.avatar.or(create_user.avatar),
            request.description,
            request.user_type.to_string(),
            request.public_key,
        );
        todo!()
    }
}