# TRACEABILITY-MGN-004.yaml
# Matriz de Trazabilidad - MGN-004: Financiero Básico
# Fecha: 2025-11-24
# Versión: 1.0

module:
  id: MGN-004
  name: "Financiero Básico"
  description: "Plan de cuentas, journals, asientos contables, impuestos, facturas y pagos"
  priority: P0
  story_points: 81
  status: Diseñado

metadata:
  total_rf: 8
  total_et_backend: 8
  total_et_frontend: 8
  total_tables: 12
  total_tests: 160
  coverage: 100%

requirements:
  - rf_id: RF-MGN-004-001
    rf_title: "Gestión de Plan de Cuentas"
    rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-001-gestión-de-plan-de-cuentas.md"
    priority: P0
    story_points: 8

    et_backend:
      file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-001-gestión-de-plan-de-cuentas.md"
      endpoints:
        - method: POST
          path: /api/v1/financial/accounts
          description: "Crear cuenta contable"
        - method: GET
          path: /api/v1/financial/accounts
          description: "Listar cuentas contables"
        - method: GET
          path: /api/v1/financial/accounts/:id
          description: "Obtener cuenta por ID"
        - method: PUT
          path: /api/v1/financial/accounts/:id
          description: "Actualizar cuenta"
        - method: DELETE
          path: /api/v1/financial/accounts/:id
          description: "Desactivar cuenta"
      services:
        - name: "AccountService"
          file: "src/modules/financial/services/account.service.ts"
          methods:
            - create
            - findAll
            - findOne
            - update
            - remove
      controllers:
        - name: "AccountController"
          file: "src/modules/financial/controllers/account.controller.ts"
      dtos:
        - name: "CreateAccountDto"
          file: "src/modules/financial/dto/create-account.dto.ts"
        - name: "UpdateAccountDto"
          file: "src/modules/financial/dto/update-account.dto.ts"

    et_frontend:
      file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-001-gestión-de-plan-de-cuentas.md"
      routes:
        - path: "/financial/accounts"
          component: "AccountsPage"
        - path: "/financial/accounts/create"
          component: "CreateAccountPage"
        - path: "/financial/accounts/:id/edit"
          component: "EditAccountPage"
        - path: "/financial/accounts/:id"
          component: "ViewAccountPage"
      components:
        - name: "AccountsTable"
          file: "src/widgets/accounts-table/ui/AccountsTable.tsx"
          type: widget
        - name: "CreateAccountForm"
          file: "src/features/create-account/ui/CreateAccountForm.tsx"
          type: feature
        - name: "AccountCard"
          file: "src/entities/account/ui/AccountCard.tsx"
          type: entity
        - name: "AccountTree"
          file: "src/widgets/account-tree/ui/AccountTree.tsx"
          type: widget
      api_client:
        - name: "accountApi"
          file: "src/entities/account/api/account.api.ts"
          methods:
            - getAll
            - getById
            - create
            - update
            - delete
      state_management:
        - name: "useAccountStore"
          file: "src/entities/account/model/account.store.ts"
          type: zustand

    database_tables:
      - schema: financial
        table: accounts
        file: "database-design/schemas/financial-schema-ddl.sql"
        operations:
          - SELECT
          - INSERT
          - UPDATE
          - DELETE (soft)
        indices:
          - idx_accounts_company_id
          - idx_accounts_code
          - idx_accounts_parent_id
          - idx_accounts_type
        rls_policy: company_isolation_accounts

    tests:
      backend:
        unit_tests:
          - file: "src/modules/financial/services/account.service.spec.ts"
            test_cases:
              - "should create account with valid data"
              - "should create hierarchical accounts"
              - "should validate account code uniqueness"
              - "should throw error when parent not found"
              - "should update account successfully"
              - "should soft delete account"
        integration_tests:
          - file: "test/financial/account.controller.e2e-spec.ts"
            test_cases:
              - "POST /api/v1/financial/accounts should create account"
              - "GET /api/v1/financial/accounts should return all accounts"
              - "GET /api/v1/financial/accounts/:id should return account"
              - "PUT /api/v1/financial/accounts/:id should update account"
              - "DELETE /api/v1/financial/accounts/:id should soft delete account"
              - "should enforce company isolation"
              - "should require authentication"
              - "should check accounting permissions"
      frontend:
        component_tests:
          - file: "src/widgets/accounts-table/ui/AccountsTable.test.tsx"
            test_cases:
              - "should render table with accounts"
              - "should handle pagination"
              - "should filter by type"
          - file: "src/features/create-account/ui/CreateAccountForm.test.tsx"
            test_cases:
              - "should validate required fields"
              - "should validate account code format"
              - "should submit valid form"
        e2e_tests:
          - file: "e2e/financial/accounts.spec.ts"
            test_cases:
              - "should create account successfully"
              - "should create child account"
              - "should edit account successfully"
              - "should delete account with confirmation"

    acceptance_criteria:
      - id: AC-001
        description: "Usuario puede crear plan de cuentas jerárquico"
        status: Pending
        test_reference: "test/financial/account.controller.e2e-spec.ts:28"
      - id: AC-002
        description: "Cuentas tienen tipos: asset, liability, equity, income, expense"
        status: Pending
        test_reference: "src/modules/financial/services/account.service.spec.ts:65"
      - id: AC-003
        description: "Código de cuenta es único por empresa"
        status: Pending
        test_reference: "test/financial/account.controller.e2e-spec.ts:95"

    business_rules:
      - id: RN-001
        description: "Código de cuenta único por empresa"
        implementation: "database-design/schemas/financial-schema-ddl.sql:CONSTRAINT uq_accounts_code_company"
        test_reference: "src/modules/financial/services/account.service.spec.ts:48"
      - id: RN-002
        description: "Cuentas soportan jerarquía con parent_id"
        implementation: "database-design/schemas/financial-schema-ddl.sql:accounts.parent_id"
        test_reference: "src/modules/financial/services/account.service.spec.ts:78"
      - id: RN-003
        description: "No se puede eliminar cuenta con movimientos"
        implementation: "src/modules/financial/services/account.service.ts:remove()"
        test_reference: "src/modules/financial/services/account.service.spec.ts:108"

    dependencies:
      rf_dependencies:
        - RF-MGN-002-001
      module_dependencies:
        - MGN-002
      external_dependencies: []

  - rf_id: RF-MGN-004-002
    rf_title: "Gestión de Journals Contables"
    rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-002-gestión-de-journals-contables.md"
    priority: P0
    story_points: 5

    et_backend:
      file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-002-gestión-de-journals-contables.md"
      endpoints:
        - method: POST
          path: /api/v1/financial/journals
          description: "Crear journal"
        - method: GET
          path: /api/v1/financial/journals
          description: "Listar journals"
        - method: GET
          path: /api/v1/financial/journals/:id
          description: "Obtener journal por ID"
        - method: PUT
          path: /api/v1/financial/journals/:id
          description: "Actualizar journal"
        - method: DELETE
          path: /api/v1/financial/journals/:id
          description: "Desactivar journal"
      services:
        - name: "JournalService"
          file: "src/modules/financial/services/journal.service.ts"
          methods:
            - create
            - findAll
            - findOne
            - update
            - remove
      controllers:
        - name: "JournalController"
          file: "src/modules/financial/controllers/journal.controller.ts"
      dtos:
        - name: "CreateJournalDto"
          file: "src/modules/financial/dto/create-journal.dto.ts"
        - name: "UpdateJournalDto"
          file: "src/modules/financial/dto/update-journal.dto.ts"

    et_frontend:
      file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-002-gestión-de-journals-contables.md"
      routes:
        - path: "/financial/journals"
          component: "JournalsPage"
        - path: "/financial/journals/create"
          component: "CreateJournalPage"
      components:
        - name: "JournalsTable"
          file: "src/widgets/journals-table/ui/JournalsTable.tsx"
          type: widget
        - name: "CreateJournalForm"
          file: "src/features/create-journal/ui/CreateJournalForm.tsx"
          type: feature
        - name: "JournalCard"
          file: "src/entities/journal/ui/JournalCard.tsx"
          type: entity
      api_client:
        - name: "journalApi"
          file: "src/entities/journal/api/journal.api.ts"
          methods:
            - getAll
            - getById
            - create
            - update
            - delete
      state_management:
        - name: "useJournalStore"
          file: "src/entities/journal/model/journal.store.ts"
          type: zustand

    database_tables:
      - schema: financial
        table: journals
        file: "database-design/schemas/financial-schema-ddl.sql"
        operations:
          - SELECT
          - INSERT
          - UPDATE
          - DELETE (soft)
        indices:
          - idx_journals_company_id
          - idx_journals_code
          - idx_journals_type
        rls_policy: company_isolation_journals

    tests:
      backend:
        unit_tests:
          - file: "src/modules/financial/services/journal.service.spec.ts"
            test_cases:
              - "should create journal with valid data"
              - "should validate journal type"
              - "should throw error when code already exists"
              - "should update journal successfully"
              - "should soft delete journal"
        integration_tests:
          - file: "test/financial/journal.controller.e2e-spec.ts"
            test_cases:
              - "POST /api/v1/financial/journals should create journal"
              - "GET /api/v1/financial/journals should return all journals"
              - "GET /api/v1/financial/journals/:id should return journal"
              - "PUT /api/v1/financial/journals/:id should update journal"
              - "DELETE /api/v1/financial/journals/:id should soft delete journal"
              - "should enforce company isolation"
              - "should require authentication"
      frontend:
        component_tests:
          - file: "src/widgets/journals-table/ui/JournalsTable.test.tsx"
            test_cases:
              - "should render table with journals"
              - "should filter by type"
          - file: "src/features/create-journal/ui/CreateJournalForm.test.tsx"
            test_cases:
              - "should validate required fields"
              - "should submit valid form"
        e2e_tests:
          - file: "e2e/financial/journals.spec.ts"
            test_cases:
              - "should create journal successfully"
              - "should edit journal successfully"
              - "should delete journal with confirmation"

    acceptance_criteria:
      - id: AC-001
        description: "Usuario puede crear journals por tipo (sale, purchase, bank, general)"
        status: Pending
        test_reference: "test/financial/journal.controller.e2e-spec.ts:28"
      - id: AC-002
        description: "Journal tiene código único por empresa"
        status: Pending
        test_reference: "src/modules/financial/services/journal.service.spec.ts:65"
      - id: AC-003
        description: "Asientos contables están vinculados a journals"
        status: Pending
        test_reference: "test/financial/journal.controller.e2e-spec.ts:95"

    business_rules:
      - id: RN-001
        description: "Código de journal único por empresa"
        implementation: "database-design/schemas/financial-schema-ddl.sql:CONSTRAINT uq_journals_code_company"
        test_reference: "src/modules/financial/services/journal.service.spec.ts:48"
      - id: RN-002
        description: "Journals tienen tipos: sale, purchase, bank, cash, general"
        implementation: "database-design/schemas/financial-schema-ddl.sql:journals.type enum"
        test_reference: "src/modules/financial/services/journal.service.spec.ts:78"
      - id: RN-003
        description: "No se puede eliminar journal con asientos"
        implementation: "src/modules/financial/services/journal.service.ts:remove()"
        test_reference: "src/modules/financial/services/journal.service.spec.ts:95"

    dependencies:
      rf_dependencies:
        - RF-MGN-002-001
        - RF-MGN-004-001
      module_dependencies:
        - MGN-002
      external_dependencies: []

  - rf_id: RF-MGN-004-003
    rf_title: "Registro de Asientos Contables"
    rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-003-registro-de-asientos-contables.md"
    priority: P0
    story_points: 13

    et_backend:
      file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-003-registro-de-asientos-contables.md"
      endpoints:
        - method: POST
          path: /api/v1/financial/journal-entries
          description: "Crear asiento contable"
        - method: GET
          path: /api/v1/financial/journal-entries
          description: "Listar asientos"
        - method: GET
          path: /api/v1/financial/journal-entries/:id
          description: "Obtener asiento por ID"
        - method: PUT
          path: /api/v1/financial/journal-entries/:id
          description: "Actualizar asiento (draft)"
        - method: POST
          path: /api/v1/financial/journal-entries/:id/post
          description: "Publicar asiento (draft → posted)"
        - method: DELETE
          path: /api/v1/financial/journal-entries/:id
          description: "Eliminar asiento (draft)"
      services:
        - name: "JournalEntryService"
          file: "src/modules/financial/services/journal-entry.service.ts"
          methods:
            - create
            - findAll
            - findOne
            - update
            - post
            - remove
            - validateBalance
      controllers:
        - name: "JournalEntryController"
          file: "src/modules/financial/controllers/journal-entry.controller.ts"
      dtos:
        - name: "CreateJournalEntryDto"
          file: "src/modules/financial/dto/create-journal-entry.dto.ts"
        - name: "UpdateJournalEntryDto"
          file: "src/modules/financial/dto/update-journal-entry.dto.ts"

    et_frontend:
      file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-003-registro-de-asientos-contables.md"
      routes:
        - path: "/financial/journal-entries"
          component: "JournalEntriesPage"
        - path: "/financial/journal-entries/create"
          component: "CreateJournalEntryPage"
        - path: "/financial/journal-entries/:id/edit"
          component: "EditJournalEntryPage"
        - path: "/financial/journal-entries/:id"
          component: "ViewJournalEntryPage"
      components:
        - name: "JournalEntriesTable"
          file: "src/widgets/journal-entries-table/ui/JournalEntriesTable.tsx"
          type: widget
        - name: "CreateJournalEntryForm"
          file: "src/features/create-journal-entry/ui/CreateJournalEntryForm.tsx"
          type: feature
        - name: "JournalEntryCard"
          file: "src/entities/journal-entry/ui/JournalEntryCard.tsx"
          type: entity
        - name: "JournalEntryLineItems"
          file: "src/widgets/journal-entry-lines/ui/JournalEntryLineItems.tsx"
          type: widget
      api_client:
        - name: "journalEntryApi"
          file: "src/entities/journal-entry/api/journal-entry.api.ts"
          methods:
            - getAll
            - getById
            - create
            - update
            - post
            - delete
      state_management:
        - name: "useJournalEntryStore"
          file: "src/entities/journal-entry/model/journal-entry.store.ts"
          type: zustand

    database_tables:
      - schema: financial
        table: journal_entries
        file: "database-design/schemas/financial-schema-ddl.sql"
        operations:
          - SELECT
          - INSERT
          - UPDATE
          - DELETE
        indices:
          - idx_journal_entries_journal_id
          - idx_journal_entries_company_id
          - idx_journal_entries_date
          - idx_journal_entries_state
        rls_policy: company_isolation_journal_entries
      - schema: financial
        table: journal_entry_lines
        file: "database-design/schemas/financial-schema-ddl.sql"
        operations:
          - SELECT
          - INSERT
          - UPDATE
          - DELETE
        indices:
          - idx_journal_entry_lines_entry_id
          - idx_journal_entry_lines_account_id
          - idx_journal_entry_lines_partner_id
        rls_policy: company_isolation_journal_entry_lines

    tests:
      backend:
        unit_tests:
          - file: "src/modules/financial/services/journal-entry.service.spec.ts"
            test_cases:
              - "should create journal entry with lines"
              - "should validate debit = credit balance"
              - "should throw error for unbalanced entry"
              - "should post entry (draft → posted)"
              - "should prevent editing posted entry"
              - "should allow deleting draft entry"
              - "should prevent deleting posted entry"
        integration_tests:
          - file: "test/financial/journal-entry.controller.e2e-spec.ts"
            test_cases:
              - "POST /api/v1/financial/journal-entries should create entry"
              - "GET /api/v1/financial/journal-entries should return all entries"
              - "GET /api/v1/financial/journal-entries/:id should return entry with lines"
              - "PUT /api/v1/financial/journal-entries/:id should update draft entry"
              - "POST /api/v1/financial/journal-entries/:id/post should post entry"
              - "DELETE /api/v1/financial/journal-entries/:id should delete draft entry"
              - "should enforce company isolation"
              - "should require authentication"
              - "should check accounting permissions"
      frontend:
        component_tests:
          - file: "src/widgets/journal-entries-table/ui/JournalEntriesTable.test.tsx"
            test_cases:
              - "should render table with entries"
              - "should filter by state"
              - "should handle pagination"
          - file: "src/features/create-journal-entry/ui/CreateJournalEntryForm.test.tsx"
            test_cases:
              - "should validate required fields"
              - "should validate debit = credit"
              - "should submit valid form"
        e2e_tests:
          - file: "e2e/financial/journal-entries.spec.ts"
            test_cases:
              - "should create journal entry successfully"
              - "should post entry successfully"
              - "should show error for unbalanced entry"
              - "should prevent editing posted entry"

    acceptance_criteria:
      - id: AC-001
        description: "Usuario puede crear asientos contables con múltiples líneas"
        status: Pending
        test_reference: "test/financial/journal-entry.controller.e2e-spec.ts:28"
      - id: AC-002
        description: "Sistema valida que suma de débitos = suma de créditos"
        status: Pending
        test_reference: "src/modules/financial/services/journal-entry.service.spec.ts:65"
      - id: AC-003
        description: "Asientos publicados no pueden modificarse"
        status: Pending
        test_reference: "test/financial/journal-entry.controller.e2e-spec.ts:105"

    business_rules:
      - id: RN-001
        description: "Suma de débitos debe igualar suma de créditos"
        implementation: "src/modules/financial/services/journal-entry.service.ts:validateBalance()"
        test_reference: "src/modules/financial/services/journal-entry.service.spec.ts:48"
      - id: RN-002
        description: "Asientos tienen estados: draft, posted"
        implementation: "database-design/schemas/financial-schema-ddl.sql:journal_entries.state"
        test_reference: "src/modules/financial/services/journal-entry.service.spec.ts:78"
      - id: RN-003
        description: "Solo asientos draft pueden modificarse o eliminarse"
        implementation: "src/modules/financial/services/journal-entry.service.ts:update()"
        test_reference: "src/modules/financial/services/journal-entry.service.spec.ts:108"

    dependencies:
      rf_dependencies:
        - RF-MGN-004-001
        - RF-MGN-004-002
        - RF-MGN-003-001
      module_dependencies:
        - MGN-003
      external_dependencies: []

  - rf_id: RF-MGN-004-004
    rf_title: "Gestión de Impuestos"
    rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-004-gestión-de-impuestos.md"
    priority: P0
    story_points: 8

    et_backend:
      file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-004-gestión-de-impuestos.md"
      endpoints:
        - method: POST
          path: /api/v1/financial/taxes
          description: "Crear impuesto"
        - method: GET
          path: /api/v1/financial/taxes
          description: "Listar impuestos"
        - method: GET
          path: /api/v1/financial/taxes/:id
          description: "Obtener impuesto por ID"
        - method: PUT
          path: /api/v1/financial/taxes/:id
          description: "Actualizar impuesto"
        - method: DELETE
          path: /api/v1/financial/taxes/:id
          description: "Desactivar impuesto"
      services:
        - name: "TaxService"
          file: "src/modules/financial/services/tax.service.ts"
          methods:
            - create
            - findAll
            - findOne
            - update
            - remove
            - calculateTax
      controllers:
        - name: "TaxController"
          file: "src/modules/financial/controllers/tax.controller.ts"
      dtos:
        - name: "CreateTaxDto"
          file: "src/modules/financial/dto/create-tax.dto.ts"
        - name: "UpdateTaxDto"
          file: "src/modules/financial/dto/update-tax.dto.ts"

    et_frontend:
      file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-004-gestión-de-impuestos.md"
      routes:
        - path: "/financial/taxes"
          component: "TaxesPage"
        - path: "/financial/taxes/create"
          component: "CreateTaxPage"
      components:
        - name: "TaxesTable"
          file: "src/widgets/taxes-table/ui/TaxesTable.tsx"
          type: widget
        - name: "CreateTaxForm"
          file: "src/features/create-tax/ui/CreateTaxForm.tsx"
          type: feature
        - name: "TaxCard"
          file: "src/entities/tax/ui/TaxCard.tsx"
          type: entity
      api_client:
        - name: "taxApi"
          file: "src/entities/tax/api/tax.api.ts"
          methods:
            - getAll
            - getById
            - create
            - update
            - delete
      state_management:
        - name: "useTaxStore"
          file: "src/entities/tax/model/tax.store.ts"
          type: zustand

    database_tables:
      - schema: financial
        table: taxes
        file: "database-design/schemas/financial-schema-ddl.sql"
        operations:
          - SELECT
          - INSERT
          - UPDATE
          - DELETE (soft)
        indices:
          - idx_taxes_company_id
          - idx_taxes_type
        rls_policy: company_isolation_taxes

    tests:
      backend:
        unit_tests:
          - file: "src/modules/financial/services/tax.service.spec.ts"
            test_cases:
              - "should create tax with valid data"
              - "should calculate tax amount"
              - "should handle percentage and fixed taxes"
              - "should validate rate between 0-100"
              - "should update tax successfully"
        integration_tests:
          - file: "test/financial/tax.controller.e2e-spec.ts"
            test_cases:
              - "POST /api/v1/financial/taxes should create tax"
              - "GET /api/v1/financial/taxes should return all taxes"
              - "GET /api/v1/financial/taxes/:id should return tax"
              - "PUT /api/v1/financial/taxes/:id should update tax"
              - "DELETE /api/v1/financial/taxes/:id should soft delete tax"
              - "should enforce company isolation"
              - "should require authentication"
      frontend:
        component_tests:
          - file: "src/widgets/taxes-table/ui/TaxesTable.test.tsx"
            test_cases:
              - "should render table with taxes"
              - "should filter by type"
          - file: "src/features/create-tax/ui/CreateTaxForm.test.tsx"
            test_cases:
              - "should validate required fields"
              - "should validate rate range"
              - "should submit valid form"
        e2e_tests:
          - file: "e2e/financial/taxes.spec.ts"
            test_cases:
              - "should create tax successfully"
              - "should edit tax successfully"
              - "should delete tax with confirmation"

    acceptance_criteria:
      - id: AC-001
        description: "Usuario puede crear impuestos con tipo (sale, purchase, both)"
        status: Pending
        test_reference: "test/financial/tax.controller.e2e-spec.ts:28"
      - id: AC-002
        description: "Sistema calcula impuestos automáticamente en facturas"
        status: Pending
        test_reference: "src/modules/financial/services/tax.service.spec.ts:65"
      - id: AC-003
        description: "Impuestos tienen cuentas contables asociadas"
        status: Pending
        test_reference: "test/financial/tax.controller.e2e-spec.ts:95"

    business_rules:
      - id: RN-001
        description: "Impuestos tienen tipos: sale (ventas), purchase (compras), both"
        implementation: "database-design/schemas/financial-schema-ddl.sql:taxes.type"
        test_reference: "src/modules/financial/services/tax.service.spec.ts:48"
      - id: RN-002
        description: "Rate debe estar entre 0 y 100"
        implementation: "src/modules/financial/dto/create-tax.dto.ts:@Min(0) @Max(100)"
        test_reference: "src/modules/financial/services/tax.service.spec.ts:78"
      - id: RN-003
        description: "Impuesto debe tener cuenta contable asignada"
        implementation: "database-design/schemas/financial-schema-ddl.sql:taxes.account_id"
        test_reference: "src/modules/financial/services/tax.service.spec.ts:95"

    dependencies:
      rf_dependencies:
        - RF-MGN-004-001
        - RF-MGN-002-001
      module_dependencies:
        - MGN-002
      external_dependencies: []

  - rf_id: RF-MGN-004-005
    rf_title: "Gestión de Facturas de Cliente"
    rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-005-gestión-de-facturas-de-cliente.md"
    priority: P0
    story_points: 13

    et_backend:
      file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-005-gestión-de-facturas-de-cliente.md"
      endpoints:
        - method: POST
          path: /api/v1/financial/customer-invoices
          description: "Crear factura de cliente"
        - method: GET
          path: /api/v1/financial/customer-invoices
          description: "Listar facturas de cliente"
        - method: GET
          path: /api/v1/financial/customer-invoices/:id
          description: "Obtener factura por ID"
        - method: PUT
          path: /api/v1/financial/customer-invoices/:id
          description: "Actualizar factura (draft)"
        - method: POST
          path: /api/v1/financial/customer-invoices/:id/validate
          description: "Validar factura (draft → open)"
        - method: POST
          path: /api/v1/financial/customer-invoices/:id/cancel
          description: "Cancelar factura"
      services:
        - name: "CustomerInvoiceService"
          file: "src/modules/financial/services/customer-invoice.service.ts"
          methods:
            - create
            - findAll
            - findOne
            - update
            - validate
            - cancel
            - generateJournalEntry
      controllers:
        - name: "CustomerInvoiceController"
          file: "src/modules/financial/controllers/customer-invoice.controller.ts"
      dtos:
        - name: "CreateCustomerInvoiceDto"
          file: "src/modules/financial/dto/create-customer-invoice.dto.ts"
        - name: "UpdateCustomerInvoiceDto"
          file: "src/modules/financial/dto/update-customer-invoice.dto.ts"

    et_frontend:
      file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-005-gestión-de-facturas-de-cliente.md"
      routes:
        - path: "/financial/customer-invoices"
          component: "CustomerInvoicesPage"
        - path: "/financial/customer-invoices/create"
          component: "CreateCustomerInvoicePage"
        - path: "/financial/customer-invoices/:id/edit"
          component: "EditCustomerInvoicePage"
        - path: "/financial/customer-invoices/:id"
          component: "ViewCustomerInvoicePage"
      components:
        - name: "CustomerInvoicesTable"
          file: "src/widgets/customer-invoices-table/ui/CustomerInvoicesTable.tsx"
          type: widget
        - name: "CreateCustomerInvoiceForm"
          file: "src/features/create-customer-invoice/ui/CreateCustomerInvoiceForm.tsx"
          type: feature
        - name: "CustomerInvoiceCard"
          file: "src/entities/customer-invoice/ui/CustomerInvoiceCard.tsx"
          type: entity
        - name: "InvoiceLineItems"
          file: "src/widgets/invoice-line-items/ui/InvoiceLineItems.tsx"
          type: widget
      api_client:
        - name: "customerInvoiceApi"
          file: "src/entities/customer-invoice/api/customer-invoice.api.ts"
          methods:
            - getAll
            - getById
            - create
            - update
            - validate
            - cancel
      state_management:
        - name: "useCustomerInvoiceStore"
          file: "src/entities/customer-invoice/model/customer-invoice.store.ts"
          type: zustand

    database_tables:
      - schema: financial
        table: invoices
        file: "database-design/schemas/financial-schema-ddl.sql"
        operations:
          - SELECT
          - INSERT
          - UPDATE
        indices:
          - idx_invoices_company_id
          - idx_invoices_partner_id
          - idx_invoices_type
          - idx_invoices_state
          - idx_invoices_invoice_date
        rls_policy: company_isolation_invoices
      - schema: financial
        table: invoice_lines
        file: "database-design/schemas/financial-schema-ddl.sql"
        operations:
          - SELECT
          - INSERT
          - UPDATE
          - DELETE
        indices:
          - idx_invoice_lines_invoice_id
          - idx_invoice_lines_product_id
        rls_policy: company_isolation_invoice_lines

    tests:
      backend:
        unit_tests:
          - file: "src/modules/financial/services/customer-invoice.service.spec.ts"
            test_cases:
              - "should create customer invoice with lines"
              - "should calculate totals with taxes"
              - "should validate invoice (draft → open)"
              - "should generate journal entry on validation"
              - "should cancel invoice"
              - "should prevent modifying validated invoice"
        integration_tests:
          - file: "test/financial/customer-invoice.controller.e2e-spec.ts"
            test_cases:
              - "POST /api/v1/financial/customer-invoices should create invoice"
              - "GET /api/v1/financial/customer-invoices should return all invoices"
              - "GET /api/v1/financial/customer-invoices/:id should return invoice with lines"
              - "PUT /api/v1/financial/customer-invoices/:id should update draft invoice"
              - "POST /api/v1/financial/customer-invoices/:id/validate should validate invoice"
              - "POST /api/v1/financial/customer-invoices/:id/cancel should cancel invoice"
              - "should enforce company isolation"
              - "should require authentication"
      frontend:
        component_tests:
          - file: "src/widgets/customer-invoices-table/ui/CustomerInvoicesTable.test.tsx"
            test_cases:
              - "should render table with invoices"
              - "should filter by state"
              - "should handle pagination"
          - file: "src/features/create-customer-invoice/ui/CreateCustomerInvoiceForm.test.tsx"
            test_cases:
              - "should validate required fields"
              - "should calculate totals"
              - "should submit valid form"
        e2e_tests:
          - file: "e2e/financial/customer-invoices.spec.ts"
            test_cases:
              - "should create customer invoice successfully"
              - "should validate invoice successfully"
              - "should cancel invoice with confirmation"
              - "should prevent editing validated invoice"

    acceptance_criteria:
      - id: AC-001
        description: "Usuario puede crear facturas de cliente con líneas y impuestos"
        status: Pending
        test_reference: "test/financial/customer-invoice.controller.e2e-spec.ts:28"
      - id: AC-002
        description: "Sistema genera asiento contable al validar factura"
        status: Pending
        test_reference: "src/modules/financial/services/customer-invoice.service.spec.ts:85"
      - id: AC-003
        description: "Facturas validadas no pueden modificarse"
        status: Pending
        test_reference: "test/financial/customer-invoice.controller.e2e-spec.ts:125"

    business_rules:
      - id: RN-001
        description: "Facturas tienen estados: draft, open, paid, cancelled"
        implementation: "database-design/schemas/financial-schema-ddl.sql:invoices.state"
        test_reference: "src/modules/financial/services/customer-invoice.service.spec.ts:58"
      - id: RN-002
        description: "Al validar factura se genera asiento contable automático"
        implementation: "src/modules/financial/services/customer-invoice.service.ts:generateJournalEntry()"
        test_reference: "src/modules/financial/services/customer-invoice.service.spec.ts:92"
      - id: RN-003
        description: "Solo facturas draft pueden modificarse"
        implementation: "src/modules/financial/services/customer-invoice.service.ts:update()"
        test_reference: "src/modules/financial/services/customer-invoice.service.spec.ts:118"

    dependencies:
      rf_dependencies:
        - RF-MGN-004-001
        - RF-MGN-004-002
        - RF-MGN-004-003
        - RF-MGN-004-004
        - RF-MGN-003-001
      module_dependencies:
        - MGN-003
      external_dependencies: []

  - rf_id: RF-MGN-004-006
    rf_title: "Gestión de Facturas de Proveedor"
    rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-006-gestión-de-facturas-de-proveedor.md"
    priority: P0
    story_points: 13

    et_backend:
      file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-006-gestión-de-facturas-de-proveedor.md"
      endpoints:
        - method: POST
          path: /api/v1/financial/vendor-invoices
          description: "Crear factura de proveedor"
        - method: GET
          path: /api/v1/financial/vendor-invoices
          description: "Listar facturas de proveedor"
        - method: GET
          path: /api/v1/financial/vendor-invoices/:id
          description: "Obtener factura por ID"
        - method: PUT
          path: /api/v1/financial/vendor-invoices/:id
          description: "Actualizar factura (draft)"
        - method: POST
          path: /api/v1/financial/vendor-invoices/:id/validate
          description: "Validar factura (draft → open)"
        - method: POST
          path: /api/v1/financial/vendor-invoices/:id/cancel
          description: "Cancelar factura"
      services:
        - name: "VendorInvoiceService"
          file: "src/modules/financial/services/vendor-invoice.service.ts"
          methods:
            - create
            - findAll
            - findOne
            - update
            - validate
            - cancel
            - generateJournalEntry
      controllers:
        - name: "VendorInvoiceController"
          file: "src/modules/financial/controllers/vendor-invoice.controller.ts"
      dtos:
        - name: "CreateVendorInvoiceDto"
          file: "src/modules/financial/dto/create-vendor-invoice.dto.ts"
        - name: "UpdateVendorInvoiceDto"
          file: "src/modules/financial/dto/update-vendor-invoice.dto.ts"

    et_frontend:
      file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-006-gestión-de-facturas-de-proveedor.md"
      routes:
        - path: "/financial/vendor-invoices"
          component: "VendorInvoicesPage"
        - path: "/financial/vendor-invoices/create"
          component: "CreateVendorInvoicePage"
        - path: "/financial/vendor-invoices/:id/edit"
          component: "EditVendorInvoicePage"
        - path: "/financial/vendor-invoices/:id"
          component: "ViewVendorInvoicePage"
      components:
        - name: "VendorInvoicesTable"
          file: "src/widgets/vendor-invoices-table/ui/VendorInvoicesTable.tsx"
          type: widget
        - name: "CreateVendorInvoiceForm"
          file: "src/features/create-vendor-invoice/ui/CreateVendorInvoiceForm.tsx"
          type: feature
        - name: "VendorInvoiceCard"
          file: "src/entities/vendor-invoice/ui/VendorInvoiceCard.tsx"
          type: entity
        - name: "InvoiceLineItems"
          file: "src/widgets/invoice-line-items/ui/InvoiceLineItems.tsx"
          type: widget
      api_client:
        - name: "vendorInvoiceApi"
          file: "src/entities/vendor-invoice/api/vendor-invoice.api.ts"
          methods:
            - getAll
            - getById
            - create
            - update
            - validate
            - cancel
      state_management:
        - name: "useVendorInvoiceStore"
          file: "src/entities/vendor-invoice/model/vendor-invoice.store.ts"
          type: zustand

    database_tables:
      - schema: financial
        table: invoices
        file: "database-design/schemas/financial-schema-ddl.sql"
        operations:
          - SELECT
          - INSERT
          - UPDATE
        indices:
          - idx_invoices_company_id
          - idx_invoices_partner_id
          - idx_invoices_type
          - idx_invoices_state
        rls_policy: company_isolation_invoices
      - schema: financial
        table: invoice_lines
        file: "database-design/schemas/financial-schema-ddl.sql"
        operations:
          - SELECT
          - INSERT
          - UPDATE
          - DELETE
        indices:
          - idx_invoice_lines_invoice_id
          - idx_invoice_lines_product_id
        rls_policy: company_isolation_invoice_lines

    tests:
      backend:
        unit_tests:
          - file: "src/modules/financial/services/vendor-invoice.service.spec.ts"
            test_cases:
              - "should create vendor invoice with lines"
              - "should calculate totals with taxes"
              - "should validate invoice (draft → open)"
              - "should generate journal entry on validation"
              - "should cancel invoice"
              - "should prevent modifying validated invoice"
        integration_tests:
          - file: "test/financial/vendor-invoice.controller.e2e-spec.ts"
            test_cases:
              - "POST /api/v1/financial/vendor-invoices should create invoice"
              - "GET /api/v1/financial/vendor-invoices should return all invoices"
              - "GET /api/v1/financial/vendor-invoices/:id should return invoice with lines"
              - "PUT /api/v1/financial/vendor-invoices/:id should update draft invoice"
              - "POST /api/v1/financial/vendor-invoices/:id/validate should validate invoice"
              - "POST /api/v1/financial/vendor-invoices/:id/cancel should cancel invoice"
              - "should enforce company isolation"
              - "should require authentication"
      frontend:
        component_tests:
          - file: "src/widgets/vendor-invoices-table/ui/VendorInvoicesTable.test.tsx"
            test_cases:
              - "should render table with invoices"
              - "should filter by state"
              - "should handle pagination"
          - file: "src/features/create-vendor-invoice/ui/CreateVendorInvoiceForm.test.tsx"
            test_cases:
              - "should validate required fields"
              - "should calculate totals"
              - "should submit valid form"
        e2e_tests:
          - file: "e2e/financial/vendor-invoices.spec.ts"
            test_cases:
              - "should create vendor invoice successfully"
              - "should validate invoice successfully"
              - "should cancel invoice with confirmation"
              - "should prevent editing validated invoice"

    acceptance_criteria:
      - id: AC-001
        description: "Usuario puede crear facturas de proveedor con líneas y impuestos"
        status: Pending
        test_reference: "test/financial/vendor-invoice.controller.e2e-spec.ts:28"
      - id: AC-002
        description: "Sistema genera asiento contable al validar factura"
        status: Pending
        test_reference: "src/modules/financial/services/vendor-invoice.service.spec.ts:85"
      - id: AC-003
        description: "Facturas validadas no pueden modificarse"
        status: Pending
        test_reference: "test/financial/vendor-invoice.controller.e2e-spec.ts:125"

    business_rules:
      - id: RN-001
        description: "Facturas tienen estados: draft, open, paid, cancelled"
        implementation: "database-design/schemas/financial-schema-ddl.sql:invoices.state"
        test_reference: "src/modules/financial/services/vendor-invoice.service.spec.ts:58"
      - id: RN-002
        description: "Al validar factura se genera asiento contable automático"
        implementation: "src/modules/financial/services/vendor-invoice.service.ts:generateJournalEntry()"
        test_reference: "src/modules/financial/services/vendor-invoice.service.spec.ts:92"
      - id: RN-003
        description: "Solo facturas draft pueden modificarse"
        implementation: "src/modules/financial/services/vendor-invoice.service.ts:update()"
        test_reference: "src/modules/financial/services/vendor-invoice.service.spec.ts:118"

    dependencies:
      rf_dependencies:
        - RF-MGN-004-001
        - RF-MGN-004-002
        - RF-MGN-004-003
        - RF-MGN-004-004
        - RF-MGN-003-001
      module_dependencies:
        - MGN-003
      external_dependencies: []

  - rf_id: RF-MGN-004-007
    rf_title: "Gestión de Pagos y Conciliación"
    rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-007-gestión-de-pagos-y-conciliación.md"
    priority: P0
    story_points: 13

    et_backend:
      file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-007-gestión-de-pagos-y-conciliación.md"
      endpoints:
        - method: POST
          path: /api/v1/financial/payments
          description: "Registrar pago"
        - method: GET
          path: /api/v1/financial/payments
          description: "Listar pagos"
        - method: GET
          path: /api/v1/financial/payments/:id
          description: "Obtener pago por ID"
        - method: POST
          path: /api/v1/financial/payments/:id/reconcile
          description: "Conciliar pago con factura(s)"
        - method: POST
          path: /api/v1/financial/payments/:id/cancel
          description: "Cancelar pago"
      services:
        - name: "PaymentService"
          file: "src/modules/financial/services/payment.service.ts"
          methods:
            - create
            - findAll
            - findOne
            - reconcile
            - cancel
            - generateJournalEntry
      controllers:
        - name: "PaymentController"
          file: "src/modules/financial/controllers/payment.controller.ts"
      dtos:
        - name: "CreatePaymentDto"
          file: "src/modules/financial/dto/create-payment.dto.ts"
        - name: "ReconcilePaymentDto"
          file: "src/modules/financial/dto/reconcile-payment.dto.ts"

    et_frontend:
      file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-007-gestión-de-pagos-y-conciliación.md"
      routes:
        - path: "/financial/payments"
          component: "PaymentsPage"
        - path: "/financial/payments/create"
          component: "CreatePaymentPage"
        - path: "/financial/payments/:id"
          component: "ViewPaymentPage"
        - path: "/financial/payments/:id/reconcile"
          component: "ReconcilePaymentPage"
      components:
        - name: "PaymentsTable"
          file: "src/widgets/payments-table/ui/PaymentsTable.tsx"
          type: widget
        - name: "CreatePaymentForm"
          file: "src/features/create-payment/ui/CreatePaymentForm.tsx"
          type: feature
        - name: "PaymentCard"
          file: "src/entities/payment/ui/PaymentCard.tsx"
          type: entity
        - name: "ReconcilePaymentForm"
          file: "src/features/reconcile-payment/ui/ReconcilePaymentForm.tsx"
          type: feature
      api_client:
        - name: "paymentApi"
          file: "src/entities/payment/api/payment.api.ts"
          methods:
            - getAll
            - getById
            - create
            - reconcile
            - cancel
      state_management:
        - name: "usePaymentStore"
          file: "src/entities/payment/model/payment.store.ts"
          type: zustand

    database_tables:
      - schema: financial
        table: payments
        file: "database-design/schemas/financial-schema-ddl.sql"
        operations:
          - SELECT
          - INSERT
          - UPDATE
        indices:
          - idx_payments_company_id
          - idx_payments_partner_id
          - idx_payments_payment_date
          - idx_payments_state
        rls_policy: company_isolation_payments
      - schema: financial
        table: payment_invoice_reconciliations
        file: "database-design/schemas/financial-schema-ddl.sql"
        operations:
          - SELECT
          - INSERT
          - DELETE
        indices:
          - idx_reconciliations_payment_id
          - idx_reconciliations_invoice_id
        rls_policy: company_isolation_reconciliations

    tests:
      backend:
        unit_tests:
          - file: "src/modules/financial/services/payment.service.spec.ts"
            test_cases:
              - "should create payment"
              - "should reconcile payment with invoice"
              - "should reconcile payment with multiple invoices"
              - "should update invoice state to paid when fully reconciled"
              - "should generate journal entry for payment"
              - "should cancel payment"
        integration_tests:
          - file: "test/financial/payment.controller.e2e-spec.ts"
            test_cases:
              - "POST /api/v1/financial/payments should create payment"
              - "GET /api/v1/financial/payments should return all payments"
              - "GET /api/v1/financial/payments/:id should return payment"
              - "POST /api/v1/financial/payments/:id/reconcile should reconcile payment"
              - "POST /api/v1/financial/payments/:id/cancel should cancel payment"
              - "should enforce company isolation"
              - "should require authentication"
      frontend:
        component_tests:
          - file: "src/widgets/payments-table/ui/PaymentsTable.test.tsx"
            test_cases:
              - "should render table with payments"
              - "should filter by state"
          - file: "src/features/create-payment/ui/CreatePaymentForm.test.tsx"
            test_cases:
              - "should validate required fields"
              - "should submit valid form"
        e2e_tests:
          - file: "e2e/financial/payments.spec.ts"
            test_cases:
              - "should create payment successfully"
              - "should reconcile payment with invoice"
              - "should cancel payment with confirmation"
              - "should show invoice as paid after full reconciliation"

    acceptance_criteria:
      - id: AC-001
        description: "Usuario puede registrar pagos de clientes y proveedores"
        status: Pending
        test_reference: "test/financial/payment.controller.e2e-spec.ts:28"
      - id: AC-002
        description: "Usuario puede conciliar pagos con facturas"
        status: Pending
        test_reference: "test/financial/payment.controller.e2e-spec.ts:68"
      - id: AC-003
        description: "Factura cambia a estado paid cuando se concilia completamente"
        status: Pending
        test_reference: "src/modules/financial/services/payment.service.spec.ts:95"

    business_rules:
      - id: RN-001
        description: "Pago puede conciliarse con una o múltiples facturas"
        implementation: "database-design/schemas/financial-schema-ddl.sql:payment_invoice_reconciliations"
        test_reference: "src/modules/financial/services/payment.service.spec.ts:58"
      - id: RN-002
        description: "Factura pasa a paid cuando monto conciliado = monto total"
        implementation: "src/modules/financial/services/payment.service.ts:reconcile()"
        test_reference: "src/modules/financial/services/payment.service.spec.ts:85"
      - id: RN-003
        description: "Al registrar pago se genera asiento contable"
        implementation: "src/modules/financial/services/payment.service.ts:generateJournalEntry()"
        test_reference: "src/modules/financial/services/payment.service.spec.ts:118"

    dependencies:
      rf_dependencies:
        - RF-MGN-004-003
        - RF-MGN-004-005
        - RF-MGN-004-006
        - RF-MGN-003-001
      module_dependencies:
        - MGN-003
      external_dependencies: []

  - rf_id: RF-MGN-004-008
    rf_title: "Reportes Financieros (Balance y P&L)"
    rf_file: "requerimientos-funcionales/mgn-004/RF-MGN-004-008-reportes-financieros-balance-y-p&l.md"
    priority: P0
    story_points: 8

    et_backend:
      file: "especificaciones-tecnicas/backend/mgn-004/ET-BACKEND-MGN-004-008-reportes-financieros-balance-y-p&l.md"
      endpoints:
        - method: GET
          path: /api/v1/financial/reports/balance-sheet
          description: "Generar Balance General"
        - method: GET
          path: /api/v1/financial/reports/profit-loss
          description: "Generar Estado de Resultados (P&L)"
        - method: GET
          path: /api/v1/financial/reports/trial-balance
          description: "Generar Balanza de Comprobación"
        - method: GET
          path: /api/v1/financial/reports/general-ledger
          description: "Generar Libro Mayor"
      services:
        - name: "FinancialReportService"
          file: "src/modules/financial/services/financial-report.service.ts"
          methods:
            - generateBalanceSheet
            - generateProfitLoss
            - generateTrialBalance
            - generateGeneralLedger
      controllers:
        - name: "FinancialReportController"
          file: "src/modules/financial/controllers/financial-report.controller.ts"
      dtos:
        - name: "ReportPeriodDto"
          file: "src/modules/financial/dto/report-period.dto.ts"

    et_frontend:
      file: "especificaciones-tecnicas/frontend/mgn-004/ET-FRONTEND-MGN-004-008-reportes-financieros-balance-y-p&l.md"
      routes:
        - path: "/financial/reports/balance-sheet"
          component: "BalanceSheetPage"
        - path: "/financial/reports/profit-loss"
          component: "ProfitLossPage"
        - path: "/financial/reports/trial-balance"
          component: "TrialBalancePage"
        - path: "/financial/reports/general-ledger"
          component: "GeneralLedgerPage"
      components:
        - name: "BalanceSheetReport"
          file: "src/widgets/balance-sheet-report/ui/BalanceSheetReport.tsx"
          type: widget
        - name: "ProfitLossReport"
          file: "src/widgets/profit-loss-report/ui/ProfitLossReport.tsx"
          type: widget
        - name: "ReportFilters"
          file: "src/features/report-filters/ui/ReportFilters.tsx"
          type: feature
      api_client:
        - name: "financialReportApi"
          file: "src/entities/financial-report/api/financial-report.api.ts"
          methods:
            - getBalanceSheet
            - getProfitLoss
            - getTrialBalance
            - getGeneralLedger
      state_management:
        - name: "useFinancialReportStore"
          file: "src/entities/financial-report/model/financial-report.store.ts"
          type: zustand

    database_tables:
      - schema: financial
        table: journal_entry_lines
        file: "database-design/schemas/financial-schema-ddl.sql"
        operations:
          - SELECT
        indices:
          - idx_journal_entry_lines_account_id
          - idx_journal_entry_lines_date
        rls_policy: company_isolation_journal_entry_lines

    tests:
      backend:
        unit_tests:
          - file: "src/modules/financial/services/financial-report.service.spec.ts"
            test_cases:
              - "should generate balance sheet"
              - "should generate profit & loss"
              - "should filter by date range"
              - "should calculate balances correctly"
              - "should handle hierarchical accounts"
        integration_tests:
          - file: "test/financial/financial-report.controller.e2e-spec.ts"
            test_cases:
              - "GET /api/v1/financial/reports/balance-sheet should return balance sheet"
              - "GET /api/v1/financial/reports/profit-loss should return P&L"
              - "GET /api/v1/financial/reports/trial-balance should return trial balance"
              - "GET /api/v1/financial/reports/general-ledger should return general ledger"
              - "should enforce company isolation"
              - "should require authentication"
      frontend:
        component_tests:
          - file: "src/widgets/balance-sheet-report/ui/BalanceSheetReport.test.tsx"
            test_cases:
              - "should render balance sheet"
              - "should show assets and liabilities"
          - file: "src/widgets/profit-loss-report/ui/ProfitLossReport.test.tsx"
            test_cases:
              - "should render P&L statement"
              - "should show income and expenses"
        e2e_tests:
          - file: "e2e/financial/reports.spec.ts"
            test_cases:
              - "should generate balance sheet successfully"
              - "should generate P&L successfully"
              - "should filter by date range"
              - "should export to PDF"

    acceptance_criteria:
      - id: AC-001
        description: "Usuario puede generar Balance General por período"
        status: Pending
        test_reference: "test/financial/financial-report.controller.e2e-spec.ts:28"
      - id: AC-002
        description: "Usuario puede generar Estado de Resultados (P&L) por período"
        status: Pending
        test_reference: "test/financial/financial-report.controller.e2e-spec.ts:58"
      - id: AC-003
        description: "Reportes pueden exportarse a PDF y Excel"
        status: Pending
        test_reference: "e2e/financial/reports.spec.ts:85"

    business_rules:
      - id: RN-001
        description: "Balance Sheet muestra Assets = Liabilities + Equity"
        implementation: "src/modules/financial/services/financial-report.service.ts:generateBalanceSheet()"
        test_reference: "src/modules/financial/services/financial-report.service.spec.ts:58"
      - id: RN-002
        description: "P&L calcula Net Income = Income - Expenses"
        implementation: "src/modules/financial/services/financial-report.service.ts:generateProfitLoss()"
        test_reference: "src/modules/financial/services/financial-report.service.spec.ts:85"
      - id: RN-003
        description: "Reportes filtran por rango de fechas (date_from, date_to)"
        implementation: "src/modules/financial/services/financial-report.service.ts:filterByPeriod()"
        test_reference: "src/modules/financial/services/financial-report.service.spec.ts:108"

    dependencies:
      rf_dependencies:
        - RF-MGN-004-001
        - RF-MGN-004-003
        - RF-MGN-002-001
      module_dependencies:
        - MGN-002
      external_dependencies:
        - name: "pdfkit"
          version: "^0.13.0"
        - name: "xlsx"
          version: "^0.18.5"

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: 40
  total_components: 32
  total_tables: 12
  total_test_cases: 160
  estimated_duration_sprints: 5
