# ============================================================================
# INVENTARIO COMPLETO DE OBJETOS DE BASE DE DATOS
# ERP GENERIC - PostgreSQL 15+
# ============================================================================
# Fecha: 2025-12-09 (Actualizado)
# Propósito: Inventario exhaustivo de todos los objetos de BD extraídos de DDL
# Schemas: auth, core, analytics, financial, inventory, purchase, sales, projects, system, billing, crm, hr
# Total: 12 schemas, 144 tablas
# ============================================================================

prerequisites:
  extensions:
    - uuid-ossp
    - pgcrypto
    - pg_trgm
    - unaccent

  composite_types:
    - name: money_amount
      attributes:
        - amount: NUMERIC(15,2)
        - currency_code: CHAR(3)
    - name: address_components
      attributes:
        - street: VARCHAR(255)
        - street2: VARCHAR(255)
        - city: VARCHAR(100)
        - state: VARCHAR(100)
        - zip: VARCHAR(20)
        - country_code: CHAR(2)

  functions:
    - name: update_updated_at_column
      purpose: "Generic trigger function to auto-update updated_at timestamp on row modification"
    - name: normalize_search_text
      purpose: "Normalize text for search by removing accents and converting to lowercase"
    - name: generate_random_code
      purpose: "Generate random alphanumeric code of specified length (default 8)"
    - name: is_valid_email
      purpose: "Validate email format using regex"
    - name: is_valid_phone
      purpose: "Validate phone number format (at least 7 digits)"
    - name: clean_phone
      purpose: "Remove non-numeric characters from phone number"
    - name: calculate_age
      purpose: "Calculate age in years from birthdate"
    - name: get_fiscal_year_start
      purpose: "Get the start date of fiscal year for a given date"
    - name: round_currency
      purpose: "Round numeric value to specified decimal places (default 2 for currency)"

