use serde::{Deserialize, Serialize}; use sqlx::FromRow; // sqlx::Any maps SQLite INTEGER to i64 (BIGINT), not bool. // These helpers let us store is_admin as i64 in DB-mapped structs // while still serializing it as a JSON boolean for the frontend. mod serde_i64_bool { use serde::{Deserialize, Deserializer, Serializer}; pub fn serialize(v: &i64, s: S) -> Result { s.serialize_bool(*v != 0) } pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result { Ok(if bool::deserialize(d)? { 1 } else { 0 }) } } #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct User { pub id: String, pub username: String, pub email: String, #[serde(skip_serializing)] pub password_hash: String, #[serde(with = "serde_i64_bool")] pub is_admin: i64, } #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct AdminUserView { pub id: String, pub username: String, pub email: String, #[serde(with = "serde_i64_bool")] pub is_admin: i64, pub created_at: String, } #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct Folder { pub id: String, pub owner_id: String, pub parent_id: Option, pub name: String, pub created_at: String, } #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct File { pub id: String, pub owner_id: String, pub document_id: Option, pub folder_id: Option, pub name: String, pub mime_type: String, pub created_at: String, } #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct Document { pub id: String, pub owner_id: String, pub folder_id: Option, pub title: String, #[serde(skip_serializing)] pub content: Option>, pub thumbnail_svg: Option, pub public_role: Option, #[serde(default)] #[sqlx(default)] pub effective_role: Option, pub created_at: String, pub updated_at: String, } #[derive(Debug, Serialize, Deserialize)] pub struct RegisterRequest { pub username: String, pub email: String, pub password: String, } #[derive(Debug, Serialize, Deserialize)] pub struct LoginRequest { pub email: String, pub password: String, } #[derive(Debug, Serialize, Deserialize)] pub struct UpdateProfileRequest { pub username: String, pub email: String, } #[derive(Debug, Serialize, Deserialize)] pub struct ChangePasswordRequest { pub current_password: String, pub new_password: String, } #[derive(Debug, Serialize, Deserialize)] pub struct CreateFolderRequest { pub name: String, pub parent_id: Option, } #[derive(Debug, Serialize, Deserialize)] pub struct CreateDocumentRequest { pub title: String, pub folder_id: Option, pub content: Option, } #[derive(Debug, Serialize, Deserialize)] pub struct UpdateDocumentRequest { pub title: Option, pub folder_id: Option, pub public_role: Option, } #[derive(Debug, Serialize, Deserialize)] pub struct StorageStats { pub documents_size_bytes: i64, pub files_size_bytes: i64, pub total_size_bytes: i64, } #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct Collaborator { pub id: String, pub document_id: String, pub user_id: String, pub role: String, pub created_at: String, } #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct CollaboratorView { pub id: String, pub user_id: String, pub username: String, pub email: String, pub role: String, pub created_at: String, } #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct Invitation { pub id: String, pub document_id: String, pub role: String, pub token: String, pub created_at: String, pub expires_at: Option, } #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct Comment { pub id: String, pub document_id: String, pub user_id: String, pub content: String, pub resolved: bool, pub created_at: String, pub author_name: Option, } #[derive(Debug, Serialize, Deserialize)] pub struct CreateCommentRequest { pub content: String, } #[derive(Debug, Serialize, Deserialize)] pub struct UpdateCommentRequest { pub content: Option, pub resolved: Option, } #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct DocumentVersion { pub id: String, pub document_id: String, pub user_id: String, pub content: String, pub created_at: String, #[sqlx(default)] pub author_name: Option, } #[derive(Debug, Serialize, Deserialize)] pub struct CreateVersionRequest { pub content: String, } #[derive(Debug, Serialize, Deserialize)] pub struct InviteRequest { pub email: String, pub role: String, } #[derive(Debug, Serialize, Deserialize)] pub struct AdminCreateUserRequest { pub username: String, pub email: String, pub password: String, pub is_admin: Option, } #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct UsagePoint { pub date: String, pub count: i64, } #[derive(Debug, Serialize, Deserialize, FromRow)] pub struct ApiKeyView { pub id: String, pub name: String, pub key_prefix: String, pub created_at: String, pub last_used_at: Option, pub rate_limit: i64, } #[derive(Debug, Serialize, Deserialize)] pub struct CreateApiKeyRequest { pub name: String, } #[derive(Debug, Serialize, Deserialize)] pub struct SetupRequest { pub username: String, pub email: String, pub password: String, } #[derive(Debug, Serialize, Deserialize)] pub struct SetupStatus { pub needs_setup: bool, pub registration_enabled: bool, } #[derive(Debug, Serialize, Deserialize)] pub struct UpdateUserRequest { pub is_admin: Option, pub username: Option, pub email: Option, }