feat(roadmap): implementar Sprints 1, 2 y 3 (MVC, Stateless JWT API y Spring Security)

This commit is contained in:
Carlos Tello
2026-09-05 01:46:57 -03:00
parent fa878cb0d5
commit 69b8b7ccef
34 changed files with 1750 additions and 21 deletions
+59
View File
@@ -0,0 +1,59 @@
from typing import Optional, List
from sqlalchemy import func
from app.models.classroom import Classroom
from app.repositories.base_repository import BaseRepository
from app import db
class ClassroomRepository(BaseRepository[Classroom]):
"""Repositorio especializado en operaciones de persistencia y filtrado de aulas."""
def __init__(self):
super().__init__(Classroom)
def get_by_code_and_building(self, building_id: int, code: str, floor: str) -> Optional[Classroom]:
"""Busca un aula por edificio, código y piso para verificar duplicados."""
return Classroom.query.filter_by(
building_id=building_id,
code=code.strip(),
floor=str(floor).strip()
).first()
def get_active_classrooms(self, building_id: Optional[int] = None, floor: Optional[str] = None,
only_virtual: bool = False, only_physical: bool = False) -> List[Classroom]:
"""Retorna aulas activas con filtros opcionales de edificio, piso y modalidad."""
query = Classroom.query.filter_by(is_active=True)
if building_id:
query = query.filter_by(building_id=building_id)
if floor:
query = query.filter_by(floor=str(floor).strip())
classrooms = query.order_by(Classroom.floor.asc(), Classroom.code.asc()).all()
if only_virtual:
return [c for c in classrooms if c.is_virtual]
elif only_physical:
return [c for c in classrooms if not c.is_virtual]
return classrooms
def get_virtual_classrooms(self) -> List[Classroom]:
"""Obtiene todas las salas virtuales activas."""
return [c for c in self.get_active_classrooms() if c.is_virtual]
def get_physical_classrooms(self) -> List[Classroom]:
"""Obtiene todas las aulas físicas activas."""
return [c for c in self.get_active_classrooms() if not c.is_virtual]
def search(self, term: str) -> List[Classroom]:
"""Búsqueda de aulas por código, edificio o descripción."""
if not term:
return self.get_all(order_by=Classroom.code.asc())
term_clean = f"%{term.strip()}%"
return Classroom.query.filter(
Classroom.is_active == True,
(Classroom.code.ilike(term_clean)) |
(Classroom.building.ilike(term_clean)) |
(Classroom.description.ilike(term_clean))
).order_by(Classroom.code.asc()).all()