149 lines
4.9 KiB
Markdown
149 lines
4.9 KiB
Markdown
# 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)
|