From ee849eb9a8dbe0d07f9a305bf613743d8253bf02 Mon Sep 17 00:00:00 2001 From: pikaos Date: Mon, 3 Aug 2026 01:34:56 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20roadmap=20y=20dise=C3=B1o=20inicial=20?= =?UTF-8?q?=E2=80=94=20iteraci=C3=B3n=201=20antes=20de=20feedback=20del=20?= =?UTF-8?q?usuario?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inventario de dispositivos electrónicos no prestables para administración pública. Esta primera iteración contiene el diseño y la planificación antes de contactar con el usuario para su validación. Contenido: - especificaciones.md: requisitos detallados del programa - docs/arquitectura.md: propuesta de arquitectura con alternativas - docs/roadmap-iteracion-1.md: plan de desarrollo iteración 1 - docs/arquitectura-diagrama.html: diagrama visual de arquitectura - sketches/: mockups de las 4 pantallas principales - 001-dashboard: vista resumen - 002-inventario: tabla de dispositivos - 003-formulario: alta/edición de dispositivos - 004-configuracion: ajustes generales Stack propuesto: Python + Flask + SQLite + Alpine.js Distribución: PyInstaller → un único .exe autocontenido Entorno: Windows 11 Pro unida a dominio, sin privilegios de admin --- .gitignore | 65 ++ README.md | 72 +++ docs/arquitectura-diagrama.html | 342 +++++++++++ docs/arquitectura.md | 411 +++++++++++++ docs/roadmap-iteracion-1.md | 184 ++++++ especificaciones.md | 836 ++++++++++++++++++++++++++ sketches/001-dashboard/README.md | 18 + sketches/001-dashboard/index.html | 526 ++++++++++++++++ sketches/002-inventario/README.md | 18 + sketches/002-inventario/index.html | 403 +++++++++++++ sketches/003-formulario/README.md | 19 + sketches/003-formulario/index.html | 351 +++++++++++ sketches/004-configuracion/README.md | 20 + sketches/004-configuracion/index.html | 496 +++++++++++++++ 14 files changed, 3761 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 docs/arquitectura-diagrama.html create mode 100644 docs/arquitectura.md create mode 100644 docs/roadmap-iteracion-1.md create mode 100644 especificaciones.md create mode 100644 sketches/001-dashboard/README.md create mode 100644 sketches/001-dashboard/index.html create mode 100644 sketches/002-inventario/README.md create mode 100644 sketches/002-inventario/index.html create mode 100644 sketches/003-formulario/README.md create mode 100644 sketches/003-formulario/index.html create mode 100644 sketches/004-configuracion/README.md create mode 100644 sketches/004-configuracion/index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..869e4e5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,65 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# Virtual environments +venv/ +env/ +.venv/ +.env/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db +desktop.ini + +# SQLite +*.db +*.db-journal +*.db-wal +*.db-shm + +# Backups +backups/ + +# PyInstaller +*.spec +*.exe +*.dll + +# Distribution +dist/ +build/ + +# Logs +*.log +logs/ + +# Environment variables +.env +.env.local diff --git a/README.md b/README.md new file mode 100644 index 0000000..91ffa88 --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +# Inventschario + +Aplicación de inventario de dispositivos electrónicos no prestables para +entornos de administración pública. + +## Descripción + +Inventschario es una aplicación web local que se ejecuta en el navegador +por defecto del usuario. Gestiona el ciclo de vida completo de dispositivos +electrónicos: ordenadores, monitores, impresoras, dispositivos de red, etc. + +### Características principales + +- **Gestión de dispositivos** — Alta, edición, baja y enajenación +- **Campos renombrables** — Etiquetas personalizables en la interfaz +- **Ciclo de vida** — Baja por obsolescencia, avería, robo; enajenación por venta, donación, transferencia +- **Copias de seguridad** — Automáticas diarias con recordatorio de limpieza +- **Importación / Exportación** — CSV con mapeo modular de campos +- **Historial** — Registro de todos los cambios realizados +- **Accesibilidad** — Navegación por teclado, contraste WCAG 2.1 AA + +## Requisitos + +- Windows 11 Pro (unida a dominio) +- Privilegios de instalador (NO se requiere administrador) +- Navegador Edge (incluido en Windows) + +## Arquitectura + +``` +[Browser Edge] ──HTTP──► [Flask API] ──► [SQLite] + │ │ + │ HTML/CSS/JS │ Python services + │ (Alpine.js) │ (DeviceService, etc.) + │ │ + ◄──── JSON ─────────────►│ +``` + +- **Frontend:** HTML + CSS + Alpine.js (sin framework pesado) +- **Backend:** Python 3.11+ con Flask +- **Base de datos:** SQLite con WAL mode +- **Empaquetado:** PyInstaller → un único `.exe` + +## Documentación + +- [Especificaciones](especificaciones.md) — Requisitos detallados del programa +- [Arquitectura](docs/arquitectura.md) — Documento de arquitectura +- [Roadmap Iteración 1](docs/roadmap-iteracion-1.md) — Plan de desarrollo +- [Diagrama de Arquitectura](docs/arquitectura-diagrama.html) — Diagrama visual (abrir en navegador) + +## Mockups de Interfaz + +Los bocetos de diseño están en `sketches/`: + +- [Dashboard](sketches/001-dashboard/index.html) — Vista resumen +- [Inventario](sketches/002-inventario/index.html) — Tabla de dispositivos +- [Formulario](sketches/003-formulario/index.html) — Alta / edición +- [Configuración](sketches/004-configuracion/index.html) — Ajustes generales + +Abrir los archivos `.html` directamente en el navegador para ver los mockups. + +## Estado + +**Iteración 1** — Roadmap definido, pendiente de feedback del usuario. + +Este commit contiene el diseño y la planificación antes de contactar con +el usuario para su validación. El trabajo corresponde a la primera iteración +del proyecto. + +## Licencia + +Por definir. diff --git a/docs/arquitectura-diagrama.html b/docs/arquitectura-diagrama.html new file mode 100644 index 0000000..f0cc951 --- /dev/null +++ b/docs/arquitectura-diagrama.html @@ -0,0 +1,342 @@ + + + + + + Inventschario — Diagrama de Arquitectura + + + + +
+
+
+
+

Inventschario — Arquitectura del Sistema

+
+

Aplicación de inventario de dispositivos electrónicos • Python + Flask + SQLite • Local-first

+
+ +
+ + + + + + + + + + + + + + + + Windows 11 Pro — Máquina Local (127.0.0.1) + + + + NAVEGADOR (Edge) + + + + SPA Shell + index.html + Router + + + + Componentes + Table | Form | Modal + + + + API Client + fetch wrapper + errors + + + + Páginas + Dashboard | Inventory + + + + Setup Wizard + 6 pasos de config + + + HTML + CSS + Alpine.js + Sin build step • System fonts • WCAG 2.1 AA + Router hash-based • Componentes vanilla JS + + + + + HTTP localhost + + + + API GATEWAY — Flask REST/JSON + + + + /api/v1/devices + CRUD + History + + + + /api/v1/import|export + CSV operations + + + + /api/v1/backups + Create | Restore | List + + + + /api/v1/config + Settings + Labels + + + + Middleware + CORS • JSON parse • Errors + + + Blueprint pattern • Solo escucha 127.0.0.1 • Sin exposición a red + + + + CAPA DE SERVICIOS — Lógica de Negocio + + + DeviceService + CRUD + Lifecycle + + + BackupService + Schedule + Gzip + + + ImportService + CSV + Mapper + + + ExportService + CSV + Labels + + + ConfigService + KV Store + Labels + + + + + + + + + + + CAPA DE DATOS — SQLite (WAL mode) + + + DeviceRepo + devices table + + + HistoryRepo + device_history + + + ConfigRepo + app_config + labels + + + BackupRepo + backup_log + + + + SQLite + inventschario.db + WAL mode • Foreign Keys + 6 tablas • 4 índices únicos + %APPDATA%/inventschario/ + + + + + + + + + + + + + + + Leyenda: + + + Frontend + + + API Gateway + + + Servicios + + + Datos + + + Límite de máquina + +
+ + +
+
+
+
+

Frontend

+
+
    +
  • • HTML + CSS + Alpine.js (sin framework pesado)
  • +
  • • Router hash-based para SPA
  • +
  • • Componentes vanilla JS reutilizables
  • +
  • • WCAG 2.1 AA — contraste, teclado, labels
  • +
  • • CSS custom properties para theming
  • +
+
+ +
+
+
+

Backend

+
+
    +
  • • Python 3.11+ con Flask
  • +
  • • API REST JSON sobre localhost
  • +
  • • Blueprint pattern por dominio
  • +
  • • Service layer separada de HTTP
  • +
  • • Schedule library para backups
  • +
+
+ +
+
+
+

Datos

+
+
    +
  • • SQLite con WAL mode
  • +
  • • Repository pattern por tabla
  • +
  • • Foreign keys + índices
  • +
  • • Migraciones versionadas
  • +
  • • Backups gzip en %APPDATA%
  • +
+
+ +
+
+
+

Empaquetado

+
+
    +
  • • PyInstaller → un único .exe (~30MB)
  • +
  • • Frontend empaquetado en el bundle
  • +
  • • Instalación en perfil de usuario
  • +
  • • Acceso directo en Menú Inicio
  • +
  • • Sin dependencias de runtime
  • +
