GestionTablets/TECHNICAL_SPECIFICATIONS.md
ijuanes 1ad0e8bf13 docs: add PostgreSQL migration guide for future scalability
- Add section 9 to TECHNICAL_SPECIFICATIONS.md with:
  - Migration criteria (DB size, connections, users, transactions)
  - Proposed repository pattern architecture
  - Migration steps overview
  - Benefits of PostgreSQL

- Create docs/MIGRATION_TO_POSTGRES.md with comprehensive guide:
  - When to migrate (detailed thresholds)
  - Architecture overview (repository pattern)
  - Step-by-step migration process (10 steps)
  - Complete code examples:
    * Base repository interfaces
    * SQLite implementation
    * PostgreSQL implementation
    * Repository factory
    * Migration script
  - Docker Compose configuration
  - Rollback plan
  - Monitoring and maintenance
  - Performance optimization
  - Troubleshooting guide

This enables future migration when database grows beyond SQLite capabilities.
2026-06-17 17:22:50 +01:00

6.4 KiB

Especificaciones Técnicas

Documento complementario a REQUIREMENTS.md con propuestas concretas de implementación técnica.


1. Concurrencia en Base de Datos

Opción Descripción Ventajas Desventajas
SQLite + WAL Modo Write-Ahead Logging Zero-config, embebido, buena para <100 conexiones Limitado a 1 escritor simultáneo
PostgreSQL Base de datos relacional Concurrencia completa, transacciones ACID Requiere servidor
Transacciones Aislamiento READ COMMITTED Previene lecturas sucias Bloqueos temporales
Locking optimista Versión de fila en actualizaciones Sin bloqueos Conflictos requieren reintento

Recomendación: SQLite con WAL para prototipos, PostgreSQL para producción. Usar transacciones para operaciones críticas (préstamo/devolución).


2. Autenticación Básica

Opción Descripción Complejidad
Sesiones (Flask) Cookies firmadas Baja
JWT Tokens sin estado Media
OAuth 2.0 Delegación a proveedores Alta
Basic Auth HTTP Basic Authentication Mínima

Flujo mínimo:

Login (user/pass) → Session/JWT → Middleware verifica rol → Acceso a endpoints

Roles sugeridos:

  • admin: CRUD completo, gestión de usuarios
  • staff: Préstamos/devoluciones
  • viewer: Solo consulta

3. Separación Frontend/Backend

Arquitectura Descripción Stack Ejemplo
Monolítica + Templates Servidor renderiza HTML Flask+Jinja2, Django
API + SPA Backend API, frontend dinámico FastAPI + React/Vue
API + SSR Backend API + renderizado servidor Next.js + API
Microservicios Servicios independientes Backend API + Frontend estático

Para este proyecto:

  • Opción A: Flask + Jinja2 (simple, suficiente para requisitos)
  • Opción B: FastAPI + React (escalable, separable)

4. Búsqueda Eficiente (500+ elementos)

Opción Descripción Implementación
Índices DB B-tree en columnas buscadas CREATE INDEX idx_brand ON tablets(brand)
Búsqueda full-text Búsqueda en texto SQLite FTS5, PostgreSQL tsvector
Filtrado cliente JavaScript filtra datos Ideal para <2000 elementos
Paginación Dividir resultados LIMIT 50 OFFSET 0

Recomendación: Índices en serial_number, brand, model, user.name, user.identification.


5. Estructura de Proyecto Propuesta

project/
├── backend/
│   ├── models/          # Entidades (Device, User, Loan)
│   ├── services/        # Lógica de negocio
│   ├── repositories/    # Acceso a datos
│   ├── routes/          # Endpoints/API
│   └── app.py           # Configuración
├── frontend/           # Opcional para opción B
│   ├── public/
│   └── src/
├── migrations/         # Control de cambios DB
├── tests/
└── docs/

6. Decisiones Clave por Tomar

Decisión Opciones Impacto
Base de datos SQLite / PostgreSQL Concurrencia, despliegue
Autenticación Sesiones / JWT / Ninguna Seguridad, complejidad
Frontend Templates / SPA / Ninguno Experiencia usuario
Despliegue Local / Docker / Cloud Escalabilidad

7. Ejemplo de Implementación Mínima (Pseudocódigo)

# modelos.py
class Device:
    id: int (PK)
    serial_number: str (unique)
    status: str (available/loaned)
    loans: List[Loan] (one-to-many)

class User:
    id: int (PK)
    identification: str (unique)
    loans: List[Loan] (one-to-many)

class Loan:
    id: int (PK)
    device_id: int (FK)
    user_id: int (FK)
    loan_date: datetime
    return_date: datetime (nullable)
    status: str (active/returned)

# servicios/loan_service.py
def loan_device(device_id: int, user_id: int) -> Loan:
    with transaction():  # Atomicidad
        device = get_device_for_update(device_id)
        if device.status != 'available':
            raise DeviceNotAvailableError()
        
        loan = Loan.create(
            device_id=device_id,
            user_id=user_id,
            loan_date=now(),
            status='active'
        )
        device.status = 'loaned'
        return loan

8. Consideraciones Adicionales

  • Validaciones: Únicas (serial_number, identification) a nivel de base de datos
  • Auditoría: Campos created_at, updated_at en todas las entidades
  • Backups: Script para exportar base de datos periódicamente
  • Logging: Registrar préstamos/devoluciones para auditoría
  • Versionado API: /api/v1/... para compatibilidad futura
  • Pruebas: Cubrir flujos críticos (préstamo con dispositivo no disponible, devolución de préstamo inexistente)

9. Migración a PostgreSQL (Futuro)

Contexto

El sistema actualmente utiliza SQLite como base de datos embebida, ideal para prototipos y aplicaciones pequeñas. Sin embargo, SQLite tiene limitaciones para escalar.

Criterios para Migración

Considerar migrar a PostgreSQL cuando:

  • Tamaño DB > 1GB
  • Más de 50 conexiones simultáneas
  • Más de 200 usuarios activos
  • Más de 500 transacciones por minuto
  • Necesidad de múltiples servidores

Arquitectura Propuesta

Usar un patrón de Repository para abstraer la base de datos:

backend/
├── repositories/
│   ├── base_repository.py       # Interfaz abstracta
│   ├── sqlite_repository.py     # Implementación SQLite
│   └── postgres_repository.py   # Implementación PostgreSQL
└── config/
    └── database.py              # Fábrica de repositorios

Schema PostgreSQL

El schema es similar al de SQLite pero con tipos de datos más específicos y índices adicionales para rendimiento.

Pasos para Migración

  1. Instalar dependencias: pip install psycopg2-binary sqlalchemy alembic
  2. Configurar PostgreSQL y crear base de datos
  3. Ejecutar script de migración: python scripts/migrate_to_postgres.py
  4. Cambiar configuración: DB_TYPE=postgres
  5. Iniciar aplicación

Beneficios

  • Concurrencia ilimitada (múltiples escritores)
  • Escalabilidad a miles de conexiones
  • Mejor rendimiento con índices
  • Seguridad integrada (autenticación, roles)
  • Backups automáticos
  • Replicación y clustering