From 4f990afe5ee867ceac570f8b6cc0c66090146566 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Thu, 14 May 2026 11:30:11 +0200 Subject: [PATCH] feat(api-types): add utoipa ToSchema and IntoParams derives --- crates/api-types/Cargo.toml | 1 + crates/api-types/src/requests.rs | 22 +++++++++++++--------- crates/api-types/src/responses.rs | 24 ++++++++++++++++-------- crates/presentation/Cargo.toml | 3 +++ 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/crates/api-types/Cargo.toml b/crates/api-types/Cargo.toml index 8793ca6..10b1a48 100644 --- a/crates/api-types/Cargo.toml +++ b/crates/api-types/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" serde = { workspace = true } uuid = { workspace = true } chrono = { workspace = true } +utoipa = { version = "5.5.0", features = ["uuid", "chrono"] } diff --git a/crates/api-types/src/requests.rs b/crates/api-types/src/requests.rs index c521dcc..50248c6 100644 --- a/crates/api-types/src/requests.rs +++ b/crates/api-types/src/requests.rs @@ -1,34 +1,37 @@ use serde::Deserialize; use uuid::Uuid; -#[derive(Deserialize)] +#[derive(Deserialize, utoipa::ToSchema)] pub struct RegisterRequest { + /// Username (1-32 chars, alphanumeric + underscore) pub username: String, pub email: String, pub password: String, } -#[derive(Deserialize)] +#[derive(Deserialize, utoipa::ToSchema)] pub struct LoginRequest { pub email: String, pub password: String, } -#[derive(Deserialize)] +#[derive(Deserialize, utoipa::ToSchema)] pub struct CreateThoughtRequest { + /// Up to 128 characters pub content: String, pub in_reply_to_id: Option, + /// One of: "public", "followers", "unlisted", "direct" pub visibility: Option, pub content_warning: Option, pub sensitive: Option, } -#[derive(Deserialize)] +#[derive(Deserialize, utoipa::ToSchema)] pub struct EditThoughtRequest { pub content: String, } -#[derive(Deserialize)] +#[derive(Deserialize, utoipa::ToSchema)] pub struct UpdateProfileRequest { pub display_name: Option, pub bio: Option, @@ -37,17 +40,18 @@ pub struct UpdateProfileRequest { pub custom_css: Option, } -#[derive(Deserialize)] +#[derive(Deserialize, utoipa::ToSchema)] pub struct SetTopFriendsRequest { + /// Ordered list of user UUIDs, max 8 pub friend_ids: Vec, } -#[derive(Deserialize)] +#[derive(Deserialize, utoipa::ToSchema)] pub struct CreateApiKeyRequest { pub name: String, } -#[derive(Deserialize)] +#[derive(Deserialize, utoipa::IntoParams)] pub struct PaginationQuery { pub page: Option, pub per_page: Option, @@ -63,7 +67,7 @@ impl PaginationQuery { } } -#[derive(Deserialize)] +#[derive(Deserialize, utoipa::IntoParams)] pub struct SearchQuery { pub q: String, pub page: Option, diff --git a/crates/api-types/src/responses.rs b/crates/api-types/src/responses.rs index bcadb60..17168d5 100644 --- a/crates/api-types/src/responses.rs +++ b/crates/api-types/src/responses.rs @@ -2,13 +2,13 @@ use chrono::{DateTime, Utc}; use serde::Serialize; use uuid::Uuid; -#[derive(Serialize)] +#[derive(Serialize, utoipa::ToSchema)] pub struct AuthResponse { pub token: String, pub user: UserResponse, } -#[derive(Serialize, Clone)] +#[derive(Serialize, Clone, utoipa::ToSchema)] pub struct UserResponse { pub id: Uuid, pub username: String, @@ -20,7 +20,7 @@ pub struct UserResponse { pub created_at: DateTime, } -#[derive(Serialize, Clone)] +#[derive(Serialize, Clone, utoipa::ToSchema)] pub struct ThoughtResponse { pub id: Uuid, pub content: String, @@ -38,22 +38,22 @@ pub struct ThoughtResponse { pub updated_at: Option>, } -#[derive(Serialize)] -pub struct PagedResponse { +#[derive(Serialize, utoipa::ToSchema)] +pub struct PagedResponse { pub items: Vec, pub total: i64, pub page: u64, pub per_page: u64, } -#[derive(Serialize)] +#[derive(Serialize, utoipa::ToSchema)] pub struct ApiKeyResponse { pub id: Uuid, pub name: String, pub created_at: DateTime, } -#[derive(Serialize)] +#[derive(Serialize, utoipa::ToSchema)] pub struct NotificationResponse { pub id: Uuid, pub notification_type: String, @@ -63,7 +63,15 @@ pub struct NotificationResponse { pub created_at: DateTime, } -#[derive(Serialize)] +#[derive(Serialize, utoipa::ToSchema)] pub struct ErrorResponse { pub error: String, } + +#[derive(Serialize, utoipa::ToSchema)] +pub struct CreatedApiKeyResponse { + pub id: Uuid, + pub name: String, + /// Raw API key — shown only once at creation + pub key: String, +} diff --git a/crates/presentation/Cargo.toml b/crates/presentation/Cargo.toml index c9611cd..4ce5adf 100644 --- a/crates/presentation/Cargo.toml +++ b/crates/presentation/Cargo.toml @@ -35,6 +35,9 @@ activitypub-base = { workspace = true } postgres-federation = { workspace = true } url = { workspace = true } activitypub_federation = "0.7.0-beta.11" +utoipa = { version = "5.5.0", features = ["axum_extras", "uuid", "chrono"] } +utoipa-scalar = { version = "0.3.0", features = ["axum"], default-features = false } +utoipa-swagger-ui = { version = "9.0.2", features = ["axum", "vendored"] } [dev-dependencies] http-body-util = "0.1"