67 lines
2.4 KiB
Python
67 lines
2.4 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, Query, status
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.auth.deps import get_current_user
|
|
from app.database import get_db
|
|
from app.models.user import User
|
|
from app.schemas.post import PostCreate, PostUpdate, PostResponse, PaginatedPostsResponse
|
|
from app.services import posts as post_service
|
|
|
|
router = APIRouter(prefix="/posts", tags=["Posts"])
|
|
|
|
|
|
@router.get("", response_model=PaginatedPostsResponse)
|
|
async def list_posts(
|
|
page: int = Query(default=1, ge=1),
|
|
per_page: int = Query(default=10, ge=1, le=100),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
"""List published posts with pagination."""
|
|
return await post_service.get_published_posts(db, page=page, per_page=per_page)
|
|
|
|
|
|
@router.get("/{slug}", response_model=PostResponse)
|
|
async def get_post(slug: str, db: AsyncSession = Depends(get_db)):
|
|
"""Get a single published post by slug."""
|
|
post = await post_service.get_post_by_slug(db, slug, published_only=True)
|
|
if post is None:
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Post '{slug}' not found")
|
|
return PostResponse.model_validate(post)
|
|
|
|
|
|
@router.post("", response_model=PostResponse, status_code=status.HTTP_201_CREATED)
|
|
async def create_post(
|
|
data: PostCreate,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
"""Create a new blog post (auth required)."""
|
|
post = await post_service.create_post(db, data)
|
|
return PostResponse.model_validate(post)
|
|
|
|
|
|
@router.put("/{slug}", response_model=PostResponse)
|
|
async def update_post(
|
|
slug: str,
|
|
data: PostUpdate,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
"""Update a post by slug (auth required)."""
|
|
post = await post_service.update_post(db, slug, data)
|
|
if post is None:
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Post '{slug}' not found")
|
|
return PostResponse.model_validate(post)
|
|
|
|
|
|
@router.delete("/{slug}", status_code=status.HTTP_204_NO_CONTENT)
|
|
async def delete_post(
|
|
slug: str,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
"""Delete a post by slug (auth required)."""
|
|
deleted = await post_service.delete_post(db, slug)
|
|
if not deleted:
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Post '{slug}' not found")
|