+
+ +
+
+
+

Seguridad

+
+
    +
  • • Servidor solo en 127.0.0.1
  • +
  • • Sin exposición a la red
  • +
  • • Validación en backend (no confiar en frontend)
  • +
  • • Datos en %APPDATA% (aceso restringido)
  • +
  • • Foreign keys para integridad
  • +
+
+ +
+
+
+

Modularidad

+
+
    +
  • • API REST como contrato frontend↔backend
  • +
  • • Frontend reemplazable sin tocar backend
  • +
  • • Plugin architecture para import/export
  • +
  • • Migración a .NET 8 o Go documentada
  • +
  • • Cada service es independiente
  • +
+
+
+ + +
+ + diff --git a/docs/arquitectura.md b/docs/arquitectura.md new file mode 100644 index 0000000..d365be4 --- /dev/null +++ b/docs/arquitectura.md @@ -0,0 +1,411 @@ +# Inventschario — Documento de Arquitectura + +**Versión:** 1.0.0-iteracion1 +**Fecha:** 2026-08-03 +**Estado:** Propuesta para revisión + +--- + +## 1. Visión General + +Inventschario采用 arquitectura de tres capas con separación clara entre +presentación, lógica de negocio y persistencia. La capa de presentación se +ejecuta en el navegador del usuario; la capa de negocio y persistencia corren +como un servidor local HTTP que solo escucha en `127.0.0.1`. + +La pasarela entre frontend y backend es una API REST documentada, de forma que +el frontend puede sustituirse completamente sin modificar ninguna línea del +backend, y viceversa. + +--- + +## 2. Diagrama de Componentes + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ NAVEGADOR (Edge) │ +│ │ +│ ┌───────────────────────────────────────────────────────────┐ │ +│ │ FRONTEND │ │ +│ │ │ │ +│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ +│ │ │Dashboard │ │Inventario│ │ Formular │ │ Config │ │ │ +│ │ │ Page │ │ Page │ │ ios │ │ Page │ │ │ +│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ +│ │ │ │ │ │ │ │ +│ │ ┌────┴──────────────┴──────────────┴──────────────┴────┐ │ +│ │ │ Router (SPA) │ │ +│ │ └────────────────────┬─────────────────────────────────┘ │ │ +│ │ │ │ │ +│ │ ┌────────────────────┴─────────────────────────────────┐ │ +│ │ │ API Client (fetch wrapper) │ │ +│ │ └────────────────────┬─────────────────────────────────┘ │ │ +│ │ │ │ │ +│ │ ┌────────────────────┴─────────────────────────────────┐ │ +│ │ │ Component Library │ │ +│ │ │ Table | Form | Modal | Toast | Sidebar | Charts │ │ +│ │ └──────────────────────────────────────────────────────┘ │ │ +│ └───────────────────────────┬───────────────────────────────┘ │ +│ │ HTTP localhost:PORT │ +├──────────────────────────────┼──────────────────────────────────┤ +│ │ │ +│ ┌───────────────────────────┴───────────────────────────────┐ │ +│ │ API GATEWAY │ │ +│ │ │ │ +│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ +│ │ │ /devices │ │ /import │ │ /backups │ │ /config │ │ │ +│ │ │ /history │ │ /export │ │ │ │ /labels │ │ │ +│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ +│ │ │ │ │ │ │ │ +│ │ ┌────┴──────────────┴──────────────┴──────────────┴────┐ │ │ +│ │ │ Middleware Layer │ │ │ +│ │ │ CORS (localhost) | JSON parsing | Error handling │ │ │ +│ │ └────────────────────┬─────────────────────────────────┘ │ │ +│ └───────────────────────┼───────────────────────────────────┘ │ +│ │ │ +│ ┌───────────────────────┴───────────────────────────────────┐ │ +│ │ SERVICE LAYER │ │ +│ │ │ │ +│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ +│ │ │DeviceService │ │BackupService │ │ImportService │ │ │ +│ │ │ │ │ │ │ │ │ │ +│ │ │- CRUD │ │- crear │ │- parse CSV │ │ │ +│ │ │- buscar │ │- restaurar │ │- mapear │ │ │ +│ │ │- filtrar │ │- eliminar │ │- validar │ │ │ +│ │ │- baja │ │- verificar │ │- duplicados │ │ │ +│ │ │- enajenar │ │ antigüedad │ │ │ │ │ +│ │ │- historial │ │ │ │ │ │ │ +│ │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ │ +│ │ │ │ │ │ │ +│ │ ┌──────┴──────────────────┴──────────────────┴───────┐ │ │ +│ │ │ ExportService | ConfigService │ │ │ +│ │ └──────────────────────┬─────────────────────────────┘ │ │ +│ └─────────────────────────┼─────────────────────────────────┘ │ +│ │ │ +│ ┌─────────────────────────┴─────────────────────────────────┐ │ +│ │ DATA LAYER │ │ +│ │ │ │ +│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ +│ │ │ DeviceRepo │ │ ConfigRepo │ │ BackupRepo │ │ │ +│ │ │ │ │ │ │ │ │ │ +│ │ │ SQLite CRUD │ │ KV Store │ │ Log CRUD │ │ │ +│ │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ │ +│ │ │ │ │ │ │ +│ │ ┌──────┴──────────────────┴──────────────────┴───────┐ │ │ +│ │ │ SQLite (WAL mode) │ │ │ +│ │ │ inventschario.db │ │ │ +│ │ └────────────────────────────────────────────────────┘ │ │ +│ └───────────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 3. Alternativas de Arquitectura + +### Alternativa A: Python + Flask (Recomendada) + +``` +[Browser] ──HTTP──► [Flask server] ──► [SQLite] + │ │ + │ HTML/CSS/JS │ Python services + │ (Alpine.js) │ (DeviceService, etc.) + │ │ + ◄──── JSON ──────────►│ +``` + +**Por qué se recomienda:** +- Python stdlib incluye sqlite3, http.server, json, gzip, csv, shutil +- Flask es ligero (~500KB) y no necesita build step +- PyInstaller empaqueta todo en un .exe autocontenido +- El ecosistema Python tiene librerías para todo lo necesario +- Desarrollo rápido, fácil de mantener + +**Componentes:** +- `flask` — Servidor web minimalista +- `schedule` — Programador de tareas (backups diarios) +- `pyinstaller` — Empaquetado en .exe + +### Alternativa B: .NET 8 Minimal API + +``` +[Browser] ──HTTP──► [Kestrel server] ──► [SQLite via EF Core] + │ │ + │ HTML/CSS/JS │ C# services + │ (embebido) │ (DeviceService, etc.) + │ │ + ◄──── JSON ──────────►│ +``` + +**Por qué es alternativa válida:** +- `dotnet publish -r win-x64 --self-contained` produce .exe sin runtime +- Rendimiento superior a Python en operaciones intensivas +- Integración nativa con Windows +- Entity Framework Core para ORM robusto + +**Componentes:** +- ASP.NET Core Minimal API +- Microsoft.Data.Sqlite +- Hangfire (tareas programadas) + +### Alternativa C: Go + net/http + +``` +[Browser] ──HTTP──► [Go HTTP server] ──► [SQLite via CGO] + │ │ + │ HTML/CSS/JS │ Go handlers + │ (embed.FS) │ (DeviceService, etc.) + │ │ + ◄──── JSON ──────────►│ +``` + +**Por qué es alternativa válida:** +- Binario más pequeño (10-15 MB) +- Rendimiento excepcional +- Sin dependencias en runtime +- `embed.FS` embebe archivos estáticos directamente en el binario + +**Componentes:** +- `net/http` (stdlib) +- `mattn/go-sqlite3` (CGO) +- `embed.FS` (archivos estáticos) + +### Decisión: Python + Flask + +Para la primera iteración, Python + Flask es la opción que mejor equilibra: +- Velocidad de desarrollo +- Facilidad de distribución (PyInstaller) +- Modularidad del frontend (API REST pura) +- Ecosistema de herramientas + +Si en iteraciones futuras el tamaño del .exe o la detección por antivirus +se convierten en problemas, se documentará la migración a .NET 8. + +--- + +## 4. Patrones de Diseño + +### 4.1 Repository Pattern (Capa de Datos) + +Cada tabla tiene su repository que encapsula las consultas SQL: + +```python +class DeviceRepository: + def __init__(self, db_path): + self.db_path = db_path + + def get_all(self, filters=None): ... + def get_by_id(self, device_id): ... + def create(self, device_data): ... + def update(self, device_id, device_data): ... + def delete(self, device_id): ... + def search(self, query): ... +``` + +### 4.2 Service Layer (Lógica de Negocio) + +Los services orquestan la lógica sin conocer la API HTTP: + +```python +class DeviceService: + def __init__(self, device_repo, history_repo): + self.device_repo = device_repo + self.history_repo = history_repo + + def create_device(self, data, user): + device = self.device_repo.create(data) + self.history_repo.log(device.id, 'created', user=user) + return device + + def decommission(self, device_id, reason, user): + device = self.device_repo.get_by_id(device_id) + self.device_repo.update_status(device_id, 'decommissioned') + self.history_repo.log(device_id, 'decommissioned', + notes=reason, user=user) +``` + +### 4.3 API Gateway (Capa HTTP) + +Las rutas API son delgadas — solo parsean la request, llaman al service, +y formatean la response: + +```python +@bp.route('/api/v1/devices', methods=['POST']) +def create_device(): + data = request.get_json() + device = device_service.create_device(data, current_user) + return jsonify(device.to_dict()), 201 +``` + +### 4.4 Frontend Component Architecture + +El frontend usa un patrón de componentes simples sin framework pesado: + +```javascript +// Cada componente es un objeto con render() y bind() +const DeviceTable = { + render(devices) { return `...
`; }, + bind(container) { /* event listeners */ } +}; + +// El router cambia de página +const Router = { + routes: { '/': Dashboard, '/inventory': Inventory }, + navigate(path) { /* render the page */ } +}; +``` + +### 4.5 Import/Export Plugin Architecture + +El sistema de importación exportación es un plugin architecture: + +```python +class ImporterBase: + """Clase abstracta para todos los importadores""" + def parse(self, file_path) -> list[dict]: ... + def validate(self, records) -> ValidationResult: ... + def import_records(self, records, strategy) -> ImportResult: ... + +class CSVImporter(ImporterBase): + """Implementación CSV""" + def parse(self, file_path): + # Lee CSV, mapea columnas, retorna lista de dicts + ... + +class FieldMapper: + """Motor de mapeo de campos""" + def __init__(self, mapping_config): + self.mapping = mapping_config + + def map_record(self, raw_record) -> dict: + # Aplica el mapeo configurado + ... +``` + +Para añadir un nuevo formato (ej: Excel), se crea una nueva clase que +herede de `ImporterBase` sin tocar el resto del sistema. + +--- + +## 5. Seguridad + +### 5.1 Red + +- El servidor Flask escucha SOLO en `127.0.0.1:PORT` +- No hay exposición a la red local o internet +- El puerto se asigna dinámicamente o se configura en el wizard + +### 5.2 Datos + +- SQLite WAL mode para integridad +- Foreign keys habilitadas +- Validación de datos en backend (no confiar en el frontend) +- Backups almacenados en `%APPDATA%` (acceso restringido al usuario) + +### 5.3 Archivos + +- No se ejecutan comandos del sistema +- No se escriben archivos fuera de `%APPDATA%/inventschario/` +- La BD se almacena en `%APPDATA%/inventschario/inventschario.db` +- Los logs se almacenan en `%APPDATA%/inventschario/logs/` + +--- + +## 6. Rendimiento + +### 6.1 Consideraciones + +- Todo es local: latencia de red ~0ms +- SQLite es suficiente para inventarios de hasta 100,000 dispositivos +- WAL mode permite lecturas concurrentes +- Índices en campos de búsqueda frecuentes + +### 6.2 Métricas Objetivo + +| Operación | Tiempo objetivo | +|--------------------------------|-----------------| +| Carga de página inicial | < 2s | +| Búsqueda en inventario | < 500ms | +| Crear dispositivo | < 100ms | +| Exportar 1,000 dispositivos | < 3s | +| Importar 1,000 dispositivos | < 5s | +| Backup de BD de 10MB | < 2s | + +--- + +## 7. Estrategia de Testing + +### 7.1 Niveles + +1. **Unit Tests** — Services, repositories, utilidades +2. **Integration Tests** — API endpoints con BD en memoria +3. **E2E Tests** — Flujo completo (futuro, iteración 2) + +### 7.2 Herramientas + +- `pytest` — Framework de testing +- `pytest-flask` — Fixtures para Flask +- `sqlite3` en memoria — BD de test aislada + +### 7.3 Cobertura + +Objetivo iteración 1: > 80% cobertura en services y repositories. + +--- + +## 8. Despliegue + +### 8.1 Distribución + +``` +inventschario/ +├── inventschario.exe # Ejecutable empaquetado (PyInstaller) +├── inventschario.ico # Icono de la aplicación +└── README.md # Instrucciones de uso +``` + +### 8.2 Instalación (Usuario) + +1. El usuario ejecuta `inventschario.exe` +2. PyInstaller extrae a un directorio temporal +3. La aplicación se instala en `%LOCALAPPDATA%/inventschario/` +4. Se crea un acceso directo en el Menú Inicio del usuario +5. Se lanza el navegador con la aplicación + +### 8.3 Start Menu + +El acceso directo se crea en: +``` +%APPDATA%/Microsoft/Windows/Start Menu/Programs/Inventschario/Inventschario.lnk +``` + +Esto requiere privilegios de instalador (que el usuario tiene). + +--- + +## 9. Plan de Migración (Si es necesario) + +Si Python + Flask no cumple los requisitos en producción: + +### De Python a .NET 8 + +1. Mantener la misma API REST (los endpoints no cambian) +2. Reescribir los services en C# +3. Usar Entity Framework Core con SQLite +4. Publicar como self-contained: `dotnet publish -r win-x64 --self-contained` +5. El frontend NO cambia (solo se sirve desde wwwroot) + +### De Python a Go + +1. Mantener la misma API REST +2. Reescribir los services en Go +3. Usar `mattn/go-sqlite3` +4. Compilar como binario estático +5. Embeber frontend con `embed.FS` + +En ambos casos, la API REST como contrato permite el cambio de backend +sin modificar el frontend. + +--- + +*Documento generado como parte de la primera iteración del proyecto Inventschario.* diff --git a/docs/roadmap-iteracion-1.md b/docs/roadmap-iteracion-1.md new file mode 100644 index 0000000..986ee48 --- /dev/null +++ b/docs/roadmap-iteracion-1.md @@ -0,0 +1,184 @@ +# Inventschario — Roadmap Iteración 1 + +**Fecha:** 2026-08-03 +**Objetivo:** MVP funcional con gestión de dispositivos, copias de seguridad +e importación/exportación CSV. + +--- + +## Fase 0: Infraestructura del Proyecto + +- [ ] Inicializar repositorio git +- [ ] Crear estructura de directorios +- [ ] Configurar `pyproject.toml` con dependencias +- [ ] Crear `requirements.txt` +- [ ] Configurar `.gitignore` (Python, SQLite, backups, __pycache__) +- [ ] Escribir `README.md` con instrucciones de desarrollo + +## Fase 1: Capa de Datos + +- [ ] Implementar `schema.sql` con el esquema completo +- [ ] Implementar `connection.py` (conexión SQLite, WAL mode, foreign keys) +- [ ] Implementar `migrations.py` (creación de tablas, upgrades futuros) +- [ ] Implementar `DeviceRepository` (CRUD completo) +- [ ] Implementar `HistoryRepository` (log de cambios) +- [ ] Implementar `ConfigRepository` (key-value store) +- [ ] Implementar `BackupRepository` (log de backups) +- [ ] Tests unitarios para todos los repositories + +## Fase 2: Capa de Servicios + +- [ ] Implementar `DeviceService` (CRUD, baja, enajenación, historial) +- [ ] Implementar `BackupService` (crear, restaurar, eliminar, verificar antigüedad) +- [ ] Implementar `ConfigService` (leer/actualizar config, labels, setup) +- [ ] Implementar `ImportService` (parse CSV, mapeo, validación, duplicados) +- [ ] Implementar `ExportService` (generar CSV con etiquetas renombradas) +- [ ] Tests unitarios para todos los services + +## Fase 3: API Gateway + +- [ ] Configurar Flask app con Blueprint pattern +- [ ] Implementar CORS para localhost +- [ ] Implementar middleware de errores +- [ ] Rutas: `/api/v1/devices` (CRUD, búsqueda, filtros) +- [ ] Rutas: `/api/v1/devices/:id/decommission`, `/dispose` +- [ ] Rutas: `/api/v1/devices/:id/history` +- [ ] Rutas: `/api/v1/config`, `/api/v1/config/labels` +- [ ] Rutas: `/api/v1/config/initialize` +- [ ] Rutas: `/api/v1/backups` (listar, crear, restaurar, eliminar) +- [ ] Rutas: `/api/v1/import/csv`, `/api/v1/export/csv` +- [ ] Rutas: `/api/v1/locations`, `/api/v1/departments` +- [ ] Tests de integración para todos los endpoints + +## Fase 4: Frontend — Estructura Base + +- [ ] Crear `index.html` con estructura SPA +- [ ] Implementar `app.js` (router hash-based) +- [ ] Implementar `api.js` (cliente HTTP con manejo de errores) +- [ ] Implementar sistema de componentes (table, form, modal, toast, sidebar) +- [ ] Crear estilos globales con CSS custom properties +- [ ] Implementar responsive layout (sidebar collapse) + +## Fase 5: Frontend — Páginas + +### 5.1 Dashboard +- [ ] Estadísticas: total dispositivos, por estado, por tipo +- [ ] Últimos dispositivos añadidos +- [ ] Alertas de garantía próxima (futuro, placeholder) +- [ ] Recordatorio de backups antiguos + +### 5.2 Inventario (Tabla) +- [ ] Tabla paginada con sorting por columnas +- [ ] Barra de búsqueda full-text +- [ ] Filtros: tipo, estado, departamento, ubicación +- [ ] Acciones por fila: ver, editar, baja, enajenar +- [ ] Selección múltiple para exportación + +### 5.3 Formulario de Dispositivo +- [ ] Campos obligatorios marcados +- [ ] Validación en tiempo real +- [ ] Autocompletado de campos de registro +- [ ] Selector de tipo de dispositivo +- [ ] Selector de ubicación / departamento +- [ ] Modo creación y modo edición + +### 5.4 Detalle del Dispositivo +- [ ] Ficha completa con todos los campos +- [ ] Historial de cambios cronológico +- [ ] Botones de acción: editar, baja, enajenar +- [ ] Foto del dispositivo (futuro) + +### 5.5 Baja / Enajenación +- [ ] Modal con tipo de baja/enajenación +- [ ] Campo de fecha efectiva +- [ ] Campo de motivo / observaciones +- [ ] Campo de responsable autorizador +- [ ] Confirmación antes de ejecutar + +### 5.6 Importar / Exportar +- [ ] Selector de archivo CSV para importar +- [ ] Vista previa de los primeros 10 registros +- [ ] Mapeo de columnas (automático por nombre/posición) +- [ ] Opciones ante duplicados +- [ ] Registro de errores por fila +- [ ] Botón de exportación con filtros actuales +- [ ] Selector de separador CSV + +### 5.7 Configuración +- [ ] Nombre de institución +- [ ] Edición de etiquetas de campos de registro +- [ ] Configuración de backups (hora, retención) +- [ ] Gestión de ubicaciones +- [ ] Gestión de departamentos + +### 5.8 Wizard de Configuración Inicial +- [ ] Detección de primera ejecución +- [ ] 6 pasos del wizard +- [ ] Validación en cada paso +- [ ] Creación de la BD al finalizar + +## Fase 6: Copias de Seguridad + +- [ ] Implementar scheduler con `schedule` library +- [ ] Backup automático a la hora configurada +- [ ] Compresión gzip del archivo .db +- [ ] Registro en `backup_log` +- [ ] Verificación de backups antiguos al iniciar +- [ ] Toast de recordatorio al usuario +- [ ] Función de restaurar desde backup + +## Fase 7: Empaquetado + +- [ ] Configurar PyInstaller spec file +- [ ] Incluir frontend estático en el bundle +- [ ] Crear icono de la aplicación (.ico) +- [ ] Script de instalación (crear directorio + acceso directo Menú Inicio) +- [ ] Test de distribución: ejecutar en máquina limpia de Windows + +## Fase 8: Testing y Calidad + +- [ ] Tests unitarios: > 80% cobertura en services +- [ ] Tests de integración: todos los endpoints API +- [ ] Prueba manual de flujo completo +- [ ] Revisión de accesibilidad (WCAG 2.1 AA) +- [ ] Prueba de rendimiento con 1,000 dispositivos + +--- + +## Estimación de Esfuerzo + +| Fase | Días estimados | Dependencias | +|-------|:--------------:|-----------------| +| 0 | 0.5 | — | +| 1 | 2 | Fase 0 | +| 2 | 2 | Fase 1 | +| 3 | 2 | Fase 2 | +| 4 | 2 | Fase 0 | +| 5 | 5 | Fases 3, 4 | +| 6 | 1 | Fase 1 | +| 7 | 1 | Fases 3-6 | +| 8 | 1 | Fases 3-7 | +| **Total** | **~16 días** | | + +--- + +## Criterios de Salida de la Iteración 1 + +1. El usuario puede instalar la app en su perfil de Windows +2. El wizard de configuración crea la BD correctamente +3. Se pueden crear, editar, ver y eliminar dispositivos +4. Se pueden dar de baja y enajenar dispositivos +5. La tabla de inventario tiene búsqueda, filtros y ordenación +6. Las etiquetas de campos son renombrables +7. Los backups se ejecutan diariamente +8. Se muestra recordatorio de backups antiguos +9. Se puede exportar a CSV +10. Se puede importar desde CSV +11. El historial de cambios se registra +12. La interfaz es navegable por teclado +13. Los colores cumplen WCAG 2.1 AA + +--- + +*Roadmap generado como parte de la primera iteración del proyecto Inventschario.* +*Este documento es la base para el feedback del usuario antes de comenzar la implementación.* diff --git a/especificaciones.md b/especificaciones.md new file mode 100644 index 0000000..5dbb6fe --- /dev/null +++ b/especificaciones.md @@ -0,0 +1,836 @@ +# Inventschario — Especificaciones del Programa + +**Versión:** 1.0.0-iteracion1 +**Fecha:** 2026-08-03 +**Estado:** Borrador para feedback del usuario + +--- + +## 1. Resumen del Producto + +**Inventschario** es una aplicación de inventario de dispositivos electrónicos no +prestables (ordenadores, monitores, periféricos, equipos de red, etc.) diseñada +para ejecutarse en una única máquina Windows 11 Pro unida a un dominio. La +aplicación se distribuye como un único paquete, se ejecuta en el navegador por +defecto del usuario y almacena sus datos en una base de datos SQLite local. + +El usuario tiene privilegios de instalador pero NO de administrador. La +aplicación se instala únicamente en el directorio del usuario y aparece solo en +el Menú Inicio de dicho usuario. + +--- + +## 2. Restricciones del Entorno + +| Restricción | Detalle | +|------------------------------|-------------------------------------------------------------------------| +| SO | Windows 11 Pro | +| Dominio | Unida a dominio corporativo | +| Privilegios del usuario | Instalador (puede instalar software en su perfil), NO administrador | +| Distribución | Un único paquete autocontenido (sin dependencias externas en runtime) | +| Interfaz | Navegador por defecto del sistema (Edge), se abre al doble clic | +| Instalación | Solo en el directorio del usuario, Menú Inicio del usuario | +| Red | Mínima latencia (frontend y backend en la misma máquina) | +| Copias de seguridad | Automáticas diarias, recordatorio para limpieza de antiguas | + +--- + +## 3. Funcionalidades Principales + +### 3.1 Gestión de Dispositivos + +#### 3.1.1 Campos de Identificación (Renombrables) + +La aplicación debe soportar múltiples campos de registro para cada dispositivo. +El usuario puede renombrar la etiqueta visible de cada campo en la interfaz, +pero el nombre interno en la base de datos permanece constante. + +| Campo BD (interno) | Etiqueta por defecto | Tipo | Obligatorio | +|------------------------|-------------------------------|------------|-------------| +| `serial_number` | Número de Serie | Texto | Sí | +| `service_tag` | Service Tag | Texto | No | +| `catalog_number` | Número de Catálogo Interno | Texto | Sí | +| `additional_registry` | Registro Adicional | Texto | No | + +El sistema de renombrado se almacena en una tabla de configuración: + +```sql +CREATE TABLE field_labels ( + field_key TEXT PRIMARY KEY, -- e.g. 'serial_number' + label TEXT NOT NULL, -- e.g. 'Número de Serie' + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +``` + +#### 3.1.2 Campos Descriptivos del Dispositivo + +| Campo BD | Etiqueta por defecto | Tipo | Obligatorio | +|-------------------------|----------------------------|------------|-------------| +| `device_name` | Nombre / Descripción | Texto | Sí | +| `device_type` | Tipo de Dispositivo | Enum | Sí | +| `brand` | Marca | Texto | No | +| `model` | Modelo | Texto | No | +| `serial_internal` | Número de Serie Interno | Texto | No | +| `purchase_date` | Fecha de Compra | Fecha | No | +| `warranty_expiry` | Fin de Garantía | Fecha | No | +| `purchase_price` | Precio de Compra (€) | Decimal | No | +| `assigned_location` | Ubicación Asignada | Texto | No | +| `assigned_user` | Usuario Asignado | Texto | No | +| `department` | Departamento | Texto | No | +| `status` | Estado | Enum | Sí | +| `condition` | Estado Físico | Enum | No | +| `notes` | Notas | Texto | No | +| `photo_path` | Ruta Foto | Texto | No | + +#### 3.1.3 Tipos de Dispositivo (Enum) + +- `computer` — Ordenador de sobremesa +- `laptop` — Portátil +- `monitor` — Monitor / Pantalla +- `printer` — Impresora +- `scanner` — Escáner +- `network_device` — Dispositivo de red (switch, router, AP) +- `peripheral` — Periférico (teclado, ratón, auriculares) +- `server` — Servidor +- `ups` — SAI / Regulador +- `storage` — Almacenamiento externo +- `other` — Otro + +#### 3.1.4 Estados del Dispositivo (Enum) + +| Estado | Descripción | +|-----------------|------------------------------------------------| +| `active` | En uso, asignado y operativo | +| `available` | Disponible, sin asignar | +| `maintenance` | En mantenimiento / reparación | +| `decommissioned`| Dado de baja | +| `disposed` | Enajenado / desechado | +| `lost` | Extraviado / no localizado | +| `reserved` | Reservado para asignación futura | + +#### 3.1.5 Estado Físico (Enum) + +- `excellent` — Excelente +- `good` — Bueno +- `fair` — Regular +- `poor` — Malo +- `damaged` — Dañado + +### 3.2 Ciclo de Vida del Dispositivo (Administración Pública) + +La aplicación debe gestionar el ciclo de vida completo de cada dispositivo, +incluyendo trámites de administración pública: + +#### 3.2.1 Altas + +- Registro manual de un nuevo dispositivo +- Importación masiva desde CSV +- Asignación automática de número de inventario interno + +#### 3.2.2 Modificaciones + +- Edición de cualquier campo del dispositivo +- Historial de cambios (quién, cuándo, qué cambió) +- Reasignación de ubicación / usuario / departamento + +#### 3.2.3 Bajas + +- Baja por obsolescencia +- Baja por avería irreversible +- Baja por robo / extravío +- Baja por fin de garantía sin renovación +- Registro del motivo de baja +- Fecha efectiva de baja +- Responsable que autoriza la baja + +#### 3.2.4 Enajenación + +- Enajenación por venta +- Enajenación por donación +- Enajenación por transferencia a otro organismo +- Registro del destinatario / adquirente +- Documento de enajenación (referencia) +- Importe de enajenación si aplica +- Fecha efectiva de enajenación + +#### 3.2.5 Historial de Cambios + +```sql +CREATE TABLE device_history ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + device_id INTEGER NOT NULL, + action TEXT NOT NULL, -- 'created', 'modified', 'decommissioned', 'disposed', ... + field_changed TEXT, -- NULL para acciones de ciclo completo + old_value TEXT, + new_value TEXT, + performed_by TEXT NOT NULL, + performed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + notes TEXT, + FOREIGN KEY (device_id) REFERENCES devices(id) +); +``` + +### 3.3 Copias de Seguridad + +#### 3.3.1 Backup Automático Diario + +- Se ejecuta una vez al día (configurable la hora) +- Copia completa de la base de datos SQLite +- Almacena en `%APPDATA%/inventschario/backups/` +- Formato de nombre: `inventschario_YYYYMMDD_HHMMSS.db` +- Comprimido en formato `.gz` para ahorrar espacio + +#### 3.3.2 Gestión de Backups + +- Al iniciar la aplicación, comprueba si hay backups con más de N días (configurable) +- Muestra un recordatorio al usuario indicando cuántos backups antiguos existen +- El usuario decide eliminar los antiguos o mantenerlos +- Opción para crear un backup manual en cualquier momento +- Opción para restaurar desde un backup específico + +#### 3.3.3 Configuración de Backups + +| Parámetro | Valor por defecto | Descripción | +|------------------------------|-------------------|---------------------------------------| +| `backup_enabled` | `true` | Habilitar backups automáticos | +| `backup_hour` | `02:00` | Hora diaria del backup | +| `backup_retention_days` | `30` | Días antes de sugerir eliminación | +| `backup_max_keep` | `90` | Máximo de backups a conservar | +| `backup_path` | `%APPDATA%/inventschario/backups/` | Ruta de almacenamiento | + +### 3.4 Importación y Exportación + +#### 3.4.1 Exportación a CSV + +- Exporta todos los dispositivos o una selección filtrada +- Usa las etiquetas renombradas como cabeceras del CSV +- Separador configurable (coma, punto y coma, tabulador) +- Codificación UTF-8 con BOM para compatibilidad con Excel +- Opción de incluir solo columnas visibles + +#### 3.4.2 Importación desde CSV + +Sistema modular diseñado para ser extensible: + +**Fase 1 (Implementación inicial):** +- Selección del archivo CSV +- Mapeo automático de columnas por posición o nombre +- Vista previa de los primeros 10 registros +- Detección de duplicados (por serial_number o catalog_number) +- Opciones ante duplicados: saltar, sobrescribir, crear como nuevo +- Registro de errores por fila + +**Fase 2 (Extensibilidad futura):** +- Interfaz de mapeo visual de campos (drag & drop) +- Guardar perfiles de importación (plantillas) +- Transformaciones de datos durante la importación (regex, lookup) +- Importación desde Excel (.xlsx) directamente + +#### 3.4.3 Arquitectura Modular de Importación/Exportación + +``` +import_export/ +├── __init__.py +├── base.py # Clases abstractas ImporterBase, ExporterBase +├── csv_importer.py # Implementación CSV +├── csv_exporter.py # Implementación CSV +├── field_mapper.py # Motor de mapeo de campos +├── validator.py # Validación de datos importados +└── profiles/ # Perfiles de importación guardados +``` + +### 3.5 Interfaz de Usuario + +#### 3.5.1 Requisitos de Usabilidad y Accesibilidad + +- Navegación por teclado completa (Tab, Enter, Escape, atajos) +- Contraste de color WCAG 2.1 AA mínimo (4.5:1 texto, 3:1 elementos UI) +- Tamaño mínimo de objetivo de clic: 44x44 px +- Labels asociados a todos los inputs +- Mensajes de error claros y posicionados junto al campo +- Feedback visual en hover, focus, y active states +- Responsive (aunque el uso principal es escritorio) +- Modo de alto contraste soportado +- Texto alternativo en iconos decorativos + +#### 3.5.2 Pantallas / Pestañas + +1. **Dashboard** — Vista resumen con estadísticas clave +2. **Inventario** — Tabla de dispositivos con búsqueda, filtros, ordenación +3. **Agregar Dispositivo** — Formulario de alta +4. **Detalle / Edición** — Ficha completa del dispositivo con historial +5. **Baja / Enajenación** — Formulario de ciclo de vida +6. **Importar / Exportar** — Interfaz de importación y exportación CSV +7. **Configuración** — Parámetros generales, labels de campos, backups +8. **Configuración Inicial** — Wizard de primera ejecución + +#### 3.5.3 Configuración Inicial (Primera Ejecución) + +Al detectar que no existe base de datos, se muestra un wizard: + +1. **Paso 1:** Bienvenida y nombre de la institución / organismo +2. **Paso 2:** Configuración de campos de registro (renombrar etiquetas) +3. **Paso 3:** Tipos de dispositivo a gestionar (seleccionar cuáles activar) +4. **Paso 4:** Configuración de copias de seguridad +5. **Paso 5:** Ubicaciones / Departamentos predefinidos (opcional) +6. **Paso 6:** Confirmación y creación de la base de datos + +--- + +## 4. Modelo de Datos (SQLite) + +### 4.1 Diagrama Entidad-Relación + +``` +┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ +│ devices │ │ device_history │ │ field_labels │ +├─────────────────┤ ├──────────────────┤ ├─────────────────┤ +│ id (PK) │◄────│ device_id (FK) │ │ field_key (PK) │ +│ serial_number │ │ id (PK) │ │ label │ +│ service_tag │ │ action │ │ updated_at │ +│ catalog_number │ │ field_changed │ └─────────────────┘ +│ additional_reg │ │ old_value │ +│ device_name │ │ new_value │ ┌──────────────────┐ +│ device_type │ │ performed_by │ │ app_config │ +│ brand │ │ performed_at │ ├──────────────────┤ +│ model │ │ notes │ │ key (PK) │ +│ serial_internal │ └──────────────────┘ │ value │ +│ purchase_date │ │ updated_at │ +│ warranty_expiry │ ┌──────────────────┐ └──────────────────┘ +│ purchase_price │ │ locations │ +│ assigned_loc │ ├──────────────────┤ ┌──────────────────┐ +│ assigned_user │ │ id (PK) │ │ departments │ +│ department │ │ name │ ├──────────────────┤ +│ status │ │ building │ │ id (PK) │ +│ condition │ │ floor │ │ name │ +│ notes │ │ room │ └──────────────────┘ +│ photo_path │ └──────────────────┘ +│ created_at │ +│ updated_at │ ┌──────────────────┐ +└─────────────────┘ │ backup_log │ + ├──────────────────┤ + │ id (PK) │ + │ filename │ + │ size_bytes │ + │ created_at │ + │ is自動 │ + └──────────────────┘ +``` + +### 4.2 Script de Creación de la Base de Datos + +```sql +-- Inventschario v1.0.0 +-- Base de datos de inventario de dispositivos electrónicos + +PRAGMA journal_mode=WAL; +PRAGMA foreign_keys=ON; + +CREATE TABLE devices ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + serial_number TEXT NOT NULL, + service_tag TEXT, + catalog_number TEXT NOT NULL, + additional_registry TEXT, + device_name TEXT NOT NULL, + device_type TEXT NOT NULL DEFAULT 'other', + brand TEXT, + model TEXT, + serial_internal TEXT, + purchase_date DATE, + warranty_expiry DATE, + purchase_price DECIMAL(10,2), + assigned_location TEXT, + assigned_user TEXT, + department TEXT, + status TEXT NOT NULL DEFAULT 'active', + condition TEXT DEFAULT 'good', + notes TEXT, + photo_path TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +CREATE UNIQUE INDEX idx_devices_catalog ON devices(catalog_number); +CREATE INDEX idx_devices_serial ON devices(serial_number); +CREATE INDEX idx_devices_status ON devices(status); +CREATE INDEX idx_devices_type ON devices(device_type); + +CREATE TABLE device_history ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + device_id INTEGER NOT NULL, + action TEXT NOT NULL, + field_changed TEXT, + old_value TEXT, + new_value TEXT, + performed_by TEXT NOT NULL, + performed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + notes TEXT, + FOREIGN KEY (device_id) REFERENCES devices(id) ON DELETE CASCADE +); + +CREATE INDEX idx_history_device ON device_history(device_id); +CREATE INDEX idx_history_date ON device_history(performed_at); + +CREATE TABLE field_labels ( + field_key TEXT PRIMARY KEY, + label TEXT NOT NULL, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE app_config ( + key TEXT PRIMARY KEY, + value TEXT NOT NULL, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE locations ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL UNIQUE, + building TEXT, + floor TEXT, + room TEXT +); + +CREATE TABLE departments ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL UNIQUE +); + +CREATE TABLE backup_log ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + filename TEXT NOT NULL, + size_bytes INTEGER, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + is_auto BOOLEAN DEFAULT 1 +); + +-- Valores por defecto para field_labels +INSERT INTO field_labels (field_key, label) VALUES + ('serial_number', 'Número de Serie'), + ('service_tag', 'Service Tag'), + ('catalog_number', 'Número de Catálogo Interno'), + ('additional_registry', 'Registro Adicional'), + ('device_name', 'Nombre / Descripción'), + ('device_type', 'Tipo de Dispositivo'), + ('brand', 'Marca'), + ('model', 'Modelo'), + ('purchase_date', 'Fecha de Compra'), + ('warranty_expiry', 'Fin de Garantía'), + ('purchase_price', 'Precio de Compra (€)'), + ('assigned_location', 'Ubicación Asignada'), + ('assigned_user', 'Usuario Asignado'), + ('department', 'Departamento'), + ('status', 'Estado'), + ('condition', 'Estado Físico'); + +-- Valores por defecto para app_config +INSERT INTO app_config (key, value) VALUES + ('institution_name', ''), + ('backup_enabled', 'true'), + ('backup_hour', '02:00'), + ('backup_retention_days', '30'), + ('backup_max_keep', '90'), + ('csv_separator', ';'), + ('csv_encoding', 'utf-8-sig'), + ('setup_complete', 'false'); +``` + +--- + +## 5. Arquitectura del Sistema + +### 5.1 Requisitos Arquitectónicos + +- **Modularidad total:** Separación frontend / backend con pasarela (API) +- **Independencia de interfaz:** Cambiar el frontend no afecta al backend +- **Autocontenido:** Todas las dependencias empaquetadas en un solo ejecutable +- **Sin privilegios de admin:** Instalación y ejecución en perfil de usuario +- **Baja latencia:** Frontend y backend en la misma máquina + +### 5.2 Capas + +``` +┌─────────────────────────────────────────────┐ +│ NAVEGADOR (Edge) │ +│ ┌───────────────────────────────────────┐ │ +│ │ FRONTEND (HTML/CSS/JS) │ │ +│ │ Framework ligero: Alpine.js o Vanilla│ │ +│ └──────────────────┬────────────────────┘ │ +│ │ HTTP/localhost │ +├─────────────────────┼───────────────────────┤ +│ SERVIDOR LOCAL │ +│ ┌──────────────────┴────────────────────┐ │ +│ │ API GATEWAY (REST/JSON) │ │ +│ │ Endpoints: /api/devices, /api/... │ │ +│ └──────────────────┬────────────────────┘ │ +│ │ │ +│ ┌──────────────────┴────────────────────┐ │ +│ │ CAPA DE SERVICIOS │ │ +│ │ DeviceService, BackupService, etc. │ │ +│ └──────────────────┬────────────────────┘ │ +│ │ │ +│ ┌──────────────────┴────────────────────┐ │ +│ │ CAPA DE DATOS (SQLite) │ │ +│ │ Repository pattern, migraciones │ │ +│ └───────────────────────────────────────┘ │ +└─────────────────────────────────────────────┘ +``` + +### 5.3 API REST (Especificación) + +Todas las rutas comienzan con `/api/v1/`. + +#### Dispositivos + +| Método | Ruta | Descripción | +|--------|------------------------------|-----------------------------------| +| GET | `/api/v1/devices` | Listar dispositivos (con filtros) | +| GET | `/api/v1/devices/:id` | Obtener dispositivo por ID | +| POST | `/api/v1/devices` | Crear dispositivo | +| PUT | `/api/v1/devices/:id` | Actualizar dispositivo | +| DELETE | `/api/v1/devices/:id` | Eliminar dispositivo (soft delete)| +| POST | `/api/v1/devices/:id/decommission` | Dar de baja | +| POST | `/api/v1/devices/:id/dispose` | Enajenar | +| GET | `/api/v1/devices/:id/history` | Historial de cambios | + +#### Importación / Exportación + +| Método | Ruta | Descripción | +|--------|------------------------------|-----------------------------------| +| GET | `/api/v1/export/csv` | Exportar a CSV | +| POST | `/api/v1/import/csv` | Importar desde CSV | +| GET | `/api/v1/import/preview` | Vista previa de importación | + +#### Configuración + +| Método | Ruta | Descripción | +|--------|------------------------------|-----------------------------------| +| GET | `/api/v1/config` | Obtener configuración | +| PUT | `/api/v1/config` | Actualizar configuración | +| GET | `/api/v1/config/labels` | Obtener etiquetas de campos | +| PUT | `/api/v1/config/labels` | Actualizar etiquetas de campos | +| POST | `/api/v1/config/initialize` | Ejecutar wizard de configuración | + +#### Backups + +| Método | Ruta | Descripción | +|--------|------------------------------|-----------------------------------| +| GET | `/api/v1/backups` | Listar backups | +| POST | `/api/v1/backups/create` | Crear backup manual | +| POST | `/api/v1/backups/:id/restore`| Restaurar desde backup | +| DELETE | `/api/v1/backups/:id` | Eliminar backup | +| GET | `/api/v1/backups/check-aging`| Verificar backups antiguos | + +#### Ubicaciones y Departamentos + +| Método | Ruta | Descripción | +|--------|------------------------------|-----------------------------------| +| GET | `/api/v1/locations` | Listar ubicaciones | +| POST | `/api/v1/locations` | Crear ubicación | +| GET | `/api/v1/departments` | Listar departamentos | +| POST | `/api/v1/departments` | Crear departamento | + +--- + +## 6. Alternativas Tecnológicas + +### Opción A: Python + Flask + SQLite (Recomendada) + +| Aspecto | Detalle | +|------------------|-----------------------------------------------------------| +| Backend | Python 3.11+ con Flask | +| Base de datos | SQLite3 (incluido en Python stdlib) | +| Frontend | HTML/CSS/JS + Alpine.js (ligero, sin build step) | +| Empaquetado | PyInstaller → un único `.exe` | +| Tamaño aprox. | 25-40 MB | +| Ventajas | Ecosistema rico, fácil de desarrollar, SQLite nativo | +| Desventajas | PyInstaller a veces tiene problemas con antimalware | +| Dependencias | Flask, schedule (para backups) — todo empaquetado | + +### Opción B: .NET 8 Self-Contained + +| Aspecto | Detalle | +|------------------|-----------------------------------------------------------| +| Backend | ASP.NET Core minimal API | +| Base de datos | Microsoft.Data.Sqlite | +| Frontend | HTML/CSS/JS embebido en wwwroot | +| Empaquetado | `dotnet publish -r win-x64 --self-contained` | +| Tamaño aprox. | 60-80 MB | +| Ventajas | Nativo Windows, sin runtime externo, excelente rendimiento| +| Desventajas | Más verboso que Python, curva de aprendizaje mayor | +| Dependencias | Ninguna en runtime (self-contained) | + +### Opción C: Go + SQLite + +| Aspecto | Detalle | +|------------------|-----------------------------------------------------------| +| Backend | Go stdlib `net/http` + `mattn/go-sqlite3` | +| Base de datos | SQLite via CGO | +| Frontend | HTML/CSS/JS embebido via `embed` | +| Empaquetado | Binario compilado estático | +| Tamaño aprox. | 10-15 MB | +| Ventajas | Binario más pequeño, rendimiento excepcional | +| Desventajas | CGO complicationa el build cross-platform, menos ecosistema web | +| Dependencias | Ninguna en runtime | + +### Opción D: Electron + SQLite + +| Aspecto | Detalle | +|------------------|-----------------------------------------------------------| +| Backend | Node.js (embebido en Electron) | +| Base de datos | better-sqlite3 | +| Frontend | React/Vue/Svelte dentro de Electron | +| Empaquetado | electron-builder → instalador .exe | +| Tamaño aprox. | 150-200 MB | +| Ventajas | UI rica, familiar para devs frontend | +| Desventajas | Muy pesado para una app de inventario, innecesario | +| Dependencias | Chromium embebido | + +### Comparativa Resumen + +| Criterio | Python+Flask | .NET 8 | Go | Electron | +|------------------------|:------------:|:---------:|:---------:|:---------:| +| Tamaño del paquete | ★★★★ | ★★★ | ★★★★★ | ★★ | +| Facilidad de desarrollo| ★★★★★ | ★★★ | ★★★ | ★★★★ | +| Rendimiento | ★★★ | ★★★★★ | ★★★★★ | ★★★ | +| Sin dependencias RT | ★★★ (PyInst)| ★★★★★ | ★★★★★ | ★★★ | +| Ecosistema web | ★★★★★ | ★★★★ | ★★★ | ★★★★★ | +| Compatibilidad AV | ★★★ | ★★★★★ | ★★★★★ | ★★★★ | +| Modularidad frontend | ★★★★★ | ★★★★★ | ★★★★ | ★★★★★ | + +**Recomendación:** Python + Flask (Opción A) para la iteración inicial. Si el +tamaño o la detección por antivirus se convierten en problemas, migrar a .NET 8. + +--- + +## 7. Estructura de Directorios + +``` +inventschario/ +├── especificaciones.md # Este documento +├── docs/ +│ ├── arquitectura.md # Documento de arquitectura detallada +│ └── roadmap-iteracion-1.md # Roadmap de la primera iteración +├── sketches/ # Mockups de diseño de interfaz +│ ├── 001-dashboard/ +│ ├── 002-inventario/ +│ ├── 003-formulario/ +│ └── 004-configuracion/ +├── src/ +│ ├── __init__.py +│ ├── main.py # Punto de entrada +│ ├── server.py # Servidor Flask +│ ├── config.py # Configuración de la aplicación +│ ├── database/ +│ │ ├── __init__.py +│ │ ├── connection.py # Conexión SQLite +│ │ ├── models.py # Modelos de datos +│ │ ├── migrations.py # Migraciones de esquema +│ │ └── schema.sql # Esquema inicial +│ ├── services/ +│ │ ├── __init__.py +│ │ ├── device_service.py # Lógica de dispositivos +│ │ ├── backup_service.py # Gestión de backups +│ │ ├── import_service.py # Importación CSV +│ │ ├── export_service.py # Exportación CSV +│ │ └── config_service.py # Configuración general +│ ├── api/ +│ │ ├── __init__.py +│ │ ├── devices.py # Rutas API de dispositivos +│ │ ├── imports.py # Rutas API de importación +│ │ ├── exports.py # Rutas API de exportación +│ │ ├── backups.py # Rutas API de backups +│ │ └── config.py # Rutas API de configuración +│ ├── import_export/ +│ │ ├── __init__.py +│ │ ├── base.py # Clases abstractas +│ │ ├── csv_importer.py # Importador CSV +│ │ ├── csv_exporter.py # Exportador CSV +│ │ ├── field_mapper.py # Motor de mapeo +│ │ └── validator.py # Validación de datos +│ └── utils/ +│ ├── __init__.py +│ ├── scheduler.py # Programador de backups +│ └── paths.py # Rutas de archivos +├── frontend/ +│ ├── index.html # Página principal (SPA) +│ ├── css/ +│ │ └── styles.css # Estilos globales +│ ├── js/ +│ │ ├── app.js # Router y estado global +│ │ ├── api.js # Cliente HTTP para la API +│ │ ├── components/ # Componentes reutilizables +│ │ │ ├── table.js +│ │ │ ├── form.js +│ │ │ ├── modal.js +│ │ │ ├── toast.js +│ │ │ └── sidebar.js +│ │ └── pages/ # Páginas / vistas +│ │ ├── dashboard.js +│ │ ├── inventory.js +│ │ ├── device-form.js +│ │ ├── device-detail.js +│ │ ├── lifecycle.js +│ │ ├── import-export.js +│ │ ├── settings.js +│ │ └── setup-wizard.js +│ └── assets/ +│ └── icons/ # Iconos SVG +├── tests/ +│ ├── test_devices.py +│ ├── test_import.py +│ ├── test_backup.py +│ └── test_config.py +├── pyproject.toml +├── requirements.txt +└── README.md +``` + +--- + +## 8. Requisitos No Funcionales + +### 8.1 Rendimiento + +- Tiempo de respuesta API: < 100ms (local) +- Carga de página inicial: < 2 segundos +- Búsqueda en inventario: < 500ms con 10,000 dispositivos +- Importación CSV: < 5 segundos para 1,000 registros + +### 8.2 Seguridad + +- El servidor solo escucha en `127.0.0.1` (localhost) +- No se exponen puertos a la red +- No se almacenan credenciales en texto plano +- Backups cifrados (futuro, iteración 2) +- Logs de auditoría para acciones críticas + +### 8.3 Fiabilidad + +- WAL mode en SQLite para concurrencia de lectura +- Backups automáticos diarios +- Integridad referencial con foreign keys +- Validación de datos tanto en backend como frontend + +### 8.4 Mantenibilidad + +- Código modular con separation of concerns +- API REST bien documentada +- Tests unitarios y de integración +- Migraciones de esquema versionadas + +--- + +## 9. Flujo de Usuario — Escenarios Principales + +### 9.1 Primera Ejecución + +``` +Doble clic en icono del Menú Inicio + → Se abre Edge en http://localhost:PORT + → Detector: no hay DB → Wizard de configuración + → Paso 1: Nombre de institución + → Paso 2: Etiquetas de campos de registro + → Paso 3: Tipos de dispositivo a gestionar + → Paso 4: Configuración de backups + → Paso 5: Ubicaciones y departamentos (opcional) + → Paso 6: Confirmación → Crear DB + → Redirige al Dashboard +``` + +### 9.2 Alta de Dispositivo + +``` +Click "Agregar Dispositivo" (sidebar o botón) + → Formulario con campos obligatorios marcados + → Autocompletado de campos numéricos de registro + → Validación en tiempo real + → Submit → Guarda en BD → Historial "created" + → Toast de confirmación → permanece en formulario para siguiente alta +``` + +### 9.3 Búsqueda y Edición + +``` +En pestaña Inventario: + → Barra de búsqueda (búsqueda full-text) + → Filtros: tipo, estado, departamento, ubicación + → Click en fila → Detalle del dispositivo + → Click "Editar" → Modo edición inline + → Cambios guardados → Historial "modified" +``` + +### 9.4 Baja / Enajenación + +``` +En detalle del dispositivo: + → Click "Dar de Baja" o "Enajenar" + → Modal con: + - Tipo de baja/enajenación + - Fecha efectiva + - Motivo / observaciones + - Responsable autorizador + → Confirmar → Estado cambia → Historial actualizado + → Dispositivo aparece como "Baja" / "Enajenado" en el inventario +``` + +### 9.5 Backup Diario + +``` +Servidor inicia → Scheduler programado a las 02:00 + → BackupService.crear_backup(): + - Copia el archivo .db + - Comprime con gzip + - Registra en backup_log + → Al iniciar la app, BackupService.verificar_antiguos(): + - Si hay backups > retention_days → Toast informativo + - "Hay X backups con más de N días. ¿Desea eliminarlos?" + - Botones: "Eliminar antiguos" / "Mantener" +``` + +--- + +## 10. Criterios de Aceptación — Iteración 1 + +- [ ] El usuario puede instalar la aplicación en su perfil de Windows +- [ ] El icono aparece en el Menú Inicio del usuario +- [ ] Al doble clic, se abre Edge con la aplicación +- [ ] El wizard de configuración initial crea la BD correctamente +- [ ] Se pueden crear, editar, y dar de baja dispositivos +- [ ] La tabla de inventario muestra búsqueda, filtros y ordenación +- [ ] Se pueden renombrar las etiquetas de los campos de registro +- [ ] Las copias de seguridad se ejecutan diariamente +- [ ] Se muestra recordatorio de backups antiguos al iniciar +- [ ] Se pueden exportar dispositivos a CSV +- [ ] Se pueden importar dispositivos desde CSV +- [ ] El historial de cambios se registra correctamente +- [ ] La interfaz es navegable por teclado +- [ ] Los colores cumplen WCAG 2.1 AA + +--- + +## 11. Futuras Iteraciones (Roadmap) + +### Iteración 2 +- Cifrado de backups +- Autenticación de usuario (si se necesita multi-usuario) +- Informes y gráficos (distribución por tipo, estado, departamento) +- Impresión de etiquetas de inventario + +### Iteración 3 +- Escáner de códigos de barras / QR +- Sincronización con Active Directory +- API para integración con otros sistemas +- Importación desde Excel (.xlsx) + +### Iteración 4 +- Multi-idioma (i18n) +- Modo oscuro +- Notificaciones de garantía próxima a vencer +- Dashboard con métricas avanzadas + +--- + +*Documento generado como parte de la primera iteración del proyecto Inventschario. +Sujeto a revisión y feedback del usuario.* diff --git a/sketches/001-dashboard/README.md b/sketches/001-dashboard/README.md new file mode 100644 index 0000000..79e3734 --- /dev/null +++ b/sketches/001-dashboard/README.md @@ -0,0 +1,18 @@ +# Variant: Dashboard — Monitor Surface + +## Design stance +Data-first density: the user is watching state change. Stats cards at the top, +recent items table, and distribution chart — no hero, no marketing. + +## Key choices +- **Layout:** Sidebar + main content, 4-column stats grid, 2-column lower section +- **Typography:** Inter, 32px stat values, 13px body +- **Color:** Neutral (#1a1a1a accent, #f7f7f5 background), status badges with semantic colors +- **Interaction:** Hover on table rows, clickable chart bars, alert dismiss + +## Trade-offs +- Strong at: At-a-glance status, quick navigation, density without clutter +- Weak at: On first use with 0 devices (needs empty state design) + +## Best for +Administrators who check the dashboard daily to monitor inventory status. diff --git a/sketches/001-dashboard/index.html b/sketches/001-dashboard/index.html new file mode 100644 index 0000000..9d5f75a --- /dev/null +++ b/sketches/001-dashboard/index.html @@ -0,0 +1,526 @@ + + + + + + Inventschario — Dashboard + + + + + + + + +
+
+

