
- Complete FastAPI application with authentication and JWT tokens - SQLite database with SQLAlchemy ORM and Alembic migrations - User management with profile features and search functionality - LinkedIn-style networking with connection requests and acceptance - Social features: posts, likes, comments, announcements, prayer requests - Event management with registration system and capacity limits - RESTful API endpoints for all features with proper authorization - Comprehensive documentation and setup instructions Key Features: - JWT-based authentication with bcrypt password hashing - User profiles with bio, position, contact information - Connection system for church member networking - Community feed with post interactions - Event creation, registration, and attendance tracking - Admin role-based permissions - Health check endpoint and API documentation Environment Variables Required: - SECRET_KEY: JWT secret key for token generation
203 lines
5.7 KiB
Python
203 lines
5.7 KiB
Python
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy.orm import Session
|
|
from typing import List
|
|
from app.db.base import get_db
|
|
from app.models.user import User
|
|
from app.models.post import Post, Comment, Like
|
|
from app.schemas.post import (
|
|
PostCreate,
|
|
PostUpdate,
|
|
PostResponse,
|
|
CommentCreate,
|
|
CommentResponse,
|
|
)
|
|
from app.api.auth import get_current_user
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post("/", response_model=PostResponse)
|
|
def create_post(
|
|
post: PostCreate,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
db_post = Post(**post.dict(), author_id=current_user.id)
|
|
db.add(db_post)
|
|
db.commit()
|
|
db.refresh(db_post)
|
|
|
|
db_post.author_name = f"{current_user.first_name} {current_user.last_name}"
|
|
db_post.likes_count = 0
|
|
db_post.comments_count = 0
|
|
|
|
return db_post
|
|
|
|
|
|
@router.get("/", response_model=List[PostResponse])
|
|
def get_posts(
|
|
skip: int = 0,
|
|
limit: int = 100,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
posts = (
|
|
db.query(Post).order_by(Post.created_at.desc()).offset(skip).limit(limit).all()
|
|
)
|
|
|
|
for post in posts:
|
|
post.author_name = f"{post.author.first_name} {post.author.last_name}"
|
|
post.likes_count = db.query(Like).filter(Like.post_id == post.id).count()
|
|
post.comments_count = (
|
|
db.query(Comment).filter(Comment.post_id == post.id).count()
|
|
)
|
|
|
|
return posts
|
|
|
|
|
|
@router.get("/{post_id}", response_model=PostResponse)
|
|
def get_post(
|
|
post_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
post = db.query(Post).filter(Post.id == post_id).first()
|
|
if not post:
|
|
raise HTTPException(status_code=404, detail="Post not found")
|
|
|
|
post.author_name = f"{post.author.first_name} {post.author.last_name}"
|
|
post.likes_count = db.query(Like).filter(Like.post_id == post.id).count()
|
|
post.comments_count = db.query(Comment).filter(Comment.post_id == post.id).count()
|
|
|
|
return post
|
|
|
|
|
|
@router.put("/{post_id}", response_model=PostResponse)
|
|
def update_post(
|
|
post_id: int,
|
|
post_update: PostUpdate,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
post = db.query(Post).filter(Post.id == post_id).first()
|
|
if not post:
|
|
raise HTTPException(status_code=404, detail="Post not found")
|
|
|
|
if post.author_id != current_user.id and not current_user.is_admin:
|
|
raise HTTPException(
|
|
status_code=403, detail="Not authorized to update this post"
|
|
)
|
|
|
|
for field, value in post_update.dict(exclude_unset=True).items():
|
|
setattr(post, field, value)
|
|
|
|
db.commit()
|
|
db.refresh(post)
|
|
return post
|
|
|
|
|
|
@router.delete("/{post_id}")
|
|
def delete_post(
|
|
post_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
post = db.query(Post).filter(Post.id == post_id).first()
|
|
if not post:
|
|
raise HTTPException(status_code=404, detail="Post not found")
|
|
|
|
if post.author_id != current_user.id and not current_user.is_admin:
|
|
raise HTTPException(
|
|
status_code=403, detail="Not authorized to delete this post"
|
|
)
|
|
|
|
db.delete(post)
|
|
db.commit()
|
|
return {"message": "Post deleted successfully"}
|
|
|
|
|
|
@router.post("/{post_id}/like")
|
|
def like_post(
|
|
post_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
post = db.query(Post).filter(Post.id == post_id).first()
|
|
if not post:
|
|
raise HTTPException(status_code=404, detail="Post not found")
|
|
|
|
existing_like = (
|
|
db.query(Like)
|
|
.filter(Like.post_id == post_id, Like.user_id == current_user.id)
|
|
.first()
|
|
)
|
|
if existing_like:
|
|
raise HTTPException(status_code=400, detail="Already liked this post")
|
|
|
|
like = Like(post_id=post_id, user_id=current_user.id)
|
|
db.add(like)
|
|
db.commit()
|
|
return {"message": "Post liked successfully"}
|
|
|
|
|
|
@router.delete("/{post_id}/like")
|
|
def unlike_post(
|
|
post_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
like = (
|
|
db.query(Like)
|
|
.filter(Like.post_id == post_id, Like.user_id == current_user.id)
|
|
.first()
|
|
)
|
|
if not like:
|
|
raise HTTPException(status_code=404, detail="Like not found")
|
|
|
|
db.delete(like)
|
|
db.commit()
|
|
return {"message": "Post unliked successfully"}
|
|
|
|
|
|
@router.post("/{post_id}/comments", response_model=CommentResponse)
|
|
def create_comment(
|
|
post_id: int,
|
|
comment: CommentCreate,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
post = db.query(Post).filter(Post.id == post_id).first()
|
|
if not post:
|
|
raise HTTPException(status_code=404, detail="Post not found")
|
|
|
|
db_comment = Comment(**comment.dict(), post_id=post_id, author_id=current_user.id)
|
|
db.add(db_comment)
|
|
db.commit()
|
|
db.refresh(db_comment)
|
|
|
|
db_comment.author_name = f"{current_user.first_name} {current_user.last_name}"
|
|
return db_comment
|
|
|
|
|
|
@router.get("/{post_id}/comments", response_model=List[CommentResponse])
|
|
def get_comments(
|
|
post_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
post = db.query(Post).filter(Post.id == post_id).first()
|
|
if not post:
|
|
raise HTTPException(status_code=404, detail="Post not found")
|
|
|
|
comments = (
|
|
db.query(Comment)
|
|
.filter(Comment.post_id == post_id)
|
|
.order_by(Comment.created_at.asc())
|
|
.all()
|
|
)
|
|
|
|
for comment in comments:
|
|
comment.author_name = f"{comment.author.first_name} {comment.author.last_name}"
|
|
|
|
return comments
|