feat: implement user follow/unfollow functionality and thought retrieval by user
- Added follow and unfollow endpoints for users. - Implemented logic to retrieve thoughts by a specific user. - Updated user error handling to include cases for already following and not following. - Created persistence layer for follow relationships. - Enhanced user and thought schemas to support new features. - Added tests for follow/unfollow endpoints and thought retrieval. - Updated frontend to display thoughts and allow posting new thoughts.
This commit is contained in:
@@ -4,8 +4,10 @@ use validator::Validate;
|
||||
|
||||
#[derive(Deserialize, Validate, ToSchema)]
|
||||
pub struct CreateThoughtParams {
|
||||
pub author_id: i32,
|
||||
|
||||
#[validate(length(min = 1, max = 128))]
|
||||
#[validate(length(
|
||||
min = 1,
|
||||
max = 128,
|
||||
message = "Content must be between 1 and 128 characters"
|
||||
))]
|
||||
pub content: String,
|
||||
}
|
||||
|
@@ -1,23 +1,26 @@
|
||||
use crate::domains::thought;
|
||||
use crate::domains::{thought, user};
|
||||
use common::DateTimeWithTimeZoneWrapper;
|
||||
use sea_orm::FromQueryResult;
|
||||
use serde::Serialize;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
#[derive(Serialize, ToSchema, FromQueryResult)]
|
||||
pub struct ThoughtSchema {
|
||||
pub id: i32,
|
||||
pub author_id: i32,
|
||||
#[schema(example = "frutiger")]
|
||||
pub author_username: String,
|
||||
#[schema(example = "This is my first thought! #welcome")]
|
||||
pub content: String,
|
||||
pub created_at: DateTimeWithTimeZoneWrapper,
|
||||
}
|
||||
|
||||
impl From<thought::Model> for ThoughtSchema {
|
||||
fn from(model: thought::Model) -> Self {
|
||||
impl ThoughtSchema {
|
||||
pub fn from_models(thought: &thought::Model, author: &user::Model) -> Self {
|
||||
Self {
|
||||
id: model.id,
|
||||
author_id: model.author_id,
|
||||
content: model.content,
|
||||
created_at: model.created_at.into(),
|
||||
id: thought.id,
|
||||
author_username: author.username.clone(),
|
||||
content: thought.content.clone(),
|
||||
created_at: thought.created_at.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,10 +30,28 @@ pub struct ThoughtListSchema {
|
||||
pub thoughts: Vec<ThoughtSchema>,
|
||||
}
|
||||
|
||||
impl From<Vec<thought::Model>> for ThoughtListSchema {
|
||||
fn from(models: Vec<thought::Model>) -> Self {
|
||||
impl From<Vec<ThoughtSchema>> for ThoughtListSchema {
|
||||
fn from(thoughts: Vec<ThoughtSchema>) -> Self {
|
||||
Self { thoughts }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, FromQueryResult)]
|
||||
pub struct ThoughtWithAuthor {
|
||||
pub id: i32,
|
||||
pub content: String,
|
||||
pub created_at: sea_orm::prelude::DateTimeWithTimeZone,
|
||||
pub author_id: i32,
|
||||
pub author_username: String,
|
||||
}
|
||||
|
||||
impl From<ThoughtWithAuthor> for ThoughtSchema {
|
||||
fn from(model: ThoughtWithAuthor) -> Self {
|
||||
Self {
|
||||
thoughts: models.into_iter().map(ThoughtSchema::from).collect(),
|
||||
id: model.id,
|
||||
author_username: model.author_username,
|
||||
content: model.content,
|
||||
created_at: model.created_at.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -5,14 +5,14 @@ use crate::domains::user;
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct UserSchema {
|
||||
pub id: u32,
|
||||
pub id: i32,
|
||||
pub username: String,
|
||||
}
|
||||
|
||||
impl From<user::Model> for UserSchema {
|
||||
fn from(user: user::Model) -> Self {
|
||||
Self {
|
||||
id: user.id as u32,
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user