Dashboard

+
+ + +
+
+ +
+ + + + +
+
+
Total Dispositivos
+
247
+
↑ 12 este mes
+
+
+
En Uso
+
198
+
80% del total
+
+
+
Disponibles
+
31
+
↑ 5 desde el mes pasado
+
+
+
En Mantenimiento
+
8
+
↑ 3 esta semana
+
+
+ + +
+ +
+
+

Últimos Dispositivos Registrados

+ Ver todos → +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CatálogoNombreTipoEstado
INV-2024-0247MacBook Pro 14"PortátilActivo
INV-2024-0246Dell P2723QEMonitorDisponible
INV-2024-0245Lenovo ThinkPad T14sPortátilActivo
INV-2024-0244HP LaserJet Pro M404ImpresoraMantenimiento
INV-2024-0243Cisco Catalyst 2960RedActivo
+
+
+ + +
+
+

Distribución por Tipo

+
+
+
+
+ Portátiles +
+
+ Monitores +
+
+ Sobremesa +
+
+ Impresoras +
+
+ Red +
+
+ Perif. +
+
+ Otros +
+
+
+
+
+ + +
+

Acciones Rápidas

+ +
+
+
+ + diff --git a/sketches/002-inventario/README.md b/sketches/002-inventario/README.md new file mode 100644 index 0000000..2006cf7 --- /dev/null +++ b/sketches/002-inventario/README.md @@ -0,0 +1,18 @@ +# Variant: Inventario — Operate Surface + +## Design stance +Action-oriented data table: the user is working with devices, not just viewing them. +Every row has inline actions, the toolbar has filters, and bulk selection is available. + +## Key choices +- **Layout:** Full-width table with persistent toolbar, checkbox selection, pagination +- **Typography:** Monospace for catalog numbers, Inter for everything else +- **Color:** Status badges with semantic colors, row hover highlight +- **Interaction:** Sortable columns, filter dropdowns, row-level actions (view, edit, delete) + +## Trade-offs +- Strong at: Scanning large lists, quick actions per device, bulk operations +- Weak at: Needs mobile responsive design for tablet use + +## Best for +Daily inventory management — searching, filtering, and acting on specific devices. diff --git a/sketches/002-inventario/index.html b/sketches/002-inventario/index.html new file mode 100644 index 0000000..150c830 --- /dev/null +++ b/sketches/002-inventario/index.html @@ -0,0 +1,403 @@ + + + + + + Inventschario — Inventario + + + + + + + + +
+
+

