4.9 KiB
4.9 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 usuariosstaff: Préstamos/devolucionesviewer: 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_aten 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)