diff --git a/api/v1/models/__init__.py b/api/v1/models/__init__.py index a39ec4bae..a38b3358e 100644 --- a/api/v1/models/__init__.py +++ b/api/v1/models/__init__.py @@ -32,5 +32,5 @@ from api.v1.models.faq_inquiries import FAQInquiries from api.v1.models.wishlist import Wishlist from api.v1.models.totp_device import TOTPDevice +from api.v1.models.report import Report from api.v1.models.bookmark import Bookmark - diff --git a/api/v1/models/report.py b/api/v1/models/report.py new file mode 100644 index 000000000..0c069bd83 --- /dev/null +++ b/api/v1/models/report.py @@ -0,0 +1,18 @@ +from sqlalchemy import Column, String, Text, ForeignKey, Enum as SqlAlchemyEnum +from api.v1.models.base_model import BaseTableModel +from enum import Enum + + +class ReportStatusEnum(Enum): + resolved = "resolved" + pending = "pending" + + +class Report(BaseTableModel): + + __tablename__ = "reports" + + reported_by = Column(String, ForeignKey("users.id", ondelete="CASCADE"), nullable=False) + reported_user = Column(String, ForeignKey("users.id", ondelete="CASCADE"), nullable=False) + reason = Column(String, nullable=False) + status = Column(SqlAlchemyEnum(ReportStatusEnum), default=ReportStatusEnum.pending) diff --git a/api/v1/routes/__init__.py b/api/v1/routes/__init__.py index fdd167d85..4d7407841 100644 --- a/api/v1/routes/__init__.py +++ b/api/v1/routes/__init__.py @@ -46,6 +46,7 @@ from api.v1.routes.settings import settings from api.v1.routes.terms_and_conditions import terms_and_conditions from api.v1.routes.stripe import subscription_ +from api.v1.routes.report import report from api.v1.routes.wishlist import wishlist api_version_one = APIRouter(prefix="/api/v1") @@ -97,4 +98,5 @@ api_version_one.include_router(terms_and_conditions) api_version_one.include_router(product_comment) api_version_one.include_router(subscription_) +api_version_one.include_router(report) api_version_one.include_router(wishlist) diff --git a/api/v1/routes/report.py b/api/v1/routes/report.py new file mode 100644 index 000000000..a956dc5fa --- /dev/null +++ b/api/v1/routes/report.py @@ -0,0 +1,51 @@ +from api.v1.models.report import Report +from api.v1.schemas.report import ReportCreateSchema, ReportResponseSchema +from fastapi import Depends, APIRouter, HTTPException, status, Request +from sqlalchemy.orm import Session +from api.db.database import get_db +from api.utils.logger import logger +from api.utils.success_response import success_response +from api.v1.models.user import User +from api.v1.services.user import user_service +from api.v1.services.report import report_service +from fastapi.encoders import jsonable_encoder + + + +report = APIRouter(prefix="/reports", tags=["Reports"]) + +@report.post("", response_model=success_response, status_code=status.HTTP_201_CREATED) +def create_report(report_request: ReportCreateSchema, reported_by: User = Depends(user_service.get_current_user), db: Session = Depends(get_db)): + + reported_user = user_service.get_user_by_id(db, report_request.reported_user) + + + if (reported_by.id == reported_user.id): + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="User cannot report itself") + + reason = report_request.reason + + if (len(reason) == 0): + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="reason user been reported cannot be empty") + + report = report_service.create(db, report_request, reported_by.id) + + return success_response( + status_code=status.HTTP_201_CREATED, + message="report successfully created", + data=jsonable_encoder(report) + ) + +@report.get("", response_model=success_response, status_code=status.HTTP_200_OK) +def get_all_report(admin_user: User = Depends(user_service.get_current_super_admin), db: Session = Depends(get_db)): + + reports = report_service.fetch_all(db) + + if not reports: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="No report Found") + + return success_response( + status_code=status.HTTP_200_OK, + message="Report retrieced successfully", + data=jsonable_encoder(reports) + ) \ No newline at end of file diff --git a/api/v1/schemas/report.py b/api/v1/schemas/report.py new file mode 100644 index 000000000..d13a9da6b --- /dev/null +++ b/api/v1/schemas/report.py @@ -0,0 +1,17 @@ +from pydantic import BaseModel +from datetime import datetime + + + +class ReportCreateSchema(BaseModel): + reported_user: str + reason: str + + +class ReportResponseSchema(BaseModel): + reported_by: str + reported_user: str + reason: str + status: str + created_at: datetime + updated_at: datetime diff --git a/api/v1/services/report.py b/api/v1/services/report.py new file mode 100644 index 000000000..e0941d83c --- /dev/null +++ b/api/v1/services/report.py @@ -0,0 +1,66 @@ +from typing import Any, Optional, List +from sqlalchemy.orm import Session +from api.core.base.services import Service +from api.v1.models.report import Report +from api.v1.schemas.report import ReportCreateSchema, ReportResponseSchema +from api.utils.db_validators import check_model_existence +from sqlalchemy import distinct +from fastapi import HTTPException + + +class ReportService(Service): + """Report Services""" + + def create(self, db: Session, schema: ReportCreateSchema, user_id: str): + '''Create a new Region''' + new_report = Report(**schema.model_dump(), reported_by=user_id) + db.add(new_report) + db.commit() + db.refresh(new_report) + + return new_report + + + def fetch_all(self, db: Session, **query_params: Optional[Any]): + '''Fetch all Region with option to search using query parameters''' + + query = db.query(Report) + + # Enable filter by query parameter + if query_params: + for column, value in query_params.items(): + if hasattr(Report, column) and value: + query = query.filter(getattr(Report, column).ilike(f'%{value}%')) + + return query.all() + + + def fetch(self, db: Session, report_id: str): + '''Fetches a Region by id''' + + report = check_model_existence(db, Report, report_id) + return report + + + def update(self, db: Session, report_id: str): + '''Updates a Region''' + + region = self.fetch(db=db, report_id=report_id) + + # Update the fields with the provided schema data + + db.commit() + db.refresh(region) + return region + + + def delete(self, db: Session, report_id: str): + '''Deletes a region service''' + + report = self.fetch(db=db, report_id=report_id) + db.delete(report) + db.commit() + + + +report_service = ReportService()