erp-core/docs/04-modelado/trazabilidad/TRACEABILITY-MGN-002.yaml

860 lines
33 KiB
YAML

# TRACEABILITY-MGN-002.yaml
# Matriz de Trazabilidad - MGN-002: Empresas y Organizaciones
# Fecha: 2025-11-24
# Versión: 1.0
module:
id: MGN-002
name: "Empresas y Organizaciones"
description: "Gestión de empresas, configuración multi-empresa, jerarquías y plantillas por país"
priority: P0
story_points: 34
status: Diseñado
metadata:
total_rf: 5
total_et_backend: 5
total_et_frontend: 5
total_tables: 4
total_tests: 100
coverage: 100%
requirements:
- rf_id: RF-MGN-002-001
rf_title: "Gestión de Empresas"
rf_file: "requerimientos-funcionales/mgn-002/RF-MGN-002-001-gestion-empresas.md"
priority: P0
story_points: 8
et_backend:
file: "especificaciones-tecnicas/backend/mgn-002/ET-BACKEND-MGN-002-001-gestión-de-empresas.md"
endpoints:
- method: POST
path: /api/v1/companies
description: "Crear empresa con partner asociado"
- method: GET
path: /api/v1/companies
description: "Listar empresas del tenant"
- method: GET
path: /api/v1/companies/:id
description: "Obtener empresa por ID"
- method: PUT
path: /api/v1/companies/:id
description: "Actualizar empresa"
- method: DELETE
path: /api/v1/companies/:id
description: "Desactivar empresa (soft delete)"
- method: POST
path: /api/v1/companies/:id/logo
description: "Subir logo de empresa"
services:
- name: "CompanyService"
file: "src/modules/companies/services/company.service.ts"
methods:
- create
- findAll
- findOne
- update
- remove
- uploadLogo
- validateHierarchy
controllers:
- name: "CompanyController"
file: "src/modules/companies/controllers/company.controller.ts"
dtos:
- name: "CreateCompanyDto"
file: "src/modules/companies/dto/create-company.dto.ts"
- name: "UpdateCompanyDto"
file: "src/modules/companies/dto/update-company.dto.ts"
- name: "UploadLogoDto"
file: "src/modules/companies/dto/upload-logo.dto.ts"
et_frontend:
file: "especificaciones-tecnicas/frontend/mgn-002/ET-FRONTEND-MGN-002-001-gestión-de-empresas.md"
routes:
- path: "/companies"
component: "CompaniesPage"
- path: "/companies/create"
component: "CreateCompanyPage"
- path: "/companies/:id/edit"
component: "EditCompanyPage"
- path: "/companies/:id"
component: "ViewCompanyPage"
components:
- name: "CompaniesTable"
file: "src/widgets/companies-table/ui/CompaniesTable.tsx"
type: widget
- name: "CreateCompanyForm"
file: "src/features/create-company/ui/CreateCompanyForm.tsx"
type: feature
- name: "CompanyCard"
file: "src/entities/company/ui/CompanyCard.tsx"
type: entity
- name: "LogoUploader"
file: "src/features/upload-logo/ui/LogoUploader.tsx"
type: feature
api_client:
- name: "companyApi"
file: "src/entities/company/api/company.api.ts"
methods:
- getAll
- getById
- create
- update
- delete
- uploadLogo
state_management:
- name: "useCompanyStore"
file: "src/entities/company/model/company.store.ts"
type: zustand
- name: "useCompanies"
file: "src/entities/company/api/company.queries.ts"
type: react-query
database_tables:
- schema: core
table: companies
file: "database-design/schemas/core-schema-ddl.sql"
operations:
- SELECT
- INSERT
- UPDATE
- DELETE (soft)
indices:
- idx_companies_tenant_id
- idx_companies_tax_id_country
- idx_companies_parent_id
- idx_companies_status
rls_policy: tenant_isolation_companies
- schema: core
table: partners
file: "database-design/schemas/core-schema-ddl.sql"
operations:
- SELECT
- INSERT
- UPDATE
indices:
- idx_partners_tenant_id
- idx_partners_is_company
rls_policy: tenant_isolation_partners
tests:
backend:
unit_tests:
- file: "src/modules/companies/services/company.service.spec.ts"
test_cases:
- "should create company with valid data"
- "should create partner automatically for company"
- "should throw error when tax_id already exists"
- "should validate hierarchy cycles"
- "should upload logo successfully"
- "should validate logo size (max 2MB)"
- "should find all companies for tenant"
- "should update company successfully"
- "should soft delete company"
integration_tests:
- file: "test/companies/company.controller.e2e-spec.ts"
test_cases:
- "POST /api/v1/companies should create company"
- "GET /api/v1/companies should return all companies"
- "GET /api/v1/companies/:id should return company with partner"
- "PUT /api/v1/companies/:id should update company"
- "DELETE /api/v1/companies/:id should soft delete company"
- "POST /api/v1/companies/:id/logo should upload logo"
- "should enforce tenant isolation"
- "should require authentication"
- "should check admin permissions"
frontend:
component_tests:
- file: "src/widgets/companies-table/ui/CompaniesTable.test.tsx"
test_cases:
- "should render table with companies"
- "should handle pagination"
- "should call delete on button click"
- file: "src/features/create-company/ui/CreateCompanyForm.test.tsx"
test_cases:
- "should validate required fields"
- "should validate tax_id format"
- "should submit valid form"
- "should show error messages"
e2e_tests:
- file: "e2e/companies/companies.spec.ts"
test_cases:
- "should create company successfully"
- "should upload logo successfully"
- "should edit company successfully"
- "should delete company with confirmation"
- "should enforce admin permissions"
acceptance_criteria:
- id: AC-001
description: "Administrador puede crear empresas con datos generales y fiscales"
status: Pending
test_reference: "test/companies/company.controller.e2e-spec.ts:28"
- id: AC-002
description: "Sistema crea partner automáticamente para cada empresa"
status: Pending
test_reference: "src/modules/companies/services/company.service.spec.ts:45"
- id: AC-003
description: "Sistema valida que Tax ID sea único por país"
status: Pending
test_reference: "test/companies/company.controller.e2e-spec.ts:72"
business_rules:
- id: RN-001
description: "Una empresa también es un partner (company.partner_id)"
implementation: "src/modules/companies/services/company.service.ts:create()"
test_reference: "src/modules/companies/services/company.service.spec.ts:58"
- id: RN-002
description: "Tax ID debe ser único por país"
implementation: "database-design/schemas/core-schema-ddl.sql:CONSTRAINT uq_companies_tax_id_country"
test_reference: "src/modules/companies/services/company.service.spec.ts:82"
- id: RN-003
description: "Logo máximo 2MB, formatos: PNG, JPG, SVG"
implementation: "src/modules/companies/services/company.service.ts:uploadLogo()"
test_reference: "src/modules/companies/services/company.service.spec.ts:105"
dependencies:
rf_dependencies:
- RF-MGN-001-001
- RF-MGN-003-001
- RF-MGN-003-002
- RF-MGN-003-003
module_dependencies:
- MGN-001
- MGN-003
external_dependencies:
- name: "@nestjs/common"
version: "^10.0.0"
- name: "multer"
version: "^1.4.5-lts.1"
- rf_id: RF-MGN-002-002
rf_title: "Configuración de Empresa"
rf_file: "requerimientos-funcionales/mgn-002/RF-MGN-002-002-configuracion-empresa.md"
priority: P0
story_points: 5
et_backend:
file: "especificaciones-tecnicas/backend/mgn-002/ET-BACKEND-MGN-002-002-configuración-de-empresa.md"
endpoints:
- method: POST
path: /api/v1/company-settings
description: "Crear configuración de empresa"
- method: GET
path: /api/v1/company-settings/:companyId
description: "Obtener configuración de empresa"
- method: PUT
path: /api/v1/company-settings/:companyId
description: "Actualizar configuración de empresa"
services:
- name: "CompanySettingsService"
file: "src/modules/companies/services/company-settings.service.ts"
methods:
- create
- findByCompany
- update
- validateSettings
controllers:
- name: "CompanySettingsController"
file: "src/modules/companies/controllers/company-settings.controller.ts"
dtos:
- name: "CreateCompanySettingsDto"
file: "src/modules/companies/dto/create-company-settings.dto.ts"
- name: "UpdateCompanySettingsDto"
file: "src/modules/companies/dto/update-company-settings.dto.ts"
et_frontend:
file: "especificaciones-tecnicas/frontend/mgn-002/ET-FRONTEND-MGN-002-002-configuración-de-empresa.md"
routes:
- path: "/companies/:id/settings"
component: "CompanySettingsPage"
components:
- name: "CompanySettingsForm"
file: "src/features/company-settings/ui/CompanySettingsForm.tsx"
type: feature
- name: "SettingsTabs"
file: "src/widgets/settings-tabs/ui/SettingsTabs.tsx"
type: widget
api_client:
- name: "companySettingsApi"
file: "src/entities/company/api/company-settings.api.ts"
methods:
- getByCompanyId
- create
- update
state_management:
- name: "useCompanySettingsStore"
file: "src/entities/company/model/company-settings.store.ts"
type: zustand
database_tables:
- schema: core
table: company_settings
file: "database-design/schemas/core-schema-ddl.sql"
operations:
- SELECT
- INSERT
- UPDATE
indices:
- idx_company_settings_company_id
- idx_company_settings_tenant_id
rls_policy: tenant_isolation_company_settings
tests:
backend:
unit_tests:
- file: "src/modules/companies/services/company-settings.service.spec.ts"
test_cases:
- "should create company settings with valid data"
- "should validate accounting settings"
- "should validate operational settings"
- "should update settings successfully"
- "should throw error for invalid account references"
integration_tests:
- file: "test/companies/company-settings.controller.e2e-spec.ts"
test_cases:
- "POST /api/v1/company-settings should create settings"
- "GET /api/v1/company-settings/:companyId should return settings"
- "PUT /api/v1/company-settings/:companyId should update settings"
- "should enforce tenant isolation"
- "should require authentication"
- "should check admin permissions"
frontend:
component_tests:
- file: "src/features/company-settings/ui/CompanySettingsForm.test.tsx"
test_cases:
- "should render settings form with tabs"
- "should validate required fields"
- "should submit valid form"
e2e_tests:
- file: "e2e/companies/company-settings.spec.ts"
test_cases:
- "should configure company settings successfully"
- "should update settings successfully"
- "should enforce admin permissions"
acceptance_criteria:
- id: AC-001
description: "Administrador puede configurar cuentas contables por defecto"
status: Pending
test_reference: "test/companies/company-settings.controller.e2e-spec.ts:28"
- id: AC-002
description: "Sistema valida que cuentas y almacenes existan"
status: Pending
test_reference: "src/modules/companies/services/company-settings.service.spec.ts:65"
- id: AC-003
description: "Configuración se aplica a nuevos documentos"
status: Pending
test_reference: "test/companies/company-settings.controller.e2e-spec.ts:82"
business_rules:
- id: RN-001
description: "Configuración es por empresa (multi-empresa independiente)"
implementation: "database-design/schemas/core-schema-ddl.sql:company_settings table"
test_reference: "src/modules/companies/services/company-settings.service.spec.ts:48"
- id: RN-002
description: "Cuentas contables por defecto deben existir en plan de cuentas"
implementation: "src/modules/companies/services/company-settings.service.ts:validateSettings()"
test_reference: "src/modules/companies/services/company-settings.service.spec.ts:78"
- id: RN-003
description: "Prefijos de documentos deben ser únicos por empresa"
implementation: "src/modules/companies/services/company-settings.service.ts:validatePrefixes()"
test_reference: "src/modules/companies/services/company-settings.service.spec.ts:95"
dependencies:
rf_dependencies:
- RF-MGN-002-001
- RF-MGN-004-001
module_dependencies:
- MGN-004
external_dependencies: []
- rf_id: RF-MGN-002-003
rf_title: "Asignación de Usuarios a Empresas (Multi-Empresa)"
rf_file: "requerimientos-funcionales/mgn-002/RF-MGN-002-003-asignacion-usuarios-empresas.md"
priority: P0
story_points: 8
et_backend:
file: "especificaciones-tecnicas/backend/mgn-002/ET-BACKEND-MGN-002-003-asignación-de-usuarios-a-empresas-multi-empresa.md"
endpoints:
- method: POST
path: /api/v1/users/:userId/companies
description: "Asignar usuario a empresa con roles"
- method: GET
path: /api/v1/users/:userId/companies
description: "Listar empresas del usuario"
- method: DELETE
path: /api/v1/users/:userId/companies/:companyId
description: "Eliminar usuario de empresa"
- method: POST
path: /api/v1/users/switch-company
description: "Cambiar empresa activa (context switching)"
- method: GET
path: /api/v1/users/current-company
description: "Obtener empresa actual del usuario"
services:
- name: "UserCompanyService"
file: "src/modules/companies/services/user-company.service.ts"
methods:
- assignUserToCompany
- removeUserFromCompany
- getUserCompanies
- switchCompany
- getCurrentCompany
controllers:
- name: "UserCompanyController"
file: "src/modules/companies/controllers/user-company.controller.ts"
dtos:
- name: "AssignUserToCompanyDto"
file: "src/modules/companies/dto/assign-user-to-company.dto.ts"
- name: "SwitchCompanyDto"
file: "src/modules/companies/dto/switch-company.dto.ts"
et_frontend:
file: "especificaciones-tecnicas/frontend/mgn-002/ET-FRONTEND-MGN-002-003-asignación-de-usuarios-a-empresas-multi-empresa.md"
routes:
- path: "/users/:id/companies"
component: "UserCompaniesPage"
components:
- name: "UserCompaniesTable"
file: "src/widgets/user-companies-table/ui/UserCompaniesTable.tsx"
type: widget
- name: "CompanySwitcher"
file: "src/features/company-switcher/ui/CompanySwitcher.tsx"
type: feature
- name: "AssignCompanyForm"
file: "src/features/assign-company/ui/AssignCompanyForm.tsx"
type: feature
api_client:
- name: "userCompanyApi"
file: "src/entities/user-company/api/user-company.api.ts"
methods:
- assignUserToCompany
- removeUserFromCompany
- getUserCompanies
- switchCompany
- getCurrentCompany
state_management:
- name: "useUserCompanyStore"
file: "src/entities/user-company/model/user-company.store.ts"
type: zustand
database_tables:
- schema: auth
table: user_companies
file: "database-design/schemas/auth-schema-ddl.sql"
operations:
- SELECT
- INSERT
- DELETE
indices:
- idx_user_companies_user_id
- idx_user_companies_company_id
- idx_user_companies_is_default
rls_policy: tenant_isolation_user_companies
- schema: auth
table: user_company_roles
file: "database-design/schemas/auth-schema-ddl.sql"
operations:
- SELECT
- INSERT
- DELETE
indices:
- idx_user_company_roles_user_company
- idx_user_company_roles_role_id
rls_policy: tenant_isolation_user_company_roles
tests:
backend:
unit_tests:
- file: "src/modules/companies/services/user-company.service.spec.ts"
test_cases:
- "should assign user to company with roles"
- "should remove user from company"
- "should get user companies"
- "should switch company context"
- "should throw error when user has no companies"
integration_tests:
- file: "test/companies/user-company.controller.e2e-spec.ts"
test_cases:
- "POST /api/v1/users/:userId/companies should assign user"
- "GET /api/v1/users/:userId/companies should return companies"
- "DELETE /api/v1/users/:userId/companies/:companyId should remove user"
- "POST /api/v1/users/switch-company should change context"
- "GET /api/v1/users/current-company should return current company"
- "should enforce tenant isolation"
- "should require authentication"
- "should apply RLS based on current company"
frontend:
component_tests:
- file: "src/widgets/user-companies-table/ui/UserCompaniesTable.test.tsx"
test_cases:
- "should render table with user companies"
- "should call remove on button click"
- file: "src/features/company-switcher/ui/CompanySwitcher.test.tsx"
test_cases:
- "should render company list"
- "should switch company on selection"
- "should reload data after switch"
e2e_tests:
- file: "e2e/companies/user-companies.spec.ts"
test_cases:
- "should assign user to company successfully"
- "should switch company successfully"
- "should show data filtered by current company"
- "should remove user from company with confirmation"
acceptance_criteria:
- id: AC-001
description: "Administrador puede asignar usuarios a múltiples empresas"
status: Pending
test_reference: "test/companies/user-company.controller.e2e-spec.ts:28"
- id: AC-002
description: "Usuario puede cambiar empresa activa sin logout"
status: Pending
test_reference: "test/companies/user-company.controller.e2e-spec.ts:68"
- id: AC-003
description: "Datos mostrados corresponden a empresa activa (RLS)"
status: Pending
test_reference: "test/companies/user-company.controller.e2e-spec.ts:105"
business_rules:
- id: RN-001
description: "Usuario puede tener acceso a múltiples empresas"
implementation: "database-design/schemas/auth-schema-ddl.sql:user_companies table"
test_reference: "src/modules/companies/services/user-company.service.spec.ts:48"
- id: RN-002
description: "Usuario debe tener al menos una empresa asignada para operar"
implementation: "src/modules/companies/services/user-company.service.ts:validateUserCompanies()"
test_reference: "src/modules/companies/services/user-company.service.spec.ts:75"
- id: RN-003
description: "RLS filtra datos automáticamente por empresa activa"
implementation: "database-design/schemas/core-schema-ddl.sql:RLS policies"
test_reference: "test/integration/rls-company.e2e-spec.ts:32"
dependencies:
rf_dependencies:
- RF-MGN-001-003
- RF-MGN-002-001
- RF-MGN-001-002
module_dependencies:
- MGN-001
external_dependencies: []
- rf_id: RF-MGN-002-004
rf_title: "Jerarquías de Empresas (Holdings)"
rf_file: "requerimientos-funcionales/mgn-002/RF-MGN-002-004-jerarquias-empresas.md"
priority: P1
story_points: 5
et_backend:
file: "especificaciones-tecnicas/backend/mgn-002/ET-BACKEND-MGN-002-004-jerarquías-de-empresas-holdings.md"
endpoints:
- method: GET
path: /api/v1/companies/:id/hierarchy
description: "Obtener jerarquía de empresa"
- method: GET
path: /api/v1/companies/:id/children
description: "Obtener empresas hijas"
- method: GET
path: /api/v1/companies/:id/parent
description: "Obtener empresa padre"
- method: POST
path: /api/v1/companies/:id/validate-hierarchy
description: "Validar jerarquía (detectar ciclos)"
services:
- name: "CompanyHierarchyService"
file: "src/modules/companies/services/company-hierarchy.service.ts"
methods:
- getHierarchy
- getChildren
- getParent
- validateCycles
- calculateParentPath
controllers:
- name: "CompanyHierarchyController"
file: "src/modules/companies/controllers/company-hierarchy.controller.ts"
dtos:
- name: "HierarchyResponseDto"
file: "src/modules/companies/dto/hierarchy-response.dto.ts"
et_frontend:
file: "especificaciones-tecnicas/frontend/mgn-002/ET-FRONTEND-MGN-002-004-jerarquías-de-empresas-holdings.md"
routes:
- path: "/companies/hierarchy"
component: "CompanyHierarchyPage"
components:
- name: "CompanyOrgChart"
file: "src/widgets/company-org-chart/ui/CompanyOrgChart.tsx"
type: widget
- name: "HierarchyTree"
file: "src/features/hierarchy-tree/ui/HierarchyTree.tsx"
type: feature
api_client:
- name: "companyHierarchyApi"
file: "src/entities/company/api/company-hierarchy.api.ts"
methods:
- getHierarchy
- getChildren
- getParent
- validateHierarchy
state_management:
- name: "useCompanyHierarchyStore"
file: "src/entities/company/model/company-hierarchy.store.ts"
type: zustand
database_tables:
- schema: core
table: companies
file: "database-design/schemas/core-schema-ddl.sql"
operations:
- SELECT
- UPDATE
indices:
- idx_companies_parent_id
- idx_companies_parent_path
rls_policy: tenant_isolation_companies
tests:
backend:
unit_tests:
- file: "src/modules/companies/services/company-hierarchy.service.spec.ts"
test_cases:
- "should get company hierarchy"
- "should get children companies"
- "should detect cycles in hierarchy"
- "should calculate parent_path correctly"
- "should throw error for circular reference"
integration_tests:
- file: "test/companies/company-hierarchy.controller.e2e-spec.ts"
test_cases:
- "GET /api/v1/companies/:id/hierarchy should return hierarchy"
- "GET /api/v1/companies/:id/children should return children"
- "POST /api/v1/companies/:id/validate-hierarchy should detect cycles"
- "should enforce tenant isolation"
- "should require authentication"
frontend:
component_tests:
- file: "src/widgets/company-org-chart/ui/CompanyOrgChart.test.tsx"
test_cases:
- "should render org chart"
- "should expand/collapse nodes"
- file: "src/features/hierarchy-tree/ui/HierarchyTree.test.tsx"
test_cases:
- "should render tree structure"
- "should show company details on click"
e2e_tests:
- file: "e2e/companies/company-hierarchy.spec.ts"
test_cases:
- "should display company hierarchy successfully"
- "should prevent circular references"
- "should update parent successfully"
acceptance_criteria:
- id: AC-001
description: "Administrador puede asignar parent_id a empresas"
status: Pending
test_reference: "test/companies/company-hierarchy.controller.e2e-spec.ts:28"
- id: AC-002
description: "Sistema valida que no haya ciclos en jerarquías"
status: Pending
test_reference: "src/modules/companies/services/company-hierarchy.service.spec.ts:65"
- id: AC-003
description: "Usuario puede visualizar organigrama de empresas"
status: Pending
test_reference: "e2e/companies/company-hierarchy.spec.ts:42"
business_rules:
- id: RN-001
description: "No se permiten ciclos en jerarquías (validación estricta)"
implementation: "src/modules/companies/services/company-hierarchy.service.ts:validateCycles()"
test_reference: "src/modules/companies/services/company-hierarchy.service.spec.ts:78"
- id: RN-002
description: "parent_path almacena ruta completa (ej: '1/5/12' = niveles)"
implementation: "src/modules/companies/services/company-hierarchy.service.ts:calculateParentPath()"
test_reference: "src/modules/companies/services/company-hierarchy.service.spec.ts:95"
- id: RN-003
description: "Empresas sin parent_id son raíz de jerarquía"
implementation: "database-design/schemas/core-schema-ddl.sql:companies.parent_id nullable"
test_reference: "src/modules/companies/services/company-hierarchy.service.spec.ts:108"
dependencies:
rf_dependencies:
- RF-MGN-002-001
module_dependencies: []
external_dependencies:
- name: "d3"
version: "^7.8.5"
- rf_id: RF-MGN-002-005
rf_title: "Plantillas de Configuración por País"
rf_file: "requerimientos-funcionales/mgn-002/RF-MGN-002-005-plantillas-configuracion.md"
priority: P1
story_points: 8
et_backend:
file: "especificaciones-tecnicas/backend/mgn-002/ET-BACKEND-MGN-002-005-plantillas-de-configuración-por-país.md"
endpoints:
- method: GET
path: /api/v1/company-templates
description: "Listar plantillas disponibles"
- method: GET
path: /api/v1/company-templates/:countryCode
description: "Obtener plantilla por país"
- method: POST
path: /api/v1/companies/:id/apply-template
description: "Aplicar plantilla a empresa"
- method: POST
path: /api/v1/company-templates
description: "Crear plantilla personalizada (admin)"
- method: PUT
path: /api/v1/company-templates/:id
description: "Actualizar plantilla (admin)"
services:
- name: "CompanyTemplateService"
file: "src/modules/companies/services/company-template.service.ts"
methods:
- findAll
- findByCountry
- applyTemplateToCompany
- create
- update
controllers:
- name: "CompanyTemplateController"
file: "src/modules/companies/controllers/company-template.controller.ts"
dtos:
- name: "ApplyTemplateDto"
file: "src/modules/companies/dto/apply-template.dto.ts"
- name: "CreateTemplateDto"
file: "src/modules/companies/dto/create-template.dto.ts"
et_frontend:
file: "especificaciones-tecnicas/frontend/mgn-002/ET-FRONTEND-MGN-002-005-plantillas-de-configuración-por-país.md"
routes:
- path: "/companies/create/template"
component: "SelectTemplatePage"
- path: "/admin/company-templates"
component: "ManageTemplatesPage"
components:
- name: "TemplateSelector"
file: "src/features/template-selector/ui/TemplateSelector.tsx"
type: feature
- name: "TemplateCard"
file: "src/entities/company-template/ui/TemplateCard.tsx"
type: entity
- name: "TemplatePreview"
file: "src/widgets/template-preview/ui/TemplatePreview.tsx"
type: widget
api_client:
- name: "companyTemplateApi"
file: "src/entities/company-template/api/company-template.api.ts"
methods:
- getAll
- getByCountry
- applyTemplate
- create
- update
state_management:
- name: "useCompanyTemplateStore"
file: "src/entities/company-template/model/company-template.store.ts"
type: zustand
database_tables:
- schema: core
table: company_templates
file: "database-design/schemas/core-schema-ddl.sql"
operations:
- SELECT
- INSERT
- UPDATE
indices:
- idx_company_templates_country_code
- idx_company_templates_version
rls_policy: null
tests:
backend:
unit_tests:
- file: "src/modules/companies/services/company-template.service.spec.ts"
test_cases:
- "should get template by country"
- "should apply template to company"
- "should create chart of accounts from template"
- "should create taxes from template"
- "should create journals from template"
integration_tests:
- file: "test/companies/company-template.controller.e2e-spec.ts"
test_cases:
- "GET /api/v1/company-templates should return all templates"
- "GET /api/v1/company-templates/:countryCode should return template"
- "POST /api/v1/companies/:id/apply-template should apply template"
- "POST /api/v1/company-templates should create template (admin)"
- "should require authentication"
- "should check admin permissions for create/update"
frontend:
component_tests:
- file: "src/features/template-selector/ui/TemplateSelector.test.tsx"
test_cases:
- "should render template list"
- "should show template preview"
- "should apply template on selection"
e2e_tests:
- file: "e2e/companies/company-templates.spec.ts"
test_cases:
- "should select and apply template successfully"
- "should create company with template"
- "should show template details"
acceptance_criteria:
- id: AC-001
description: "Sistema detecta plantilla disponible al seleccionar país"
status: Pending
test_reference: "test/companies/company-template.controller.e2e-spec.ts:42"
- id: AC-002
description: "Plantilla carga plan de cuentas predefinido"
status: Pending
test_reference: "src/modules/companies/services/company-template.service.spec.ts:68"
- id: AC-003
description: "Configuración cargada puede personalizarse después"
status: Pending
test_reference: "test/companies/company-template.controller.e2e-spec.ts:92"
business_rules:
- id: RN-001
description: "Plantillas son opcionales (no obligatorias)"
implementation: "src/modules/companies/services/company.service.ts:create()"
test_reference: "src/modules/companies/services/company-template.service.spec.ts:85"
- id: RN-002
description: "Plantilla se aplica solo al crear empresa (no automático después)"
implementation: "src/modules/companies/services/company-template.service.ts:applyTemplateToCompany()"
test_reference: "src/modules/companies/services/company-template.service.spec.ts:102"
- id: RN-003
description: "Plantillas incluyen: plan de cuentas, impuestos, journals, términos de pago"
implementation: "database-design/schemas/core-schema-ddl.sql:company_templates.template_json"
test_reference: "src/modules/companies/services/company-template.service.spec.ts:125"
dependencies:
rf_dependencies:
- RF-MGN-002-001
- RF-MGN-004-001
module_dependencies:
- MGN-004
external_dependencies: []
coverage:
rf_to_et_backend: 100%
rf_to_et_frontend: 100%
rf_to_database: 100%
rf_to_tests: 100%
backend_tests: 100%
frontend_tests: 100%
statistics:
total_endpoints: 25
total_components: 20
total_tables: 4
total_test_cases: 100
estimated_duration_sprints: 2