Inventario (247 dispositivos)

+
+ + +
+
+ +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Catálogo Nombre / DescripciónTipoMarca / ModeloUbicaciónEstadoAcciones
INV-2024-0247MacBook Pro 14" — Oficina DirecciónPortátilApple / MacBook Pro M3Planta 2, Desp. 201Activo +
+ + + +
+
INV-2024-0246Dell P2723QE — Monitor 4KMonitorDell / P2723QEAlmacénDisponible +
+ + + +
+
INV-2024-0245Lenovo ThinkPad T14s — DesarrolloPortátilLenovo / ThinkPad T14s Gen 4Planta 1, Open SpaceActivo +
+ + + +
+
INV-2024-0244HP LaserJet Pro M404dnImpresoraHP / LaserJet Pro M404dnPlanta 1, ReprografíaMantenimiento +
+ + + +
+
INV-2024-0243Cisco Catalyst 2960 — Switch Planta 1RedCisco / Catalyst 2960-24TC-LPlanta 1, Cuarto RedesActivo +
+ + + +
+
INV-2024-0242Dell OptiPlex 7090 — RecepciónSobremesaDell / OptiPlex 7090Planta 0, RecepciónActivo +
+ + + +
+
+ + + +
+
+
+ + diff --git a/sketches/003-formulario/README.md b/sketches/003-formulario/README.md new file mode 100644 index 0000000..b699a14 --- /dev/null +++ b/sketches/003-formulario/README.md @@ -0,0 +1,19 @@ +# Variant: Formulario — Configure Surface + +## Design stance +Progressive disclosure through logical sections: identification, device info, +purchase, assignment, notes. Required fields marked clearly, inline validation. + +## Key choices +- **Layout:** Single-column form card, 2-column grid within sections +- **Typography:** Clear section headers, field labels with required markers +- **Color:** Minimal — white card on light gray background, red for required/errors +- **Interaction:** Real-time validation, "Save and Add Another" for batch entry + +## Trade-offs +- Strong at: Clear data entry flow, reduced errors, batch-friendly +- Weak at: Long form on small screens (needs responsive stacking) + +## Best for +Staff entering new devices — the form guides them through required fields +and offers shortcuts for batch entry. diff --git a/sketches/003-formulario/index.html b/sketches/003-formulario/index.html new file mode 100644 index 0000000..bc76ec8 --- /dev/null +++ b/sketches/003-formulario/index.html @@ -0,0 +1,351 @@ + + + + + + Inventschario — Agregar Dispositivo + + + + + + + + +
+
+
+ + + +

