# 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
