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
+3 -1
View File
@@ -8,6 +8,7 @@ from .reservation import Reservation, ReservationStatus
from .genetic_algorithm import GeneticAlgorithm, ReservationOptimizer
from .role import Role, Permission, SYSTEM_MODULES
from .milestone import MilestoneType, AcademicMilestone, BASE_MILESTONE_TYPES
from .audit_log import AuditLog
__all__ = [
'User',
@@ -27,5 +28,6 @@ __all__ = [
'SYSTEM_MODULES',
'MilestoneType',
'AcademicMilestone',
'BASE_MILESTONE_TYPES'
'BASE_MILESTONE_TYPES',
'AuditLog'
]
+25
View File
@@ -0,0 +1,25 @@
from app import db
from datetime import datetime
class AuditLog(db.Model):
"""
Bitácora inmutable de auditoría para registro de eventos críticos
y trazabilidad de operaciones institucionales.
"""
__tablename__ = 'audit_logs'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='SET NULL'), nullable=True)
user_email = db.Column(db.String(255), nullable=True)
action = db.Column(db.String(50), nullable=False, index=True) # CREATE, UPDATE, DELETE, LOGIN, LOGOUT
module = db.Column(db.String(50), nullable=False, index=True) # classrooms, reservations, auth, users
entity_id = db.Column(db.Integer, nullable=True) # ID del registro afectado
details = db.Column(db.Text, nullable=True) # Detalles de cambios o parámetros
ip_address = db.Column(db.String(45), nullable=True) # Soporta IPv4 e IPv6
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False, index=True)
# Relación con usuario
user = db.relationship('User', foreign_keys=[user_id], backref=db.backref('audit_records', lazy='dynamic'))
def __repr__(self):
return f"<AuditLog #{self.id} {self.action} on {self.module} by {self.user_email or 'System'}>"