.gitignore and v0.2.0

This commit is contained in:
2026-08-12 03:44:07 -06:00
parent 26851fa750
commit 8f009bb1ed
22 changed files with 1175 additions and 25 deletions
+138
View File
@@ -0,0 +1,138 @@
# Herramientas interactivas
Estado: primera versión funcional. Este documento conserva el contexto necesario para extender `DsSortableList` y `DsLogicTree` sin cambiar accidentalmente sus contratos públicos.
## Principios compartidos
- Los modelos son serializables y no contienen referencias DOM ni estado interno de Vue.
- Cada elemento o nodo necesita un `id` estable y único.
- Las actualizaciones reemplazan arreglos y nodos en lugar de mutar los objetos recibidos.
- La interacción con puntero siempre debe tener una alternativa de teclado.
- La lógica de negocio, persistencia y traducción a consultas pertenece a la aplicación consumidora o a adaptadores independientes.
- Cualquier ampliación debe actualizar tipos, API pública, pruebas, playground y documentación.
## `DsSortableList`
### Contrato actual
Recibe `v-model<DsSortableItem[]>`. Cada elemento contiene:
```ts
interface DsSortableItem {
id: string;
label: string;
description?: string;
disabled?: boolean;
}
```
El usuario puede arrastrar un elemento o utilizar los botones subir/bajar. Cada cambio reemplaza el arreglo y emite:
```ts
interface DsSortableChange {
item: DsSortableItem;
from: number;
to: number;
}
```
El slot predeterminado puede personalizar la representación, pero `id` y `label` continúan formando parte del contrato porque se utilizan para identidad y nombres accesibles.
### Decisiones
- Se usa drag-and-drop nativo del navegador para mantener pequeña la primera versión y evitar una dependencia runtime.
- Los botones subir/bajar son la alternativa accesible y también permiten operar la lista en pantallas táctiles.
- La nueva posición se anuncia mediante una región `status`.
- Un elemento `disabled` no puede iniciar un movimiento.
### Limitaciones conocidas
- Solo reordena elementos dentro de una misma lista.
- No tiene gesto táctil de arrastre; en móvil se usan los botones.
- No ofrece clonación, selección múltiple, grupos ni zonas de descarte.
- El destino corresponde al elemento sobre el que se suelta; todavía no existe un indicador entre filas.
- No administra persistencia ni historial para deshacer/rehacer.
### Próximas extensiones
1. Mejorar el indicador de inserción antes/después de una fila.
2. Evaluar Pointer Events para arrastre táctil sin eliminar la alternativa por botones.
3. Diseñar drag-and-drop entre listas. Antes de implementarlo hay que definir `sourceListId`, `targetListId`, copia frente a movimiento y el evento público resultante.
4. Añadir soporte opcional para deshacer/rehacer como composable independiente.
5. Incorporar pruebas visuales y de interacción en navegadores reales.
## `DsLogicTree`
### Contrato actual
Recibe `v-model<DsLogicGroup>`. El árbol utiliza una unión discriminada:
```ts
type DsLogicNode = DsLogicCondition | DsLogicGroup;
interface DsLogicGroup {
id: string;
type: "group";
operator: "and" | "or";
children: DsLogicNode[];
}
interface DsLogicCondition {
id: string;
type: "condition";
field: string;
comparison: string;
value: string;
}
```
`fields` y `comparisons` usan opciones `{ label, value, disabled? }`. La prop `labels` permite adaptar todos los textos del editor y `readonly` conserva la estructura sin permitir cambios. Cada edición actualiza el `v-model` y emite `change` con el árbol completo.
El render recursivo vive en `DsLogicTreeNode.vue`, que es una implementación interna y no forma parte de la API pública.
### Decisiones
- `AND` y `OR` se almacenan como `and` y `or`; los textos visibles son configurables.
- Las condiciones usan cadenas para que la primera versión sea neutral respecto al dominio.
- Los nodos nuevos reciben UUID y los nodos proporcionados por el consumidor deben conservar IDs estables.
- El árbol solamente describe reglas. No evalúa condiciones ni genera SQL, JSON Logic u otra sintaxis.
- Los controles nativos mantienen nombres accesibles y el anidamiento se representa con listas y grupos.
### Limitaciones conocidas
- Todos los valores se editan como texto, sin tipos `number`, `boolean`, fecha o selección múltiple.
- No existe validación de campos vacíos, operadores incompatibles o grupos sin condiciones.
- Los nodos no pueden reordenarse ni moverse entre grupos.
- No hay operadores unarios como `is-empty` ni condiciones que omitan `value`.
- No se muestran resúmenes en lenguaje natural.
- No se incluye un evaluador ni adaptadores para backends.
### Próximas extensiones
1. Añadir validación sin cambiar el modelo serializable; los errores deben asociarse al control correspondiente.
2. Diseñar definiciones de campo tipadas con un `valueType` y opciones de valor. Hay que conservar compatibilidad con el esquema actual o introducir el cambio en una versión mayor.
3. Permitir comparadores que no requieran valor y editores personalizados mediante slots.
4. Reordenar condiciones y mover nodos entre grupos reutilizando un contrato de drag-and-drop estable.
5. Crear adaptadores separados para evaluar el árbol o convertirlo a formatos como JSON Logic. Estos adaptadores no deben acoplar el componente visual a un backend.
6. Añadir colapsado de grupos, resumen legible y deshacer/rehacer cuando el árbol crezca.
## Checklist para futuras sesiones
Antes de modificar estas herramientas:
1. Revisa este documento, `src/types.ts` y las pruebas de `tests/data-tools.test.ts`.
2. Decide si el cambio es compatible con los modelos actuales y documenta cualquier migración.
3. Conserva una alternativa completa al arrastre para teclado y tecnologías asistivas.
4. Añade el caso nuevo al playground en `?section=tools`.
5. Actualiza `docs/components.md` si cambia la API pública.
6. Ejecuta `npm run check` y `npm run test:coverage`.
## Fuera de alcance actual
- Ejecución de reglas contra datos reales.
- Generación directa de SQL o llamadas a APIs.
- Colaboración en tiempo real.
- Persistencia automática.
- Un editor visual de flujos con nodos y conexiones libres.
Estas capacidades requieren contratos y análisis de seguridad propios; no deben incorporarse como comportamiento implícito de los componentes visuales.