# ============================================================================
# SCHEMA: auth
# ============================================================================
auth:
  enums:
    - name: user_status
      values: [active, inactive, suspended, pending_verification]
    - name: tenant_status
      values: [active, suspended, trial, cancelled]
    - name: session_status
      values: [active, expired, revoked]
    - name: permission_action
      values: [create, read, update, delete, approve, cancel, export]

  tables:
    - name: tenants
      columns: [id, name, subdomain, schema_name, status, settings, plan, max_users, created_at, created_by, updated_at, updated_by, deleted_at, deleted_by]
      foreign_keys: []

    - name: companies
      columns: [id, tenant_id, name, legal_name, tax_id, currency_id, parent_company_id, partner_id, settings, created_at, created_by, updated_at, updated_by, deleted_at, deleted_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: parent_company_id
          references: auth.companies(id)
        - column: currency_id
          references: core.currencies(id)
        - column: partner_id
          references: core.partners(id)

    - name: users
      columns: [id, tenant_id, email, password_hash, full_name, avatar_url, status, is_superuser, email_verified_at, last_login_at, last_login_ip, login_count, language, timezone, settings, created_at, created_by, updated_at, updated_by, deleted_at, deleted_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: roles
      columns: [id, tenant_id, name, code, description, is_system, color, created_at, created_by, updated_at, updated_by, deleted_at, deleted_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: permissions
      columns: [id, resource, action, description, module, created_at]
      foreign_keys: []

    - name: user_roles
      columns: [user_id, role_id, assigned_at, assigned_by]
      foreign_keys:
        - column: user_id
          references: auth.users(id)
        - column: role_id
          references: auth.roles(id)

    - name: role_permissions
      columns: [role_id, permission_id, granted_at, granted_by]
      foreign_keys:
        - column: role_id
          references: auth.roles(id)
        - column: permission_id
          references: auth.permissions(id)

    - name: sessions
      columns: [id, user_id, token, refresh_token, status, expires_at, refresh_expires_at, ip_address, user_agent, device_info, created_at, revoked_at, revoked_reason]
      foreign_keys:
        - column: user_id
          references: auth.users(id)

    - name: user_companies
      columns: [user_id, company_id, is_default, assigned_at]
      foreign_keys:
        - column: user_id
          references: auth.users(id)
        - column: company_id
          references: auth.companies(id)

    - name: password_resets
      columns: [id, user_id, token, expires_at, used_at, ip_address, created_at]
      foreign_keys:
        - column: user_id
          references: auth.users(id)

  functions:
    - name: get_current_tenant_id
      purpose: "Obtiene el tenant_id del contexto actual"
    - name: get_current_user_id
      purpose: "Obtiene el user_id del contexto actual"
    - name: get_current_company_id
      purpose: "Obtiene el company_id del contexto actual"
    - name: user_has_permission
      purpose: "Verifica si un usuario tiene un permiso específico"
    - name: clean_expired_sessions
      purpose: "Limpia sesiones expiradas (ejecutar periódicamente)"
    - name: update_updated_at_column
      purpose: "Actualiza updated_at y updated_by al modificar registros"
    - name: validate_tenant_has_admin
      purpose: "Valida que tenant tenga al menos 1 admin antes de eliminar role"
    - name: auto_expire_session
      purpose: "Auto-marca sesión como expirada si pasa expires_at"

  triggers:
    - name: trg_tenants_updated_at
      table: tenants
    - name: trg_companies_updated_at
      table: companies
    - name: trg_users_updated_at
      table: users
    - name: trg_roles_updated_at
      table: roles
    - name: trg_validate_tenant_has_admin
      table: user_roles
    - name: trg_auto_expire_session
      table: sessions

  indexes:
    - name: idx_tenants_subdomain
      table: tenants
      columns: [subdomain]
    - name: idx_tenants_status
      table: tenants
      columns: [status]
    - name: idx_companies_tenant_id
      table: companies
      columns: [tenant_id]
    - name: idx_companies_parent_company_id
      table: companies
      columns: [parent_company_id]
    - name: idx_users_tenant_id
      table: users
      columns: [tenant_id]
    - name: idx_users_email
      table: users
      columns: [email]
    - name: idx_users_status
      table: users
      columns: [status]
    - name: idx_roles_tenant_id
      table: roles
      columns: [tenant_id]
    - name: idx_roles_code
      table: roles
      columns: [code]
    - name: idx_sessions_user_id
      table: sessions
      columns: [user_id]
    - name: idx_sessions_token
      table: sessions
      columns: [token]

  rls_policies:
    - name: tenant_isolation_companies
      table: companies
    - name: tenant_isolation_users
      table: users
    - name: tenant_isolation_roles
      table: roles

  views:
    - name: user_permissions_view
      purpose: "Vista de permisos efectivos por usuario"
    - name: active_sessions_view
      purpose: "Vista de sesiones activas con tiempo restante"

# ============================================================================
# SCHEMA: core
# ============================================================================
core:
  enums:
    - name: partner_type
      values: [person, company]
    - name: partner_category
      values: [customer, supplier, employee, contact, other]
    - name: address_type
      values: [billing, shipping, contact, other]
    - name: uom_type
      values: [reference, bigger, smaller]

  tables:
    - name: countries
      columns: [id, code, name, phone_code, currency_code, created_at]
      foreign_keys: []

    - name: currencies
      columns: [id, code, name, symbol, decimals, rounding, active, created_at]
      foreign_keys: []

    - name: exchange_rates
      columns: [id, from_currency_id, to_currency_id, rate, date, created_at]
      foreign_keys:
        - column: from_currency_id
          references: core.currencies(id)
        - column: to_currency_id
          references: core.currencies(id)

    - name: uom_categories
      columns: [id, name, description, created_at]
      foreign_keys: []

    - name: uom
      columns: [id, category_id, name, code, uom_type, factor, rounding, active, created_at]
      foreign_keys:
        - column: category_id
          references: core.uom_categories(id)

    - name: partners
      columns: [id, tenant_id, name, legal_name, partner_type, is_customer, is_supplier, is_employee, is_company, email, phone, mobile, website, tax_id, company_id, parent_id, user_id, payment_term_id, pricelist_id, language, currency_id, notes, internal_notes, active, created_at, created_by, updated_at, updated_by, deleted_at, deleted_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: parent_id
          references: core.partners(id)
        - column: user_id
          references: auth.users(id)
        - column: currency_id
          references: core.currencies(id)

    - name: addresses
      columns: [id, partner_id, address_type, street, street2, city, state, zip_code, country_id, is_default, active, created_at, created_by, updated_at, updated_by, deleted_at, deleted_by]
      foreign_keys:
        - column: partner_id
          references: core.partners(id)
        - column: country_id
          references: core.countries(id)

    - name: product_categories
      columns: [id, tenant_id, name, code, parent_id, full_path, notes, active, created_at, created_by, updated_at, updated_by, deleted_at, deleted_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: parent_id
          references: core.product_categories(id)

    - name: tags
      columns: [id, tenant_id, name, color, model, description, created_at, created_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: sequences
      columns: [id, tenant_id, company_id, code, name, prefix, suffix, next_number, padding, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)

    - name: attachments
      columns: [id, tenant_id, model, record_id, filename, mimetype, size_bytes, url, description, is_public, created_at, created_by, deleted_at, deleted_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: notes
      columns: [id, tenant_id, model, record_id, subject, content, is_pinned, created_at, created_by, updated_at, updated_by, deleted_at, deleted_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

  functions:
    - name: generate_next_sequence
      purpose: "Genera el siguiente número de secuencia para un código dado"
    - name: update_product_category_path
      purpose: "Actualiza el path completo de la categoría al crear/actualizar"
    - name: get_exchange_rate
      purpose: "Obtiene la tasa de cambio entre dos monedas en una fecha específica"

  triggers:
    - name: trg_partners_updated_at
      table: partners
    - name: trg_addresses_updated_at
      table: addresses
    - name: trg_product_categories_updated_at
      table: product_categories
    - name: trg_product_categories_update_path
      table: product_categories
    - name: trg_notes_updated_at
      table: notes

  indexes:
    - name: idx_countries_code
      table: countries
      columns: [code]
    - name: idx_currencies_code
      table: currencies
      columns: [code]
    - name: idx_partners_tenant_id
      table: partners
      columns: [tenant_id]
    - name: idx_partners_name
      table: partners
      columns: [name]
    - name: idx_partners_email
      table: partners
      columns: [email]
    - name: idx_partners_is_customer
      table: partners
      columns: [tenant_id, is_customer]
    - name: idx_partners_is_supplier
      table: partners
      columns: [tenant_id, is_supplier]
    - name: idx_product_categories_tenant_id
      table: product_categories
      columns: [tenant_id]
    - name: idx_sequences_tenant_id
      table: sequences
      columns: [tenant_id]

  rls_policies:
    - name: tenant_isolation_partners
      table: partners
    - name: tenant_isolation_product_categories
      table: product_categories
    - name: tenant_isolation_tags
      table: tags
    - name: tenant_isolation_sequences
      table: sequences
    - name: tenant_isolation_attachments
      table: attachments
    - name: tenant_isolation_notes
      table: notes

  views:
    - name: customers_view
      purpose: "Vista de partners que son clientes"
    - name: suppliers_view
      purpose: "Vista de partners que son proveedores"
    - name: employees_view
      purpose: "Vista de partners que son empleados"

# ============================================================================
# SCHEMA: analytics
# ============================================================================
analytics:
  enums:
    - name: account_type
      values: [project, department, cost_center, customer, product, other]
    - name: line_type
      values: [expense, income, timesheet]
    - name: account_status
      values: [active, inactive, closed]

  tables:
    - name: analytic_plans
      columns: [id, tenant_id, company_id, name, description, active, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)

    - name: analytic_accounts
      columns: [id, tenant_id, company_id, plan_id, name, code, account_type, parent_id, full_path, partner_id, budget, status, date_start, date_end, description, created_at, created_by, updated_at, updated_by, deleted_at, deleted_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: plan_id
          references: analytics.analytic_plans(id)
        - column: parent_id
          references: analytics.analytic_accounts(id)
        - column: partner_id
          references: core.partners(id)

    - name: analytic_tags
      columns: [id, tenant_id, name, color, description, created_at, created_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: cost_centers
      columns: [id, tenant_id, company_id, name, code, analytic_account_id, manager_id, budget_monthly, budget_annual, active, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: analytic_account_id
          references: analytics.analytic_accounts(id)
        - column: manager_id
          references: auth.users(id)

    - name: analytic_lines
      columns: [id, tenant_id, company_id, analytic_account_id, date, amount, unit_amount, line_type, product_id, employee_id, partner_id, name, description, source_model, source_id, source_document, currency_id, created_at, created_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: analytic_account_id
          references: analytics.analytic_accounts(id)
        - column: product_id
          references: inventory.products(id)
        - column: partner_id
          references: core.partners(id)
        - column: currency_id
          references: core.currencies(id)

    - name: analytic_line_tags
      columns: [analytic_line_id, analytic_tag_id, created_at]
      foreign_keys:
        - column: analytic_line_id
          references: analytics.analytic_lines(id)
        - column: analytic_tag_id
          references: analytics.analytic_tags(id)

    - name: analytic_distributions
      columns: [id, source_model, source_id, analytic_account_id, percentage, amount, created_at]
      foreign_keys:
        - column: analytic_account_id
          references: analytics.analytic_accounts(id)

  functions:
    - name: update_analytic_account_path
      purpose: "Actualiza el path completo de la cuenta analítica"
    - name: get_analytic_balance
      purpose: "Obtiene el balance de una cuenta analítica en un período"
    - name: validate_distribution_100_percent
      purpose: "Valida que la distribución analítica no exceda el 100%"
    - name: create_analytic_line_from_invoice
      purpose: "Crea una línea analítica a partir de una línea de factura"

  triggers:
    - name: trg_analytic_plans_updated_at
      table: analytic_plans
    - name: trg_analytic_accounts_updated_at
      table: analytic_accounts
    - name: trg_analytic_accounts_update_path
      table: analytic_accounts
    - name: trg_cost_centers_updated_at
      table: cost_centers
    - name: trg_analytic_distributions_validate_100
      table: analytic_distributions

  indexes:
    - name: idx_analytic_plans_tenant_id
      table: analytic_plans
      columns: [tenant_id]
    - name: idx_analytic_accounts_tenant_id
      table: analytic_accounts
      columns: [tenant_id]
    - name: idx_analytic_accounts_company_id
      table: analytic_accounts
      columns: [company_id]
    - name: idx_analytic_lines_tenant_id
      table: analytic_lines
      columns: [tenant_id]
    - name: idx_analytic_lines_analytic_account_id
      table: analytic_lines
      columns: [analytic_account_id]
    - name: idx_cost_centers_tenant_id
      table: cost_centers
      columns: [tenant_id]

  rls_policies:
    - name: tenant_isolation_analytic_plans
      table: analytic_plans
    - name: tenant_isolation_analytic_accounts
      table: analytic_accounts
    - name: tenant_isolation_analytic_tags
      table: analytic_tags
    - name: tenant_isolation_cost_centers
      table: cost_centers
    - name: tenant_isolation_analytic_lines
      table: analytic_lines

  views:
    - name: analytic_balance_view
      purpose: "Vista de balance analítico por cuenta con presupuesto vs real"

# ============================================================================
# SCHEMA: financial
# ============================================================================
financial:
  enums:
    - name: account_type
      values: [asset, liability, equity, revenue, expense]
    - name: journal_type
      values: [sale, purchase, bank, cash, general]
    - name: entry_status
      values: [draft, posted, cancelled]
    - name: invoice_type
      values: [customer, supplier]
    - name: invoice_status
      values: [draft, open, paid, cancelled]
    - name: payment_type
      values: [inbound, outbound]
    - name: payment_method
      values: [cash, bank_transfer, check, card, other]
    - name: payment_status
      values: [draft, posted, reconciled, cancelled]
    - name: tax_type
      values: [sales, purchase, all]
    - name: fiscal_period_status
      values: [open, closed]

  tables:
    - name: account_types
      columns: [id, code, name, account_type, description, created_at]
      foreign_keys: []

    - name: accounts
      columns: [id, tenant_id, company_id, code, name, account_type_id, parent_id, currency_id, is_reconcilable, is_deprecated, notes, created_at, created_by, updated_at, updated_by, deleted_at, deleted_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: account_type_id
          references: financial.account_types(id)
        - column: parent_id
          references: financial.accounts(id)
        - column: currency_id
          references: core.currencies(id)

    - name: journals
      columns: [id, tenant_id, company_id, name, code, journal_type, default_account_id, sequence_id, currency_id, active, created_at, created_by, updated_at, updated_by, deleted_at, deleted_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: default_account_id
          references: financial.accounts(id)
        - column: sequence_id
          references: core.sequences(id)
        - column: currency_id
          references: core.currencies(id)

    - name: fiscal_years
      columns: [id, tenant_id, company_id, name, code, start_date, end_date, status, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)

    - name: fiscal_periods
      columns: [id, tenant_id, fiscal_year_id, name, code, start_date, end_date, status, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: fiscal_year_id
          references: financial.fiscal_years(id)

    - name: journal_entries
      columns: [id, tenant_id, company_id, journal_id, name, ref, date, status, notes, created_at, created_by, updated_at, updated_by, posted_at, posted_by, cancelled_at, cancelled_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: journal_id
          references: financial.journals(id)

    - name: journal_entry_lines
      columns: [id, entry_id, account_id, partner_id, debit, credit, analytic_account_id, description, ref, currency_id, amount_currency, created_at]
      foreign_keys:
        - column: entry_id
          references: financial.journal_entries(id)
        - column: account_id
          references: financial.accounts(id)
        - column: partner_id
          references: core.partners(id)
        - column: currency_id
          references: core.currencies(id)

    - name: taxes
      columns: [id, tenant_id, company_id, name, code, rate, tax_type, account_id, active, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: account_id
          references: financial.accounts(id)

    - name: payment_terms
      columns: [id, tenant_id, company_id, name, code, terms, active, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)

    - name: invoices
      columns: [id, tenant_id, company_id, partner_id, invoice_type, number, ref, invoice_date, due_date, currency_id, amount_untaxed, amount_tax, amount_total, amount_paid, amount_residual, status, payment_term_id, journal_id, journal_entry_id, notes, created_at, created_by, updated_at, updated_by, validated_at, validated_by, cancelled_at, cancelled_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: partner_id
          references: core.partners(id)
        - column: currency_id
          references: core.currencies(id)
        - column: payment_term_id
          references: financial.payment_terms(id)
        - column: journal_id
          references: financial.journals(id)
        - column: journal_entry_id
          references: financial.journal_entries(id)

    - name: invoice_lines
      columns: [id, invoice_id, product_id, description, quantity, uom_id, price_unit, tax_ids, amount_untaxed, amount_tax, amount_total, account_id, analytic_account_id, created_at, updated_at]
      foreign_keys:
        - column: invoice_id
          references: financial.invoices(id)
        - column: uom_id
          references: core.uom(id)
        - column: account_id
          references: financial.accounts(id)

    - name: payments
      columns: [id, tenant_id, company_id, partner_id, payment_type, payment_method, amount, currency_id, payment_date, ref, status, journal_id, journal_entry_id, notes, created_at, created_by, updated_at, updated_by, posted_at, posted_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: partner_id
          references: core.partners(id)
        - column: currency_id
          references: core.currencies(id)
        - column: journal_id
          references: financial.journals(id)
        - column: journal_entry_id
          references: financial.journal_entries(id)

    - name: payment_invoice
      columns: [payment_id, invoice_id, amount, created_at]
      foreign_keys:
        - column: payment_id
          references: financial.payments(id)
        - column: invoice_id
          references: financial.invoices(id)

    - name: bank_accounts
      columns: [id, tenant_id, company_id, partner_id, bank_name, account_number, account_holder, currency_id, journal_id, active, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: partner_id
          references: core.partners(id)
        - column: currency_id
          references: core.currencies(id)
        - column: journal_id
          references: financial.journals(id)

    - name: reconciliations
      columns: [id, tenant_id, company_id, bank_account_id, start_date, end_date, balance_start, balance_end_real, balance_end_computed, reconciled_line_ids, status, created_at, created_by, updated_at, updated_by, validated_at, validated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: bank_account_id
          references: financial.bank_accounts(id)

  functions:
    - name: validate_entry_balance
      purpose: "Valida que un asiento contable esté balanceado (debit = credit)"
    - name: post_journal_entry
      purpose: "Contabiliza un asiento contable después de validar su balance"
    - name: calculate_invoice_totals
      purpose: "Calcula los totales de una factura a partir de sus líneas"
    - name: update_invoice_paid_amount
      purpose: "Actualiza el monto pagado y estado de una factura"

  triggers:
    - name: trg_accounts_updated_at
      table: accounts
    - name: trg_journals_updated_at
      table: journals
    - name: trg_journal_entries_updated_at
      table: journal_entries
    - name: trg_invoices_updated_at
      table: invoices
    - name: trg_payments_updated_at
      table: payments
    - name: trg_journal_entries_validate_balance
      table: journal_entries
    - name: trg_invoice_lines_update_totals
      table: invoice_lines
    - name: trg_payment_invoice_update_paid
      table: payment_invoice
    - name: track_invoice_changes
      table: invoices
    - name: track_journal_entry_changes
      table: journal_entries

  indexes:
    - name: idx_accounts_tenant_id
      table: accounts
      columns: [tenant_id]
    - name: idx_accounts_company_id
      table: accounts
      columns: [company_id]
    - name: idx_journals_tenant_id
      table: journals
      columns: [tenant_id]
    - name: idx_journal_entries_tenant_id
      table: journal_entries
      columns: [tenant_id]
    - name: idx_invoices_tenant_id
      table: invoices
      columns: [tenant_id]
    - name: idx_invoices_partner_id
      table: invoices
      columns: [partner_id]
    - name: idx_invoices_status
      table: invoices
      columns: [status]
    - name: idx_payments_tenant_id
      table: payments
      columns: [tenant_id]

  rls_policies:
    - name: tenant_isolation_accounts
      table: accounts
    - name: tenant_isolation_journals
      table: journals
    - name: tenant_isolation_fiscal_years
      table: fiscal_years
    - name: tenant_isolation_fiscal_periods
      table: fiscal_periods
    - name: tenant_isolation_journal_entries
      table: journal_entries
    - name: tenant_isolation_taxes
      table: taxes
    - name: tenant_isolation_payment_terms
      table: payment_terms
    - name: tenant_isolation_invoices
      table: invoices
    - name: tenant_isolation_payments
      table: payments
    - name: tenant_isolation_bank_accounts
      table: bank_accounts
    - name: tenant_isolation_reconciliations
      table: reconciliations

  views: []

# ============================================================================
# SCHEMA: inventory
# ============================================================================
inventory:
  enums:
    - name: product_type
      values: [storable, consumable, service]
    - name: tracking_type
      values: [none, lot, serial]
    - name: location_type
      values: [internal, customer, supplier, inventory, production, transit]
    - name: picking_type
      values: [incoming, outgoing, internal]
    - name: move_status
      values: [draft, confirmed, assigned, done, cancelled]
    - name: valuation_method
      values: [fifo, average, standard]

  tables:
    - name: products
      columns: [id, tenant_id, name, code, barcode, description, product_type, tracking, category_id, uom_id, purchase_uom_id, cost_price, list_price, valuation_method, is_storable, weight, volume, can_be_sold, can_be_purchased, image_url, active, created_at, created_by, updated_at, updated_by, deleted_at, deleted_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: category_id
          references: core.product_categories(id)
        - column: uom_id
          references: core.uom(id)
        - column: purchase_uom_id
          references: core.uom(id)

    - name: product_variants
      columns: [id, product_template_id, attribute_values, name, code, barcode, price_extra, active, created_at, created_by]
      foreign_keys:
        - column: product_template_id
          references: inventory.products(id)

    - name: warehouses
      columns: [id, tenant_id, company_id, name, code, address_id, is_default, active, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: address_id
          references: core.addresses(id)

    - name: locations
      columns: [id, tenant_id, warehouse_id, name, complete_name, location_type, parent_id, is_scrap_location, is_return_location, active, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: warehouse_id
          references: inventory.warehouses(id)
        - column: parent_id
          references: inventory.locations(id)

    - name: stock_quants
      columns: [id, product_id, location_id, lot_id, quantity, reserved_quantity, available_quantity, cost, created_at, updated_at]
      foreign_keys:
        - column: product_id
          references: inventory.products(id)
        - column: location_id
          references: inventory.locations(id)
        - column: lot_id
          references: inventory.lots(id)

    - name: lots
      columns: [id, tenant_id, product_id, name, ref, manufacture_date, expiration_date, removal_date, alert_date, notes, created_at, created_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: product_id
          references: inventory.products(id)

    - name: pickings
      columns: [id, tenant_id, company_id, name, picking_type, location_id, location_dest_id, partner_id, scheduled_date, date_done, origin, status, notes, created_at, created_by, updated_at, updated_by, validated_at, validated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: location_id
          references: inventory.locations(id)
        - column: location_dest_id
          references: inventory.locations(id)
        - column: partner_id
          references: core.partners(id)

    - name: stock_moves
      columns: [id, tenant_id, product_id, product_uom_id, location_id, location_dest_id, product_qty, quantity_done, lot_id, picking_id, origin, ref, status, date_expected, date, price_unit, analytic_account_id, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: product_id
          references: inventory.products(id)
        - column: product_uom_id
          references: core.uom(id)
        - column: location_id
          references: inventory.locations(id)
        - column: location_dest_id
          references: inventory.locations(id)
        - column: lot_id
          references: inventory.lots(id)
        - column: picking_id
          references: inventory.pickings(id)
        - column: analytic_account_id
          references: analytics.analytic_accounts(id)

    - name: inventory_adjustments
      columns: [id, tenant_id, company_id, name, location_id, date, status, notes, created_at, created_by, updated_at, updated_by, validated_at, validated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: location_id
          references: inventory.locations(id)

    - name: inventory_adjustment_lines
      columns: [id, adjustment_id, product_id, location_id, lot_id, theoretical_qty, counted_qty, difference_qty, created_at]
      foreign_keys:
        - column: adjustment_id
          references: inventory.inventory_adjustments(id)
        - column: product_id
          references: inventory.products(id)
        - column: location_id
          references: inventory.locations(id)
        - column: lot_id
          references: inventory.lots(id)

  functions:
    - name: update_stock_quant
      purpose: "Actualiza la cantidad en stock de un producto en una ubicación"
    - name: reserve_quantity
      purpose: "Reserva cantidad de un producto en una ubicación"
    - name: get_product_stock
      purpose: "Obtiene el stock disponible de un producto por ubicación"
    - name: process_stock_move
      purpose: "Procesa un movimiento de inventario y actualiza los quants"
    - name: update_location_complete_name
      purpose: "Actualiza el nombre completo de la ubicación"

  triggers:
    - name: trg_products_updated_at
      table: products
    - name: trg_warehouses_updated_at
      table: warehouses
    - name: trg_locations_updated_at
      table: locations
    - name: trg_locations_update_complete_name
      table: locations
    - name: trg_pickings_updated_at
      table: pickings
    - name: trg_stock_moves_updated_at
      table: stock_moves
    - name: track_stock_move_changes
      table: stock_moves

  indexes:
    - name: idx_products_tenant_id
      table: products
      columns: [tenant_id]
    - name: idx_products_code
      table: products
      columns: [code]
    - name: idx_products_barcode
      table: products
      columns: [barcode]
    - name: idx_warehouses_tenant_id
      table: warehouses
      columns: [tenant_id]
    - name: idx_locations_tenant_id
      table: locations
      columns: [tenant_id]
    - name: idx_stock_quants_product_id
      table: stock_quants
      columns: [product_id]
    - name: idx_pickings_tenant_id
      table: pickings
      columns: [tenant_id]
    - name: idx_stock_moves_tenant_id
      table: stock_moves
      columns: [tenant_id]

  rls_policies:
    - name: tenant_isolation_products
      table: products
    - name: tenant_isolation_warehouses
      table: warehouses
    - name: tenant_isolation_locations
      table: locations
    - name: tenant_isolation_lots
      table: lots
    - name: tenant_isolation_pickings
      table: pickings
    - name: tenant_isolation_stock_moves
      table: stock_moves
    - name: tenant_isolation_inventory_adjustments
      table: inventory_adjustments

  views:
    - name: stock_by_product_view
      purpose: "Vista de stock disponible por producto y ubicación"

# ============================================================================
# SCHEMA: purchase
# ============================================================================
purchase:
  enums:
    - name: order_status
      values: [draft, sent, confirmed, received, billed, cancelled]
    - name: rfq_status
      values: [draft, sent, responded, accepted, rejected, cancelled]
    - name: agreement_type
      values: [price, discount, blanket]

  tables:
    - name: purchase_orders
      columns: [id, tenant_id, company_id, name, ref, partner_id, order_date, expected_date, effective_date, currency_id, payment_term_id, amount_untaxed, amount_tax, amount_total, status, receipt_status, invoice_status, picking_id, invoice_id, notes, created_at, created_by, updated_at, updated_by, confirmed_at, confirmed_by, cancelled_at, cancelled_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: partner_id
          references: core.partners(id)
        - column: currency_id
          references: core.currencies(id)
        - column: payment_term_id
          references: financial.payment_terms(id)
        - column: picking_id
          references: inventory.pickings(id)
        - column: invoice_id
          references: financial.invoices(id)

    - name: purchase_order_lines
      columns: [id, order_id, product_id, description, quantity, qty_received, qty_invoiced, uom_id, price_unit, discount, tax_ids, amount_untaxed, amount_tax, amount_total, expected_date, analytic_account_id, created_at, updated_at]
      foreign_keys:
        - column: order_id
          references: purchase.purchase_orders(id)
        - column: product_id
          references: inventory.products(id)
        - column: uom_id
          references: core.uom(id)
        - column: analytic_account_id
          references: analytics.analytic_accounts(id)

    - name: rfqs
      columns: [id, tenant_id, company_id, name, partner_ids, request_date, deadline_date, response_date, status, description, notes, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)

    - name: rfq_lines
      columns: [id, rfq_id, product_id, description, quantity, uom_id, created_at]
      foreign_keys:
        - column: rfq_id
          references: purchase.rfqs(id)
        - column: product_id
          references: inventory.products(id)
        - column: uom_id
          references: core.uom(id)

    - name: vendor_pricelists
      columns: [id, tenant_id, partner_id, product_id, price, currency_id, min_quantity, valid_from, valid_to, active, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: partner_id
          references: core.partners(id)
        - column: product_id
          references: inventory.products(id)
        - column: currency_id
          references: core.currencies(id)

    - name: purchase_agreements
      columns: [id, tenant_id, company_id, name, code, agreement_type, partner_id, start_date, end_date, amount_max, currency_id, is_active, terms, notes, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: partner_id
          references: core.partners(id)
        - column: currency_id
          references: core.currencies(id)

    - name: purchase_agreement_lines
      columns: [id, agreement_id, product_id, quantity, qty_ordered, price_unit, discount, created_at]
      foreign_keys:
        - column: agreement_id
          references: purchase.purchase_agreements(id)
        - column: product_id
          references: inventory.products(id)

    - name: vendor_evaluations
      columns: [id, tenant_id, company_id, partner_id, evaluation_date, period_start, period_end, quality_rating, delivery_rating, service_rating, price_rating, overall_rating, on_time_delivery_rate, defect_rate, comments, created_at, created_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: partner_id
          references: core.partners(id)

  functions:
    - name: calculate_purchase_order_totals
      purpose: "Calcula los totales de una orden de compra"
    - name: create_picking_from_po
      purpose: "Crea un picking de recepción a partir de una orden de compra"

  triggers:
    - name: trg_purchase_orders_updated_at
      table: purchase_orders
    - name: trg_rfqs_updated_at
      table: rfqs
    - name: trg_vendor_pricelists_updated_at
      table: vendor_pricelists
    - name: trg_purchase_order_lines_update_totals
      table: purchase_order_lines
    - name: track_purchase_order_changes
      table: purchase_orders

  indexes:
    - name: idx_purchase_orders_tenant_id
      table: purchase_orders
      columns: [tenant_id]
    - name: idx_purchase_orders_partner_id
      table: purchase_orders
      columns: [partner_id]
    - name: idx_purchase_orders_status
      table: purchase_orders
      columns: [status]
    - name: idx_rfqs_tenant_id
      table: rfqs
      columns: [tenant_id]
    - name: idx_vendor_pricelists_tenant_id
      table: vendor_pricelists
      columns: [tenant_id]

  rls_policies:
    - name: tenant_isolation_purchase_orders
      table: purchase_orders
    - name: tenant_isolation_rfqs
      table: rfqs
    - name: tenant_isolation_vendor_pricelists
      table: vendor_pricelists
    - name: tenant_isolation_purchase_agreements
      table: purchase_agreements
    - name: tenant_isolation_vendor_evaluations
      table: vendor_evaluations

  views: []

# ============================================================================
# SCHEMA: sales
# ============================================================================
sales:
  enums:
    - name: order_status
      values: [draft, sent, sale, done, cancelled]
    - name: quotation_status
      values: [draft, sent, approved, rejected, converted, expired]
    - name: invoice_policy
      values: [order, delivery]
    - name: delivery_status
      values: [pending, partial, delivered]
    - name: invoice_status
      values: [pending, partial, invoiced]

  tables:
    - name: sales_orders
      columns: [id, tenant_id, company_id, name, client_order_ref, partner_id, order_date, validity_date, commitment_date, currency_id, pricelist_id, payment_term_id, user_id, sales_team_id, amount_untaxed, amount_tax, amount_total, status, invoice_status, delivery_status, invoice_policy, picking_id, notes, terms_conditions, signature, signature_date, signature_ip, created_at, created_by, updated_at, updated_by, confirmed_at, confirmed_by, cancelled_at, cancelled_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: partner_id
          references: core.partners(id)
        - column: currency_id
          references: core.currencies(id)
        - column: pricelist_id
          references: sales.pricelists(id)
        - column: payment_term_id
          references: financial.payment_terms(id)
        - column: user_id
          references: auth.users(id)
        - column: sales_team_id
          references: sales.sales_teams(id)
        - column: picking_id
          references: inventory.pickings(id)

    - name: sales_order_lines
      columns: [id, order_id, product_id, description, quantity, qty_delivered, qty_invoiced, uom_id, price_unit, discount, tax_ids, amount_untaxed, amount_tax, amount_total, analytic_account_id, created_at, updated_at]
      foreign_keys:
        - column: order_id
          references: sales.sales_orders(id)
        - column: product_id
          references: inventory.products(id)
        - column: uom_id
          references: core.uom(id)
        - column: analytic_account_id
          references: analytics.analytic_accounts(id)

    - name: quotations
      columns: [id, tenant_id, company_id, name, partner_id, quotation_date, validity_date, currency_id, pricelist_id, user_id, sales_team_id, amount_untaxed, amount_tax, amount_total, status, sale_order_id, notes, terms_conditions, signature, signature_date, signature_ip, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: partner_id
          references: core.partners(id)
        - column: currency_id
          references: core.currencies(id)
        - column: pricelist_id
          references: sales.pricelists(id)
        - column: user_id
          references: auth.users(id)
        - column: sales_team_id
          references: sales.sales_teams(id)
        - column: sale_order_id
          references: sales.sales_orders(id)

    - name: quotation_lines
      columns: [id, quotation_id, product_id, description, quantity, uom_id, price_unit, discount, tax_ids, amount_untaxed, amount_tax, amount_total, created_at]
      foreign_keys:
        - column: quotation_id
          references: sales.quotations(id)
        - column: product_id
          references: inventory.products(id)
        - column: uom_id
          references: core.uom(id)

    - name: pricelists
      columns: [id, tenant_id, company_id, name, currency_id, active, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: currency_id
          references: core.currencies(id)

    - name: pricelist_items
      columns: [id, pricelist_id, product_id, product_category_id, price, min_quantity, valid_from, valid_to, active, created_at, created_by]
      foreign_keys:
        - column: pricelist_id
          references: sales.pricelists(id)
        - column: product_id
          references: inventory.products(id)
        - column: product_category_id
          references: core.product_categories(id)

    - name: customer_groups
      columns: [id, tenant_id, name, description, discount_percentage, created_at, created_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: customer_group_members
      columns: [customer_group_id, partner_id, joined_at]
      foreign_keys:
        - column: customer_group_id
          references: sales.customer_groups(id)
        - column: partner_id
          references: core.partners(id)

    - name: sales_teams
      columns: [id, tenant_id, company_id, name, code, team_leader_id, target_monthly, target_annual, active, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: team_leader_id
          references: auth.users(id)

    - name: sales_team_members
      columns: [sales_team_id, user_id, joined_at]
      foreign_keys:
        - column: sales_team_id
          references: sales.sales_teams(id)
        - column: user_id
          references: auth.users(id)

  functions:
    - name: calculate_sales_order_totals
      purpose: "Calcula los totales de una orden de venta"
    - name: calculate_quotation_totals
      purpose: "Calcula los totales de una cotización"
    - name: convert_quotation_to_order
      purpose: "Convierte una cotización aprobada en orden de venta"

  triggers:
    - name: trg_sales_orders_updated_at
      table: sales_orders
    - name: trg_quotations_updated_at
      table: quotations
    - name: trg_pricelists_updated_at
      table: pricelists
    - name: trg_sales_order_lines_update_totals
      table: sales_order_lines
    - name: trg_quotation_lines_update_totals
      table: quotation_lines
    - name: track_sales_order_changes
      table: sales_orders

  indexes:
    - name: idx_sales_orders_tenant_id
      table: sales_orders
      columns: [tenant_id]
    - name: idx_sales_orders_partner_id
      table: sales_orders
      columns: [partner_id]
    - name: idx_sales_orders_status
      table: sales_orders
      columns: [status]
    - name: idx_quotations_tenant_id
      table: quotations
      columns: [tenant_id]
    - name: idx_pricelists_tenant_id
      table: pricelists
      columns: [tenant_id]

  rls_policies:
    - name: tenant_isolation_sales_orders
      table: sales_orders
    - name: tenant_isolation_quotations
      table: quotations
    - name: tenant_isolation_pricelists
      table: pricelists
    - name: tenant_isolation_customer_groups
      table: customer_groups
    - name: tenant_isolation_sales_teams
      table: sales_teams

  views: []

# ============================================================================
# SCHEMA: projects
# ============================================================================
projects:
  enums:
    - name: project_status
      values: [draft, active, completed, cancelled, on_hold]
    - name: privacy_type
      values: [public, private, followers]
    - name: task_status
      values: [todo, in_progress, review, done, cancelled]
    - name: task_priority
      values: [low, normal, high, urgent]
    - name: dependency_type
      values: [finish_to_start, start_to_start, finish_to_finish, start_to_finish]
    - name: milestone_status
      values: [pending, completed]

  tables:
    - name: projects
      columns: [id, tenant_id, company_id, name, code, description, manager_id, partner_id, analytic_account_id, date_start, date_end, status, privacy, allow_timesheets, color, created_at, created_by, updated_at, updated_by, deleted_at, deleted_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: manager_id
          references: auth.users(id)
        - column: partner_id
          references: core.partners(id)
        - column: analytic_account_id
          references: analytics.analytic_accounts(id)

    - name: project_stages
      columns: [id, tenant_id, project_id, name, sequence, is_closed, fold, created_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: project_id
          references: projects.projects(id)

    - name: tasks
      columns: [id, tenant_id, project_id, stage_id, name, description, assigned_to, partner_id, parent_id, date_start, date_deadline, planned_hours, actual_hours, progress, priority, status, milestone_id, created_at, created_by, updated_at, updated_by, deleted_at, deleted_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: project_id
          references: projects.projects(id)
        - column: stage_id
          references: projects.project_stages(id)
        - column: assigned_to
          references: auth.users(id)
        - column: partner_id
          references: core.partners(id)
        - column: parent_id
          references: projects.tasks(id)
        - column: milestone_id
          references: projects.milestones(id)

    - name: milestones
      columns: [id, tenant_id, project_id, name, description, target_date, status, created_at, created_by, updated_at, updated_by, completed_at, completed_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: project_id
          references: projects.projects(id)

    - name: task_dependencies
      columns: [id, task_id, depends_on_id, dependency_type, created_at]
      foreign_keys:
        - column: task_id
          references: projects.tasks(id)
        - column: depends_on_id
          references: projects.tasks(id)

    - name: task_tags
      columns: [id, tenant_id, name, color, created_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: task_tag_assignments
      columns: [task_id, tag_id, created_at]
      foreign_keys:
        - column: task_id
          references: projects.tasks(id)
        - column: tag_id
          references: projects.task_tags(id)

    - name: timesheets
      columns: [id, tenant_id, company_id, task_id, project_id, employee_id, user_id, date, hours, description, analytic_account_id, analytic_line_id, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: task_id
          references: projects.tasks(id)
        - column: project_id
          references: projects.projects(id)
        - column: user_id
          references: auth.users(id)
        - column: analytic_account_id
          references: analytics.analytic_accounts(id)
        - column: analytic_line_id
          references: analytics.analytic_lines(id)

    - name: task_checklists
      columns: [id, task_id, item_name, is_completed, sequence, created_at, completed_at, completed_by]
      foreign_keys:
        - column: task_id
          references: projects.tasks(id)

    - name: project_templates
      columns: [id, tenant_id, name, description, template_data, active, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

  functions:
    - name: update_task_actual_hours
      purpose: "Actualiza las horas reales de una tarea al cambiar timesheets"
    - name: check_task_dependencies
      purpose: "Verifica si todas las dependencias de una tarea están completadas"
    - name: prevent_circular_dependencies
      purpose: "Previene la creación de dependencias circulares entre tareas"

  triggers:
    - name: trg_projects_updated_at
      table: projects
    - name: trg_tasks_updated_at
      table: tasks
    - name: trg_milestones_updated_at
      table: milestones
    - name: trg_timesheets_updated_at
      table: timesheets
    - name: trg_timesheets_update_task_hours
      table: timesheets
    - name: trg_task_dependencies_prevent_circular
      table: task_dependencies
    - name: track_project_changes
      table: projects

  indexes:
    - name: idx_projects_tenant_id
      table: projects
      columns: [tenant_id]
    - name: idx_projects_company_id
      table: projects
      columns: [company_id]
    - name: idx_tasks_tenant_id
      table: tasks
      columns: [tenant_id]
    - name: idx_tasks_project_id
      table: tasks
      columns: [project_id]
    - name: idx_tasks_assigned_to
      table: tasks
      columns: [assigned_to]
    - name: idx_timesheets_tenant_id
      table: timesheets
      columns: [tenant_id]

  rls_policies:
    - name: tenant_isolation_projects
      table: projects
    - name: tenant_isolation_project_stages
      table: project_stages
    - name: tenant_isolation_tasks
      table: tasks
    - name: tenant_isolation_milestones
      table: milestones
    - name: tenant_isolation_task_tags
      table: task_tags
    - name: tenant_isolation_timesheets
      table: timesheets
    - name: tenant_isolation_project_templates
      table: project_templates

  views: []

# ============================================================================
# SCHEMA: system
# ============================================================================
system:
  enums:
    - name: message_type
      values: [comment, note, email, notification, system]
    - name: notification_status
      values: [pending, sent, read, failed]
    - name: activity_type
      values: [call, meeting, email, todo, follow_up, custom]
    - name: activity_status
      values: [planned, done, cancelled, overdue]
    - name: email_status
      values: [draft, queued, sending, sent, failed, bounced]
    - name: log_level
      values: [debug, info, warning, error, critical]
    - name: report_format
      values: [pdf, excel, csv, html]

  tables:
    - name: messages
      columns: [id, tenant_id, model, record_id, message_type, subject, body, author_id, author_name, author_email, email_from, reply_to, message_id, parent_id, attachment_ids, created_at, updated_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: author_id
          references: auth.users(id)
        - column: parent_id
          references: system.messages(id)

    - name: message_followers
      columns: [id, model, record_id, partner_id, user_id, email_notifications, created_at]
      foreign_keys:
        - column: partner_id
          references: core.partners(id)
        - column: user_id
          references: auth.users(id)

    - name: notifications
      columns: [id, tenant_id, user_id, title, message, url, model, record_id, status, read_at, created_at, sent_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: user_id
          references: auth.users(id)

    - name: activities
      columns: [id, tenant_id, model, record_id, activity_type, summary, description, assigned_to, assigned_by, due_date, due_time, status, created_at, created_by, completed_at, completed_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: assigned_to
          references: auth.users(id)
        - column: assigned_by
          references: auth.users(id)

    - name: message_templates
      columns: [id, tenant_id, name, model, subject, body_html, body_text, email_from, reply_to, cc, bcc, active, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: email_queue
      columns: [id, tenant_id, email_to, email_cc, email_bcc, subject, body_html, body_text, email_from, reply_to, attachment_ids, status, attempts, max_attempts, error_message, message_id, opened_at, clicked_at, created_at, scheduled_at, sent_at, failed_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: logs
      columns: [id, tenant_id, level, logger, message, stack_trace, user_id, ip_address, user_agent, request_id, model, record_id, metadata, created_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: user_id
          references: auth.users(id)

    - name: reports
      columns: [id, tenant_id, name, code, description, model, report_type, query_template, template_file, default_format, is_public, active, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: report_executions
      columns: [id, tenant_id, report_id, parameters, format, file_url, file_size, error_message, status, created_at, created_by, started_at, completed_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: report_id
          references: system.reports(id)

    - name: dashboards
      columns: [id, tenant_id, name, description, layout, is_default, user_id, is_public, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: user_id
          references: auth.users(id)

    - name: dashboard_widgets
      columns: [id, dashboard_id, widget_type, title, config, position, data_source, query_params, refresh_interval, created_at, updated_at]
      foreign_keys:
        - column: dashboard_id
          references: system.dashboards(id)

    - name: field_tracking_config
      columns: [id, table_schema, table_name, field_name, track_changes, field_type, display_label, created_at]
      foreign_keys: []

    - name: change_log
      columns: [id, tenant_id, table_schema, table_name, record_id, changed_by, changed_at, change_type, field_name, field_label, old_value, new_value, change_context, created_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: changed_by
          references: auth.users(id)

  functions:
    - name: notify_followers
      purpose: "Notifica a los seguidores de un registro cuando hay un nuevo mensaje"
    - name: mark_activities_as_overdue
      purpose: "Marca actividades vencidas como overdue (ejecutar diariamente)"
    - name: clean_old_logs
      purpose: "Limpia logs antiguos (mantener solo críticos)"
    - name: track_field_changes
      purpose: "Función trigger para trackear cambios automáticamente según configuración en field_tracking_config (patrón mail.thread de Odoo)"

  triggers:
    - name: trg_messages_updated_at
      table: messages
    - name: trg_message_templates_updated_at
      table: message_templates
    - name: trg_reports_updated_at
      table: reports
    - name: trg_dashboards_updated_at
      table: dashboards
    - name: trg_dashboard_widgets_updated_at
      table: dashboard_widgets

  indexes:
    - name: idx_messages_tenant_id
      table: messages
      columns: [tenant_id]
    - name: idx_messages_model_record
      table: messages
      columns: [model, record_id]
    - name: idx_notifications_tenant_id
      table: notifications
      columns: [tenant_id]
    - name: idx_notifications_user_id
      table: notifications
      columns: [user_id]
    - name: idx_activities_tenant_id
      table: activities
      columns: [tenant_id]
    - name: idx_logs_tenant_id
      table: logs
      columns: [tenant_id]
    - name: idx_logs_level
      table: logs
      columns: [level]
    - name: idx_change_log_tenant_id
      table: change_log
      columns: [tenant_id]
    - name: idx_change_log_record
      table: change_log
      columns: [table_schema, table_name, record_id]

  rls_policies:
    - name: tenant_isolation_messages
      table: messages
    - name: tenant_isolation_notifications
      table: notifications
    - name: tenant_isolation_activities
      table: activities
    - name: tenant_isolation_message_templates
      table: message_templates
    - name: tenant_isolation_logs
      table: logs
    - name: tenant_isolation_reports
      table: reports
    - name: tenant_isolation_report_executions
      table: report_executions
    - name: tenant_isolation_dashboards
      table: dashboards
    - name: tenant_isolation_change_log
      table: change_log

  views: []

# ============================================================================
# RESUMEN DE INVENTARIO (ACTUALIZADO 2025-12-09)
# ============================================================================
summary:
  total_schemas: 12
  total_enums: 49
  total_tables: 144
  total_functions: 52
  total_triggers: 95
  total_indexes: 350+
  total_rls_policies: 80+
  total_views: 8

  schemas:
    - name: prerequisites
      tables: 0
      functions: 9
      types: 2
    - name: auth
      tables: 26      # 10 (auth.sql) + 16 (auth-extensions.sql)
      functions: 10
      enums: 4
    - name: core
      tables: 12
      functions: 3
      enums: 4
    - name: analytics
      tables: 7
      functions: 4
      enums: 3
    - name: financial
      tables: 15
      functions: 4
      enums: 10
    - name: inventory
      tables: 20      # 10 (inventory.sql) + 10 (inventory-extensions.sql)
      functions: 8
      enums: 6
    - name: purchase
      tables: 8
      functions: 2
      enums: 3
    - name: sales
      tables: 10
      functions: 3
      enums: 5
    - name: projects
      tables: 10
      functions: 3
      enums: 6
    - name: system
      tables: 13
      functions: 4
      enums: 7
    - name: billing
      tables: 11
      functions: 3
      enums: 5
    - name: crm
      tables: 6
      functions: 0
      enums: 4
    - name: hr
      tables: 6
      functions: 0
      enums: 5

# ============================================================================
# SCHEMA: billing (NUEVO - SaaS/Multi-tenant)
# DDL: 10-billing.sql - 11 tablas
# ============================================================================
billing:
  enums:
    - name: subscription_status
      values: [trialing, active, past_due, paused, cancelled, suspended, expired]
    - name: billing_cycle
      values: [monthly, quarterly, semi_annual, annual]
    - name: payment_method_type
      values: [card, bank_transfer, paypal, oxxo, spei, other]
    - name: invoice_status
      values: [draft, open, paid, void, uncollectible]
    - name: payment_status
      values: [pending, processing, succeeded, failed, cancelled, refunded]

  tables:
    - name: subscription_plans
      columns: [id, code, name, description, price_monthly, price_yearly, currency_code, max_users, max_companies, max_storage_gb, max_api_calls_month, features, is_active, is_public, is_default, trial_days, sort_order, created_at, created_by, updated_at, updated_by]
      foreign_keys: []
      note: "Planes globales (no por tenant)"

    - name: tenant_owners
      columns: [id, tenant_id, user_id, ownership_type, billing_email, billing_phone, billing_name, created_at, created_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: user_id
          references: auth.users(id)

    - name: subscriptions
      columns: [id, tenant_id, plan_id, status, billing_cycle, trial_start_at, trial_end_at, current_period_start, current_period_end, cancelled_at, cancel_at_period_end, paused_at, discount_percent, coupon_code, stripe_subscription_id, stripe_customer_id, created_at, created_by, updated_at, updated_by]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: plan_id
          references: billing.subscription_plans(id)

    - name: payment_methods
      columns: [id, tenant_id, type, is_default, card_last_four, card_brand, card_exp_month, card_exp_year, billing_name, billing_email, billing_address_line1, billing_address_line2, billing_city, billing_state, billing_postal_code, billing_country, stripe_payment_method_id, created_at, created_by, updated_at, deleted_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: invoices
      columns: [id, tenant_id, subscription_id, invoice_number, status, period_start, period_end, due_date, paid_at, voided_at, subtotal, tax_amount, discount_amount, total, amount_paid, amount_due, currency_code, customer_name, customer_tax_id, customer_email, customer_address, pdf_url, cfdi_uuid, cfdi_xml_url, stripe_invoice_id, notes, created_at, created_by, updated_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: subscription_id
          references: billing.subscriptions(id)

    - name: invoice_lines
      columns: [id, invoice_id, description, quantity, unit_price, amount, period_start, period_end, created_at]
      foreign_keys:
        - column: invoice_id
          references: billing.invoices(id)

    - name: payments
      columns: [id, tenant_id, invoice_id, payment_method_id, amount, currency_code, status, paid_at, failed_at, refunded_at, failure_reason, failure_code, transaction_id, stripe_payment_intent_id, created_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: invoice_id
          references: billing.invoices(id)
        - column: payment_method_id
          references: billing.payment_methods(id)

    - name: usage_records
      columns: [id, tenant_id, subscription_id, metric_type, quantity, billing_period, recorded_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: subscription_id
          references: billing.subscriptions(id)

    - name: coupons
      columns: [id, code, name, description, discount_type, discount_value, currency_code, max_redemptions, max_redemptions_per_tenant, redemptions_count, valid_from, valid_until, applicable_plans, is_active, created_at, created_by]
      foreign_keys: []

    - name: coupon_redemptions
      columns: [id, coupon_id, tenant_id, subscription_id, redeemed_at, redeemed_by]
      foreign_keys:
        - column: coupon_id
          references: billing.coupons(id)
        - column: tenant_id
          references: auth.tenants(id)
        - column: subscription_id
          references: billing.subscriptions(id)

    - name: subscription_history
      columns: [id, subscription_id, event_type, previous_plan_id, new_plan_id, previous_status, new_status, metadata, notes, created_at, created_by]
      foreign_keys:
        - column: subscription_id
          references: billing.subscriptions(id)
        - column: previous_plan_id
          references: billing.subscription_plans(id)
        - column: new_plan_id
          references: billing.subscription_plans(id)

  functions:
    - name: get_tenant_plan
      purpose: "Obtiene información del plan actual de un tenant"
    - name: can_add_user
      purpose: "Verifica si el tenant puede agregar más usuarios según su plan"
    - name: has_feature
      purpose: "Verifica si una feature está habilitada para el tenant"

  rls_policies: []
  note: "Sin RLS - gestionado a nivel aplicación por razones de seguridad"

# ============================================================================
# SCHEMA: crm (NUEVO - Customer Relationship Management)
# DDL: 11-crm.sql - 6 tablas
# ============================================================================
crm:
  enums:
    - name: lead_status
      values: [new, contacted, qualified, converted, lost]
    - name: opportunity_status
      values: [open, won, lost]
    - name: activity_type
      values: [call, email, meeting, task, note]
    - name: lead_source
      values: [website, phone, email, referral, social_media, advertising, event, other]

  tables:
    - name: lead_stages
      columns: [id, tenant_id, name, sequence, is_won, probability, requirements, active, created_at, updated_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: opportunity_stages
      columns: [id, tenant_id, name, sequence, is_won, probability, requirements, active, created_at, updated_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: lost_reasons
      columns: [id, tenant_id, name, description, active, created_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: leads
      columns: [id, tenant_id, company_id, name, ref, contact_name, email, phone, mobile, website, company_name, job_position, industry, employee_count, annual_revenue, street, city, state, zip, country, stage_id, status, user_id, sales_team_id, source, campaign_id, medium, priority, probability, expected_revenue, date_open, date_closed, date_deadline, date_last_activity, partner_id, opportunity_id, lost_reason_id, lost_notes, description, notes, tags, created_by, updated_by, created_at, updated_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: stage_id
          references: crm.lead_stages(id)
        - column: user_id
          references: auth.users(id)
        - column: sales_team_id
          references: sales.sales_teams(id)
        - column: partner_id
          references: core.partners(id)
        - column: lost_reason_id
          references: crm.lost_reasons(id)

    - name: opportunities
      columns: [id, tenant_id, company_id, name, ref, partner_id, contact_name, email, phone, stage_id, status, user_id, sales_team_id, priority, probability, expected_revenue, recurring_revenue, recurring_plan, date_deadline, date_closed, date_last_activity, lead_id, source, campaign_id, medium, lost_reason_id, lost_notes, quotation_id, order_id, description, notes, tags, created_by, updated_by, created_at, updated_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: partner_id
          references: core.partners(id)
        - column: stage_id
          references: crm.opportunity_stages(id)
        - column: user_id
          references: auth.users(id)
        - column: sales_team_id
          references: sales.sales_teams(id)
        - column: lead_id
          references: crm.leads(id)
        - column: lost_reason_id
          references: crm.lost_reasons(id)
        - column: quotation_id
          references: sales.quotations(id)
        - column: order_id
          references: sales.sales_orders(id)

    - name: activities
      columns: [id, tenant_id, res_model, res_id, activity_type, summary, description, date_deadline, date_done, user_id, assigned_to, done, created_by, created_at, updated_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: user_id
          references: auth.users(id)
        - column: assigned_to
          references: auth.users(id)

  rls_policies:
    - name: tenant_isolation_lead_stages
      table: lead_stages
    - name: tenant_isolation_opportunity_stages
      table: opportunity_stages
    - name: tenant_isolation_lost_reasons
      table: lost_reasons
    - name: tenant_isolation_leads
      table: leads
    - name: tenant_isolation_opportunities
      table: opportunities
    - name: tenant_isolation_crm_activities
      table: activities

# ============================================================================
# SCHEMA: hr (NUEVO - Human Resources)
# DDL: 12-hr.sql - 6 tablas
# ============================================================================
hr:
  enums:
    - name: contract_status
      values: [draft, active, expired, terminated, cancelled]
    - name: contract_type
      values: [permanent, temporary, contractor, internship, part_time]
    - name: leave_status
      values: [draft, submitted, approved, rejected, cancelled]
    - name: leave_type
      values: [vacation, sick, personal, maternity, paternity, bereavement, unpaid, other]
    - name: employee_status
      values: [active, inactive, on_leave, terminated]

  tables:
    - name: departments
      columns: [id, tenant_id, company_id, name, code, parent_id, manager_id, description, color, active, created_by, created_at, updated_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: parent_id
          references: hr.departments(id)
        - column: manager_id
          references: hr.employees(id)

    - name: job_positions
      columns: [id, tenant_id, name, department_id, description, requirements, responsibilities, min_salary, max_salary, active, created_at, updated_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: department_id
          references: hr.departments(id)

    - name: employees
      columns: [id, tenant_id, company_id, employee_number, first_name, last_name, middle_name, user_id, birth_date, gender, marital_status, nationality, identification_id, identification_type, social_security_number, tax_id, email, work_email, phone, work_phone, mobile, emergency_contact, emergency_phone, street, city, state, zip, country, department_id, job_position_id, manager_id, hire_date, termination_date, status, bank_name, bank_account, bank_clabe, photo_url, notes, created_by, updated_by, created_at, updated_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: user_id
          references: auth.users(id)
        - column: department_id
          references: hr.departments(id)
        - column: job_position_id
          references: hr.job_positions(id)
        - column: manager_id
          references: hr.employees(id)

    - name: contracts
      columns: [id, tenant_id, company_id, employee_id, name, reference, contract_type, status, job_position_id, department_id, date_start, date_end, trial_date_end, wage, wage_type, currency_id, resource_calendar_id, hours_per_week, vacation_days, christmas_bonus_days, document_url, notes, created_by, updated_by, created_at, updated_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: employee_id
          references: hr.employees(id)
        - column: job_position_id
          references: hr.job_positions(id)
        - column: department_id
          references: hr.departments(id)
        - column: currency_id
          references: core.currencies(id)

    - name: leave_types
      columns: [id, tenant_id, name, code, leave_type, requires_approval, max_days, is_paid, color, active, created_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)

    - name: leaves
      columns: [id, tenant_id, company_id, employee_id, leave_type_id, name, date_from, date_to, number_of_days, status, description, approved_by, approved_at, rejection_reason, created_by, updated_by, created_at, updated_at]
      foreign_keys:
        - column: tenant_id
          references: auth.tenants(id)
        - column: company_id
          references: auth.companies(id)
        - column: employee_id
          references: hr.employees(id)
        - column: leave_type_id
          references: hr.leave_types(id)
        - column: approved_by
          references: auth.users(id)

  rls_policies:
    - name: tenant_isolation_departments
      table: departments
    - name: tenant_isolation_job_positions
      table: job_positions
    - name: tenant_isolation_employees
      table: employees
    - name: tenant_isolation_contracts
      table: contracts
    - name: tenant_isolation_leave_types
      table: leave_types
    - name: tenant_isolation_leaves
      table: leaves

# ============================================================================
# SCHEMA: auth (EXTENSIONES - auth-extensions.sql)
# DDL: 01-auth-extensions.sql - 16 tablas adicionales
# ============================================================================
auth_extensions:
  note: "Estas tablas complementan el schema auth base (01-auth.sql)"
  tables:
    - name: groups
      purpose: "Grupos de usuarios para permisos"
    - name: group_implied
      purpose: "Herencia entre grupos"
    - name: user_groups
      purpose: "Asignación usuarios a grupos"
    - name: models
      purpose: "Registro de modelos del sistema"
    - name: model_access
      purpose: "Permisos CRUD por modelo y grupo"
    - name: record_rules
      purpose: "Reglas de acceso a nivel registro (domain filters)"
    - name: rule_groups
      purpose: "Asignación reglas a grupos"
    - name: model_fields
      purpose: "Campos de modelos"
    - name: field_permissions
      purpose: "Permisos a nivel campo"
    - name: api_keys
      purpose: "API Keys para autenticación"
    - name: trusted_devices
      purpose: "Dispositivos de confianza para 2FA"
    - name: verification_codes
      purpose: "Códigos de verificación (2FA, email)"
    - name: mfa_audit_log
      purpose: "Auditoría de operaciones MFA"
    - name: oauth_providers
      purpose: "Proveedores OAuth2 configurados"
    - name: oauth_user_links
      purpose: "Vinculación usuarios con cuentas OAuth"
    - name: oauth_states
      purpose: "Estados temporales para flow OAuth"

# ============================================================================
# SCHEMA: inventory (EXTENSIONES - inventory-extensions.sql)
# DDL: 05-inventory-extensions.sql - 10 tablas adicionales
# ============================================================================
inventory_extensions:
  note: "Estas tablas complementan el schema inventory base (05-inventory.sql)"
  tables:
    - name: stock_valuation_layers
      purpose: "Capas de valoración FIFO/AVCO"
    - name: category_stock_accounts
      purpose: "Cuentas contables por categoría de producto"
    - name: valuation_settings
      purpose: "Configuración de valoración por empresa"
    - name: lots
      purpose: "Lotes de productos (trazabilidad)"
    - name: stock_move_consume_rel
      purpose: "Relación movimientos produce/consume"
    - name: removal_strategies
      purpose: "Estrategias de remoción (FIFO/LIFO/AVCO)"
    - name: inventory_count_sessions
      purpose: "Sesiones de conteo cíclico"
    - name: inventory_count_lines
      purpose: "Líneas de conteo"
    - name: abc_classification_rules
      purpose: "Reglas de clasificación ABC"
    - name: product_abc_classification
      purpose: "Clasificación ABC de productos"

# ============================================================================
# FIN DEL INVENTARIO
# Última actualización: 2025-12-09
# Total: 12 schemas, 144 tablas
# ============================================================================
