# US-MGN-004-001-002: Jerarquía y Vista Árbol de Cuentas Contables **RF Asociado:** [RF-MGN-004-001](../../02-modelado/requerimientos-funcionales/mgn-004/RF-MGN-004-001-gestión-de-plan-de-cuentas.md) **Módulo:** MGN-004 - Financiero Básico **Epic:** Plan de Cuentas **Prioridad:** P0 (MVP) **Story Points:** 3 **Sprint:** Sprint 7 **Estado:** Ready for Development **Fecha:** 2025-11-24 --- ## User Story **Como** contador de la empresa, **Quiero** organizar las cuentas contables en una estructura jerárquica (árbol), **Para** agrupar las cuentas por categorías y subcategorías y visualizarlas de forma organizada. --- ## Descripción Detallada Esta user story implementa la funcionalidad de jerarquía de cuentas contables mediante el uso del campo `parent_id`. Permite: - Crear cuentas con cuentas padre (subcuentas) - Visualizar el plan de cuentas como árbol jerárquico - Calcular niveles de profundidad (nivel 0 = cuenta raíz, nivel 1 = hijos directos, etc.) - Navegar por la jerarquía (expandir/colapsar nodos) Ejemplo de jerarquía: ``` 1 - Activos (parent_id: null) 1.1 - Activos Corrientes (parent_id: 1) 1.1.01 - Efectivo y Equivalentes (parent_id: 1.1) 1.1.01.001 - Caja General (parent_id: 1.1.01) 1.1.01.002 - Banco Santander (parent_id: 1.1.01) ``` --- ## Criterios de Aceptación ### Escenario 1: Crear cuenta con cuenta padre **Dado que** tengo una cuenta padre "1.1 Activos Corrientes" con id=10, **Cuando** creo una cuenta "1.1.01 Efectivo" con parent_id=10, **Entonces** el sistema crea la cuenta y establece la relación jerárquica correctamente. ### Escenario 2: Obtener árbol jerárquico de cuentas **Dado que** tengo cuentas con jerarquía definida, **Cuando** solicito GET /api/v1/financial/accounts/tree, **Entonces** el sistema retorna un JSON con estructura de árbol incluyendo hijos (children array). ### Escenario 3: Validar que parent_id existe **Dado que** intento crear una cuenta con parent_id=999 (no existe), **Cuando** envío el request, **Entonces** el sistema retorna error 400 "Cuenta padre no encontrada". ### Escenario 4: Prevenir ciclos en jerarquía **Dado que** tengo cuenta A (id=1) con parent_id=null, **Cuando** intento actualizar cuenta A con parent_id=1 (a sí misma), **Entonces** el sistema retorna error 400 "Una cuenta no puede ser su propia cuenta padre". ### Escenario 5: Calcular nivel jerárquico **Dado que** tengo una cuenta con 3 niveles de padres, **Cuando** consulto el endpoint GET /api/v1/financial/accounts/:id?include=hierarchy_level, **Entonces** el sistema retorna hierarchy_level=3. --- ## Reglas de Negocio - **RN-1:** Una cuenta puede tener parent_id (opcional). Si parent_id=null, es cuenta raíz. - **RN-2:** parent_id debe existir en la tabla accounts y pertenecer a la misma empresa. - **RN-3:** Una cuenta no puede ser su propia cuenta padre (prevenir ciclos directos). - **RN-4:** No se permiten ciclos indirectos (A → B → C → A). Validar recursivamente. - **RN-5:** Nivel jerárquico se calcula recursivamente: nivel_padre + 1. Máximo 10 niveles. - **RN-6:** Al eliminar (soft delete) una cuenta padre, las cuentas hijas NO se eliminan automáticamente. --- ## Tareas Técnicas (Checklist de Implementación) ### Backend - [ ] Endpoint: `GET /api/v1/financial/accounts/tree` (retorna estructura jerárquica) - [ ] Endpoint: `GET /api/v1/financial/accounts/:id/children` (hijos directos) - [ ] Endpoint: `GET /api/v1/financial/accounts/:id/ancestors` (padres hasta la raíz) - [ ] Service método: `AccountService.getTree()` (construye árbol con children) - [ ] Service método: `AccountService.getChildren(parentId)` - [ ] Service método: `AccountService.getAncestors(accountId)` - [ ] Service método: `AccountService.validateParent(parentId)` (existe y no crea ciclos) - [ ] Service método: `AccountService.calculateLevel(accountId)` (recursivo) - [ ] Validación: Prevenir ciclos directos e indirectos - [ ] Unit tests: Jerarquía (6 test cases) - [ ] Integration tests: Tree endpoints (5 test cases) - [ ] Swagger docs para endpoints de jerarquía ### Frontend - [ ] Componente: `AccountTree.tsx` (vista árbol con expandir/colapsar) - [ ] Componente: `AccountNode.tsx` (nodo individual del árbol) - [ ] Componente: `AccountHierarchyBreadcrumb.tsx` (breadcrumb de jerarquía) - [ ] Hook: `useAccountTree.ts` (manejo de estado del árbol) - [ ] Función: `buildTree(flatAccounts)` (convierte array plano a árbol) - [ ] Icono: Expandir/Colapsar nodos (chevron-right / chevron-down) - [ ] Indentación visual por nivel (padding-left: nivel * 20px) - [ ] Component tests: AccountTree.test.tsx (5 test cases) - [ ] E2E test: "should expand and collapse account tree nodes" ### Database - [ ] Validar foreign key: `accounts.parent_id → accounts.id` - [ ] Índice: `idx_accounts_parent_id` (ya existe) - [ ] Query recursivo: Common Table Expression (CTE) para calcular niveles - [ ] Seed data: Plan de cuentas jerárquico de ejemplo (3 niveles) --- ## Mockups / Wireframes **Vista Árbol de Plan de Cuentas:** ``` 📂 1 - Activos [Editar] [+] 📂 1.1 - Activos Corrientes [Editar] [+] 📂 1.1.01 - Efectivo y Equivalentes [Editar] [+] 📄 1.1.01.001 - Caja General [Editar] [×] 📄 1.1.01.002 - Banco Santander [Editar] [×] 📂 1.1.02 - Cuentas por Cobrar [Editar] [+] 📂 2 - Pasivos [Editar] [+] 📂 2.1 - Pasivos Corrientes [Editar] [+] ``` **Interacciones:** - Click en icono 📂 / 📄 : Expandir/colapsar nodos - Click en [+]: Crear subcuenta - Click en nombre: Ver detalle de cuenta - Hover: Resaltar nodo completo --- ## Casos de Prueba (Test Scenarios) ### Pruebas Funcionales 1. **TC-001: Crear cuenta con parent_id válido** - Input: parent_id=10 (existe) - Expected: Status 201, cuenta creada con parent_id=10 2. **TC-002: Error por parent_id inexistente** - Input: parent_id=999 - Expected: Status 400, error "Cuenta padre no encontrada" 3. **TC-003: Prevenir ciclo directo (A → A)** - Input: id=1, parent_id=1 - Expected: Status 400, error "Cuenta no puede ser su propia padre" 4. **TC-004: Prevenir ciclo indirecto (A → B → A)** - Input: Cuenta B (parent_id=A) luego actualizar A (parent_id=B) - Expected: Status 400, error "Ciclo detectado en jerarquía" 5. **TC-005: Obtener árbol jerárquico** - Input: GET /accounts/tree - Expected: JSON con structure { id, code, name, children: [...] } 6. **TC-006: Calcular nivel jerárquico correcto** - Input: Cuenta con 3 niveles de padres - Expected: hierarchy_level=3 ### Pruebas No Funcionales 1. **Performance:** GET /accounts/tree < 500ms (hasta 1000 cuentas) 2. **Usabilidad:** Árbol carga niveles lazy (cargar hijos al expandir) --- ## Dependencias - **US bloqueantes:** - US-MGN-004-001-001 (CRUD de Cuentas) - Requerido para crear cuentas base - **Módulos requeridos:** MGN-004 --- ## Notas de Implementación - Usar Common Table Expressions (CTE) recursivos para calcular niveles y ancestros: ```sql WITH RECURSIVE account_hierarchy AS ( SELECT id, parent_id, code, name, 0 as level FROM financial.accounts WHERE parent_id IS NULL UNION ALL SELECT a.id, a.parent_id, a.code, a.name, ah.level + 1 FROM financial.accounts a JOIN account_hierarchy ah ON a.parent_id = ah.id ) SELECT * FROM account_hierarchy ORDER BY code; ``` - Validación de ciclos: Función recursiva que recorre padres hasta root o detecta ciclo - Frontend: Usar `react-arborist` o `react-complex-tree` para vista árbol avanzada - Cache: Cachear árbol completo en Redis (TTL 10 minutos) para evitar recalcular --- ## Estimación Detallada | Tarea | Estimación | |-------|------------| | Backend Development | 2 horas | | Frontend Development (Tree Component) | 2 horas | | Testing | 1.5 horas | | Code Review | 0.5 hora | | **TOTAL** | **6 horas** | **Equivalente:** 3 Story Points --- ## Definition of Done (DoD) - [ ] Código backend implementado (tree endpoints + validación ciclos) - [ ] Código frontend implementado (AccountTree component) - [ ] Unit tests escritos y pasando (cobertura > 80%) - [ ] Integration tests pasando - [ ] E2E test pasando (expand/collapse tree) - [ ] Code review aprobado - [ ] Documentación Swagger actualizada - [ ] RLS aplicado - [ ] Merge a develop - [ ] QA manual completado - [ ] PO aprobado --- ## Referencias - [RF-MGN-004-001: Gestión de Plan de Cuentas](../../02-modelado/requerimientos-funcionales/mgn-004/RF-MGN-004-001-gestión-de-plan-de-cuentas.md) - [ET-BACKEND-MGN-004-001](../../02-modelado/especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-001-gestión-de-plan-de-cuentas.md) - [ET-FRONTEND-MGN-004-001](../../02-modelado/especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-001-gestión-de-plan-de-cuentas.md) - [TRACEABILITY-MGN-004.yaml](../../02-modelado/trazabilidad/TRACEABILITY-MGN-004.yaml) - [Financial Schema DDL](../../02-modelado/database-design/schemas/financial-schema-ddl.sql)