feat: admin routing part 4

This commit is contained in:
Ahmet Kaan GÜMÜŞ 2025-01-27 17:54:57 +03:00
parent 8fb39f27ca
commit c3156aeb41
6 changed files with 111 additions and 36 deletions

View file

@ -1,6 +1,7 @@
-- Add up migration script here -- Add up migration script here
CREATE TABLE IF NOT EXISTS "post"( CREATE TABLE IF NOT EXISTS "post"(
creation_time TIMESTAMPTZ PRIMARY KEY UNIQUE NOT NULL DEFAULT NOW(),
user_id BIGSERIAL NOT NULL REFERENCES "user"(user_id), user_id BIGSERIAL NOT NULL REFERENCES "user"(user_id),
post VARCHAR(8192) NOT NULL UNIQUE creation_time TIMESTAMPTZ UNIQUE NOT NULL DEFAULT NOW(),
post VARCHAR(8192) NOT NULL UNIQUE,
PRIMARY KEY(user_id, creation_time)
); );

View file

@ -19,12 +19,13 @@ pub async fn create(user_id: &i64, post: &String) -> Result<Post, sqlx::Error> {
.await .await
} }
pub async fn read(creation_time: &DateTime<Utc>) -> Result<Post, sqlx::Error> { pub async fn read(user_id: &i64, creation_time: &DateTime<Utc>) -> Result<Post, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
Post, Post,
r#" r#"
SELECT * FROM "post" WHERE "creation_time" = $1 SELECT * FROM "post" WHERE "user_id"= $1 AND "creation_time" = $2
"#, "#,
user_id,
creation_time creation_time
) )
.fetch_one(&*DATABASE_CONNECTIONS) .fetch_one(&*DATABASE_CONNECTIONS)
@ -32,31 +33,32 @@ pub async fn read(creation_time: &DateTime<Utc>) -> Result<Post, sqlx::Error> {
} }
pub async fn update( pub async fn update(
creation_time: &DateTime<Utc>,
user_id: &i64, user_id: &i64,
creation_time: &DateTime<Utc>,
post: &String, post: &String,
) -> Result<Post, sqlx::Error> { ) -> Result<Post, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
Post, Post,
r#" r#"
UPDATE "post" SET user_id = $2, post = $3 WHERE "creation_time" = $1 UPDATE "post" SET post = $3 WHERE "user_id" = $1 AND "creation_time" = $2
RETURNING * RETURNING *
"#, "#,
creation_time,
user_id, user_id,
creation_time,
post post
) )
.fetch_one(&*DATABASE_CONNECTIONS) .fetch_one(&*DATABASE_CONNECTIONS)
.await .await
} }
pub async fn delete(creation_time: &DateTime<Utc>) -> Result<Post, sqlx::Error> { pub async fn delete(user_id: &i64, creation_time: &DateTime<Utc>) -> Result<Post, sqlx::Error> {
sqlx::query_as!( sqlx::query_as!(
Post, Post,
r#" r#"
DELETE FROM "post" WHERE "creation_time" = $1 DELETE FROM "post" WHERE "user_id" = $1 AND "creation_time" = $2
RETURNING * RETURNING *
"#, "#,
user_id,
creation_time creation_time
) )
.fetch_one(&*DATABASE_CONNECTIONS) .fetch_one(&*DATABASE_CONNECTIONS)

View file

@ -15,20 +15,20 @@ impl Post {
post::create(user_id, post).await post::create(user_id, post).await
} }
pub async fn read(creation_time: &DateTime<Utc>) -> Result<Post, sqlx::Error> { pub async fn read(user_id: &i64, creation_time: &DateTime<Utc>) -> Result<Post, sqlx::Error> {
post::read(creation_time).await post::read(user_id, creation_time).await
} }
pub async fn update( pub async fn update(
creation_time: &DateTime<Utc>,
user_id: &i64, user_id: &i64,
creation_time: &DateTime<Utc>,
post: &String, post: &String,
) -> Result<Post, sqlx::Error> { ) -> Result<Post, sqlx::Error> {
post::update(creation_time, user_id, post).await post::update(user_id, creation_time, post).await
} }
pub async fn delete(creation_time: &DateTime<Utc>) -> Result<Post, sqlx::Error> { pub async fn delete(user_id: &i64, creation_time: &DateTime<Utc>) -> Result<Post, sqlx::Error> {
post::delete(creation_time).await post::delete(user_id, creation_time).await
} }
pub async fn read_all() -> Result<Vec<Post>, sqlx::Error> { pub async fn read_all() -> Result<Vec<Post>, sqlx::Error> {

View file

@ -1,6 +1,7 @@
pub mod contact; pub mod contact;
pub mod interaction; pub mod interaction;
pub mod login; pub mod login;
pub mod post;
pub mod role; pub mod role;
pub mod user; pub mod user;
pub mod user_contact; pub mod user_contact;
@ -17,6 +18,7 @@ pub fn route() -> Router {
.nest("/contacts", contact::route()) .nest("/contacts", contact::route())
.nest("/user_contacts", user_contact::route()) .nest("/user_contacts", user_contact::route())
.nest("/interactions", interaction::route()) .nest("/interactions", interaction::route())
.nest("/posts", post::route())
.route_layer(axum::middleware::from_fn( .route_layer(axum::middleware::from_fn(
builder_or_admin_by_authorization_token, builder_or_admin_by_authorization_token,
)) ))

32
src/routing/admin/post.rs Normal file
View file

@ -0,0 +1,32 @@
use std::sync::Arc;
use axum::{
extract::Path, http::StatusCode, response::IntoResponse, routing::delete, Extension, Json,
Router,
};
use chrono::{DateTime, Utc};
use crate::{
feature::{post::Post, user::User},
routing::middleware::by_uri_then_insert,
};
pub fn route() -> Router {
Router::new().route(
"/users/{user_id}/creation_times/{creation_time}",
delete(delete_).route_layer(axum::middleware::from_fn(by_uri_then_insert)),
)
}
async fn delete_(
Extension(user): Extension<Arc<User>>,
Path(creation_time): Path<DateTime<Utc>>,
) -> impl IntoResponse {
match Post::delete(&user.user_id, &creation_time).await {
Ok(post) => (StatusCode::NO_CONTENT, Json(serde_json::json!(post))),
Err(err_val) => (
StatusCode::BAD_REQUEST,
Json(serde_json::json!(err_val.to_string())),
),
}
}

View file

@ -1,39 +1,64 @@
use std::sync::Arc;
use axum::{ use axum::{
extract::Path, extract::Path,
http::StatusCode, http::StatusCode,
response::IntoResponse, response::IntoResponse,
routing::{delete, get, patch, post}, routing::{delete, get, patch, post},
Json, Router, Extension, Json, Router,
}; };
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::feature::post::Post; use crate::feature::{post::Post, user::User};
use super::middleware::{by_authorization_token_then_insert, by_uri_then_insert};
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct CreatePost { struct CreatePost {
user_id: i64,
post: String, post: String,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct UpdatePost { struct UpdatePost {
creation_time: DateTime<Utc>, creation_time: DateTime<Utc>,
user_id: i64,
post: String, post: String,
} }
pub fn route() -> Router { pub fn route() -> Router {
Router::new() Router::new()
.route("/", post(create)) .route(
.route("/{creation_time}", get(read)) "/",
post(create).route_layer(axum::middleware::from_fn(
by_authorization_token_then_insert,
)),
)
.route(
"/users/{user_id}/creation_times/{creation_time}",
get(read).route_layer(axum::middleware::from_fn(by_uri_then_insert)),
)
.route("/", patch(update)) .route("/", patch(update))
.route("/{creation_time}", delete(delete_)) .route_layer(axum::middleware::from_fn(
by_authorization_token_then_insert,
))
.route(
"/creation_times/{creation_time}",
delete(delete_).route_layer(axum::middleware::from_fn(
by_authorization_token_then_insert,
)),
)
.route("/", get(read_all)) .route("/", get(read_all))
.route(
"/users/{user_id}",
get(read_all_for_user).route_layer(axum::middleware::from_fn(by_uri_then_insert)),
)
} }
async fn create(Json(create_post): Json<CreatePost>) -> impl IntoResponse { async fn create(
match Post::create(&create_post.user_id, &create_post.post).await { Extension(user): Extension<Arc<User>>,
Json(create_post): Json<CreatePost>,
) -> impl IntoResponse {
match Post::create(&user.user_id, &create_post.post).await {
Ok(post) => (StatusCode::CREATED, Json(serde_json::json!(post))), Ok(post) => (StatusCode::CREATED, Json(serde_json::json!(post))),
Err(err_val) => ( Err(err_val) => (
StatusCode::BAD_REQUEST, StatusCode::BAD_REQUEST,
@ -42,8 +67,11 @@ async fn create(Json(create_post): Json<CreatePost>) -> impl IntoResponse {
} }
} }
async fn read(Path(creation_time): Path<DateTime<Utc>>) -> impl IntoResponse { async fn read(
match Post::read(&creation_time).await { Extension(user): Extension<Arc<User>>,
Path(creation_time): Path<DateTime<Utc>>,
) -> impl IntoResponse {
match Post::read(&user.user_id, &creation_time).await {
Ok(post) => (StatusCode::OK, Json(serde_json::json!(post))), Ok(post) => (StatusCode::OK, Json(serde_json::json!(post))),
Err(err_val) => ( Err(err_val) => (
StatusCode::BAD_REQUEST, StatusCode::BAD_REQUEST,
@ -52,14 +80,11 @@ async fn read(Path(creation_time): Path<DateTime<Utc>>) -> impl IntoResponse {
} }
} }
async fn update(Json(update_role): Json<UpdatePost>) -> impl IntoResponse { async fn update(
match Post::update( Extension(user): Extension<Arc<User>>,
&update_role.creation_time, Json(update_role): Json<UpdatePost>,
&update_role.user_id, ) -> impl IntoResponse {
&update_role.post, match Post::update(&user.user_id, &update_role.creation_time, &update_role.post).await {
)
.await
{
Ok(post) => (StatusCode::ACCEPTED, Json(serde_json::json!(post))), Ok(post) => (StatusCode::ACCEPTED, Json(serde_json::json!(post))),
Err(err_val) => ( Err(err_val) => (
StatusCode::BAD_REQUEST, StatusCode::BAD_REQUEST,
@ -68,8 +93,11 @@ async fn update(Json(update_role): Json<UpdatePost>) -> impl IntoResponse {
} }
} }
async fn delete_(Path(creation_time): Path<DateTime<Utc>>) -> impl IntoResponse { async fn delete_(
match Post::delete(&creation_time).await { Extension(user): Extension<Arc<User>>,
Path(creation_time): Path<DateTime<Utc>>,
) -> impl IntoResponse {
match Post::delete(&user.user_id, &creation_time).await {
Ok(post) => (StatusCode::NO_CONTENT, Json(serde_json::json!(post))), Ok(post) => (StatusCode::NO_CONTENT, Json(serde_json::json!(post))),
Err(err_val) => ( Err(err_val) => (
StatusCode::BAD_REQUEST, StatusCode::BAD_REQUEST,
@ -87,3 +115,13 @@ async fn read_all() -> impl IntoResponse {
), ),
} }
} }
async fn read_all_for_user(Extension(user): Extension<Arc<User>>) -> impl IntoResponse {
match Post::read_all_for_user(&user.user_id).await {
Ok(posts) => (StatusCode::OK, Json(serde_json::json!(posts))),
Err(err_val) => (
StatusCode::BAD_REQUEST,
Json(serde_json::json!(err_val.to_string())),
),
}
}