Переглянути джерело

Create route to create a new game

Lee Morgan 1 місяць тому
батько
коміт
5fb5c910f6

+ 1 - 1
sql/games.sql

@@ -2,6 +2,6 @@ CREATE TABLE IF NOT EXISTS games(
     id UUID PRIMARY KEY,
     user_id UUID NOT NULL REFERENCES users(id),
     title TEXT NOT NULL,
-    world_context TEXT NOT NULL,
+    game_context TEXT NOT NULL,
     created_at TIMESTAMPTZ NOT NULL
 );

+ 1 - 1
sql/turns.sql

@@ -1,6 +1,6 @@
 CREATE TABLE IF NOT EXISTS turns(
     id UUID PRIMARY KEY,
-    session_id UUID NOT NULL REFERENCES session(id),
+    session_id UUID NOT NULL REFERENCES sessions(id),
     user_text TEXT NOT NULL,
     llm_text TEXT NULL,
     sequence_number INTEGER NOT NULL,

+ 10 - 1
src/auth.rs

@@ -15,7 +15,11 @@ struct UserJwt{
     session_token: Uuid
 }
 
-pub async fn user_auth(db: &PgPool, req: &HttpRequest) -> Result<User, HttpError> {
+pub async fn user_auth(
+    db: &PgPool,
+    req: &HttpRequest,
+    check_tokens: bool
+) -> Result<User, HttpError> {
     let cookie = req.cookie("user").ok_or(HttpError::Auth)?;
     let user_data = decode::<UserJwt>(
         &cookie.value(),
@@ -23,5 +27,10 @@ pub async fn user_auth(db: &PgPool, req: &HttpRequest) -> Result<User, HttpError
         &Validation::default()
     )?.claims;
     let user = User::find_one_by_session(db, user_data.id, user_data.session_token).await?;
+
+    if check_tokens && user.tokens <= 0 {
+        return Err(HttpError::InsufficientTokens);
+    }
+
     Ok(user)
 }

+ 6 - 3
src/controllers/game/create.rs

@@ -3,7 +3,8 @@ use sqlx::PgPool;
 use serde::Deserialize;
 use crate::{
     http_error::HttpError,
-    auth::user_auth
+    auth::user_auth,
+    models::game::Game
 };
 
 #[derive(Deserialize)]
@@ -18,6 +19,8 @@ pub async fn route(
     web::Json(body): web::Json<Body>,
     req: HttpRequest
 ) -> Result<HttpResponse, HttpError> {
-    let user = user_auth(&db, &req).await?;
-    Ok(HttpResponse::Ok().body("something"))
+    let user = user_auth(&db, &req, true).await?;
+    let game = Game::new(body.title, body.world_context, user.id);
+    game.insert(&db).await?;
+    Ok(HttpResponse::Ok().json(game))
 }

+ 1 - 1
src/controllers/user/get_one.rs

@@ -10,6 +10,6 @@ pub async fn route(
     db: web::Data<PgPool>,
     req: HttpRequest
 ) -> Result<HttpResponse, HttpError> {
-    let user = user_auth(&db, &req).await?;
+    let user = user_auth(&db, &req, false).await?;
     Ok(HttpResponse::Ok().json(user.response()))
 }

+ 1 - 1
src/controllers/user/payment_intent.rs

@@ -25,7 +25,7 @@ pub async fn route(
     if body.token_packs < 5 {
         return Err(HttpError::InvalidInput("Must buy minimum 5 token packs".into()));
     }
-    let user = user_auth(&db, &req).await?;
+    let user = user_auth(&db, &req, false).await?;
     let (pi_id, client_secret) = request_payment_intent(body.token_packs, user.id).await?;
     let purchase = create_purchase(user.id, pi_id, body.token_packs)?;
     purchase.insert_one(&db).await?;

+ 6 - 2
src/http_error.rs

@@ -37,7 +37,10 @@ pub enum HttpError {
     InvalidJwt(#[from] jsonwebtoken::errors::Error),
 
     #[error("{0}")]
-    NotFound(String)
+    NotFound(String),
+
+    #[error("Insufficient Tokens")]
+    InsufficientTokens
 }
 
 impl ResponseError for HttpError {
@@ -50,7 +53,8 @@ impl ResponseError for HttpError {
             HttpError::Auth => StatusCode::UNAUTHORIZED,
             HttpError::InvalidUuid(_) => StatusCode::BAD_REQUEST,
             HttpError::InvalidJwt(_) => StatusCode::UNAUTHORIZED,
-            HttpError::NotFound(_) => StatusCode::NOT_FOUND
+            HttpError::NotFound(_) => StatusCode::NOT_FOUND,
+            HttpError::InsufficientTokens => StatusCode::FORBIDDEN
         }
     }
 

+ 34 - 2
src/models/game.rs

@@ -1,10 +1,42 @@
 use uuid::Uuid;
 use chrono::{DateTime, Utc};
+use sqlx::PgPool;
+use serde::Serialize;
+use crate::http_error::HttpError;
 
+#[derive(Serialize)]
 pub struct Game {
     pub id: Uuid,
     pub user_id: Uuid,
     pub title: String,
-    pub world_context: String,
-    pub createdAt: DateTime<Utc>
+    pub game_context: String,
+    pub created_at: DateTime<Utc>
+}
+
+impl Game {
+    pub fn new(title: String, game_context: String, user_id: Uuid) -> Self {
+        Self {
+            id: Uuid::now_v7(),
+            user_id: user_id,
+            title: title,
+            game_context: game_context,
+            created_at: Utc::now()
+        }
+    }
+
+    pub async fn insert(&self, db: &PgPool) -> Result<(), HttpError> {
+        sqlx::query(
+            "INSERT into games(id, user_id, title, game_context, created_at)
+            VALUES($1, $2, $3, $4, $5)"
+        )
+            .bind(&self.id)
+            .bind(&self.user_id)
+            .bind(&self.title)
+            .bind(&self.game_context)
+            .bind(&self.created_at)
+            .execute(db)
+            .await?;
+
+        Ok(())
+    }
 }