Added everything
This commit is contained in:
0
src/application/__init__.py
Normal file
0
src/application/__init__.py
Normal file
0
src/application/ports/__init__.py
Normal file
0
src/application/ports/__init__.py
Normal file
46
src/application/ports/report_repository.py
Normal file
46
src/application/ports/report_repository.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from domain.reports import Report
|
||||
from typing import List, Optional
|
||||
|
||||
class ReportRepository(ABC):
|
||||
"""Puerto (interfaz) para el repositorio de Reportes"""
|
||||
|
||||
@abstractmethod
|
||||
def save(self, report: Report) -> Report:
|
||||
"""Guarda un reporte en la base de datos"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_by_id(self, report_id: str) -> Optional[Report]:
|
||||
"""Obtiene un reporte por ID"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_by_user_id(self, user_id: int) -> List[Report]:
|
||||
"""Obtiene todos los reportes de un usuario"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_all(self) -> List[Report]:
|
||||
"""Obtiene todos los reportes"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_by_visibility_range(self, min_visibility: float, max_visibility: float) -> List[Report]:
|
||||
"""Obtiene reportes dentro de un rango de visibilidad"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def update_visibility(self, report_id: str, new_visibility: float) -> None:
|
||||
"""Actualiza la visibilidad de un reporte"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def delete(self, report_id: str) -> bool:
|
||||
"""Elimina un reporte"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_shadowbanned(self, visibility_threshold: float = 20) -> List[Report]:
|
||||
"""Obtiene reportes con baja visibilidad (shadowbaneados)"""
|
||||
pass
|
||||
46
src/application/ports/user_repository.py
Normal file
46
src/application/ports/user_repository.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from domain.users import User
|
||||
from typing import List, Optional
|
||||
|
||||
class UserRepository(ABC):
|
||||
"""Puerto (interfaz) para el repositorio de Usuarios"""
|
||||
|
||||
@abstractmethod
|
||||
def save(self, user: User) -> User:
|
||||
"""Guarda un usuario en la base de datos"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_by_id(self, user_id: int) -> Optional[User]:
|
||||
"""Obtiene un usuario por ID"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_by_email(self, email: str) -> Optional[User]:
|
||||
"""Obtiene un usuario por email"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def find_all(self) -> List[User]:
|
||||
"""Obtiene todos los usuarios"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def update(self, user: User) -> User:
|
||||
"""Actualiza un usuario"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def delete(self, user_id: int) -> bool:
|
||||
"""Elimina un usuario"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def increment_reports(self, user_id: int) -> None:
|
||||
"""Incrementa el contador de reportes de un usuario"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def update_rating(self, user_id: int, new_rating: float) -> None:
|
||||
"""Actualiza la calificación de un usuario"""
|
||||
pass
|
||||
0
src/application/services/__init__.py
Normal file
0
src/application/services/__init__.py
Normal file
115
src/application/services/report_services.py
Normal file
115
src/application/services/report_services.py
Normal file
@@ -0,0 +1,115 @@
|
||||
from domain.reports import Report
|
||||
from application.ports.report_repository import ReportRepository
|
||||
from application.ports.user_repository import UserRepository
|
||||
from datetime import datetime
|
||||
from typing import List, Optional
|
||||
from uuid import uuid4
|
||||
|
||||
class CreateReport:
|
||||
"""Use case para crear un nuevo reporte"""
|
||||
def __init__(self, repo: ReportRepository, user_repo: UserRepository):
|
||||
if not isinstance(repo, ReportRepository):
|
||||
raise TypeError("repo must implement ReportRepository")
|
||||
if not isinstance(user_repo, UserRepository):
|
||||
raise TypeError("user_repo must implement UserRepository")
|
||||
self.repo = repo
|
||||
self.user_repo = user_repo
|
||||
|
||||
def execute(self, id_usuario: int, tipo_reporte: int, descripcion: str,
|
||||
ubicacion: Optional[str] = None) -> Report:
|
||||
# Verificar que el usuario existe
|
||||
user = self.user_repo.find_by_id(id_usuario)
|
||||
if not user:
|
||||
raise ValueError(f"Usuario con ID {id_usuario} no existe")
|
||||
|
||||
report = Report(
|
||||
id_reporte=str(uuid4()),
|
||||
id_usuario=id_usuario,
|
||||
tipo_reporte=tipo_reporte,
|
||||
descripcion=descripcion,
|
||||
ubicacion=ubicacion,
|
||||
visibilidad=50.0, # Visibilidad inicial neutral
|
||||
fecha_creacion=datetime.now()
|
||||
)
|
||||
|
||||
# Incrementar contador de reportes del usuario
|
||||
self.user_repo.increment_reports(id_usuario)
|
||||
|
||||
return self.repo.save(report)
|
||||
|
||||
class GetReportById:
|
||||
"""Use case para obtener un reporte por ID"""
|
||||
def __init__(self, repo: ReportRepository):
|
||||
if not isinstance(repo, ReportRepository):
|
||||
raise TypeError("repo must implement ReportRepository")
|
||||
self.repo = repo
|
||||
|
||||
def execute(self, report_id: str) -> Optional[Report]:
|
||||
return self.repo.find_by_id(report_id)
|
||||
|
||||
class GetReportsByUser:
|
||||
"""Use case para obtener todos los reportes de un usuario"""
|
||||
def __init__(self, repo: ReportRepository):
|
||||
if not isinstance(repo, ReportRepository):
|
||||
raise TypeError("repo must implement ReportRepository")
|
||||
self.repo = repo
|
||||
|
||||
def execute(self, user_id: int) -> List[Report]:
|
||||
return self.repo.find_by_user_id(user_id)
|
||||
|
||||
class ListAllReports:
|
||||
"""Use case para obtener todos los reportes"""
|
||||
def __init__(self, repo: ReportRepository):
|
||||
if not isinstance(repo, ReportRepository):
|
||||
raise TypeError("repo must implement ReportRepository")
|
||||
self.repo = repo
|
||||
|
||||
def execute(self) -> List[Report]:
|
||||
return self.repo.find_all()
|
||||
|
||||
class UpdateReportVisibility:
|
||||
"""Use case para actualizar la visibilidad de un reporte basado en votación comunitaria"""
|
||||
def __init__(self, repo: ReportRepository, user_repo: UserRepository):
|
||||
if not isinstance(repo, ReportRepository):
|
||||
raise TypeError("repo must implement ReportRepository")
|
||||
self.repo = repo
|
||||
self.user_repo = user_repo
|
||||
|
||||
def execute(self, report_id: str, new_visibility: float, penalize_author: bool = False) -> None:
|
||||
# Validar rango de visibilidad
|
||||
if new_visibility < 0 or new_visibility > 100:
|
||||
raise ValueError("La visibilidad debe estar entre 0 y 100")
|
||||
|
||||
report = self.repo.find_by_id(report_id)
|
||||
if not report:
|
||||
raise ValueError(f"Reporte con ID {report_id} no existe")
|
||||
|
||||
self.repo.update_visibility(report_id, new_visibility)
|
||||
|
||||
# Si la visibilidad es muy baja (shadowban), penalizar al autor
|
||||
if penalize_author and new_visibility < 20:
|
||||
user = self.user_repo.find_by_id(report.id_usuario)
|
||||
if user:
|
||||
# Reducir calificación del usuario
|
||||
new_rating = max(0, user.calificacion - 5)
|
||||
self.user_repo.update_rating(report.id_usuario, new_rating)
|
||||
|
||||
class GetShadowbannedReports:
|
||||
"""Use case para obtener reportes shadowbaneados (baja visibilidad)"""
|
||||
def __init__(self, repo: ReportRepository):
|
||||
if not isinstance(repo, ReportRepository):
|
||||
raise TypeError("repo must implement ReportRepository")
|
||||
self.repo = repo
|
||||
|
||||
def execute(self, visibility_threshold: float = 20) -> List[Report]:
|
||||
return self.repo.find_shadowbanned(visibility_threshold)
|
||||
|
||||
class DeleteReport:
|
||||
"""Use case para eliminar un reporte"""
|
||||
def __init__(self, repo: ReportRepository):
|
||||
if not isinstance(repo, ReportRepository):
|
||||
raise TypeError("repo must implement ReportRepository")
|
||||
self.repo = repo
|
||||
|
||||
def execute(self, report_id: str) -> bool:
|
||||
return self.repo.delete(report_id)
|
||||
90
src/application/services/user_services.py
Normal file
90
src/application/services/user_services.py
Normal file
@@ -0,0 +1,90 @@
|
||||
from domain.users import User
|
||||
from application.ports.user_repository import UserRepository
|
||||
from datetime import datetime
|
||||
from typing import List, Optional
|
||||
|
||||
class CreateUser:
|
||||
"""Use case para crear un nuevo usuario"""
|
||||
def __init__(self, repo: UserRepository):
|
||||
if not isinstance(repo, UserRepository):
|
||||
raise TypeError("repo must implement UserRepository")
|
||||
self.repo = repo
|
||||
|
||||
def execute(self, nombre: str, apellido: str, email: str,
|
||||
fecha_nacimiento: datetime, url_foto_perfil: Optional[str] = None,
|
||||
biografia: Optional[str] = None) -> User:
|
||||
user = User(
|
||||
user_id=0,
|
||||
nombre=nombre,
|
||||
apellido=apellido,
|
||||
email=email,
|
||||
fecha_nacimiento=fecha_nacimiento,
|
||||
fecha_creacion=datetime.now(),
|
||||
calificacion=50.0, # Puntuación inicial
|
||||
numero_reportes=0,
|
||||
url_foto_perfil=url_foto_perfil,
|
||||
biografia=biografia
|
||||
)
|
||||
return self.repo.save(user)
|
||||
|
||||
class GetUserById:
|
||||
"""Use case para obtener un usuario por ID"""
|
||||
def __init__(self, repo: UserRepository):
|
||||
if not isinstance(repo, UserRepository):
|
||||
raise TypeError("repo must implement UserRepository")
|
||||
self.repo = repo
|
||||
|
||||
def execute(self, user_id: int) -> Optional[User]:
|
||||
return self.repo.find_by_id(user_id)
|
||||
|
||||
class GetUserByEmail:
|
||||
"""Use case para obtener un usuario por email"""
|
||||
def __init__(self, repo: UserRepository):
|
||||
if not isinstance(repo, UserRepository):
|
||||
raise TypeError("repo must implement UserRepository")
|
||||
self.repo = repo
|
||||
|
||||
def execute(self, email: str) -> Optional[User]:
|
||||
return self.repo.find_by_email(email)
|
||||
|
||||
class ListAllUsers:
|
||||
"""Use case para obtener todos los usuarios"""
|
||||
def __init__(self, repo: UserRepository):
|
||||
if not isinstance(repo, UserRepository):
|
||||
raise TypeError("repo must implement UserRepository")
|
||||
self.repo = repo
|
||||
|
||||
def execute(self) -> List[User]:
|
||||
return self.repo.find_all()
|
||||
|
||||
class UpdateUser:
|
||||
"""Use case para actualizar un usuario"""
|
||||
def __init__(self, repo: UserRepository):
|
||||
if not isinstance(repo, UserRepository):
|
||||
raise TypeError("repo must implement UserRepository")
|
||||
self.repo = repo
|
||||
|
||||
def execute(self, user_id: int, nombre: str = None, apellido: str = None,
|
||||
url_foto_perfil: str = None, biografia: str = None) -> Optional[User]:
|
||||
user = self.repo.find_by_id(user_id)
|
||||
if user:
|
||||
if nombre:
|
||||
user.nombre = nombre
|
||||
if apellido:
|
||||
user.apellido = apellido
|
||||
if url_foto_perfil is not None:
|
||||
user.url_foto_perfil = url_foto_perfil
|
||||
if biografia is not None:
|
||||
user.biografia = biografia
|
||||
return self.repo.update(user)
|
||||
return None
|
||||
|
||||
class DeleteUser:
|
||||
"""Use case para eliminar un usuario"""
|
||||
def __init__(self, repo: UserRepository):
|
||||
if not isinstance(repo, UserRepository):
|
||||
raise TypeError("repo must implement UserRepository")
|
||||
self.repo = repo
|
||||
|
||||
def execute(self, user_id: int) -> bool:
|
||||
return self.repo.delete(user_id)
|
||||
Reference in New Issue
Block a user