- Add migration 002_posts.sql with posts, tags, post_tags tables - Add Post/Tag/PostStats models with PostStatus enum - Add posts API with full CRUD: - create_post, update_post, delete_post (admin only) - get_post_by_slug, list_published_posts (public) - list_posts, get_post_stats (admin) - list_tags, get_posts_by_tag, search_posts (public) - Slug auto-generation with uniqueness check - Server-side markdown rendering with pulldown-cmark - Auto-summary extraction from markdown - Soft delete support
58 lines
1.3 KiB
Rust
58 lines
1.3 KiB
Rust
use chrono::{DateTime, Utc};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub enum PostStatus {
|
|
Draft,
|
|
Published,
|
|
}
|
|
|
|
impl PostStatus {
|
|
#[allow(dead_code)]
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
PostStatus::Draft => "draft",
|
|
PostStatus::Published => "published",
|
|
}
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub fn from_str(s: &str) -> Option<Self> {
|
|
match s {
|
|
"draft" => Some(PostStatus::Draft),
|
|
"published" => Some(PostStatus::Published),
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Post {
|
|
pub id: i32,
|
|
pub author_id: i32,
|
|
pub title: String,
|
|
pub slug: String,
|
|
pub summary: Option<String>,
|
|
pub content_md: String,
|
|
pub content_html: Option<String>,
|
|
pub status: PostStatus,
|
|
pub published_at: Option<DateTime<Utc>>,
|
|
pub created_at: DateTime<Utc>,
|
|
pub updated_at: DateTime<Utc>,
|
|
pub tags: Vec<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Tag {
|
|
pub id: i32,
|
|
pub name: String,
|
|
pub post_count: i64,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct PostStats {
|
|
pub total: i64,
|
|
pub drafts: i64,
|
|
pub published: i64,
|
|
}
|