inventschario/especificaciones.md
pikaos ee849eb9a8 feat: roadmap y diseño inicial — iteración 1 antes de feedback del usuario
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
2026-08-03 01:34:56 +01:00

36 KiB

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
service_tag Service Tag Texto No
catalog_number Número de Catálogo Interno Texto
additional_registry Registro Adicional Texto No

El sistema de renombrado se almacena en una tabla de configuración:

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
device_type Tipo de Dispositivo Enum
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
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

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

-- 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.