
Complete rewrite from task management to full-featured chat system: Core Features: - Real-time WebSocket messaging with connection management - Direct messages and group chats with admin controls - Message types: text, images, videos, audio, documents - Message status tracking: sent, delivered, read receipts - Typing indicators and user presence (online/offline) - Message replies, editing, and deletion Security & Encryption: - End-to-end encryption with RSA + AES hybrid approach - JWT authentication for API and WebSocket connections - Secure file storage with access control - Automatic RSA key pair generation per user Media & File Sharing: - Multi-format file upload (images, videos, audio, documents) - Automatic thumbnail generation for images/videos - File size validation and MIME type checking - Secure download endpoints with permission checks Notifications & Alerts: - Real-time WebSocket notifications - Push notifications via Firebase integration - @username mention alerts with notification history - Unread message and mention counting - Custom notification types (message, mention, group invite) Advanced Features: - Group chat management with roles (member, admin, owner) - User search and chat member management - Message pagination and chat history - Last seen timestamps and activity tracking - Comprehensive API documentation with WebSocket events Architecture: - Clean layered architecture with services, models, schemas - WebSocket connection manager for real-time features - Modular notification system with multiple channels - Comprehensive error handling and validation - Production-ready with Docker support Technologies: FastAPI, WebSocket, SQLAlchemy, SQLite, Cryptography, Firebase, Pillow
112 lines
3.3 KiB
Python
112 lines
3.3 KiB
Python
from typing import List
|
|
from fastapi import APIRouter, Depends, Query
|
|
from sqlalchemy.orm import Session
|
|
from app.db.session import get_db
|
|
from app.core.deps import get_current_active_user
|
|
from app.models.user import User
|
|
from app.services.notification_service import notification_service
|
|
from pydantic import BaseModel
|
|
|
|
router = APIRouter()
|
|
|
|
class NotificationResponse(BaseModel):
|
|
id: int
|
|
type: str
|
|
title: str
|
|
body: str
|
|
data: dict
|
|
is_read: bool
|
|
created_at: str
|
|
read_at: str = None
|
|
|
|
class MentionResponse(BaseModel):
|
|
id: int
|
|
message_id: int
|
|
chat_id: int
|
|
chat_name: str
|
|
sender_username: str
|
|
message_content: str
|
|
created_at: str
|
|
|
|
@router.get("/", response_model=List[NotificationResponse])
|
|
def get_notifications(
|
|
unread_only: bool = Query(False),
|
|
limit: int = Query(50, ge=1, le=100),
|
|
offset: int = Query(0, ge=0),
|
|
current_user: User = Depends(get_current_active_user)
|
|
):
|
|
"""Get user notifications"""
|
|
notifications = notification_service.get_user_notifications(
|
|
user_id=current_user.id,
|
|
unread_only=unread_only,
|
|
limit=limit,
|
|
offset=offset
|
|
)
|
|
|
|
return [NotificationResponse(**notif) for notif in notifications]
|
|
|
|
@router.get("/mentions", response_model=List[MentionResponse])
|
|
def get_unread_mentions(
|
|
current_user: User = Depends(get_current_active_user)
|
|
):
|
|
"""Get unread mentions for user"""
|
|
mentions = notification_service.get_unread_mentions(current_user.id)
|
|
return [MentionResponse(**mention) for mention in mentions]
|
|
|
|
@router.post("/{notification_id}/read")
|
|
async def mark_notification_read(
|
|
notification_id: int,
|
|
current_user: User = Depends(get_current_active_user)
|
|
):
|
|
"""Mark notification as read"""
|
|
await notification_service.mark_notification_read(notification_id, current_user.id)
|
|
return {"message": "Notification marked as read"}
|
|
|
|
@router.post("/mentions/{mention_id}/read")
|
|
async def mark_mention_read(
|
|
mention_id: int,
|
|
current_user: User = Depends(get_current_active_user)
|
|
):
|
|
"""Mark mention as read"""
|
|
await notification_service.mark_mention_read(mention_id, current_user.id)
|
|
return {"message": "Mention marked as read"}
|
|
|
|
@router.post("/read-all")
|
|
async def mark_all_notifications_read(
|
|
current_user: User = Depends(get_current_active_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""Mark all notifications as read"""
|
|
from app.models.notification import Notification
|
|
from datetime import datetime
|
|
|
|
db.query(Notification).filter(
|
|
Notification.user_id == current_user.id,
|
|
Notification.is_read.is_(False)
|
|
).update({
|
|
"is_read": True,
|
|
"read_at": datetime.utcnow()
|
|
})
|
|
|
|
db.commit()
|
|
|
|
return {"message": "All notifications marked as read"}
|
|
|
|
@router.get("/count")
|
|
def get_notification_count(
|
|
current_user: User = Depends(get_current_active_user)
|
|
):
|
|
"""Get unread notification count"""
|
|
notifications = notification_service.get_user_notifications(
|
|
user_id=current_user.id,
|
|
unread_only=True,
|
|
limit=1000
|
|
)
|
|
|
|
mentions = notification_service.get_unread_mentions(current_user.id)
|
|
|
|
return {
|
|
"unread_notifications": len(notifications),
|
|
"unread_mentions": len(mentions),
|
|
"total_unread": len(notifications) + len(mentions)
|
|
} |