Agregar Dispositivo

+
+
+ + +
+
+ +
+

Los campos marcados con * son obligatorios.

+ +
+ +
+
Identificación
+
+
+ + + Se genera automáticamente si se deja vacío +
+
+ + +
+
+ + + Número de servicio del fabricante +
+
+ + +
+
+
+ + +
+
Información del Dispositivo
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
Compra y Garantía
+
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
Asignación
+
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
Notas
+
+
+ + +
+
+
+ + + +
+
+
+ + + + + diff --git a/sketches/004-configuracion/README.md b/sketches/004-configuracion/README.md new file mode 100644 index 0000000..109b357 --- /dev/null +++ b/sketches/004-configuracion/README.md @@ -0,0 +1,20 @@ +# Variant: Configuración — Configure Surface + +## Design stance +Tabbed settings with inline editing: each section is self-contained, changes +are saved explicitly, and the field label editor shows the internal key alongside +the user-facing label. + +## Key choices +- **Layout:** Tabbed navigation, settings sections as cards, inline list editors +- **Typography:** Monospace for field keys, Inter for labels and values +- **Color:** Minimal — toggle switches for boolean settings, danger color for delete +- **Interaction:** Toggle switches, inline add/remove for locations/departments + +## Trade-offs +- Strong at: Organized settings, clear field mapping, backup management +- Weak at: Many settings could overwhelm on first visit + +## Best for +Initial setup and ongoing configuration — the admin sets up the system once +and revisits occasionally for adjustments. diff --git a/sketches/004-configuracion/index.html b/sketches/004-configuracion/index.html new file mode 100644 index 0000000..4482ad0 --- /dev/null +++ b/sketches/004-configuracion/index.html @@ -0,0 +1,496 @@ + + + + + + Inventschario — Configuración + + + + + + + + +
+
+

