feat: v2 rewrite — hexagonal arch, ActivityPub federation, NATS, deployment-ready #1
@@ -1,6 +1,6 @@
|
||||
use axum::{extract::{Path, Query, State}, Json};
|
||||
use api_types::requests::{PaginationQuery, SearchQuery};
|
||||
use application::use_cases::feed::{get_home_feed, get_public_feed, get_followers, get_following};
|
||||
use application::use_cases::feed::{get_home_feed, get_public_feed, get_followers, get_following, get_user_feed, get_by_tag};
|
||||
use domain::models::feed::PageParams;
|
||||
use crate::{errors::ApiError, extractors::{AuthUser, OptionalAuthUser}, handlers::auth::to_user_response, state::AppState};
|
||||
use application::use_cases::profile::get_user_by_username;
|
||||
@@ -62,3 +62,49 @@ pub async fn get_followers_handler(State(s): State<AppState>, Path(username): Pa
|
||||
let result = get_followers(&*s.follows, &user.id, page).await?;
|
||||
Ok(Json(serde_json::json!({ "total": result.total, "items": result.items.iter().map(to_user_response).collect::<Vec<_>>() })))
|
||||
}
|
||||
|
||||
pub async fn user_thoughts_handler(
|
||||
State(s): State<AppState>,
|
||||
Path(username): Path<String>,
|
||||
Query(q): Query<PaginationQuery>,
|
||||
) -> Result<Json<serde_json::Value>, ApiError> {
|
||||
let user = get_user_by_username(&*s.users, &username).await?;
|
||||
let page = PageParams { page: q.page(), per_page: q.per_page() };
|
||||
let result = get_user_feed(&*s.thoughts, &user.id, page).await?;
|
||||
Ok(Json(serde_json::json!({
|
||||
"total": result.total,
|
||||
"page": result.page,
|
||||
"per_page": result.per_page,
|
||||
"items": result.items.iter().map(|e| serde_json::json!({
|
||||
"id": e.thought.id.as_uuid(),
|
||||
"content": e.thought.content.as_str(),
|
||||
"visibility": e.thought.visibility.as_str(),
|
||||
"like_count": e.like_count,
|
||||
"boost_count": e.boost_count,
|
||||
"reply_count": e.reply_count,
|
||||
"created_at": e.thought.created_at,
|
||||
"updated_at": e.thought.updated_at,
|
||||
})).collect::<Vec<_>>()
|
||||
})))
|
||||
}
|
||||
|
||||
pub async fn tag_thoughts_handler(
|
||||
State(s): State<AppState>,
|
||||
Path(tag_name): Path<String>,
|
||||
Query(q): Query<PaginationQuery>,
|
||||
) -> Result<Json<serde_json::Value>, ApiError> {
|
||||
let page = PageParams { page: q.page(), per_page: q.per_page() };
|
||||
let result = get_by_tag(&*s.tags, &tag_name, page).await?;
|
||||
Ok(Json(serde_json::json!({
|
||||
"tag": tag_name,
|
||||
"total": result.total,
|
||||
"page": result.page,
|
||||
"per_page": result.per_page,
|
||||
"items": result.items.iter().map(|t| serde_json::json!({
|
||||
"id": t.id.as_uuid(),
|
||||
"content": t.content.as_str(),
|
||||
"visibility": t.visibility.as_str(),
|
||||
"created_at": t.created_at,
|
||||
})).collect::<Vec<_>>()
|
||||
})))
|
||||
}
|
||||
|
||||
@@ -13,3 +13,8 @@ pub async fn patch_profile(State(s): State<AppState>, AuthUser(uid): AuthUser, J
|
||||
let user = s.users.find_by_id(&uid).await?.ok_or(domain::errors::DomainError::NotFound)?;
|
||||
Ok(Json(to_user_response(&user)))
|
||||
}
|
||||
|
||||
pub async fn get_me(State(s): State<AppState>, AuthUser(uid): AuthUser) -> Result<Json<UserResponse>, ApiError> {
|
||||
let user = s.users.find_by_id(&uid).await?.ok_or(domain::errors::DomainError::NotFound)?;
|
||||
Ok(Json(to_user_response(&user)))
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ pub fn router(fed_config: &ApFederationConfig) -> Router<AppState> {
|
||||
.route("/auth/register", post(auth::post_register))
|
||||
.route("/auth/login", post(auth::post_login))
|
||||
// users — static paths before parameterised
|
||||
.route("/users/me", patch(users::patch_profile))
|
||||
.route("/users/me", get(users::get_me).patch(users::patch_profile))
|
||||
.route("/users/me/top-friends", put(social::put_top_friends))
|
||||
.route("/users/{username}/top-friends", get(social::get_top_friends_handler))
|
||||
// follows & blocks (use {id} param)
|
||||
@@ -54,6 +54,8 @@ pub fn router(fed_config: &ApFederationConfig) -> Router<AppState> {
|
||||
.route("/feed", get(feed::home_feed))
|
||||
.route("/feed/public", get(feed::public_feed))
|
||||
.route("/search", get(feed::search_handler))
|
||||
.route("/users/{username}/thoughts", get(feed::user_thoughts_handler))
|
||||
.route("/tags/{name}", get(feed::tag_thoughts_handler))
|
||||
// notifications
|
||||
.route("/notifications", get(notifications::list_notifications))
|
||||
.route("/notifications/read-all", post(notifications::mark_all_read))
|
||||
|
||||
Reference in New Issue
Block a user