GestionTablets/TECHNICAL_SPECIFICATIONS.md

150 lines
4.9 KiB
Markdown
Raw Normal View History

# 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)
```python
# 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)