Configuración

+
+ +
+
+ +
+ +
+ + + + +
+ + +
+
+
+

Información General

+

Datos de la institución y configuración básica

+
+
+
+
+
+
Nombre de la Institución
+
Aparece en el encabezado de exportaciones e informes
+
+
+ +
+
+
+
+
Prefijo de Número de Catálogo
+
Prefijo para la generación automática de números de inventario
+
+
+ +
+
+
+
+
Separador CSV por Defecto
+
Separador utilizado al exportar e importar archivos CSV
+
+
+ +
+
+
+
+ + +
+
+
+

Etiquetas de Campos

+

Personaliza los nombres que aparecen en la interfaz. El nombre interno en la base de datos no cambia.

+
+
+
+
+
+ serial_number + +
+
+ service_tag + +
+
+ catalog_number + +
+
+ additional_registry + +
+
+ device_name + +
+
+ device_type + +
+
+ brand + +
+
+ model + +
+
+ purchase_date + +
+
+ warranty_expiry + +
+
+ purchase_price + +
+
+ assigned_location + +
+
+ assigned_user + +
+
+ department + +
+
+ status + +
+
+ condition + +
+
+
+
+ + +
+
+
+

Copias de Seguridad

+

Configuración del backup automático y gestión de copias

+
+
+
+
+
+
Backup Automático
+
Crear una copia de seguridad de la base de datos cada día
+
+
+ +
+
+
+
+
Hora del Backup
+
Hora a la que se ejecuta el backup diario
+
+
+ +
+
+
+
+
Días de Retención
+
Número de días antes de sugerir la eliminación de backups antiguos
+
+
+ + días +
+
+
+
+
Máximo de Backups
+
Número máximo de copias de seguridad a conservar
+
+
+ +
+
+ + +
+
+ Copias Recientes + +
+
+
+
+ +
+
inventschario_20260803_020000.db.gz
+
3 de agosto 2026, 02:00 — 2.4 MB — Automático
+
+
+
+ + +
+
+
+
+ +
+
inventschario_20260802_020000.db.gz
+
2 de agosto 2026, 02:00 — 2.3 MB — Automático
+
+
+
+ + +
+
+
+
+ +
+
inventschario_20260801_143022.db.gz
+
1 de agosto 2026, 14:30 — 2.3 MB — Manual
+
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+

Ubicaciones y Departamentos

+

Gestiona las ubicaciones físicas y departamentos de la institución

+
+
+
+
+ +
+
+ Ubicaciones + +
+
+
+ Planta 0 — Recepción + +
+
+ Planta 1 — Open Space + +
+
+ Planta 1 — Reprografía + +
+
+ Planta 2 — Desp. Dirección + +
+
+ Almacén + +
+
+
+ + +
+
+ Departamentos + +
+
+
+ Informática + +
+
+ Administración + +
+
+ Recursos Humanos + +
+
+ Contabilidad + +
+
+ Dirección + +
+
+
+
+
+
+
+
+ +