# Dicionário de dados da cabine PIX Monetarie

Data: 2026-07-10. Trilha: arquitetura da cabine PIX. Documento gerado a partir do código (somente leitura).

## Fontes e método

- DDL base: squash `pix/backend/apps/shared/priv/repo/migrations/20260101000000_create_schema.exs`, que aplica o dump `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql` (pg_dump schema-only do banco `mon_pix`, 207 CREATE TABLE, 12 schemas Postgres).
- Migrations pós-squash: 45 em `pix/backend/apps/shared/priv/repo/migrations/` e 11 em `pix/backend/apps/settlement_service/priv/repo/migrations/` (criam 37 tabelas adicionais e alteram outras).
- Ecto schemas: 123 módulos `schema "..."` nos 4 apps do umbrella (`shared`, `spi_service`, `dict_service`, `settlement_service`).
- Banco físico: UM único PostgreSQL (banco `mon_pix` em dev; em AWS via secret `DATABASE_URL`, `monetarie/{env}/db/mon_pix/url`). Os 4 repos Ecto (`Shared.Repo`, `SpiService.Repo`, `DictService.Repo`, `SettlementService.Repo`, `pix/backend/config/config.exs:8,36,54,119`) apontam para o mesmo banco e se separam por schema Postgres via `@schema_prefix`.
- Nas tabelas abaixo, a linha do DDL refere-se a `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql` quando a tabela vem do dump, ou à migration citada quando criada depois.

## Visão geral dos schemas Postgres

| Schema | Tabelas | Domínio |
|---|---|---|
| `monetarie_spi` | 51 | SPI: mensageria, transações e saldos (app `spi_service` + schemas em `shared`) |
| `monetarie_spi_msg` | 3 | SPI: XML bruto e criptografia (certificados) |
| `monetarie_spi_ref` | 11 | SPI: dados de referência BACEN |
| `monetarie_dict` | 38 | DICT: chaves, claims, MED e antifraude (app `dict_service` + schemas em `shared`) |
| `monetarie_settlement` | 55 | Settlement: liquidação, tarifas, QR/CobV, relatórios e contabilidade (app `settlement_service`) |
| `monetarie_audit` | 5 | Auditoria de tráfego BACEN |
| `monetarie_auth` | 23 | Autenticação, RBAC e administração |
| `monetarie_webhook` | 2 | Webhooks (infra de dados; dispatch é do Core) |
| `bacen_simulator` | 27 | Simulador BACEN (apenas dev/homolog; `SIMULATOR_ENABLED=false` nos ambientes reais) |
| `public` | 7 | Schema public: MED 2.0, limites e Oban |
| `monetarie_accounting`, `monetarie_spi_hist`, `monetarie_settlement_hist` | 0 | Schemas criados no dump sem nenhuma tabela (reservados para histórico/contabilidade). |

## Tabelas particionadas

A cabine tem 3 tabelas particionadas (declarativo, `PARTITION BY RANGE`), com filhos mensais criados/mantidos pelo `Shared.PartitionManager` (`pix/backend/apps/shared/lib/shared/partition_manager.ex:10-28`, roda a cada 24h com 60 dias de lookahead):

- `monetarie_spi.messages` PARTITION BY RANGE (`operation_time`) (`pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5361`); filhos no dump: messages_2026_03, messages_2026_04, messages_2026_05, messages_2026_06, messages_2026_07, messages_2026_08, messages_default.
- `monetarie_auth.activity_log` PARTITION BY RANGE (`created_at`) (`pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1310`); filhos no dump: activity_log_2026_01, activity_log_2026_02, activity_log_2026_03, activity_log_2026_04, activity_log_default.
- `monetarie_auth.login_history` PARTITION BY RANGE (`logged_in_at`) (`pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1582`); filhos no dump: login_history_2026_01, login_history_2026_02, login_history_2026_03, login_history_2026_04, login_history_default.

As demais tabelas grandes (`monetarie_spi.transactions`, `monetarie_audit.xml_audit_logs`, `monetarie_spi.message_history`) NÃO são particionadas nesta base. As tabelas `message_timeline`, `fee_transactions` e `fee_split_transactions` citadas em handoffs anteriores pertencem ao banco do Core, não à cabine PIX.

## Observações de higiene

- `monetarie_spi_ref.xsd_schemas` foi REMOVIDA (`pix/backend/apps/shared/priv/repo/migrations/20260426170000_drop_xsd_schemas_table.exs`); permanece documentada abaixo por constar no dump.
- 3 Ecto schemas SEM prefixo apontam para tabelas que NÃO existem no dump em `public` e aparentam ser código legado sem uso: `dict_keys` (`pix/backend/apps/shared/lib/shared/schemas/dict_key.ex:20`), `participants` (`pix/backend/apps/shared/lib/shared/schemas/participant.ex:14`) e `settlement_batches` (`pix/backend/apps/shared/lib/shared/schemas/settlement_batch.ex:15`).
- Tabelas com dois Ecto schemas (um em `shared`, outro no app do domínio) são normais no repo: ex. `monetarie_dict.claims`, `monetarie_dict.keys`, `monetarie_dict.funds_recoveries`, `monetarie_spi.statements`, `monetarie_settlement.fee_tables`; ambos os arquivos são citados.

## Schema `monetarie_spi`

SPI: mensageria, transações e saldos (app `spi_service` + schemas em `shared`).

### `monetarie_spi.accounts`

Cadastro de contas transacionais conhecidas pela cabine (ISPB, agência, número, tipo, status), usado na validação de conta do PIX-in.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4590` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/account.ex:15`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `institution_id` | `integer` | NOT NULL |
| `branch_id` | `integer` | NOT NULL |
| `cpf_cnpj` | `character varying(14)` | NOT NULL |
| `account_no` | `character varying(34)` | NOT NULL |
| `account_type` | `character(4)` | default `'CACC'::bpchar` |
| `is_default` | `boolean` | default `false` |
| `issuer` | `character varying(35)` |  |
| `proxy` | `character varying(2048)` |  |
| `status_id` | `integer` | default `1` |
| `created_at` | `timestamp with time zone` | default `now()` |
| `ispb` | `character(8)` |  |
| `holder_name` | `character varying(140)` |  |

Constraints e índices: `PK (id)`; `INDEX idx_spi_accounts_cpf (cpf_cnpj)`; `INDEX idx_spi_accounts_inst (institution_id)`; `INDEX idx_spi_accounts_ispb (ispb)`.

### `monetarie_spi.alcada_parameters`

Regras de alçada: faixas de valor e número de vistos exigidos por tipo de mensagem.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4630` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/alcada/parameter.ex:13`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `description` | `text` |  |
| `min_amount` | `numeric(18,2)` | default `0` |
| `max_amount` | `numeric(18,2)` |  |
| `accumulated_amount` | `numeric(18,2)` |  |
| `accumulated_period` | `character varying(20)` | default `'daily'::character varying` |
| `required_vistos` | `integer` | NOT NULL; default `1` |
| `start_hour` | `time without time zone` | default `'00:00:00'::time without time zone` |
| `end_hour` | `time without time zone` | default `'23:59:00'::time without time zone` |
| `message_types` | `jsonb` | default `'[]'::jsonb` |
| `is_active` | `boolean` | default `true` |
| `priority` | `integer` | default `0` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_alcada_params_active (is_active, priority) WHERE (is_active = true)`.

### `monetarie_spi.alcada_registrations`

Registros de operação pendentes de aprovação por alçada.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4672` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/alcada/registration.ex:12`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `operation_id` | `character varying(50)` | NOT NULL |
| `operation_type` | `character varying(30)` | NOT NULL |
| `parameter_id` | `bigint` |  |
| `amount` | `numeric(18,2)` | NOT NULL |
| `status` | `character varying(20)` | NOT NULL; default `'pending'::character varying` |
| `required_vistos` | `integer` | NOT NULL; default `1` |
| `current_vistos` | `integer` | NOT NULL; default `0` |
| `description` | `text` |  |
| `created_by` | `bigint` |  |
| `resolved_at` | `timestamp with time zone` |  |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `FK (parameter_id) REFERENCES monetarie_spi.alcada_parameters(id)`; `INDEX idx_alcada_reg_operation (operation_id, operation_type)`; `INDEX idx_alcada_reg_status (status) WHERE ((status)::text = 'pending'::text)`.

### `monetarie_spi.alcada_vistos`

Vistos (assinaturas individuais de aprovação) sobre um registro de alçada.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4712` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/alcada/visto.ex:10`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `registration_id` | `bigint` | NOT NULL |
| `user_id` | `bigint` | NOT NULL |
| `user_name` | `character varying(100)` |  |
| `status` | `character varying(20)` | NOT NULL; default `'approved'::character varying` |
| `notes` | `text` |  |
| `signed_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `FK (registration_id) REFERENCES monetarie_spi.alcada_registrations(id)`; `INDEX idx_alcada_vistos_reg (registration_id)`; `UNIQUE INDEX idx_alcada_vistos_user_reg (registration_id, user_id)`.

### `monetarie_spi.alert_configs`

Configuração de alertas operacionais por código de mensagem (filtros e tipos de notificação).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4747`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `message_code` | `character varying(20)` |  |
| `filter_criteria` | `jsonb` |  |
| `notification_types` | `jsonb` |  |
| `is_active` | `boolean` | default `true` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`.

### `monetarie_spi.alert_user_subscriptions`

Inscrição de usuários nos alertas configurados.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4783`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `alert_config_id` | `integer` |  |
| `user_id` | `integer` | NOT NULL |
| `notification_type` | `character varying(50)` | NOT NULL |
| `is_active` | `boolean` | default `true` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `FK (alert_config_id) REFERENCES monetarie_spi.alert_configs(id)`; `INDEX idx_alert_subs_user (user_id)`.

### `monetarie_spi.approval_records`

Trilha de aprovação LSO/RSO de operações acima de limiar.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4817`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `threshold_id` | `integer` |  |
| `operation_id` | `bigint` | NOT NULL |
| `operation_type` | `character varying(50)` | NOT NULL |
| `amount` | `numeric(18,2)` | NOT NULL |
| `status` | `character varying(20)` | default `'PENDING'::character varying` |
| `requested_by` | `integer` |  |
| `requested_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `lso_approved_by` | `integer` |  |
| `lso_approved_at` | `timestamp with time zone` |  |
| `rso_approved_by` | `integer` |  |
| `rso_approved_at` | `timestamp with time zone` |  |
| `rejected_by` | `integer` |  |
| `rejected_at` | `timestamp with time zone` |  |
| `rejection_reason` | `text` |  |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `FK (threshold_id) REFERENCES monetarie_spi.approval_thresholds(id)`; `INDEX idx_approval_records_operation (operation_id)`; `INDEX idx_approval_records_status (status)`.

### `monetarie_spi.approval_thresholds`

Limiares de valor por instituição/mensagem que exigem aprovação LSO/RSO.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4862`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `institution_id` | `integer` |  |
| `message_code` | `character varying(20)` |  |
| `min_amount` | `numeric(18,2)` | NOT NULL; default `0` |
| `max_amount` | `numeric(18,2)` |  |
| `daily_limit` | `numeric(18,2)` |  |
| `requires_lso` | `boolean` | default `false` |
| `requires_rso` | `boolean` | default `false` |
| `user_groups` | `jsonb` |  |
| `is_active` | `boolean` | default `true` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_approval_thresholds_inst (institution_id)`.

### `monetarie_spi.automation_configs`

Configuração de automação de mensagens periódicas (cron, canal secundário, filtros).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4903`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `message_code` | `character varying(20)` |  |
| `schedule_type` | `character varying(20)` |  |
| `schedule_cron` | `character varying(100)` |  |
| `secondary_channel` | `boolean` | default `false` |
| `filter_criteria` | `jsonb` |  |
| `is_active` | `boolean` | default `true` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`.

### `monetarie_spi.bacen_inbound`

Acervo de toda mensagem RECEBIDA do BACEN (XML bruto, status de processamento, erro de assinatura); insumo do PIX-in e da reconciliação camt.054.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4941` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/bacen_inbound.ex:16`

| Coluna | Tipo | Observações |
|---|---|---|
| `ispb` | `character(8)` | NOT NULL |
| `resource_id` | `character varying(50)` | NOT NULL |
| `receive_time` | `timestamp with time zone` | NOT NULL; default `now()` |
| `receive_date` | `date` | NOT NULL |
| `return_code` | `integer` | NOT NULL |
| `content_type` | `character varying(100)` |  |
| `next_url` | `character varying(400)` |  |
| `problem` | `text` |  |
| `xml_content` | `text` |  |
| `processing_time` | `timestamp with time zone` |  |
| `processing_status` | `character varying(20)` | default `'RECEIVED'::character varying` |
| `validation_errors` | `text` |  |
| `xsd_valid` | `boolean` |  |
| `signature_valid` | `boolean` |  |
| `message_type` | `character varying(20)` |  |
| `channel` | `character varying(3)` |  |
| `signature_error` | `:text` | adicionada por `20260503180000_add_signature_error_to_bacen_inbound.exs` |

Constraints e índices: `PK (ispb, resource_id, receive_time)`; `INDEX idx_bacen_in_channel (channel)`; `INDEX idx_bacen_in_status (processing_status)`; `INDEX idx_spi_bacen_in_date (receive_date)`.

### `monetarie_spi.bacen_outbound`

Acervo/auditoria de tudo que foi ENVIADO ao BACEN (XML bruto, chave message_id+send_time); NÃO é a fila de envio (a fila é NATS `monetarie.spi.outbound.>`).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4965` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/bacen_outbound.ex:13`

| Coluna | Tipo | Observações |
|---|---|---|
| `message_id` | `character varying(50)` | NOT NULL |
| `send_time` | `timestamp with time zone` | NOT NULL; default `now()` |
| `send_date` | `date` | NOT NULL |
| `ispb` | `character(8)` | NOT NULL |
| `return_code` | `integer` | NOT NULL |
| `resource_id` | `character varying(50)` |  |
| `xml_content` | `text` |  |
| `content_type` | `character varying(100)` |  |
| `problem` | `text` |  |

Constraints e índices: `PK (message_id, send_time)`; `INDEX idx_spi_bacen_out_date (send_date)`; `INDEX idx_spi_bacen_out_ispb (ispb)`.

### `monetarie_spi.balance_blocks`

Bloqueios (reservas) de saldo da Conta PI por PIX-out (debit-then-send); confirmados no ACK/liquidação e revertidos na rejeição.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4982` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/balances/balance_block.ex:16`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `ispb` | `character varying(255)` | NOT NULL |
| `amount` | `numeric(18,2)` | NOT NULL |
| `reason` | `character varying(500)` |  |
| `status` | `character varying(20)` | default `'active'::character varying` |
| `reference_id` | `character varying(100)` |  |
| `reference_type` | `character varying(50)` |  |
| `expires_at` | `timestamp without time zone` |  |
| `released_at` | `timestamp without time zone` |  |
| `release_reason` | `character varying(500)` |  |
| `created_by` | `integer` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX balance_blocks_ispb_index (ispb)`; `INDEX balance_blocks_status_index (status)`.

### `monetarie_spi.balance_cache`

Cache do último saldo conhecido da Conta PI por ISPB.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5003` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/balance.ex:13`

| Coluna | Tipo | Observações |
|---|---|---|
| `ispb` | `character varying(8)` | NOT NULL |
| `available_amount` | `numeric(18,2)` | NOT NULL; default `0` |
| `blocked_amount` | `numeric(18,2)` | NOT NULL; default `0` |
| `projected_amount` | `numeric(18,2)` | NOT NULL; default `0` |
| `last_updated` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (ispb)`.

### `monetarie_spi.balance_history`

Histórico de variações de saldo da Conta PI (auditoria de créditos/débitos).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5016` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/balances/balance_history.ex:16`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `ispb` | `character varying(255)` | NOT NULL |
| `available_before` | `numeric(18,2)` |  |
| `available_after` | `numeric(18,2)` |  |
| `change_amount` | `numeric(18,2)` |  |
| `blocked` | `numeric(18,2)` | default `0` |
| `direction` | `character varying(10)` |  |
| `reference_type` | `character varying(50)` |  |
| `reference_id` | `character varying(100)` |  |
| `description` | `character varying(500)` |  |
| `recorded_at` | `timestamp without time zone` | NOT NULL |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX balance_history_ispb_index (ispb)`; `INDEX balance_history_recorded_at_index (recorded_at)`; `INDEX idx_spi_balance_history_composite (ispb, recorded_at DESC)`; `INDEX idx_spi_balance_history_ispb_time (ispb, recorded_at DESC)`.

### `monetarie_spi.balance_queries`

Registro das consultas de saldo camt.060 enviadas e das respostas correlacionadas.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5056` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/balance.ex:106`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `message_id` | `character varying(32)` | NOT NULL |
| `ispb` | `character varying(8)` | NOT NULL |
| `query_type` | `character varying(20)` | NOT NULL |
| `requested_msg` | `character varying(10)` | NOT NULL |
| `balance_type` | `character varying(10)` |  |
| `reporting_from` | `timestamp with time zone` | NOT NULL |
| `reporting_to` | `timestamp with time zone` |  |
| `time_from` | `time without time zone` |  |
| `time_to` | `time without time zone` |  |
| `reference_id` | `character varying(32)` |  |
| `status` | `character varying(20)` | NOT NULL; default `'PENDING'::character varying` |
| `error_code` | `character varying(10)` |  |
| `error_message` | `text` |  |
| `response_data` | `jsonb` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_spi_balq_ispb (ispb)`; `INDEX idx_spi_balq_status (status)`.

### `monetarie_spi.balances`

Saldo corrente da Conta PI por participante (ISPB); fonte do débito/crédito operacional da cabine.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5081` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/balances/balance.ex:14`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `ispb` | `character varying(255)` | NOT NULL |
| `available` | `numeric(18,2)` | NOT NULL |
| `blocked` | `numeric(18,2)` | default `0` |
| `projected` | `numeric(18,2)` |  |
| `pending_credits` | `numeric(18,2)` | default `0` |
| `pending_debits` | `numeric(18,2)` | default `0` |
| `as_of` | `timestamp without time zone` |  |
| `source` | `character varying(255)` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |
| `confirmed` | `numeric(18,2)` |  |
| `confirmed_at` | `timestamp without time zone` |  |

Constraints e índices: `PK (id)`; `UNIQUE INDEX balances_ispb_index (ispb)`.

### `monetarie_spi.batch_items`

Itens individuais de lote de pagamentos (um pacs.008 potencial por item, com pagador/recebedor/erros).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5121`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `batch_id` | `uuid` | NOT NULL |
| `item_index` | `integer` | NOT NULL |
| `status` | `character varying(20)` | NOT NULL; default `'PENDING'::character varying` |
| `message_id` | `integer` |  |
| `end_to_end_id` | `character varying(32)` |  |
| `local_instrument` | `character varying(4)` | NOT NULL |
| `priority` | `character varying(10)` | NOT NULL; default `'PAGPRI'::character varying` |
| `purpose` | `character varying(10)` | NOT NULL; default `'IPAY'::character varying` |
| `amount` | `numeric(18,2)` | NOT NULL |
| `currency` | `character varying(3)` | NOT NULL; default `'BRL'::character varying` |
| `debtor_ispb` | `character varying(8)` | NOT NULL |
| `debtor_name` | `character varying(140)` |  |
| `debtor_document` | `character varying(14)` | NOT NULL |
| `debtor_account` | `character varying(20)` | NOT NULL |
| `debtor_account_type` | `character varying(4)` | NOT NULL; default `'CACC'::character varying` |
| `debtor_branch` | `character varying(4)` |  |
| `creditor_ispb` | `character varying(8)` | NOT NULL |
| `creditor_name` | `character varying(140)` |  |
| `creditor_document` | `character varying(14)` | NOT NULL |
| `creditor_account` | `character varying(20)` | NOT NULL |
| `creditor_account_type` | `character varying(4)` | NOT NULL; default `'CACC'::character varying` |
| `creditor_branch` | `character varying(4)` |  |
| `creditor_proxy` | `character varying(77)` |  |
| `tx_id` | `character varying(35)` |  |
| `initiating_party` | `character varying(14)` |  |
| `description` | `character varying(140)` |  |
| `error_code` | `character varying(10)` |  |
| `error_message` | `text` |  |
| `reason_code` | `character varying(10)` |  |
| `reason_description` | `character varying(140)` |  |
| `validated_at` | `timestamp with time zone` |  |
| `sent_at` | `timestamp with time zone` |  |
| `completed_at` | `timestamp with time zone` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `FK (batch_id) REFERENCES monetarie_spi.batches(id)`; `INDEX idx_spi_batch_items_batch (batch_id)`; `INDEX idx_spi_batch_items_status (status)`.

### `monetarie_spi.batches`

Lotes de pagamentos PIX (controle de processamento, contagens e totais).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5165`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `batch_number` | `character varying(50)` | NOT NULL |
| `ispb` | `character varying(8)` | NOT NULL |
| `status` | `character varying(20)` | NOT NULL; default `'CREATED'::character varying` |
| `total_items` | `integer` | NOT NULL; default `0` |
| `processed_items` | `integer` | NOT NULL; default `0` |
| `successful_items` | `integer` | NOT NULL; default `0` |
| `failed_items` | `integer` | NOT NULL; default `0` |
| `total_amount` | `numeric(18,2)` | NOT NULL; default `0` |
| `successful_amount` | `numeric(18,2)` | NOT NULL; default `0` |
| `failed_amount` | `numeric(18,2)` | NOT NULL; default `0` |
| `description` | `character varying(255)` |  |
| `error_message` | `text` |  |
| `institution_id` | `integer` | NOT NULL |
| `branch_id` | `integer` | NOT NULL |
| `system_id` | `integer` | NOT NULL |
| `user_id` | `integer` |  |
| `started_at` | `timestamp with time zone` |  |
| `completed_at` | `timestamp with time zone` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_spi_batches_ispb (ispb)`; `UNIQUE INDEX idx_spi_batches_number (batch_number)`; `INDEX idx_spi_batches_status (status)`.

### `monetarie_spi.credit_notifications`

Notificações de crédito (camt.054 CRDT) recebidas, para conciliação.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5194`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `message_id` | `character varying(32)` | NOT NULL |
| `notification_id` | `character varying(50)` | NOT NULL |
| `creation_datetime` | `timestamp with time zone` | NOT NULL |
| `ispb` | `character varying(8)` | NOT NULL |
| `account_id` | `character varying(20)` | NOT NULL |
| `amount` | `numeric(18,2)` | NOT NULL |
| `currency` | `character varying(3)` | NOT NULL; default `'BRL'::character varying` |
| `booking_date` | `date` | NOT NULL |
| `value_date` | `date` | NOT NULL |
| `end_to_end_id` | `character varying(32)` | NOT NULL |
| `original_message_id` | `character varying(32)` |  |
| `debtor_ispb` | `character varying(8)` | NOT NULL |
| `debtor_name` | `character varying(140)` |  |
| `debtor_document` | `character varying(14)` |  |
| `debtor_account` | `character varying(20)` |  |
| `description` | `character varying(140)` |  |
| `processed` | `boolean` | NOT NULL; default `false` |
| `processed_at` | `timestamp with time zone` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_spi_creditnotif_e2e (end_to_end_id)`; `INDEX idx_spi_creditnotif_ispb (ispb)`.

### `monetarie_spi.debit_notifications`

Notificações de débito (camt.054 DBIT) recebidas, para conciliação.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5222`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `message_id` | `character varying(32)` | NOT NULL |
| `notification_id` | `character varying(50)` | NOT NULL |
| `creation_datetime` | `timestamp with time zone` | NOT NULL |
| `ispb` | `character varying(8)` | NOT NULL |
| `account_id` | `character varying(20)` | NOT NULL |
| `amount` | `numeric(18,2)` | NOT NULL |
| `currency` | `character varying(3)` | NOT NULL; default `'BRL'::character varying` |
| `booking_date` | `date` | NOT NULL |
| `value_date` | `date` | NOT NULL |
| `end_to_end_id` | `character varying(32)` | NOT NULL |
| `original_message_id` | `character varying(32)` |  |
| `creditor_ispb` | `character varying(8)` | NOT NULL |
| `creditor_name` | `character varying(140)` |  |
| `creditor_document` | `character varying(14)` |  |
| `creditor_account` | `character varying(20)` |  |
| `description` | `character varying(140)` |  |
| `reason_code` | `character varying(10)` |  |
| `reason_description` | `character varying(140)` |  |
| `processed` | `boolean` | NOT NULL; default `false` |
| `processed_at` | `timestamp with time zone` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_spi_debitnotif_ispb (ispb)`.

### `monetarie_spi.e2e_id_seeds`

Sequência por instituição/prefixo de data para geração de EndToEndId únicos.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5252`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `institution_id` | `integer` | NOT NULL |
| `date_prefix` | `date` | NOT NULL |
| `sequence_no` | `bigint` | NOT NULL; default `0` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_spi_e2e_seeds_inst_date (institution_id, date_prefix)`.

### `monetarie_spi.endtoend_id_registry`

Registro de dedup de EndToEndId já processados.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5283` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/id_registry.ex:13`

| Coluna | Tipo | Observações |
|---|---|---|
| `endtoend_id` | `character(32)` | NOT NULL |
| `ispb` | `character(8)` | NOT NULL |
| `message_id` | `bigint` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (endtoend_id)`; `INDEX idx_e2e_registry_created (created_at DESC)`; `INDEX idx_e2e_registry_ispb (ispb)`.

### `monetarie_spi.message_history`

Transições de status por mensagem (timeline SYSTEM/USER/BACEN). Não particionada.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5295` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/transaction.ex:266`

| Coluna | Tipo | Observações |
|---|---|---|
| `message_id` | `bigint` | NOT NULL |
| `history_time` | `timestamp with time zone` | NOT NULL; default `now()` |
| `status_id` | `integer` | NOT NULL |
| `direction` | `monetarie_spi.message_direction` |  |
| `message_code` | `character varying(10)` |  |
| `message_time` | `timestamp with time zone` |  |
| `msg_def_idr` | `character varying(30)` |  |
| `status_details` | `text` |  |
| `user_id` | `integer` |  |
| `status_origin` | `character varying(100)` | NOT NULL |
| `resource_id` | `character varying(40)` |  |
| `return_data` | `text` |  |

Constraints e índices: `PK (message_id, history_time, status_id)`; `INDEX idx_spi_msghist_msgid (message_id)`; `INDEX idx_spi_msghist_msgid_time_desc (message_id, history_time DESC)`; `INDEX idx_spi_msghist_time (history_time DESC)`.

### `monetarie_spi.message_id_registry`

Registro de dedup de MessageId.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5315` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/id_registry.ex:56`

| Coluna | Tipo | Observações |
|---|---|---|
| `message_id` | `character varying(35)` | NOT NULL |
| `ispb` | `character(8)` | NOT NULL |
| `operation_id` | `bigint` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (message_id)`; `INDEX idx_msgid_registry_ispb (ispb)`.

### `monetarie_spi.messages` (PARTICIONADA: RANGE `operation_time`)

Tabela CENTRAL de mensagens/transações SPI: uma linha por mensagem de negócio (direção, valores, status, correlações).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5327` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/transaction.ex:38`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `message_code` | `character varying(10)` | NOT NULL |
| `msg_def_idr` | `character varying(30)` |  |
| `institution_id` | `integer` | NOT NULL |
| `branch_id` | `integer` | NOT NULL |
| `movement_date` | `date` | NOT NULL |
| `operation_time` | `timestamp with time zone` | NOT NULL |
| `debtor_ispb` | `character(8)` | NOT NULL |
| `creditor_ispb` | `character(8)` | NOT NULL |
| `system_id` | `integer` | NOT NULL |
| `unique_id` | `character varying(36)` | NOT NULL |
| `message_id` | `character varying(32)` | NOT NULL |
| `end_to_end_id` | `character(32)` |  |
| `debit_credit` | `monetarie_spi.debit_credit` | default `'DEBIT'::monetarie_spi.debit_credit` |
| `status_id` | `integer` | NOT NULL; default `1` |
| `direction` | `monetarie_spi.message_direction` | default `'OUTBOUND'::monetarie_spi.message_direction` |
| `message_time` | `timestamp with time zone` |  |
| `completion_time` | `timestamp with time zone` |  |
| `settlement_time` | `timestamp with time zone` |  |
| `accounting_date` | `date` |  |
| `ustrd` | `character varying(140)` |  |
| `last_updated` | `timestamp with time zone` |  |
| `resource_id` | `character varying(40)` |  |
| `return_id` | `character varying(32)` |  |
| `original_message_id` | `character varying(32)` |  |
| `original_operation_id` | `bigint` |  |
| `original_end_to_end_id` | `character(32)` |  |
| `original_system_id` | `integer` |  |
| `json_input` | `jsonb` |  |
| `str_control` | `character varying(50)` |  |
| `user_id` | `integer` |  |
| `created_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (id, operation_time)`; `INDEX idx_spi_messages_branch (branch_id)`; `INDEX idx_spi_messages_branch_status (branch_id, status_id, operation_time DESC)`; `INDEX idx_spi_messages_creditor (creditor_ispb)`; `INDEX idx_spi_messages_debtor (debtor_ispb)`; `INDEX idx_spi_messages_direction_status (direction, status_id, operation_time DESC)`; `INDEX idx_spi_messages_e2e (end_to_end_id)`; `INDEX idx_spi_messages_e2e_trigram (((end_to_end_id)::text) public.gin_trgm_ops)`; `INDEX idx_spi_messages_inst (institution_id)`; `INDEX idx_spi_messages_msgid (message_id)`; `INDEX idx_spi_messages_mvdate (movement_date)`; `INDEX idx_spi_messages_mvdate_status (movement_date, status_id)`; `INDEX idx_spi_messages_optime (operation_time DESC)`; `INDEX idx_spi_messages_status (status_id)`; `INDEX idx_spi_messages_status_optime (status_id, operation_time DESC)`; `UNIQUE INDEX idx_spi_messages_unique (unique_id, operation_time)`; `UNIQUE INDEX spi_messages_end_to_end_id_operation_time_unique (end_to_end_id, operation_time)`.

Partições filhas no dump: messages_2026_03, messages_2026_04, messages_2026_05, messages_2026_06, messages_2026_07, messages_2026_08, messages_default (novos filhos mensais criados pelo `Shared.PartitionManager`).

### `monetarie_spi.movement_dates`

Datas de movimento (abertura/fechamento do dia) por instituição.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5667`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `institution_id` | `integer` |  |
| `movement_date` | `date` | NOT NULL |
| `is_active` | `boolean` | default `true` |
| `previous_movement_date` | `date` |  |
| `opened_at` | `timestamp with time zone` |  |
| `closed_at` | `timestamp with time zone` |  |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_movement_dates_active (is_active) WHERE (is_active = true)`; `INDEX idx_movement_dates_date (movement_date)`.

### `monetarie_spi.msg_id_seeds`

Sequência por instituição/prefixo de data para geração de MessageId únicos.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5704`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `institution_id` | `integer` | NOT NULL |
| `date_prefix` | `date` | NOT NULL |
| `sequence_no` | `bigint` | NOT NULL; default `0` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_spi_msg_seeds_inst_date (institution_id, date_prefix)`.

### `monetarie_spi.operation_status_codes`

Catálogo local de códigos de status de operação.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5735`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(20)` | NOT NULL |
| `description` | `character varying(200)` | NOT NULL |
| `is_final` | `boolean` | default `false` |
| `is_error` | `boolean` | default `false` |
| `sort_order` | `integer` | default `0` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_spi_op_status_code (code)`.

### `monetarie_spi.parameters`

Parâmetros do SPI por código de mensagem/instituição.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5771`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `message_code` | `character varying(10)` |  |
| `param_name` | `character varying(100)` | NOT NULL |
| `param_value` | `character varying(400)` |  |
| `institution_id` | `integer` |  |
| `created_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_spi_params_code (message_code)`; `INDEX idx_spi_params_name (param_name)`.

### `monetarie_spi.participants`

Cadastro de participantes SPI conhecidos pela cabine (dados de liquidação).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5805` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/participants/participant.ex:17`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `ispb` | `character varying(255)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `short_name` | `character varying(255)` |  |
| `participation_type` | `character varying(255)` | NOT NULL |
| `status` | `character varying(255)` | default `'active'::character varying` |
| `bacen_category` | `character varying(255)` |  |
| `start_date` | `date` |  |
| `end_date` | `date` |  |
| `settlement_account` | `character varying(255)` |  |
| `settlement_branch` | `character varying(255)` |  |
| `contact_email` | `character varying(255)` |  |
| `contact_phone` | `character varying(255)` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `UNIQUE INDEX participants_ispb_index (ispb)`; `INDEX participants_status_index (status)`.

### `monetarie_spi.payments`

Detalhe do pagamento por mensagem (pagador, recebedor, valores, chave), 1:1 com `messages`.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5847` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/transaction.ex:168`

| Coluna | Tipo | Observações |
|---|---|---|
| `message_id` | `bigint` | NOT NULL |
| `operation_time` | `timestamp with time zone` | NOT NULL |
| `method_id` | `smallint` | NOT NULL; default `1` |
| `priority_id` | `smallint` | NOT NULL; default `1` |
| `amount` | `numeric(18,5)` | NOT NULL; default `0` |
| `currency` | `character(3)` | NOT NULL; default `'BRL'::bpchar` |
| `tx_id` | `character varying(35)` |  |
| `charge_bearer` | `integer` | NOT NULL; default `1` |
| `initiating_party` | `character(14)` |  |
| `debtor_cpf_cnpj` | `character varying(14)` |  |
| `debtor_account` | `character varying(34)` |  |
| `debtor_issuer` | `character varying(35)` |  |
| `debtor_account_type` | `character(4)` |  |
| `debtor_proxy` | `character varying(72)` |  |
| `debtor_name` | `character varying(140)` |  |
| `creditor_cpf_cnpj` | `character varying(14)` |  |
| `creditor_account` | `character varying(34)` |  |
| `creditor_issuer` | `character varying(35)` |  |
| `creditor_account_type` | `character(4)` |  |
| `creditor_proxy` | `character varying(72)` |  |
| `creditor_name` | `character varying(140)` |  |
| `return_reason_codes` | `jsonb` |  |
| `acceptance_time` | `timestamp with time zone` |  |
| `initiation_form` | `character varying(10)` |  |
| `priority_type` | `character varying(10)` |  |
| `transaction_purpose` | `character varying(10)` |  |
| `value_type` | `jsonb` |  |
| `agent_modality` | `character varying(10)` |  |
| `withdrawal_provider` | `character varying(10)` |  |
| `id` | `bigint` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX idx_spi_payments_creditor (creditor_cpf_cnpj)`; `INDEX idx_spi_payments_creditor_cpf (creditor_cpf_cnpj)`; `INDEX idx_spi_payments_debtor (debtor_cpf_cnpj)`; `INDEX idx_spi_payments_debtor_cpf (debtor_cpf_cnpj)`; `INDEX idx_spi_payments_msgid (message_id)`; `INDEX idx_spi_payments_txid (tx_id)`.

### `monetarie_spi.recurrence_instructions`

Instruções (pagamentos agendados individuais) de uma recorrência Pix Automático.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5904` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/recurrences/instruction.ex:25`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `recurrence_id` | `uuid` | NOT NULL |
| `scheduled_date` | `timestamp with time zone` | NOT NULL |
| `executed_at` | `timestamp with time zone` |  |
| `payment_id` | `bigint` |  |
| `status` | `character varying(20)` | NOT NULL; default `'PENDING'::character varying` |
| `error_message` | `text` |  |
| `error_code` | `character varying(10)` |  |
| `retry_count` | `integer` | NOT NULL; default `0` |
| `max_retries` | `integer` | NOT NULL; default `3` |
| `next_retry_at` | `timestamp with time zone` |  |
| `amount` | `numeric(18,2)` |  |
| `sequence_number` | `integer` | NOT NULL |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `FK (recurrence_id) REFERENCES monetarie_spi.recurrences(id)`; `INDEX idx_spi_recinstr_recurrence (recurrence_id)`; `INDEX idx_spi_recinstr_scheduled (scheduled_date)`.

### `monetarie_spi.recurrences`

Mandatos de recorrência do Pix Automático (pain.009/011/012), com ciclo de vida completo.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5927` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/recurrences/recurrence.ex:35`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `mandate_id` | `character varying(35)` |  |
| `participant_ispb` | `character varying(8)` | NOT NULL |
| `debtor_ispb` | `character varying(8)` | NOT NULL |
| `debtor_branch` | `character varying(4)` |  |
| `debtor_account` | `character varying(20)` | NOT NULL |
| `debtor_account_type` | `character varying(4)` | NOT NULL; default `'CACC'::character varying` |
| `debtor_name` | `character varying(140)` |  |
| `debtor_document` | `character varying(14)` | NOT NULL |
| `creditor_ispb` | `character varying(8)` | NOT NULL |
| `creditor_branch` | `character varying(4)` |  |
| `creditor_account` | `character varying(20)` | NOT NULL |
| `creditor_account_type` | `character varying(4)` | NOT NULL; default `'CACC'::character varying` |
| `creditor_name` | `character varying(140)` |  |
| `creditor_document` | `character varying(14)` | NOT NULL |
| `creditor_pix_key` | `character varying(77)` |  |
| `amount` | `numeric(18,2)` | NOT NULL |
| `currency` | `character varying(3)` | NOT NULL; default `'BRL'::character varying` |
| `frequency` | `character varying(20)` | NOT NULL |
| `start_date` | `date` | NOT NULL |
| `end_date` | `date` |  |
| `next_execution` | `timestamp with time zone` | NOT NULL |
| `execution_count` | `integer` | NOT NULL; default `0` |
| `max_executions` | `integer` |  |
| `status` | `character varying(20)` | NOT NULL; default `'PENDING_APPROVAL'::character varying` |
| `description` | `character varying(140)` |  |
| `original_message_id` | `character varying(35)` |  |
| `last_modification_id` | `character varying(35)` |  |
| `last_cancellation_id` | `character varying(35)` |  |
| `reason_code` | `character varying(10)` |  |
| `reason_description` | `character varying(140)` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `created_by` | `integer` |  |
| `last_execution_at` | `timestamp with time zone` |  |
| `cancelled_at` | `timestamp with time zone` |  |
| `paused_at` | `timestamp with time zone` |  |
| `resumed_at` | `timestamp with time zone` |  |

Constraints e índices: `PK (id)`; `INDEX idx_spi_recurrences_ispb (participant_ispb)`; `INDEX idx_spi_recurrences_status (status)`.

### `monetarie_spi.return_id_registry`

Registro de dedup de ReturnId de devoluções.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5973` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/id_registry.ex:98`

| Coluna | Tipo | Observações |
|---|---|---|
| `return_id` | `character varying(35)` | NOT NULL |
| `ispb` | `character(8)` | NOT NULL |
| `original_endtoend_id` | `character(32)` |  |
| `operation_id` | `bigint` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (return_id)`; `INDEX idx_retid_registry_ispb (ispb)`; `INDEX idx_retid_registry_orig (original_endtoend_id)`.

### `monetarie_spi.returns`

Devoluções (pacs.004) no modelo detalhado (requestor/counterparty, envio ao BACEN, liquidação).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:5986`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `return_id` | `character varying(35)` |  |
| `message_id` | `character varying(35)` | NOT NULL |
| `original_payment_id` | `bigint` | NOT NULL |
| `original_end_to_end_id` | `character varying(32)` | NOT NULL |
| `original_message_id` | `character varying(35)` |  |
| `original_amount` | `bigint` | NOT NULL |
| `amount` | `numeric(18,2)` | NOT NULL |
| `currency` | `character varying(3)` | NOT NULL; default `'BRL'::character varying` |
| `reason_code` | `character varying(10)` | NOT NULL |
| `reason_text` | `character varying(140)` |  |
| `requestor_ispb` | `character varying(8)` | NOT NULL |
| `requestor_account` | `character varying(20)` | NOT NULL |
| `requestor_name` | `character varying(140)` |  |
| `requestor_document` | `character varying(14)` | NOT NULL |
| `counterparty_ispb` | `character varying(8)` | NOT NULL |
| `counterparty_account` | `character varying(20)` | NOT NULL |
| `counterparty_name` | `character varying(140)` |  |
| `counterparty_document` | `character varying(14)` | NOT NULL |
| `status` | `character varying(20)` | NOT NULL; default `'REQUESTED'::character varying` |
| `status_code` | `character varying(10)` |  |
| `status_message` | `character varying(140)` |  |
| `resource_id` | `character varying(100)` |  |
| `sent_to_bacen` | `timestamp with time zone` |  |
| `bacen_response` | `timestamp with time zone` |  |
| `requested_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `settled_at` | `timestamp with time zone` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `institution_id` | `integer` | NOT NULL |
| `system_id` | `integer` | NOT NULL |
| `user_id` | `integer` |  |

Constraints e índices: `PK (id)`; `INDEX idx_spi_returns_orig_e2e (original_end_to_end_id)`; `UNIQUE INDEX idx_spi_returns_retid (return_id)`; `INDEX idx_spi_returns_status (status)`.

### `monetarie_spi.statement_entries`

Lançamentos individuais de extrato da Conta PI (derivados de camt.052/053/054).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6026` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/statement.ex:139`, `pix/backend/apps/spi_service/lib/spi_service/statements/statement_entry.ex:17`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `statement_id` | `uuid` | NOT NULL |
| `entry_index` | `integer` | NOT NULL |
| `amount` | `numeric(18,2)` | NOT NULL |
| `currency` | `character varying(3)` | default `'BRL'::character varying` |
| `credit_debit` | `character varying(10)` | NOT NULL |
| `status` | `character varying(20)` | default `'booked'::character varying` |
| `booking_date` | `date` | NOT NULL |
| `value_date` | `date` | NOT NULL |
| `end_to_end_id` | `character varying(255)` |  |
| `entry_message_id` | `character varying(255)` |  |
| `account_servicer_ref` | `character varying(255)` |  |
| `counterparty_ispb` | `character varying(255)` |  |
| `counterparty_name` | `character varying(255)` |  |
| `description` | `text` |  |
| `transaction_code` | `character varying(50)` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX statement_entries_booking_date_index (booking_date)`; `INDEX statement_entries_end_to_end_id_index (end_to_end_id)`; `INDEX statement_entries_statement_id_index (statement_id)`.

### `monetarie_spi.statement_exports`

Exportações de extrato geradas (arquivos e status de download).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6052` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/statements/statement_export.ex:16`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `statement_id` | `uuid` | NOT NULL |
| `format` | `character varying(20)` | NOT NULL |
| `file_name` | `character varying(255)` | NOT NULL |
| `file_size` | `integer` |  |
| `file_path` | `character varying(1024)` |  |
| `content_type` | `character varying(100)` |  |
| `checksum` | `character varying(64)` |  |
| `exported_by` | `integer` |  |
| `exported_at` | `timestamp without time zone` | NOT NULL |
| `expires_at` | `timestamp without time zone` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX statement_exports_exported_at_index (exported_at)`; `INDEX statement_exports_format_index (format)`; `INDEX statement_exports_statement_id_index (statement_id)`.

### `monetarie_spi.statements`

Extratos da Conta PI por período (cabeçalho, saldos de abertura/fechamento).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6073` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/statement.ex:17`, `pix/backend/apps/spi_service/lib/spi_service/statements/statement.ex:16`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `message_id` | `character varying(255)` |  |
| `statement_id` | `character varying(255)` | NOT NULL |
| `sequence_number` | `integer` |  |
| `statement_type` | `character varying(50)` | NOT NULL |
| `creation_datetime` | `timestamp without time zone` |  |
| `ispb` | `character varying(255)` | NOT NULL |
| `account_id` | `character varying(255)` |  |
| `from_date` | `date` | NOT NULL |
| `to_date` | `date` | NOT NULL |
| `from_time` | `timestamp without time zone` |  |
| `to_time` | `timestamp without time zone` |  |
| `opening_balance` | `numeric(18,2)` |  |
| `closing_balance` | `numeric(18,2)` |  |
| `available_balance` | `numeric(18,2)` |  |
| `total_credits` | `numeric(18,2)` |  |
| `total_debits` | `numeric(18,2)` |  |
| `credit_count` | `integer` | default `0` |
| `debit_count` | `integer` | default `0` |
| `additional_info` | `text` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |
| `source` | `:string` | NOT NULL; default `"internal"`; adicionada por `20260705120000_create_daily_recon_and_balance_snapshots.exs` |

Constraints e índices: `PK (id)`; `INDEX statements_from_date_index (from_date)`; `INDEX statements_ispb_index (ispb)`; `UNIQUE INDEX statements_message_id_index (message_id)`; `UNIQUE INDEX statements_statement_id_index (statement_id)`; `INDEX statements_statement_type_index (statement_type)`; `INDEX statements_to_date_index (to_date)`.

### `monetarie_spi.transaction_returns`

Devoluções vinculadas a transação (contexto SpiService.Transactions).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6103` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/transactions/return.ex:36`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `return_id` | `character varying(255)` | NOT NULL |
| `original_transaction_id` | `integer` |  |
| `original_end_to_end_id` | `character varying(255)` | NOT NULL |
| `return_end_to_end_id` | `character varying(255)` |  |
| `amount` | `bigint` | NOT NULL |
| `reason_code` | `character varying(255)` | NOT NULL |
| `reason_description` | `character varying(255)` |  |
| `status` | `character varying(255)` | default `'pending'::character varying` |
| `requested_at` | `timestamp without time zone` |  |
| `processed_at` | `timestamp without time zone` |  |
| `requester_ispb` | `character varying(255)` |  |
| `requester_type` | `character varying(255)` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX transaction_returns_original_end_to_end_id_index (original_end_to_end_id)`; `INDEX transaction_returns_original_transaction_id_index (original_transaction_id)`; `UNIQUE INDEX transaction_returns_return_id_index (return_id)`; `INDEX transaction_returns_status_index (status)`.

### `monetarie_spi.transaction_status_history`

Histórico de status por transação, com trace_id.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6145` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/transactions/status_history.ex:17`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `transaction_id` | `integer` | NOT NULL |
| `end_to_end_id` | `character varying(255)` |  |
| `history_time` | `timestamp without time zone` | NOT NULL |
| `old_status` | `character varying(255)` |  |
| `new_status` | `character varying(255)` | NOT NULL |
| `direction` | `character varying(255)` |  |
| `message_code` | `character varying(255)` |  |
| `message_time` | `timestamp without time zone` |  |
| `msg_def_idr` | `character varying(255)` |  |
| `status_details` | `character varying(255)` |  |
| `user_id` | `integer` |  |
| `status_origin` | `character varying(255)` |  |
| `resource_id` | `character varying(255)` |  |
| `return_data` | `character varying(255)` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX idx_spi_tx_history_composite (transaction_id, inserted_at DESC)`; `INDEX transaction_status_history_end_to_end_id_index (end_to_end_id)`; `INDEX transaction_status_history_transaction_id_index (transaction_id)`.

### `monetarie_spi.transactions`

Transações PIX no modelo do SpiService (visão operacional usada por limites, relatórios e telas).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6188` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/transactions/transaction.ex:20`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `end_to_end_id` | `character varying(255)` |  |
| `message_id` | `character varying(255)` |  |
| `tx_id` | `character varying(255)` |  |
| `unique_id` | `uuid` |  |
| `local_instrument` | `character varying(255)` |  |
| `priority_type` | `character varying(255)` | default `'PAGPRI'::character varying` |
| `priority_id` | `integer` | default `2` |
| `purpose` | `character varying(255)` | default `'IPAY'::character varying` |
| `amount` | `bigint` | NOT NULL |
| `currency` | `character varying(255)` | default `'BRL'::character varying` |
| `debtor_ispb` | `character varying(255)` | NOT NULL |
| `debtor_name` | `character varying(255)` |  |
| `debtor_document` | `character varying(255)` | NOT NULL |
| `debtor_account` | `character varying(255)` | NOT NULL |
| `debtor_account_type` | `character varying(255)` |  |
| `debtor_branch` | `character varying(255)` |  |
| `debtor_proxy` | `character varying(255)` |  |
| `creditor_ispb` | `character varying(255)` | NOT NULL |
| `creditor_name` | `character varying(255)` |  |
| `creditor_document` | `character varying(255)` | NOT NULL |
| `creditor_account` | `character varying(255)` | NOT NULL |
| `creditor_account_type` | `character varying(255)` |  |
| `creditor_branch` | `character varying(255)` |  |
| `creditor_proxy` | `character varying(255)` |  |
| `initiating_party` | `character varying(255)` |  |
| `agent_modality` | `character varying(255)` |  |
| `withdrawal_provider` | `character varying(255)` |  |
| `description` | `character varying(255)` |  |
| `resource_id` | `character varying(255)` |  |
| `status` | `character varying(255)` | default `'pending'::character varying` |
| `reason_code` | `character varying(255)` |  |
| `reason_description` | `character varying(255)` |  |
| `operation_datetime` | `timestamp without time zone` |  |
| `message_datetime` | `timestamp without time zone` |  |
| `acceptance_datetime` | `timestamp without time zone` |  |
| `settlement_datetime` | `timestamp without time zone` |  |
| `completion_datetime` | `timestamp without time zone` |  |
| `movement_date` | `date` |  |
| `accounting_date` | `date` |  |
| `institution_id` | `integer` |  |
| `branch_id` | `integer` |  |
| `system_id` | `integer` |  |
| `user_id` | `integer` |  |
| `direction` | `character varying(255)` | default `'outbound'::character varying` |
| `return_id` | `character varying(255)` |  |
| `original_message_id` | `character varying(255)` |  |
| `original_end_to_end_id` | `character varying(255)` |  |
| `original_operation_id` | `integer` |  |
| `dict_correlation_id` | `character varying(255)` |  |
| `token_refunded` | `boolean` | default `false` |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX transactions_creditor_ispb_index (creditor_ispb)`; `INDEX transactions_debtor_ispb_index (debtor_ispb)`; `UNIQUE INDEX transactions_end_to_end_id_index (end_to_end_id) WHERE (end_to_end_id IS NOT NULL)`; `INDEX transactions_institution_id_index (institution_id)`; `UNIQUE INDEX transactions_message_id_index (message_id) WHERE (message_id IS NOT NULL)`; `INDEX transactions_operation_datetime_index (operation_datetime)`; `INDEX transactions_status_index (status)`.

### `monetarie_spi.alcada_held_messages`

Mensagens outbound construídas manualmente (tela Construir Mensagem) retidas aguardando aprovação por alçada.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260704190000_create_alcada_held_messages.exs` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/alcada/held_message.ex:19`

| Coluna | Tipo | Observações |
|---|---|---|
| `message_type` | `:string` | NOT NULL |
| `xml_content` | `:text` | NOT NULL |
| `builder_params` | `:map` | default `%{}` |
| `amount` | `:decimal` | NOT NULL; default `0` |
| `status` | `:string` | NOT NULL; default `"awaiting_approval"` |
| `created_by` | `:bigint` |  |
| `created_by_name` | `:string` |  |
| `approved_by` | `:bigint` |  |
| `approved_by_name` | `:string` |  |
| `rejection_reason` | `:text` |  |
| `dispatch_result` | `:text` |  |
| `sent_at` | `:utc_datetime_usec` |  |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `INDEX [:status]`; `INDEX [:created_by]`.

### `monetarie_spi.camt060_requests`

Rastreio de cada camt.060 (AcctRptgReq) enviada e correlação com a resposta camt.052/053/054.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260704170000_create_camt060_requests.exs` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/camt060_request.ex:22`

| Coluna | Tipo | Observações |
|---|---|---|
| `msg_id` | `:string` | NOT NULL |
| `ispb` | `:string` | NOT NULL |
| `action` | `:string` |  |
| `reqd_msg_nm_id` | `:string` | NOT NULL |
| `prtry` | `:string` |  |
| `status` | `:string` | NOT NULL; default `"sent"` |
| `sent_at` | `:utc_datetime_usec` | NOT NULL |
| `responded_at` | `:utc_datetime_usec` |  |
| `response_type` | `:string` |  |
| `response_msg_id` | `:string` |  |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `UNIQUE INDEX [:msg_id]`; `INDEX [:status, :sent_at]`; `INDEX [:ispb]`.

### `monetarie_spi.daily_balance_snapshots`

Snapshot EOD do saldo da Conta PI por (ISPB, data) para a conciliação diária.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260705120000_create_daily_recon_and_balance_snapshots.exs` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/daily_reconciliation/balance_snapshot.ex:25`

| Coluna | Tipo | Observações |
|---|---|---|
| `ispb` | `:string` | NOT NULL |
| `snapshot_date` | `:date` | NOT NULL |
| `opening_balance` | `:decimal` | NOT NULL; default `0` |
| `closing_balance` | `:decimal` | NOT NULL |
| `opening_source` | `:string` | NOT NULL; default `"previous_close"` |
| `closing_source` | `:string` | NOT NULL |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `UNIQUE INDEX [:ispb, :snapshot_date]`.

### `monetarie_spi.daily_reconciliations`

Resultado da conciliação diária por (ISPB, data, tipo), com contagens e divergências.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260705120000_create_daily_recon_and_balance_snapshots.exs` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/daily_reconciliation/result.ex:33`

| Coluna | Tipo | Observações |
|---|---|---|
| `ispb` | `:string` | NOT NULL |
| `recon_date` | `:date` | NOT NULL |
| `kind` | `:string` | NOT NULL; default `"eod_3way"` |
| `our_credits` | `:decimal` |  |
| `our_debits` | `:decimal` |  |
| `our_net` | `:decimal` |  |
| `bacen_credits` | `:decimal` |  |
| `bacen_debits` | `:decimal` |  |
| `bacen_net` | `:decimal` |  |
| `bacen_source` | `:string` |  |
| `clbd_balance` | `:decimal` |  |
| `expected_closing` | `:decimal` |  |
| `delta_net` | `:decimal` |  |
| `delta_closing` | `:decimal` |  |
| `status` | `:string` | NOT NULL |
| `details` | `:map` |  |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `UNIQUE INDEX [:ispb, :recon_date, :kind]`; `INDEX [:status]`.

### `monetarie_spi.echo_probes`

Evidência de cada probe de eco pibr.001 por canal (RTT, resultado); alimenta o circuit breaker de canal ICOM.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260704230000_create_echo_probes.exs` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/echo_probe.ex:20`

| Coluna | Tipo | Observações |
|---|---|---|
| `canal` | `:string` | NOT NULL |
| `sent_at` | `:utc_datetime_usec` | NOT NULL |
| `rtt_ms` | `:integer` |  |
| `result` | `:string` | NOT NULL |
| `error_reason` | `:string` |  |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `INDEX [:canal, :sent_at]`; `INDEX [:result, :sent_at]`.

### `monetarie_spi.icom_received`

Registro durável de cada mensagem puxada do ICOM ANTES do ACK (invariante pre-ACK), dedup por message_id, retenção 10 anos.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260514143000_create_icom_long_polling_tables.exs` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/icom_received.ex:27`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `:uuid` | PK |
| `message_id` | `:string` | NOT NULL |
| `msg_type` | `:string` | NOT NULL |
| `pi_resource_id` | `:string` |  |
| `canal` | `:string` | NOT NULL |
| `raw_xml` | `:text` | NOT NULL |
| `received_at` | `:utc_datetime_usec` | NOT NULL |
| `nats_published_at` | `:utc_datetime_usec` |  |
| `direction` | `:string` | NOT NULL; default `"INBOUND"` |
| `retention_expires_at` | `:utc_datetime_usec` | NOT NULL |

Constraints e índices: `UNIQUE INDEX [:message_id]`; `INDEX [:received_at]`; `INDEX [:session_id]`; `INDEX [:retention_expires_at]`; `INDEX [:direction]`.

### `monetarie_spi.icom_sessions`

Estado das sessões de long-poll ICOM por (ISPB, canal, slot): token, last_pull_next e status, para retomada após crash/failover.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260514143000_create_icom_long_polling_tables.exs` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/icom_session.ex:24`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `:uuid` | PK |
| `ispb` | `:string` | NOT NULL |
| `canal` | `:string` | NOT NULL |
| `slot_id` | `:smallint` | NOT NULL |
| `session_token` | `:string` | NOT NULL |
| `last_pull_next` | `:text` |  |
| `last_ack_at` | `:utc_datetime_usec` |  |
| `opened_at` | `:utc_datetime_usec` | NOT NULL |
| `closed_at` | `:utc_datetime_usec` |  |
| `status` | `:string` | NOT NULL; default `"open"` |
| `error_reason` | `:text` |  |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `UNIQUE INDEX [:ispb, :canal, :slot_id]`.

### `monetarie_spi.operational_alerts`

Alertas operacionais persistentes (ex.: stuck_outbound) com estado de reconhecimento.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260705000000_create_operational_alerts.exs` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/operational_alert.ex:40`

| Coluna | Tipo | Observações |
|---|---|---|
| `alert_type` | `:string` | NOT NULL |
| `severity` | `:string` | NOT NULL; default `"warning"` |
| `title` | `:string` | NOT NULL |
| `message` | `:text` | NOT NULL |
| `service` | `:string` | NOT NULL; default `"settlement-service"` |
| `payload` | `:map` | NOT NULL; default `%{}` |
| `dedupe_key` | `:string` | NOT NULL |
| `status` | `:string` | NOT NULL; default `"open"` |
| `count` | `:integer` | NOT NULL; default `1` |
| `first_seen_at` | `:utc_datetime_usec` | NOT NULL |
| `last_seen_at` | `:utc_datetime_usec` | NOT NULL |
| `acked_by` | `:string` |  |
| `acked_at` | `:utc_datetime_usec` |  |
| `resolved_by` | `:string` |  |
| `resolved_at` | `:utc_datetime_usec` |  |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `UNIQUE INDEX [:alert_type, :dedupe_key]`; `INDEX [:status, :last_seen_at]`; `INDEX [:alert_type, :last_seen_at]`.

### `monetarie_spi.pix_in_orphans`

Auditoria de órfãos de PIX-in detectados na reconciliação por camt.054 (crédito liquidado pelo BACEN sem transaction/evento local).

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260709190000_create_pix_in_orphans.exs` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/pix_in_orphan.ex:30`

| Coluna | Tipo | Observações |
|---|---|---|
| `end_to_end_id` | `:string` | NOT NULL |
| `amount` | `:decimal` |  |
| `amount_cents` | `:bigint` |  |
| `credit_debit_indicator` | `:string` |  |
| `camt054_resource_id` | `:string` |  |
| `camt054_received_at` | `:utc_datetime_usec` |  |
| `reason` | `:string` | NOT NULL |
| `message_status_id` | `:integer` |  |
| `outbox_enqueued` | `:boolean` | NOT NULL; default `false` |
| `status` | `:string` | NOT NULL; default `"open"` |
| `first_detected_at` | `:utc_datetime_usec` | NOT NULL |
| `last_detected_at` | `:utc_datetime_usec` | NOT NULL |
| `resolved_at` | `:utc_datetime_usec` |  |
| `auto_republished` | `:boolean` | NOT NULL; default `false` |
| `republished_at` | `:utc_datetime_usec` |  |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `UNIQUE INDEX [:end_to_end_id]`; `INDEX [:status, :last_detected_at]`; `INDEX [:reason, :last_detected_at]`.

### `monetarie_spi.scheduled_message_jobs`

Jobs de mensagens BACEN periódicas configurados pela tela de automação.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618130000_create_api_clients_and_scheduled_message_jobs.exs` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/automation/scheduled_message_job.ex:21`

| Coluna | Tipo | Observações |
|---|---|---|
| `ispb` | `:string` | NOT NULL |
| `message_type` | `:string` | NOT NULL |
| `query_type` | `:string` |  |
| `crontab` | `:string` | NOT NULL |
| `params` | `:map` | default `%{}` |
| `enabled` | `:boolean` | NOT NULL; default `true` |
| `last_run_at` | `:utc_datetime` |  |
| `last_run_status` | `:string` |  |
| `last_run_message_id` | `:string` |  |
| `created_by_user_id` | `:integer` |  |
| `inserted_at / updated_at` | `timestamps Ecto` |  |
| `ispb` | `varchar(8)` | adicionada por `20260618131000_ensure_api_clients_and_scheduled_message_jobs.exs` |

Constraints e índices: `INDEX [:enabled, :crontab]`.

## Schema `monetarie_spi_msg`

SPI: XML bruto e criptografia (certificados).

### `monetarie_spi_msg.crypto_keys`

Certificados criptográficos (nossos e do BACEN): PEM, kid, uso (assinatura/mTLS), metadados de Secrets Manager.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6268` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/crypto/certificate.ex:20`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `key_type` | `character varying(20)` | NOT NULL |
| `ispb` | `character(8)` |  |
| `domain` | `character varying(50)` |  |
| `public_key` | `text` |  |
| `certificate` | `text` |  |
| `valid_from` | `date` |  |
| `valid_until` | `date` |  |
| `is_active` | `boolean` | default `true` |
| `created_at` | `timestamp with time zone` | default `now()` |
| `serial_number` | `character varying(128)` |  |
| `cn` | `character varying(255)` |  |
| `cert_type` | `character varying(10)` |  |
| `cert_purpose` | `character varying(50)` |  |
| `issuer_dn` | `character varying(500)` |  |
| `subject_dn` | `character varying(500)` |  |
| `thumbprint` | `character varying(128)` |  |
| `activated_at` | `timestamp with time zone` |  |
| `deactivated_at` | `timestamp with time zone` |  |
| `deactivation_reason` | `character varying(255)` |  |
| `updated_at` | `timestamp with time zone` | default `now()` |
| `ca_pem` | `:text` | adicionada por `20260623140000_add_aws_fields_to_crypto_keys.exs` |
| `secrets_manager_version` | `:string` | adicionada por `20260623140000_add_aws_fields_to_crypto_keys.exs` |
| `secrets_manager_secret_id` | `:string` | adicionada por `20260623140000_add_aws_fields_to_crypto_keys.exs` |
| `audit_metadata` | `:map` | adicionada por `20260623140000_add_aws_fields_to_crypto_keys.exs` |

Constraints e índices: `PK (id)`; `INDEX idx_crypto_keys_cert_type (cert_type)`; `INDEX idx_crypto_keys_serial (serial_number)`; `INDEX idx_crypto_keys_thumbprint (thumbprint)`; `INDEX idx_spimsg_crypto_active (is_active) WHERE (is_active = true)`; `INDEX idx_spimsg_crypto_ispb (ispb)`.

### `monetarie_spi_msg.crypto_private_keys`

Chaves privadas cifradas associadas a certificados (quando a chave não vive no HSM).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6317` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/crypto/private_key.ex:16`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `certificate_id` | `integer` | NOT NULL |
| `encrypted_key_pem` | `text` | NOT NULL |
| `key_algorithm` | `character varying(20)` | NOT NULL; default `'RSA'::character varying` |
| `key_size` | `integer` | NOT NULL; default `2048` |
| `passphrase_encrypted` | `text` |  |
| `encryption_method` | `character varying(50)` | default `'AES-256-GCM'::character varying` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `FK (certificate_id) REFERENCES monetarie_spi_msg.crypto_keys(id) ON DELETE CASCADE`; `UNIQUE INDEX idx_crypto_privkeys_cert (certificate_id)`.

### `monetarie_spi_msg.xml_messages`

Arquivo do XML bruto por message_id (direção, código de mensagem, conteúdo).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6353`

| Coluna | Tipo | Observações |
|---|---|---|
| `message_id` | `bigint` | NOT NULL |
| `message_time` | `timestamp with time zone` | NOT NULL; default `now()` |
| `xml_content` | `text` | NOT NULL |
| `direction` | `monetarie_spi.message_direction` |  |
| `message_code` | `character varying(10)` |  |

Constraints e índices: `PK (message_id, message_time)`; `INDEX idx_spimsg_xml_code (message_code)`.

## Schema `monetarie_spi_ref`

SPI: dados de referência BACEN.

### `monetarie_spi_ref.banks`

Referência de bancos (código, nome).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6366` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/participant.ex:119`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `ispb` | `character varying(255)` | NOT NULL |
| `code` | `character varying(255)` |  |
| `name` | `character varying(255)` | NOT NULL |
| `short_name` | `character varying(255)` |  |
| `is_pix_participant` | `boolean` | default `false` |
| `participation_start` | `date` |  |
| `participation_end` | `date` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |
| `compe_code` | `character varying(3)` |  |
| `is_active` | `boolean` | default `true` |

Constraints e índices: `PK (id)`; `INDEX banks_code_index (code)`; `UNIQUE INDEX banks_ispb_index (ispb)`.

### `monetarie_spi_ref.domain_values`

Dicionário de domínios BACEN (valores permitidos por campo/domínio).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6405` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi_ref/domain_value.ex:22`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `domain_name` | `character varying(100)` | NOT NULL |
| `code` | `character varying(50)` | NOT NULL |
| `description` | `character varying(500)` |  |
| `is_active` | `boolean` | default `true` |
| `sort_order` | `integer` | default `0` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `description_en` | `text` |  |

Constraints e índices: `PK (id)`; `INDEX idx_domain_values_name_active (domain_name) WHERE (is_active = true)`; `UNIQUE INDEX idx_spi_ref_domain_values_uniq (domain_name, code)`.

### `monetarie_spi_ref.error_codes`

Catálogo de códigos de erro BACEN.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6442` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi_ref/error_code.ex:15`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(10)` | NOT NULL |
| `message` | `character varying(500)` | NOT NULL |
| `category` | `character varying(50)` |  |
| `http_status` | `integer` |  |
| `is_retriable` | `boolean` | default `false` |
| `source` | `character varying(20)` | NOT NULL; default `'SPI'::character varying` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_error_codes_category (category)`; `UNIQUE INDEX idx_error_codes_code_src (code, source)`.

### `monetarie_spi_ref.message_types`

Catálogo de tipos de mensagem (código, direção, versão de schema).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6478`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(64)` | NOT NULL |
| `name` | `character varying(200)` | NOT NULL |
| `description` | `character varying(500)` |  |
| `direction` | `character varying(10)` |  |
| `schema_version` | `character varying(20)` |  |
| `is_active` | `boolean` | default `true` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_spi_ref_message_types_code (code)`.

### `monetarie_spi_ref.message_versions`

Versões de MsgDefIdr suportadas por tipo de mensagem.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6515` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi_ref/message_version.ex:17`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `message_type_id` | `integer` |  |
| `message_code` | `character varying(64)` | NOT NULL |
| `schema_version` | `character varying(20)` | NOT NULL |
| `xsd_name` | `character varying(200)` |  |
| `valid_from` | `date` | NOT NULL |
| `valid_until` | `date` |  |
| `is_current` | `boolean` | default `true` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `is_financial` | `boolean` | default `false` |
| `requires_signature` | `boolean` | default `true` |
| `classification` | `character varying(20)` |  |
| `characteristic` | `character varying(50)` |  |
| `channel` | `character varying(3)` | default `'CPM'::character varying` |

Constraints e índices: `PK (id)`; `FK (message_type_id) REFERENCES monetarie_spi_ref.message_types(id)`; `INDEX idx_spi_ref_msg_versions_code (message_code)`; `INDEX idx_spi_ref_msg_versions_current (is_current) WHERE (is_current = true)`.

### `monetarie_spi_ref.reason_codes`

Catálogo de reason codes (categoria, atividade).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6558`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(10)` | NOT NULL |
| `description` | `character varying(500)` | NOT NULL |
| `category` | `character varying(50)` |  |
| `is_active` | `boolean` | default `true` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_spi_ref_reason_codes_code (code)`.

### `monetarie_spi_ref.ref_sources`

Origem dos dados de referência.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6593`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(50)` | NOT NULL |
| `name` | `character varying(200)` | NOT NULL |
| `description` | `character varying(500)` |  |
| `is_active` | `boolean` | default `true` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_spi_ref_sources_code (code)`.

### `monetarie_spi_ref.status_codes`

Mapa canônico de status_id (fonte única `Shared.Spi.StatusCodes`, reseed na migration 20260701090000).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6628`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(10)` | NOT NULL |
| `description` | `character varying(200)` | NOT NULL |
| `is_final` | `boolean` | default `false` |
| `is_pending` | `boolean` | default `false` |
| `is_error` | `boolean` | default `false` |
| `category` | `character varying(50)` |  |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_spi_ref_status_codes_code (code)`.

### `monetarie_spi_ref.systems`

Sistemas de origem das mensagens (BACEN ou interno, ISPB de origem).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6665`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `description` | `character varying(100)` | NOT NULL |
| `is_bacen` | `boolean` | NOT NULL; default `false` |
| `origin_ispb` | `character(8)` |  |

Constraints e índices: `PK (id)`.

### `monetarie_spi_ref.xsd_schemas` (REMOVIDA)

REMOVIDA pela migration 20260426170000 (guardava XSDs placeholder nunca usados; a validação real usa `priv/xsd/spi/v5.12.1` + xmllint).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6697`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `message_type` | `character varying(20)` | NOT NULL |
| `schema_version` | `character varying(20)` | NOT NULL |
| `xsd_content` | `text` | NOT NULL |
| `xsd_hash` | `character varying(128)` | NOT NULL |
| `is_active` | `boolean` | default `true` |
| `valid_from` | `date` | NOT NULL |
| `valid_until` | `date` |  |
| `source_file` | `character varying(255)` |  |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_xsd_schemas_active (is_active) WHERE (is_active = true)`; `UNIQUE INDEX idx_xsd_schemas_type_ver (message_type, schema_version)`.

### `monetarie_spi_ref.bacen_pix_participants`

Snapshot da lista oficial de participantes ativos do PIX do BACEN (import diário).

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618100000_create_bacen_pix_participants.exs` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi_ref/bacen_pix_participant.ex:19`

| Coluna | Tipo | Observações |
|---|---|---|
| `source_date` | `:date` | NOT NULL |
| `row_number` | `:integer` | NOT NULL |
| `name` | `:string` | NOT NULL |
| `ispb` | `:string` |  |
| `cnpj` | `:string` | NOT NULL |
| `cnpj_digits` | `:string` | NOT NULL |
| `institution_type` | `:string` |  |
| `authorized_by_bcb` | `:boolean` |  |
| `spi_participation_type` | `:string` |  |
| `pix_participation_type` | `:string` |  |
| `pix_participation_modality` | `:string` |  |
| `payment_initiator` | `:boolean` |  |
| `fss` | `:boolean` |  |
| `is_active` | `:boolean` | NOT NULL; default `true` |
| `source_url` | `:text` | NOT NULL |
| `source_hash` | `:string` | NOT NULL |
| `imported_at` | `:utc_datetime_usec` | NOT NULL |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `UNIQUE INDEX [:source_date, :cnpj_digits]`; `INDEX [:source_date, :is_active]`; `INDEX [:ispb]`; `INDEX [:cnpj_digits]`.

## Schema `monetarie_dict`

DICT: chaves, claims, MED e antifraude (app `dict_service` + schemas em `shared`).

### `monetarie_dict.cid_events`

Eventos CID recebidos do DICT (poll `/cids/events`) por participante.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1948`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `event_type` | `character varying(50)` | NOT NULL |
| `cid` | `character varying(100)` |  |
| `entry_key` | `character varying(77)` |  |
| `entry_key_type` | `character varying(20)` |  |
| `file_id` | `uuid` |  |
| `participant_ispb` | `character varying(8)` |  |
| `details` | `jsonb` |  |
| `created_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (id)`; `FK (file_id) REFERENCES monetarie_dict.cid_files(id)`; `INDEX idx_dict_cid_events_file (file_id)`; `INDEX idx_dict_cid_events_type (event_type)`.

### `monetarie_dict.cid_files`

Arquivos CID solicitados/baixados do DICT (sincronização completa `/cids/files`).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1965`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `request_id` | `character varying(100)` |  |
| `participant_ispb` | `character varying(8)` | NOT NULL |
| `status` | `character varying(20)` | NOT NULL; default `'PENDING'::character varying` |
| `file_url` | `text` |  |
| `entry_count` | `integer` | default `0` |
| `error_message` | `text` |  |
| `created_at` | `timestamp with time zone` | default `now()` |
| `processing_started_at` | `timestamp with time zone` |  |
| `completed_at` | `timestamp with time zone` |  |
| `expires_at` | `timestamp with time zone` |  |

Constraints e índices: `PK (id)`; `INDEX idx_dict_cid_files_ispb (participant_ispb)`; `INDEX idx_dict_cid_files_status (status)`.

### `monetarie_dict.claim_status_types`

Catálogo de status de reivindicação.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1984`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(50)` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `description` | `character varying(500)` |  |
| `is_final` | `boolean` | default `false` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_dict_claim_status_code (code)`.

### `monetarie_dict.claims`

Reivindicações e portabilidades de chave PIX (ciclo completo com prazos de 7/14/30 dias).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2017` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/dict/entry_claim.ex:21`, `pix/backend/apps/dict_service/lib/dict_service/claims/entry_claim.ex:20`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `claim_id` | `character varying(255)` | NOT NULL |
| `key_type` | `character varying(255)` | NOT NULL |
| `key_value` | `character varying(255)` | NOT NULL |
| `claim_type` | `character varying(255)` | NOT NULL |
| `claimer_ispb` | `character varying(255)` | NOT NULL |
| `claimer_name` | `character varying(255)` |  |
| `claimer_cpf_cnpj` | `character varying(255)` |  |
| `claimer_account` | `character varying(255)` |  |
| `claimer_branch` | `character varying(255)` |  |
| `claimer_account_type` | `character varying(255)` |  |
| `donor_ispb` | `character varying(255)` |  |
| `donor_name` | `character varying(255)` |  |
| `status` | `character varying(255)` | default `'OPEN'::character varying` |
| `confirm_reason` | `character varying(255)` |  |
| `cancelled_by` | `character varying(255)` |  |
| `cancel_reason` | `character varying(255)` |  |
| `completion_date` | `timestamp without time zone` |  |
| `resolution_period_end` | `timestamp without time zone` |  |
| `donor_deadline` | `timestamp without time zone` |  |
| `claimer_deadline` | `timestamp without time zone` |  |
| `last_modified` | `timestamp without time zone` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `UNIQUE INDEX claims_claim_id_index (claim_id)`; `INDEX claims_claimer_ispb_index (claimer_ispb)`; `INDEX claims_donor_ispb_index (donor_ispb)`; `INDEX claims_key_value_index (key_value)`; `INDEX claims_status_index (status)`.

### `monetarie_dict.delete_reasons`

Catálogo de motivos de exclusão de chave.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2068`

| Coluna | Tipo | Observações |
|---|---|---|
| `code` | `character varying(20)` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `description` | `character varying(500)` |  |
| `created_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (code)`.

### `monetarie_dict.entry_status`

Catálogo de status de vínculo (chave).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2080`

| Coluna | Tipo | Observações |
|---|---|---|
| `code` | `character varying(20)` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `description` | `character varying(500)` |  |
| `is_active` | `boolean` | default `true` |
| `created_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (code)`.

### `monetarie_dict.event_notifications`

Notificações de eventos do DICT para participantes, com ack e expiração.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2093`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `participant_ispb` | `character varying(8)` | NOT NULL |
| `event_type` | `monetarie_dict.event_notification_type` | NOT NULL |
| `entity_type` | `character varying(50)` |  |
| `entity_id` | `uuid` |  |
| `event_data` | `jsonb` |  |
| `acknowledged` | `boolean` | default `false` |
| `acknowledged_at` | `timestamp with time zone` |  |
| `created_at` | `timestamp with time zone` | default `now()` |
| `expires_at` | `timestamp with time zone` |  |

Constraints e índices: `PK (id)`; `INDEX idx_dict_notifications_ispb (participant_ispb)`; `INDEX idx_dict_notifications_unack (participant_ispb) WHERE (acknowledged = false)`.

### `monetarie_dict.funds_recoveries`

Processos MED 2.0 de recuperação de fundos.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2111` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/dict/funds_recovery.ex:27`, `pix/backend/apps/dict_service/lib/dict_service/funds_recovery/recovery.ex:17`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `recovery_id` | `character varying(255)` | NOT NULL |
| `debtor_ispb` | `character varying(255)` | NOT NULL |
| `creditor_ispb` | `character varying(255)` | NOT NULL |
| `fraud_type` | `character varying(255)` | NOT NULL |
| `amount` | `numeric(18,2)` |  |
| `original_end_to_end_id` | `character varying(255)` |  |
| `status` | `character varying(255)` | default `'CREATED'::character varying` |
| `reason` | `character varying(255)` |  |
| `tracking_graph_id` | `integer` |  |
| `requested_at` | `timestamp without time zone` |  |
| `completed_at` | `timestamp without time zone` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX funds_recoveries_creditor_ispb_index (creditor_ispb)`; `INDEX funds_recoveries_debtor_ispb_index (debtor_ispb)`; `UNIQUE INDEX funds_recoveries_recovery_id_index (recovery_id)`; `INDEX funds_recoveries_status_index (status)`.

### `monetarie_dict.infraction_reports`

Relatos de infração MED 2.0 (forma DICT 2.11, com Reason/SituationType/Reporter/Counterparty).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2152` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/dict/infraction_report.ex:23`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `funds_recovery_id` | `uuid` |  |
| `end_to_end_id` | `character varying(32)` | NOT NULL |
| `debtor_ispb` | `character varying(8)` | NOT NULL |
| `creditor_ispb` | `character varying(8)` | NOT NULL |
| `transaction_amount` | `numeric(18,2)` | NOT NULL |
| `status` | `character varying(30)` | NOT NULL; default `'OPEN'::character varying` |
| `analysis_result` | `character varying(20)` |  |
| `analysis_details` | `text` |  |
| `fraud_marker_id` | `uuid` |  |
| `fraud_marker_message` | `text` |  |
| `blocked_amount` | `numeric(18,2)` |  |
| `blocked_at` | `timestamp with time zone` |  |
| `analysed_at` | `timestamp with time zone` |  |
| `closed_at` | `timestamp with time zone` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `last_updated` | `timestamp with time zone` | NOT NULL; default `now()` |
| `reported_cpf_cnpj` | `character varying(14)` |  |

Constraints e índices: `PK (id)`; `INDEX idx_infraction_reports_creditor (creditor_ispb)`; `INDEX idx_infraction_reports_debtor (debtor_ispb)`; `INDEX idx_infraction_reports_e2e_id (end_to_end_id)`; `INDEX idx_infraction_reports_recovery (funds_recovery_id)`; `INDEX idx_infraction_reports_status (status)`.

### `monetarie_dict.infraction_types`

Catálogo de tipos de infração.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2178`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(50)` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `description` | `character varying(500)` |  |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_dict_infraction_types_code (code)`.

### `monetarie_dict.infractions`

Relatos de infração no modelo legado, correlacionados a med_requests.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2210`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `infraction_id` | `character varying(100)` |  |
| `infraction_type_id` | `integer` |  |
| `status_id` | `integer` |  |
| `reporter_ispb` | `character varying(8)` | NOT NULL |
| `reported_ispb` | `character varying(8)` | NOT NULL |
| `end_to_end_id` | `character varying(32)` |  |
| `key_type` | `monetarie_dict.key_type` |  |
| `key_value` | `character varying(77)` |  |
| `debtor_cpf_cnpj` | `character varying(14)` |  |
| `creditor_cpf_cnpj` | `character varying(14)` |  |
| `transaction_amount` | `numeric(18,2)` |  |
| `fraud_type` | `character varying(50)` |  |
| `details` | `text` |  |
| `creation_date` | `timestamp with time zone` |  |
| `analysis_result` | `character varying(20)` |  |
| `analysis_date` | `timestamp with time zone` |  |
| `last_updated` | `timestamp with time zone` | default `now()` |
| `funds_recovery_id` | `uuid` |  |

Constraints e índices: `PK (id)`; `FK (infraction_type_id) REFERENCES monetarie_dict.infraction_types(id)`; `INDEX idx_dict_infractions_e2e (end_to_end_id)`; `UNIQUE INDEX idx_dict_infractions_id (infraction_id)`; `INDEX idx_dict_infractions_recovery_id (funds_recovery_id)`; `INDEX idx_dict_infractions_reported (reported_ispb)`; `INDEX idx_dict_infractions_reporter (reporter_ispb)`; `INDEX idx_dict_infractions_type_id (infraction_type_id)`.

### `monetarie_dict.institutions`

Instituições participantes do DICT (categoria, overrides de bucket).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2256`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `ispb` | `character varying(8)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `trade_name` | `character varying(255)` |  |
| `category` | `character varying(50)` |  |
| `category_changed_at` | `timestamp with time zone` |  |
| `category_changed_by` | `character varying(100)` |  |
| `status` | `character varying(20)` | default `'ACTIVE'::character varying` |
| `created_at` | `timestamp with time zone` | default `now()` |
| `updated_at` | `timestamp with time zone` | default `now()` |
| `bucket_capacity_override` | `integer` |  |
| `bucket_refill_override` | `integer` |  |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_dict_institutions_ispb (ispb)`.

### `monetarie_dict.key_block_events`

Eventos de bloqueio/desbloqueio de chave PIX.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2276` | Ecto: `pix/backend/apps/dict_service/lib/dict_service/keys/block_event.ex:16`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `entry_id` | `integer` | NOT NULL |
| `event_type` | `character varying(255)` | NOT NULL |
| `reason` | `character varying(255)` |  |
| `blocked_by` | `character varying(255)` |  |
| `blocked_until` | `timestamp without time zone` |  |
| `created_at` | `timestamp without time zone` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX key_block_events_entry_id_index (entry_id)`.

### `monetarie_dict.key_statistics_cache`

Cache de estatísticas antifraude por chave (retornadas no GetEntry).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2312`

| Coluna | Tipo | Observações |
|---|---|---|
| `key_type` | `character varying(10)` | NOT NULL |
| `key_value` | `character varying(77)` | NOT NULL |
| `settlements_d90` | `integer` | default `0` |
| `settlements_m12` | `integer` | default `0` |
| `settlements_m60` | `integer` | default `0` |
| `application_frauds` | `integer` | default `0` |
| `fraud_distinct_reporters` | `integer` | default `0` |
| `open_infraction_reports` | `integer` | default `0` |
| `rejected_infraction_reports` | `integer` | default `0` |
| `infraction_distinct_reporters` | `integer` | default `0` |
| `distinct_accounts` | `integer` | default `0` |
| `watermark` | `bigint` | default `0` |
| `created_at` | `timestamp with time zone` | default `now()` |
| `updated_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (key_type, key_value)`.

### `monetarie_dict.keys`

Vínculos (chaves PIX) locais com titular/conta e estado no DICT.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2334` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/dict/entry.ex:21`, `pix/backend/apps/dict_service/lib/dict_service/keys/entry.ex:22`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `key_type` | `character varying(255)` | NOT NULL |
| `key_value` | `character varying(255)` | NOT NULL |
| `owner_cpf_cnpj` | `character varying(255)` | NOT NULL |
| `owner_name` | `character varying(255)` | NOT NULL |
| `owner_type` | `character varying(255)` | NOT NULL |
| `trade_name` | `character varying(255)` |  |
| `ispb` | `character varying(255)` | NOT NULL |
| `branch_code` | `character varying(255)` |  |
| `account_number` | `character varying(255)` | NOT NULL |
| `account_type` | `character varying(255)` | NOT NULL |
| `opening_date` | `date` |  |
| `account_opening_date` | `date` |  |
| `key_owner_since` | `timestamp without time zone` |  |
| `status` | `character varying(255)` | default `'ACTIVE'::character varying` |
| `status_id` | `integer` | default `1` |
| `cid` | `character varying(255)` |  |
| `sync_version` | `integer` | default `0` |
| `ownership_confirmed` | `boolean` | default `false` |
| `ownership_confirmed_at` | `timestamp without time zone` |  |
| `ownership_validation_id` | `integer` |  |
| `deleted_at` | `timestamp without time zone` |  |
| `delete_reason` | `character varying(255)` |  |
| `open_claim_creation_date` | `timestamp without time zone` |  |
| `blocked_at` | `timestamp without time zone` |  |
| `blocked_reason` | `character varying(255)` |  |
| `blocked_until` | `timestamp without time zone` |  |
| `blocked_by` | `character varying(255)` |  |
| `creation_date` | `timestamp without time zone` | NOT NULL |
| `last_updated` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX idx_dict_keys_owner_status (owner_cpf_cnpj, status)`; `INDEX keys_ispb_index (ispb)`; `UNIQUE INDEX keys_key_type_key_value_index (key_type, key_value)`; `INDEX keys_owner_cpf_cnpj_index (owner_cpf_cnpj)`; `INDEX keys_status_index (status)`.

### `monetarie_dict.med_requests`

Solicitações MED no modelo legado, vinculadas a infrações.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2391`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `request_id` | `character varying(100)` |  |
| `infraction_id` | `character varying(100)` |  |
| `status_id` | `integer` |  |
| `requester_ispb` | `character varying(8)` | NOT NULL |
| `target_ispb` | `character varying(8)` | NOT NULL |
| `end_to_end_id` | `character varying(32)` |  |
| `original_amount` | `numeric(18,2)` |  |
| `requested_amount` | `numeric(18,2)` |  |
| `returned_amount` | `numeric(18,2)` |  |
| `reason` | `text` |  |
| `creation_date` | `timestamp with time zone` |  |
| `response_deadline` | `timestamp with time zone` |  |
| `response_date` | `timestamp with time zone` |  |
| `completion_date` | `timestamp with time zone` |  |
| `last_updated` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_dict_med_req_id (request_id)`; `INDEX idx_dict_med_req_infraction (infraction_id)`.

### `monetarie_dict.operation_status`

Catálogo de status de operação DICT.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2434`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(50)` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `description` | `character varying(500)` |  |
| `is_final` | `boolean` | default `false` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_dict_opstatus_code (code)`.

### `monetarie_dict.operation_types`

Catálogo de tipos de operação DICT.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2467`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(50)` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `description` | `character varying(500)` |  |
| `is_active` | `boolean` | default `true` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_dict_optypes_code (code)`.

### `monetarie_dict.operations`

Log de operações DICT executadas (request/response, correlação BACEN, erros).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2500`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `operation_id` | `character varying(64)` |  |
| `operation_type` | `character varying(50)` | NOT NULL |
| `key_type` | `character varying(20)` |  |
| `key_value` | `character varying(200)` |  |
| `ispb` | `character varying(8)` | NOT NULL |
| `cpf_cnpj` | `character varying(14)` |  |
| `status` | `character varying(20)` | default `'PENDING'::character varying` |
| `motive` | `character varying(50)` |  |
| `request_data` | `jsonb` |  |
| `response_data` | `jsonb` |  |
| `bacen_correlation_id` | `character varying(100)` |  |
| `error_code` | `character varying(20)` |  |
| `error_message` | `text` |  |
| `requested_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `completed_at` | `timestamp with time zone` |  |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_dict_operations_ispb (ispb)`; `INDEX idx_dict_operations_requested (requested_at)`; `INDEX idx_dict_operations_status (status)`; `INDEX idx_dict_operations_type (operation_type)`.

### `monetarie_dict.ownership_validations`

Validação de posse de chave por OTP (e-mail/telefone) antes do registro.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2546` | Ecto: `pix/backend/apps/dict_service/lib/dict_service/ownership/validation.ex:20`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `validation_id` | `character varying(100)` |  |
| `validation_type` | `character varying(50)` |  |
| `key_id` | `uuid` |  |
| `claim_id` | `uuid` |  |
| `method` | `character varying(20)` |  |
| `destination` | `character varying(255)` |  |
| `code_hash` | `character varying(255)` |  |
| `attempts` | `integer` | default `0` |
| `max_attempts` | `integer` | default `5` |
| `status` | `character varying(20)` | default `'PENDING'::character varying` |
| `owner_tax_id` | `character varying(14)` |  |
| `owner_type` | `character varying(20)` |  |
| `created_at` | `timestamp with time zone` | default `now()` |
| `sent_at` | `timestamp with time zone` |  |
| `verified_at` | `timestamp with time zone` |  |
| `expires_at` | `timestamp with time zone` |  |
| `updated_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_dict_ownval_claim (claim_id)`; `INDEX idx_dict_ownval_key (key_id)`; `INDEX idx_dict_ownval_status (status)`.

### `monetarie_dict.parameters`

Parâmetros do serviço DICT.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2591`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `param_name` | `character varying(100)` | NOT NULL |
| `param_value` | `character varying(400)` |  |
| `param_type` | `character varying(50)` |  |
| `description` | `character varying(500)` |  |
| `created_at` | `timestamp with time zone` | default `now()` |
| `updated_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_dict_params_name (param_name)`.

### `monetarie_dict.participant_buckets`

Token bucket de rate limit por participante (política de fichas do DICT).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2626`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `participant_ispb` | `character varying(8)` | NOT NULL |
| `tokens` | `integer` | NOT NULL; default `0` |
| `last_refill_at` | `timestamp with time zone` | default `now()` |
| `created_at` | `timestamp with time zone` | default `now()` |
| `updated_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_dict_part_buckets_ispb (participant_ispb)`.

### `monetarie_dict.participant_hours`

Janelas de funcionamento por participante (dia/horário).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2640`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `ispb` | `character varying(8)` | NOT NULL |
| `day_type` | `character varying(20)` | NOT NULL |
| `hour_type` | `character varying(20)` | NOT NULL |
| `start_time` | `time without time zone` | NOT NULL |
| `end_time` | `time without time zone` | NOT NULL |
| `is_active` | `boolean` | default `true` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_participant_hours_ispb (ispb)`.

### `monetarie_dict.person_statistics_cache`

Cache de estatísticas antifraude por CPF/CNPJ.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2677`

| Coluna | Tipo | Observações |
|---|---|---|
| `tax_id` | `character varying(14)` | NOT NULL |
| `tax_id_type` | `character varying(10)` |  |
| `settlements_d90` | `integer` | default `0` |
| `settlements_m12` | `integer` | default `0` |
| `settlements_m60` | `integer` | default `0` |
| `application_frauds` | `integer` | default `0` |
| `mule_accounts` | `integer` | default `0` |
| `scammer_accounts` | `integer` | default `0` |
| `other_accounts` | `integer` | default `0` |
| `fraud_total_amount` | `numeric(18,2)` | default `0` |
| `fraud_distinct_reporters` | `integer` | default `0` |
| `open_infraction_reports` | `integer` | default `0` |
| `rejected_infraction_reports` | `integer` | default `0` |
| `infraction_distinct_reporters` | `integer` | default `0` |
| `registered_accounts` | `integer` | default `0` |
| `watermark` | `bigint` | default `0` |
| `created_at` | `timestamp with time zone` | default `now()` |
| `updated_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (tax_id)`.

### `monetarie_dict.protection_rules`

Regras de proteção antifraude (posse mínima, máximo de claims por período).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2703`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `rule_code` | `character varying(50)` | NOT NULL |
| `rule_type` | `character varying(50)` | NOT NULL |
| `description` | `character varying(500)` |  |
| `key_type` | `character varying(20)` |  |
| `operation_type` | `character varying(50)` |  |
| `min_ownership_days` | `integer` |  |
| `max_claims_per_period` | `integer` |  |
| `period_days` | `integer` |  |
| `is_active` | `boolean` | default `true` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_protection_rules_code (rule_code)`.

### `monetarie_dict.query_correlations`

Correlação de consultas GetEntry por E2E (cobrança e restituição de fichas).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2743`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `end_to_end_id` | `character varying(32)` |  |
| `participant_ispb` | `character varying(8)` | NOT NULL |
| `payer_id` | `character varying(14)` |  |
| `payer_type` | `character varying(20)` |  |
| `key_type` | `character varying(10)` |  |
| `key_value` | `character varying(77)` |  |
| `tokens_charged` | `integer` | default `0` |
| `found` | `boolean` | default `false` |
| `query_time` | `timestamp with time zone` | default `now()` |
| `refunded` | `boolean` | default `false` |
| `refunded_at` | `timestamp with time zone` |  |
| `expires_at` | `timestamp with time zone` |  |

Constraints e índices: `PK (id)`; `INDEX idx_dict_qcorr_e2e (end_to_end_id)`; `INDEX idx_dict_qcorr_ispb (participant_ispb)`; `INDEX idx_dict_qcorr_time (query_time DESC)`.

### `monetarie_dict.query_metrics`

Métricas agregadas de consultas DICT por janela de tempo.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2764`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `participant_ispb` | `character varying(8)` | NOT NULL |
| `payer_id` | `character varying(14)` |  |
| `window_start` | `timestamp with time zone` | NOT NULL |
| `window_end` | `timestamp with time zone` | NOT NULL |
| `total_queries` | `integer` | default `0` |
| `found_queries` | `integer` | default `0` |
| `not_found_queries` | `integer` | default `0` |
| `created_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_dict_qmetrics_ispb (participant_ispb)`; `INDEX idx_dict_qmetrics_window (window_start, window_end)`.

### `monetarie_dict.rate_limit_policies`

Políticas de rate limit do DICT.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2781`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `policy_name` | `character varying(100)` | NOT NULL |
| `description` | `character varying(500)` |  |
| `rate_per_minute` | `integer` |  |
| `bucket_capacity` | `integer` |  |
| `is_daily_limit` | `boolean` | default `false` |
| `daily_limit` | `integer` |  |
| `enabled` | `boolean` | default `true` |
| `created_at` | `timestamp with time zone` | default `now()` |
| `updated_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (id)`.

### `monetarie_dict.refund_requests`

Pedidos de devolução MED (forma `<Refund>` completa do DICT 2.11).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2799` | Ecto: `pix/backend/apps/dict_service/lib/dict_service/funds_recovery/refund_request.ex:20`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `refund_id` | `character varying(255)` | NOT NULL |
| `funds_recovery_id` | `integer` |  |
| `debtor_ispb` | `character varying(255)` | NOT NULL |
| `creditor_ispb` | `character varying(255)` | NOT NULL |
| `amount` | `numeric(18,2)` |  |
| `status` | `character varying(255)` | default `'PENDING'::character varying` |
| `reason` | `character varying(255)` |  |
| `requested_at` | `timestamp without time zone` |  |
| `completed_at` | `timestamp without time zone` |  |
| `refund_end_to_end_id` | `character varying(255)` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX refund_requests_funds_recovery_id_index (funds_recovery_id)`; `UNIQUE INDEX refund_requests_refund_id_index (refund_id)`; `INDEX refund_requests_status_index (status)`.

### `monetarie_dict.sync_log`

Log de sincronizações (VSYNC/CID) por instituição.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2839`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `sync_time` | `timestamp with time zone` | NOT NULL; default `now()` |
| `institution_id` | `uuid` |  |
| `sync_type` | `character varying(50)` |  |
| `last_version` | `bigint` |  |
| `new_version` | `bigint` |  |
| `records_processed` | `integer` | default `0` |
| `status` | `character varying(20)` |  |
| `error_message` | `text` |  |

Constraints e índices: `PK (id, sync_time)`.

### `monetarie_dict.tracking_graph_accounts`

Nós de conta do grafo de rastreamento MED 2.0.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2875` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/dict/tracking_graph.ex:119`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `tracking_graph_id` | `integer` | NOT NULL |
| `ispb` | `character varying(255)` | NOT NULL |
| `branch` | `character varying(255)` |  |
| `account_number` | `character varying(255)` |  |
| `account_type` | `character varying(255)` |  |
| `holder_cpf_cnpj` | `character varying(255)` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX tracking_graph_accounts_tracking_graph_id_index (tracking_graph_id)`.

### `monetarie_dict.tracking_graph_persons`

Nós de pessoa do grafo de rastreamento MED 2.0.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2911` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/dict/tracking_graph.ex:92`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `tracking_graph_id` | `integer` | NOT NULL |
| `cpf_cnpj` | `character varying(255)` | NOT NULL |
| `name` | `character varying(255)` |  |
| `is_fraud_suspect` | `boolean` | default `false` |
| `role` | `character varying(255)` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX tracking_graph_persons_tracking_graph_id_index (tracking_graph_id)`.

### `monetarie_dict.tracking_graph_transactions`

Arestas de transação do grafo de rastreamento MED 2.0.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2946` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/dict/tracking_graph.ex:157`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `tracking_graph_id` | `integer` | NOT NULL |
| `end_to_end_id` | `character varying(255)` | NOT NULL |
| `amount` | `numeric(18,2)` |  |
| `debtor_ispb` | `character varying(255)` |  |
| `creditor_ispb` | `character varying(255)` |  |
| `hop_number` | `integer` |  |
| `transaction_date` | `timestamp without time zone` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX tracking_graph_transactions_end_to_end_id_index (end_to_end_id)`; `INDEX tracking_graph_transactions_tracking_graph_id_index (tracking_graph_id)`.

### `monetarie_dict.tracking_graphs`

Grafos de rastreamento de fundos MED 2.0.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:2983` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/dict/tracking_graph.ex:14`, `pix/backend/apps/dict_service/lib/dict_service/funds_recovery/tracking_graph.ex:19`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `graph_id` | `character varying(255)` | NOT NULL |
| `funds_recovery_id` | `integer` |  |
| `status` | `character varying(255)` | default `'PENDING'::character varying` |
| `total_amount` | `numeric(18,2)` |  |
| `hop_count` | `integer` | default `0` |
| `max_hops` | `integer` | default `5` |
| `generated_at` | `timestamp without time zone` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX tracking_graphs_funds_recovery_id_index (funds_recovery_id)`; `UNIQUE INDEX tracking_graphs_graph_id_index (graph_id)`.

### `monetarie_dict.user_buckets`

Token bucket por usuário pagador (fichas telefone/e-mail vs demais).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3020`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `participant_ispb` | `character varying(8)` | NOT NULL |
| `payer_id` | `character varying(14)` | NOT NULL |
| `payer_type` | `character varying(20)` |  |
| `tokens_phone_email` | `integer` | NOT NULL; default `0` |
| `tokens_other` | `integer` | NOT NULL; default `0` |
| `last_refill_at` | `timestamp with time zone` | default `now()` |
| `created_at` | `timestamp with time zone` | default `now()` |
| `updated_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_dict_user_buckets_ispb (participant_ispb)`; `UNIQUE INDEX idx_dict_user_buckets_payer (participant_ispb, payer_id)`.

### `monetarie_dict.dict_external_operations`

Auditoria de cada operação DICT externa contra o BACEN (request/response, latência, correlação).

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260509102000_create_dict_external_operations.exs` | Ecto: `pix/backend/apps/dict_service/lib/dict_service/dict_external_operation.ex:26`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `:uuid` | PK |
| `operation_id` | `:string` | NOT NULL |
| `operation_type` | `:string` | NOT NULL |
| `external_mode` | `:string` | NOT NULL |
| `idempotency_key` | `:string` | NOT NULL |
| `correlation_id` | `:string` | NOT NULL |
| `key_type` | `:string` |  |
| `key_value` | `:string` |  |
| `ispb` | `:string` |  |
| `requester_ispb` | `:string` |  |
| `cpf_cnpj` | `:string` |  |
| `status` | `:string` | NOT NULL; default `"pending_external"` |
| `request_data` | `:map` |  |
| `response_data` | `:map` |  |
| `error_code` | `:string` |  |
| `error_message` | `:text` |  |
| `attempted_at` | `:utc_datetime_usec` | NOT NULL |
| `completed_at` | `:utc_datetime_usec` |  |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `UNIQUE INDEX [:operation_id]`; `INDEX [:operation_type]`; `INDEX [:status]`; `INDEX [:correlation_id]`; `INDEX [:idempotency_key]`; `INDEX [:key_value]`; `INDEX [:attempted_at]`; `INDEX [:claim_id]`; `INDEX [:recovery_id]`; `INDEX [:report_id]`; `INDEX [:refund_id]`.

### `monetarie_dict.dict_sync_cursors`

Marca d'água persistida por tipo de poll da sincronização inbound do DICT (claims, refunds, infrações).

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260706150000_dict_inbound_sync_state_and_fields.exs` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/dict/sync_cursor.ex:24`

| Coluna | Tipo | Observações |
|---|---|---|
| `poll_type` | `varchar(40) PRIMARY KEY` |  |
| `watermark` | `timestamptz` |  |
| `last_synced_at` | `timestamptz` |  |
| `last_summary` | `jsonb NOT NULL DEFAULT '{}'::jsonb` |  |
| `inserted_at` | `timestamptz NOT NULL DEFAULT now()` |  |
| `updated_at` | `timestamptz NOT NULL DEFAULT now()` |  |

### `monetarie_dict.fraud_markers`

Acervo local de marcadores de fraude do DICT.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260706233000_create_dict_fraud_markers.exs` | Ecto: `pix/backend/apps/dict_service/lib/dict_service/fraud_markers/fraud_marker.ex:22`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigserial PRIMARY KEY` |  |
| `fraud_marker_id` | `varchar(64) NOT NULL` |  |
| `participant_ispb` | `varchar(8)` |  |
| `tax_id_number` | `varchar(14)` |  |
| `key_value` | `varchar(140)` |  |
| `fraud_type` | `varchar(40)` |  |
| `status` | `varchar(20)` |  |
| `details` | `text` |  |
| `bacen_creation_time` | `timestamptz` |  |
| `bacen_last_modified` | `timestamptz` |  |
| `inserted_at` | `timestamptz NOT NULL DEFAULT now()` |  |
| `updated_at` | `timestamptz NOT NULL DEFAULT now()` |  |

## Schema `monetarie_settlement`

Settlement: liquidação, tarifas, QR/CobV, relatórios e contabilidade (app `settlement_service`).

### `monetarie_settlement.accounting_events`

Eventos contábeis (fonte dos lançamentos; materializados em journal_entries de forma fail-fast).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3037` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/accounting/accounting_event.ex:14`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `type` | `character varying(20)` | NOT NULL |
| `event_type` | `character varying(50)` | NOT NULL |
| `description` | `text` |  |
| `amount` | `bigint` | NOT NULL |
| `debit_account` | `character varying(20)` | NOT NULL |
| `credit_account` | `character varying(20)` | NOT NULL |
| `date` | `date` | NOT NULL; default `CURRENT_DATE` |
| `user` | `character varying(100)` | NOT NULL; default `'system'::character varying` |
| `status` | `character varying(20)` | NOT NULL; default `'pending'::character varying` |
| `reference` | `character varying(100)` |  |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_accounting_events_date (date DESC)`; `INDEX idx_accounting_events_type_status (type, status)`; `CONSTRAINT accounting_events_amount_check CHECK ((amount >= 0))`; `CONSTRAINT accounting_events_status_check CHECK (((status)::text = ANY ((ARRAY['processed'::character varying, 'pending'::character varying, 'error'::character varying])::text[])))`; `CONSTRAINT accounting_events_type_check CHECK (((type)::text = ANY ((ARRAY['automatic'::character varying, 'manual'::character varying])::text[])))`.

### `monetarie_settlement.additional_info`

Pares chave/valor adicionais de payment_requests.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3061`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `payment_request_id` | `bigint` | NOT NULL |
| `info_key` | `character varying(50)` | NOT NULL |
| `info_value` | `character varying(200)` | NOT NULL |

Constraints e índices: `PK (id)`; `FK (payment_request_id) REFERENCES monetarie_settlement.payment_requests(id)`; `INDEX idx_stl_addinfo_payreq (payment_request_id)`.

### `monetarie_settlement.chart_of_accounts`

Plano de contas COSIF da cabine (contas âncora de disponibilidade e obrigações).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3092` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/accounting/chart_of_accounts.ex:13`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `cosif_code` | `character varying(20)` | NOT NULL |
| `name` | `character varying(200)` | NOT NULL |
| `account_type` | `character varying(20)` | NOT NULL |
| `parent_code` | `character varying(20)` |  |
| `level` | `integer` | NOT NULL; default `1` |
| `active` | `boolean` | NOT NULL; default `true` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_chart_of_accounts_active_type (active, account_type) WHERE (active = true)`; `UNIQUE INDEX idx_chart_of_accounts_cosif_code (cosif_code)`; `INDEX idx_chart_of_accounts_parent_code (parent_code) WHERE (parent_code IS NOT NULL)`; `CONSTRAINT chart_of_accounts_account_type_check CHECK (((account_type)::text = ANY ((ARRAY['asset'::character varying, 'liability'::character varying, 'equity'::character varying, 'revenue'::character varying, 'expense'::character varying])::text[])))`.

### `monetarie_settlement.cost_centers`

Centros de custo (BCB 4010).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3110` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/accounting/cost_center.ex:13`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `code` | `character varying(20)` | NOT NULL |
| `name` | `character varying(200)` | NOT NULL |
| `responsible` | `character varying(200)` | NOT NULL |
| `status` | `character varying(20)` | NOT NULL; default `'active'::character varying` |
| `budget` | `bigint` | NOT NULL; default `0` |
| `spent` | `bigint` | NOT NULL; default `0` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_cost_centers_code (code)`; `CONSTRAINT cost_centers_status_check CHECK (((status)::text = ANY ((ARRAY['active'::character varying, 'inactive'::character varying])::text[])))`.

### `monetarie_settlement.emv_payments`

Pagamentos recebidos via payload EMV (QR) correlacionados a QR e payment_request.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3128`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `qr_code_id` | `bigint` |  |
| `payment_request_id` | `bigint` |  |
| `emv_version` | `character varying(10)` |  |
| `emv_payload` | `text` | NOT NULL |
| `amount` | `bigint` | NOT NULL |
| `tip_amount` | `bigint` | NOT NULL; default `0` |
| `status` | `character varying(20)` | NOT NULL |
| `processed_at` | `timestamp with time zone` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `FK (payment_request_id) REFERENCES monetarie_settlement.payment_requests(id)`; `FK (qr_code_id) REFERENCES monetarie_settlement.qr_codes(id)`.

### `monetarie_settlement.error_details`

Detalhes de erros de operação (stack, request/response).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3165`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `error_time` | `timestamp with time zone` | NOT NULL; default `now()` |
| `operation_id` | `bigint` |  |
| `error_code` | `character varying(20)` | NOT NULL |
| `error_source` | `character varying(50)` |  |
| `error_message` | `text` |  |
| `stack_trace` | `text` |  |
| `request_data` | `jsonb` |  |
| `response_data` | `jsonb` |  |

Constraints e índices: `PK (id, error_time)`; `INDEX idx_stl_errdet_code (error_code)`; `INDEX idx_stl_errdet_opid (operation_id)`.

### `monetarie_settlement.error_messages`

Catálogo de mensagens de erro pt/en com dica de resolução.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3201`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `error_code` | `character varying(20)` | NOT NULL |
| `message_pt` | `character varying(500)` | NOT NULL |
| `message_en` | `character varying(500)` |  |
| `resolution_hint` | `text` |  |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_stl_errmsg_code (error_code)`.

### `monetarie_settlement.fee_entries`

Lançamentos de tarifa por transação.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3234` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/settlement/fee.ex:19`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `entry_id` | `character varying(255)` | NOT NULL |
| `transaction_id` | `integer` |  |
| `end_to_end_id` | `character varying(255)` |  |
| `ispb` | `character varying(255)` | NOT NULL |
| `fee_type` | `character varying(255)` | NOT NULL |
| `fee_amount` | `numeric(18,4)` | NOT NULL |
| `transaction_amount` | `numeric(18,2)` |  |
| `fee_rule_id` | `integer` |  |
| `status` | `character varying(255)` | default `'pending'::character varying` |
| `billed_at` | `timestamp without time zone` |  |
| `paid_at` | `timestamp without time zone` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX fee_entries_end_to_end_id_index (end_to_end_id)`; `UNIQUE INDEX fee_entries_entry_id_index (entry_id)`; `INDEX fee_entries_ispb_index (ispb)`; `INDEX fee_entries_status_index (status)`.

### `monetarie_settlement.fee_exemptions`

Isenções de tarifa por cliente/regra.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3275` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/settlement/fee.ex:306`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `exemption_id` | `character varying(255)` | NOT NULL |
| `ispb` | `character varying(255)` | NOT NULL |
| `fee_type` | `character varying(255)` |  |
| `transaction_type` | `character varying(255)` |  |
| `exemption_type` | `character varying(255)` | NOT NULL |
| `percentage` | `numeric(5,2)` |  |
| `max_amount` | `numeric(18,2)` |  |
| `reason` | `character varying(255)` |  |
| `effective_from` | `date` | NOT NULL |
| `effective_until` | `date` |  |
| `status` | `character varying(255)` | default `'active'::character varying` |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |
| `unique_id` | `UUID` | adicionada por `20260617194000_align_settlement_fee_schema.exs` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX fee_exemptions_exemption_id_index (exemption_id)`; `INDEX fee_exemptions_ispb_index (ispb)`; `INDEX fee_exemptions_status_index (status)`.

### `monetarie_settlement.fee_rules`

Regras de cálculo de tarifa.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3316` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/settlement/fee.ex:219`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `fee_table_id` | `integer` | NOT NULL |
| `rule_id` | `character varying(255)` | NOT NULL |
| `transaction_type` | `character varying(255)` | NOT NULL |
| `fee_type` | `character varying(255)` | NOT NULL |
| `calculation_type` | `character varying(255)` | NOT NULL |
| `fixed_amount` | `numeric(18,4)` |  |
| `percentage` | `numeric(8,6)` |  |
| `min_amount` | `numeric(18,2)` |  |
| `max_amount` | `numeric(18,2)` |  |
| `tier_from` | `numeric(18,2)` |  |
| `tier_to` | `numeric(18,2)` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |
| `fee_value` | `INTEGER` | adicionada por `20260617194000_align_settlement_fee_schema.exs` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX fee_rules_fee_table_id_rule_id_index (fee_table_id, rule_id)`; `INDEX fee_rules_transaction_type_index (transaction_type)`.

### `monetarie_settlement.fee_tables`

Tabelas de tarifas vigentes (por tipo, faixa e vigência).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3357` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/settlement/fee.ex:153`, `pix/backend/apps/settlement_service/lib/settlement_service/fees/fee_schedule.ex:16`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `table_id` | `character varying(255)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `description` | `character varying(255)` |  |
| `effective_from` | `date` | NOT NULL |
| `effective_until` | `date` |  |
| `status` | `character varying(255)` | default `'active'::character varying` |
| `is_default` | `boolean` | default `false` |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |
| `unique_id` | `UUID` | adicionada por `20260617194000_align_settlement_fee_schema.exs` |
| `fee_type` | `varchar(64)` | adicionada por `20260618120000_create_settlement_runtime_tables.exs` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX fee_tables_table_id_index (table_id)`.

### `monetarie_settlement.file_import_records`

Linhas individuais de arquivos importados.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3394`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `file_import_id` | `bigint` | NOT NULL |
| `line_number` | `integer` | NOT NULL |
| `raw_data` | `text` | NOT NULL |
| `status` | `character varying(20)` | NOT NULL; default `'PENDING'::character varying` |
| `payment_request_id` | `bigint` |  |
| `error_message` | `text` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `FK (file_import_id) REFERENCES monetarie_settlement.file_imports(id)`; `INDEX idx_stl_fimprec_fileid (file_import_id)`.

### `monetarie_settlement.file_imports`

Controle de arquivos de pagamento importados.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3429`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `filename` | `character varying(255)` | NOT NULL |
| `file_type` | `character varying(20)` | NOT NULL |
| `file_size` | `bigint` | NOT NULL |
| `status` | `character varying(20)` | NOT NULL; default `'PENDING'::character varying` |
| `total_records` | `integer` | NOT NULL; default `0` |
| `processed_records` | `integer` | NOT NULL; default `0` |
| `failed_records` | `integer` | NOT NULL; default `0` |
| `started_at` | `timestamp with time zone` |  |
| `completed_at` | `timestamp with time zone` |  |
| `error_log` | `jsonb` |  |
| `created_by` | `integer` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`.

### `monetarie_settlement.fixed_date_discounts`

Descontos por data fixa usados no CobV.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3469`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `discount_date` | `date` | NOT NULL |
| `discount_type` | `character varying(50)` | NOT NULL |
| `percentage` | `numeric(5,2)` |  |
| `fixed_amount` | `numeric(18,2)` |  |
| `description` | `character varying(200)` |  |
| `is_active` | `boolean` | default `true` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_fixed_date_discounts_date (discount_date)`.

### `monetarie_settlement.holidays`

Feriados municipais/estaduais para o calendário de dia útil do CobV (nacionais são computados em código).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3506` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/settlement/holiday.ex:21`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `holiday_date` | `date` | NOT NULL |
| `description` | `character varying(200)` | NOT NULL |
| `holiday_type` | `character varying(50)` | NOT NULL; default `'NATIONAL'::character varying` |
| `region` | `character varying(10)` |  |
| `is_active` | `boolean` | default `true` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_settlement_holidays_date (holiday_date)`.

### `monetarie_settlement.init_payment_types`

Catálogo de tipos de iniciação de pagamento.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3542`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(20)` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `description` | `character varying(500)` |  |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_stl_initpay_code (code)`.

### `monetarie_settlement.journal_entries`

Lançamentos contábeis (partidas COSIF débito/crédito).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3574` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/accounting/journal_entry.ex:14`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `date` | `date` | NOT NULL |
| `debit_account_id` | `uuid` | NOT NULL |
| `credit_account_id` | `uuid` | NOT NULL |
| `amount` | `bigint` | NOT NULL |
| `description` | `character varying(500)` | NOT NULL |
| `reference` | `character varying(100)` |  |
| `source_type` | `character varying(30)` | NOT NULL; default `'manual'::character varying` |
| `source_id` | `uuid` |  |
| `status` | `character varying(20)` | NOT NULL; default `'pending'::character varying` |
| `created_by` | `character varying(100)` | NOT NULL; default `'system'::character varying` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `FK (credit_account_id) REFERENCES monetarie_settlement.chart_of_accounts(id)`; `FK (debit_account_id) REFERENCES monetarie_settlement.chart_of_accounts(id)`; `INDEX idx_journal_entries_credit_account (credit_account_id)`; `INDEX idx_journal_entries_date (date DESC)`; `INDEX idx_journal_entries_debit_account (debit_account_id)`; `INDEX idx_journal_entries_source (source_type, source_id) WHERE (source_id IS NOT NULL)`; `INDEX idx_journal_entries_status_pending (status) WHERE ((status)::text = 'pending'::text)`; `CONSTRAINT journal_entries_amount_check CHECK ((amount > 0))`; `CONSTRAINT journal_entries_status_check CHECK (((status)::text = ANY ((ARRAY['pending'::character varying, 'posted'::character varying, 'reversed'::character varying])::text[])))`.

### `monetarie_settlement.netting_cycles`

Ciclos de compensação/liquidação (netting).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3597` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/settlement/settlement_session.ex:20`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `cycle_id` | `character varying(255)` | NOT NULL |
| `settlement_date` | `date` | NOT NULL |
| `cycle_number` | `integer` | NOT NULL |
| `status` | `character varying(255)` | default `'open'::character varying` |
| `opened_at` | `timestamp without time zone` |  |
| `closed_at` | `timestamp without time zone` |  |
| `settled_at` | `timestamp without time zone` |  |
| `total_transactions` | `integer` | default `0` |
| `total_amount` | `numeric(18,2)` | default `0` |
| `net_amount` | `numeric(18,2)` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |
| `unique_id` | `UUID` | adicionada por `20260617194000_align_settlement_fee_schema.exs` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX netting_cycles_cycle_id_index (cycle_id)`; `UNIQUE INDEX netting_cycles_settlement_date_cycle_number_index (settlement_date, cycle_number)`; `INDEX netting_cycles_status_index (status)`.

### `monetarie_settlement.netting_operations`

Operações/resultados de netting.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3637` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/settlement/netting_result.ex:30`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `operation_id` | `character varying(255)` | NOT NULL |
| `cycle_id` | `integer` | NOT NULL |
| `debtor_ispb` | `character varying(255)` | NOT NULL |
| `creditor_ispb` | `character varying(255)` | NOT NULL |
| `net_amount` | `numeric(18,2)` | NOT NULL |
| `status` | `character varying(255)` | default `'pending'::character varying` |
| `settled_at` | `timestamp without time zone` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX netting_operations_cycle_id_index (cycle_id)`; `UNIQUE INDEX netting_operations_operation_id_index (operation_id)`.

### `monetarie_settlement.netting_positions`

Posições líquidas por participante no ciclo de netting.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3674` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/settlement/settlement_position.ex:20`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `cycle_id` | `integer` | NOT NULL |
| `ispb` | `character varying(255)` | NOT NULL |
| `gross_credits` | `numeric(18,2)` | default `0` |
| `gross_debits` | `numeric(18,2)` | default `0` |
| `net_position` | `numeric(18,2)` | default `0` |
| `credit_count` | `integer` | default `0` |
| `debit_count` | `integer` | default `0` |
| `status` | `character varying(255)` | default `'pending'::character varying` |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `UNIQUE INDEX netting_positions_cycle_id_ispb_index (cycle_id, ispb)`; `INDEX netting_positions_ispb_index (ispb)`.

### `monetarie_settlement.netting_transactions`

Obrigações de liquidação incluídas no netting.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3712` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/settlement/settlement_obligations.ex:17`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `cycle_id` | `integer` | NOT NULL |
| `transaction_id` | `integer` | NOT NULL |
| `end_to_end_id` | `character varying(255)` | NOT NULL |
| `amount` | `numeric(18,2)` | NOT NULL |
| `debtor_ispb` | `character varying(255)` |  |
| `creditor_ispb` | `character varying(255)` |  |
| `included_at` | `timestamp without time zone` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX netting_transactions_cycle_id_index (cycle_id)`; `INDEX netting_transactions_end_to_end_id_index (end_to_end_id)`.

### `monetarie_settlement.operation_controls`

Locks de operação (chave, dono, expiração) para exclusão mútua.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3749`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `operation_type` | `character varying(50)` | NOT NULL |
| `lock_key` | `character varying(200)` | NOT NULL |
| `locked_by` | `character varying(100)` |  |
| `locked_at` | `timestamp with time zone` |  |
| `expires_at` | `timestamp with time zone` |  |
| `status` | `character varying(20)` | default `'ACTIVE'::character varying` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_op_controls_key (lock_key)`.

### `monetarie_settlement.operation_history`

Histórico de mudanças de situação das operações.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3785`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `history_time` | `timestamp with time zone` | NOT NULL; default `now()` |
| `operation_id` | `bigint` | NOT NULL |
| `old_situation_id` | `integer` |  |
| `new_situation_id` | `integer` | NOT NULL |
| `user_id` | `integer` |  |
| `notes` | `text` |  |

Constraints e índices: `PK (id, history_time)`; `INDEX idx_stl_ophist_opid (operation_id)`.

### `monetarie_settlement.operation_types`

Catálogo de tipos de operação.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3819`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(20)` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `description` | `character varying(500)` |  |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_stl_optype_code (code)`.

### `monetarie_settlement.operations`

Operações de negócio (espelho do pagamento com dados completos, correlacionado a `spi_message_id`).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3851`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `operation_time` | `timestamp with time zone` | NOT NULL; default `now()` |
| `operation_type_id` | `integer` |  |
| `situation_id` | `integer` |  |
| `institution_id` | `integer` | NOT NULL |
| `branch_id` | `integer` | NOT NULL |
| `end_to_end_id` | `character(32)` |  |
| `tx_id` | `character varying(35)` |  |
| `message_id` | `character varying(32)` |  |
| `amount` | `numeric(18,2)` | NOT NULL |
| `currency` | `character(3)` | default `'BRL'::bpchar` |
| `debtor_ispb` | `character(8)` |  |
| `debtor_cpf_cnpj` | `character varying(14)` |  |
| `debtor_account` | `character varying(34)` |  |
| `debtor_name` | `character varying(140)` |  |
| `creditor_ispb` | `character(8)` |  |
| `creditor_cpf_cnpj` | `character varying(14)` |  |
| `creditor_account` | `character varying(34)` |  |
| `creditor_name` | `character varying(140)` |  |
| `pix_key_type` | `character varying(10)` |  |
| `pix_key` | `character varying(77)` |  |
| `description` | `character varying(140)` |  |
| `confirmation_code` | `character varying(50)` |  |
| `schedule_date` | `date` |  |
| `spi_message_id` | `bigint` |  |
| `user_id` | `integer` |  |
| `error_code` | `character varying(20)` |  |
| `error_message` | `text` |  |
| `created_at` | `timestamp with time zone` | default `now()` |
| `updated_at` | `timestamp with time zone` |  |
| `completed_at` | `timestamp with time zone` |  |

Constraints e índices: `PK (id, operation_time)`; `FK (operation_type_id) REFERENCES monetarie_settlement.operation_types(id)`; `FK (situation_id) REFERENCES monetarie_settlement.situation_types(id)`; `INDEX idx_stl_ops_e2e (end_to_end_id)`; `INDEX idx_stl_ops_inst (institution_id)`; `INDEX idx_stl_ops_status (situation_id)`; `INDEX idx_stl_ops_time (operation_time DESC)`.

### `monetarie_settlement.parameter_groups`

Grupos de parâmetros de configuração.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3909`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `description` | `character varying(500)` |  |

Constraints e índices: `PK (id)`.

### `monetarie_settlement.parameters`

Parâmetros de configuração do settlement.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3940`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `param_key` | `character varying(100)` | NOT NULL |
| `param_value` | `character varying(500)` |  |
| `param_type` | `character varying(50)` | default `'STRING'::character varying` |
| `description` | `character varying(500)` |  |
| `group_name` | `character varying(100)` |  |
| `is_active` | `boolean` | default `true` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_settlement_params_composite (group_name, param_key) WHERE (is_active = true)`; `UNIQUE INDEX idx_settlement_params_key (param_key)`.

### `monetarie_settlement.participants`

Participantes SPI/SPB para fins de liquidação.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:3977` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/spi/participant.ex:15`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `ispb` | `character varying(255)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `short_name` | `character varying(255)` |  |
| `participation_type` | `character varying(255)` | NOT NULL |
| `status` | `character varying(255)` | default `'active'::character varying` |
| `bacen_category` | `character varying(255)` |  |
| `start_date` | `date` |  |
| `end_date` | `date` |  |
| `settlement_account` | `character varying(255)` |  |
| `settlement_branch` | `character varying(255)` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `UNIQUE INDEX participants_ispb_index (ispb)`.

### `monetarie_settlement.payment_file_details`

Detalhe por linha dos arquivos de pagamento.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4017`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `file_id` | `bigint` | NOT NULL |
| `line_number` | `integer` | NOT NULL |
| `debtor_cpf_cnpj` | `character varying(14)` |  |
| `creditor_cpf_cnpj` | `character varying(14)` |  |
| `creditor_account` | `character varying(34)` |  |
| `pix_key` | `character varying(77)` |  |
| `amount` | `numeric(18,2)` |  |
| `description` | `character varying(140)` |  |
| `status` | `character varying(20)` | default `'PENDING'::character varying` |
| `operation_id` | `bigint` |  |
| `error_code` | `character varying(20)` |  |
| `error_message` | `text` |  |

Constraints e índices: `PK (id)`; `FK (file_id) REFERENCES monetarie_settlement.payment_files(id)`; `INDEX idx_stl_payfiledet_fileid (file_id)`.

### `monetarie_settlement.payment_files`

Arquivos de pagamento (lote) processados.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4057`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `institution_id` | `integer` | NOT NULL |
| `file_name` | `character varying(200)` | NOT NULL |
| `file_type` | `character varying(20)` | NOT NULL |
| `file_size` | `bigint` |  |
| `total_records` | `integer` | default `0` |
| `processed_records` | `integer` | default `0` |
| `total_amount` | `numeric(18,2)` |  |
| `status` | `character varying(20)` | default `'PENDING'::character varying` |
| `error_count` | `integer` | default `0` |
| `created_at` | `timestamp with time zone` | default `now()` |
| `processed_at` | `timestamp with time zone` |  |

Constraints e índices: `PK (id)`.

### `monetarie_settlement.payment_requests`

Solicitações de pagamento da API de iniciação (QR, agendamento, retries).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4096`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `unique_id` | `character varying(64)` | NOT NULL |
| `external_id` | `character varying(64)` |  |
| `status` | `monetarie_settlement.payment_status` | NOT NULL; default `'PENDING'::monetarie_settlement.payment_status` |
| `amount` | `bigint` | NOT NULL |
| `currency` | `character varying(3)` | NOT NULL; default `'BRL'::character varying` |
| `debtor_ispb` | `character(8)` | NOT NULL |
| `debtor_document` | `character varying(14)` | NOT NULL |
| `debtor_name` | `character varying(140)` | NOT NULL |
| `debtor_account_no` | `character varying(20)` | NOT NULL |
| `debtor_account_type` | `character varying(4)` | NOT NULL |
| `debtor_branch` | `character varying(4)` | NOT NULL |
| `creditor_ispb` | `character(8)` | NOT NULL |
| `creditor_document` | `character varying(14)` | NOT NULL |
| `creditor_name` | `character varying(140)` | NOT NULL |
| `creditor_account_no` | `character varying(20)` | NOT NULL |
| `creditor_account_type` | `character varying(4)` | NOT NULL |
| `creditor_branch` | `character varying(4)` | NOT NULL |
| `description` | `character varying(140)` |  |
| `qr_code_data` | `text` |  |
| `tx_id` | `character varying(35)` |  |
| `end_to_end_id` | `character varying(32)` |  |
| `scheduled_date` | `timestamp with time zone` |  |
| `processed_at` | `timestamp with time zone` |  |
| `error_code` | `character varying(10)` |  |
| `error_message` | `text` |  |
| `retry_count` | `integer` | NOT NULL; default `0` |
| `created_by` | `integer` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_stl_payreq_e2e (end_to_end_id)`; `INDEX idx_stl_payreq_status (status)`; `UNIQUE INDEX idx_stl_payreq_unique (unique_id)`.

### `monetarie_settlement.qr_code_receivers`

Recebedores adicionais (split) de um QR composto.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4153`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `qr_code_id` | `bigint` | NOT NULL |
| `cpf_cnpj` | `character varying(14)` | NOT NULL |
| `name` | `character varying(140)` | NOT NULL |
| `percentage` | `numeric(5,2)` |  |
| `fixed_amount` | `numeric(18,2)` |  |
| `created_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (id)`; `FK (qr_code_id) REFERENCES monetarie_settlement.qr_codes(id)`; `INDEX idx_stl_qrrecv_qrid (qr_code_id)`.

### `monetarie_settlement.qr_codes`

QR Codes estáticos/dinâmicos/CobV emitidos (txid, payload JWS, status, expiração).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4187` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/qr_codes/qr_code.ex:57`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `init_type_id` | `integer` |  |
| `institution_id` | `integer` | NOT NULL |
| `branch_id` | `integer` | NOT NULL |
| `tx_id` | `character varying(35)` | NOT NULL |
| `qr_type` | `character varying(20)` | NOT NULL |
| `amount` | `numeric(18,2)` |  |
| `currency` | `character(3)` | default `'BRL'::bpchar` |
| `receiver_cpf_cnpj` | `character varying(14)` | NOT NULL |
| `receiver_name` | `character varying(140)` | NOT NULL |
| `receiver_city` | `character varying(50)` |  |
| `pix_key_type` | `character varying(10)` |  |
| `pix_key` | `character varying(77)` |  |
| `description` | `character varying(140)` |  |
| `emv_payload` | `text` |  |
| `expiration_time` | `timestamp with time zone` |  |
| `times_used` | `integer` | default `0` |
| `max_uses` | `integer` |  |
| `is_active` | `boolean` | default `true` |
| `created_at` | `timestamp with time zone` | default `now()` |
| `updated_at` | `timestamp with time zone` |  |

Constraints e índices: `PK (id)`; `FK (init_type_id) REFERENCES monetarie_settlement.init_payment_types(id)`; `INDEX idx_stl_qr_inst (institution_id)`; `INDEX idx_stl_qr_txid (tx_id)`.

### `monetarie_settlement.recurring_payments`

Pagamentos recorrentes (modelo legado).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4235`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `institution_id` | `integer` | NOT NULL |
| `branch_id` | `integer` | NOT NULL |
| `frequency` | `character varying(20)` | NOT NULL |
| `day_of_month` | `integer` |  |
| `day_of_week` | `integer` |  |
| `amount` | `numeric(18,2)` | NOT NULL |
| `debtor_cpf_cnpj` | `character varying(14)` | NOT NULL |
| `debtor_account` | `character varying(34)` | NOT NULL |
| `creditor_cpf_cnpj` | `character varying(14)` | NOT NULL |
| `creditor_account` | `character varying(34)` |  |
| `pix_key_type` | `character varying(10)` |  |
| `pix_key` | `character varying(77)` |  |
| `description` | `character varying(140)` |  |
| `start_date` | `date` | NOT NULL |
| `end_date` | `date` |  |
| `next_execution` | `date` |  |
| `is_active` | `boolean` | default `true` |
| `created_at` | `timestamp with time zone` | default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_stl_recurpay_next (next_execution)`.

### `monetarie_settlement.sanctions_screening`

Triagem de sanções por operação (resultado, score, resolução).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4281`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `operation_id` | `bigint` |  |
| `cpf_cnpj` | `character varying(14)` | NOT NULL |
| `name` | `character varying(200)` |  |
| `screening_type` | `character varying(50)` | NOT NULL |
| `screening_result` | `character varying(20)` | NOT NULL |
| `score` | `numeric(5,2)` |  |
| `matched_list` | `character varying(100)` |  |
| `matched_entry` | `character varying(500)` |  |
| `details` | `jsonb` |  |
| `screened_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `resolved_at` | `timestamp with time zone` |  |
| `resolved_by` | `integer` |  |
| `resolution_notes` | `text` |  |
| `status` | `character varying(20)` | default `'PENDING'::character varying` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_sanctions_cpf_cnpj (cpf_cnpj)`; `INDEX idx_sanctions_operation (operation_id)`; `INDEX idx_sanctions_screened_at (screened_at)`; `INDEX idx_sanctions_status (status)`.

### `monetarie_settlement.sanctions_screening_errors`

Erros ocorridos na triagem de sanções.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4306`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `screening_id` | `integer` |  |
| `error_code` | `character varying(50)` |  |
| `error_message` | `text` |  |
| `occurred_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `FK (screening_id) REFERENCES monetarie_settlement.sanctions_screening(id)`.

### `monetarie_settlement.sanctions_status_types`

Catálogo de status da triagem de sanções.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4359`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(20)` | NOT NULL |
| `description` | `character varying(200)` | NOT NULL |
| `is_final` | `boolean` | default `false` |

Constraints e índices: `PK (id)`; `UNIQUE sanctions_status_types_code_key (code)`.

### `monetarie_settlement.scheduled_payments`

Pagamentos agendados (modelo legado).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4391`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `institution_id` | `integer` | NOT NULL |
| `branch_id` | `integer` | NOT NULL |
| `schedule_date` | `date` | NOT NULL |
| `amount` | `numeric(18,2)` | NOT NULL |
| `debtor_cpf_cnpj` | `character varying(14)` | NOT NULL |
| `debtor_account` | `character varying(34)` | NOT NULL |
| `creditor_cpf_cnpj` | `character varying(14)` | NOT NULL |
| `creditor_account` | `character varying(34)` |  |
| `pix_key_type` | `character varying(10)` |  |
| `pix_key` | `character varying(77)` |  |
| `description` | `character varying(140)` |  |
| `status` | `character varying(20)` | default `'PENDING'::character varying` |
| `operation_id` | `bigint` |  |
| `created_at` | `timestamp with time zone` | default `now()` |
| `processed_at` | `timestamp with time zone` |  |

Constraints e índices: `PK (id)`; `INDEX idx_stl_schedpay_date (schedule_date)`; `INDEX idx_stl_schedpay_status (status)`.

### `monetarie_settlement.schedules`

Agendamentos de payment_requests (execução única ou recorrente).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4434`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `payment_request_id` | `bigint` | NOT NULL |
| `schedule_type` | `character varying(20)` | NOT NULL |
| `scheduled_date` | `date` | NOT NULL |
| `scheduled_time` | `time without time zone` |  |
| `recurrence_end_date` | `date` |  |
| `status` | `character varying(20)` | NOT NULL; default `'ACTIVE'::character varying` |
| `last_run_at` | `timestamp with time zone` |  |
| `next_run_at` | `timestamp with time zone` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `FK (payment_request_id) REFERENCES monetarie_settlement.payment_requests(id)`; `INDEX idx_stl_schedules_date (scheduled_date)`; `INDEX idx_stl_schedules_payreq (payment_request_id)`.

### `monetarie_settlement.situation_classifications`

Catálogo de classificações de situação.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4472`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(20)` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `description` | `character varying(500)` |  |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_stl_sitclass_code (code)`.

### `monetarie_settlement.situation_types`

Catálogo de tipos de situação (com flag final).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4504`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(20)` | NOT NULL |
| `name` | `character varying(100)` | NOT NULL |
| `description` | `character varying(500)` |  |
| `classification_id` | `integer` |  |
| `is_final` | `boolean` | default `false` |

Constraints e índices: `PK (id)`; `FK (classification_id) REFERENCES monetarie_settlement.situation_classifications(id)`; `UNIQUE INDEX idx_stl_sittype_code (code)`.

### `monetarie_settlement.status_types`

Catálogo de status (categoria, flag final, ordenação).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4538`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `integer` | NOT NULL |
| `code` | `character varying(20)` | NOT NULL |
| `description` | `character varying(200)` | NOT NULL |
| `category` | `character varying(50)` |  |
| `is_final` | `boolean` | default `false` |
| `sort_order` | `integer` | default `0` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_settlement_status_types_code (code)`.

### `monetarie_settlement.system_configs`

Configurações chave/valor do sistema (seed 20260703120000).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:4574` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/system_config/system_config.ex:13`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `key` | `character varying(255)` | NOT NULL |
| `value` | `text` | NOT NULL |
| `description` | `character varying(255)` |  |
| `category` | `character varying(255)` | NOT NULL; default `'general'::character varying` |
| `updated_by` | `character varying(255)` | NOT NULL; default `'system'::character varying` |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `UNIQUE INDEX system_configs_key_index (key)`.

### `monetarie_settlement.apix001_files`

Arquivo regulatório mensal APIX001 gerado (período, conteúdo, status).

- Migration: `pix/backend/apps/settlement_service/priv/repo/migrations/20260609130000_create_apix001_files.exs` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/apix/apix_file.ex:30`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `:binary_id` | default `fragment("gen_random_uuid()")`; PK |
| `mes` | `:integer` | NOT NULL |
| `ano` | `:integer` | NOT NULL |
| `nr_spb` | `:string` | NOT NULL |
| `tipo_envio` | `:string` |  |
| `nome_arquivo` | `:string` |  |
| `dados_calculados` | `:map` | NOT NULL; default `%{}` |
| `dados_arquivo` | `:map` | NOT NULL; default `%{}` |
| `ativo` | `:boolean` | NOT NULL; default `true` |
| `created_by_user_id` | `:binary_id` |  |
| `updated_by_user_id` | `:binary_id` |  |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `INDEX [:ano, :mes, :nr_spb]`; `INDEX [:ativo, :inserted_at]`.

### `monetarie_settlement.custom_reports`

Definições salvas de relatórios customizados.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618120000_create_settlement_runtime_tables.exs` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/reports/custom_report.ex:31`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `:binary_id` | default `fragment("gen_random_uuid()")`; PK |
| `name` | `:string` | NOT NULL |
| `report_type` | `:string` | NOT NULL |
| `params` | `:map` | NOT NULL; default `%{}` |
| `owner_id` | `:binary_id` |  |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `INDEX [:owner_id, :inserted_at]`.

### `monetarie_settlement.fee_calculations`

Cálculos de tarifa agregados por período/execução.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618120000_create_settlement_runtime_tables.exs` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/fees/fee_calculation.ex:34`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid PRIMARY KEY DEFAULT gen_random_uuid()` |  |
| `transaction_id` | `uuid NOT NULL` |  |
| `fee_schedule_id` | `bigint REFERENCES monetarie_settlement.fee_tables(id)` |  |
| `participant_ispb` | `varchar(8) NOT NULL` |  |
| `transaction_amount` | `numeric(18,2) NOT NULL` |  |
| `fee_amount` | `numeric(18,4) NOT NULL` |  |
| `fee_type` | `varchar(64) NOT NULL DEFAULT 'standard'` |  |
| `calculation_method` | `varchar(32) NOT NULL DEFAULT 'percentage'` |  |
| `calculated_at` | `timestamp without time zone NOT NULL DEFAULT now()` |  |
| `metadata` | `jsonb NOT NULL DEFAULT '{}'::jsonb` |  |
| `inserted_at` | `timestamp without time zone NOT NULL DEFAULT now()` |  |
| `updated_at` | `timestamp without time zone NOT NULL DEFAULT now()` |  |

### `monetarie_settlement.fee_reports`

Relatórios de tarifas gerados.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618120000_create_settlement_runtime_tables.exs` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/fees/fee_report.ex:37`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid PRIMARY KEY DEFAULT gen_random_uuid()` |  |
| `report_type` | `varchar(32) NOT NULL` |  |
| `session_id` | `uuid` |  |
| `participant_ispb` | `varchar(8)` |  |
| `from_date` | `timestamp without time zone` |  |
| `to_date` | `timestamp without time zone` |  |
| `total_transactions` | `integer NOT NULL DEFAULT 0` |  |
| `total_fees` | `numeric(18,4) NOT NULL DEFAULT 0` |  |
| `total_transaction_volume` | `numeric(18,2) NOT NULL DEFAULT 0` |  |
| `fees_by_type` | `jsonb NOT NULL DEFAULT '{}'::jsonb` |  |
| `fees_by_participant` | `jsonb NOT NULL DEFAULT '{}'::jsonb` |  |
| `generated_at` | `timestamp without time zone NOT NULL DEFAULT now()` |  |
| `metadata` | `jsonb NOT NULL DEFAULT '{}'::jsonb` |  |
| `inserted_at` | `timestamp without time zone NOT NULL DEFAULT now()` |  |
| `updated_at` | `timestamp without time zone NOT NULL DEFAULT now()` |  |

### `monetarie_settlement.generated_reports`

Relatórios gerados (arquivo, formato, status).

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618120000_create_settlement_runtime_tables.exs` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/reports/generated_report.ex:25`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `:binary_id` | default `fragment("gen_random_uuid()")`; PK |
| `report_type` | `:string` | NOT NULL |
| `name` | `:string` |  |
| `params` | `:map` | NOT NULL; default `%{}` |
| `format` | `:string` | NOT NULL; default `"csv"` |
| `status` | `:string` | NOT NULL |
| `content` | `:text` |  |
| `row_count` | `:integer` | NOT NULL; default `0` |
| `error` | `:text` |  |
| `generated_by` | `:binary_id` |  |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `INDEX [:report_type, :inserted_at]`; `INDEX [:status, :inserted_at]`.

### `monetarie_settlement.indirect_participants`

Participantes indiretos gerenciados pela Monetarie no BACEN (reda.016/017/041).

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260629033456_create_indirect_participants.exs` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/reda/indirect_participant.ex:15`

| Coluna | Tipo | Observações |
|---|---|---|
| `indirect_ispb` | `:string` | NOT NULL |
| `indirect_cnpj` | `:string` | NOT NULL |
| `name` | `:string` | NOT NULL |
| `status` | `:string` | NOT NULL; default `"PENDING"` |
| `client_request_id` | `:string` |  |
| `last_request_msg_id` | `:string` |  |
| `last_response_msg_id` | `:string` |  |
| `last_status_reason` | `:string` |  |
| `director_name` | `:string` |  |
| `director_cpf` | `:string` |  |
| `director_phone` | `:string` |  |
| `director_email` | `:string` |  |
| `contact_phone` | `:string` |  |
| `contact_email` | `:string` |  |
| `tech_keyword` | `:string` |  |
| `registered_at` | `:utc_datetime_usec` |  |
| `deregistered_at` | `:utc_datetime_usec` |  |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `UNIQUE INDEX [:indirect_ispb]`; `UNIQUE INDEX [:client_request_id]`; `INDEX [:last_request_msg_id]`; `INDEX [:status]`.

### `monetarie_settlement.reconciliation_discrepancies`

Divergências encontradas pela conciliação.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618120000_create_settlement_runtime_tables.exs` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/reconciliation/discrepancy.ex:49`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid PRIMARY KEY DEFAULT gen_random_uuid()` |  |
| `reconciliation_run_id` | `uuid NOT NULL REFERENCES monetarie_settlement.reconciliation_runs(id) ON DELETE CASCADE` |  |
| `type` | `varchar(64) NOT NULL` |  |
| `severity` | `varchar(32) NOT NULL DEFAULT 'medium'` |  |
| `status` | `varchar(32) NOT NULL DEFAULT 'pending'` |  |
| `transaction_id` | `uuid` |  |
| `local_value` | `text` |  |
| `bacen_value` | `text` |  |
| `amount_difference` | `numeric(18,2)` |  |
| `description` | `text NOT NULL` |  |
| `resolved_at` | `timestamp without time zone` |  |
| `resolved_by` | `varchar(255)` |  |
| `resolution_notes` | `text` |  |
| `resolution_action` | `varchar(500)` |  |
| `metadata` | `jsonb NOT NULL DEFAULT '{}'::jsonb` |  |
| `inserted_at` | `timestamp without time zone NOT NULL DEFAULT now()` |  |
| `updated_at` | `timestamp without time zone NOT NULL DEFAULT now()` |  |

### `monetarie_settlement.reconciliation_matches`

Casamentos bem-sucedidos da conciliação.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618120000_create_settlement_runtime_tables.exs` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/reconciliation/reconciliation_match.ex:31`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid PRIMARY KEY DEFAULT gen_random_uuid()` |  |
| `reconciliation_run_id` | `uuid NOT NULL REFERENCES monetarie_settlement.reconciliation_runs(id) ON DELETE CASCADE` |  |
| `transaction_id` | `uuid` |  |
| `end_to_end_id` | `varchar(64) NOT NULL` |  |
| `amount` | `numeric(18,2) NOT NULL` |  |
| `match_status` | `varchar(32) NOT NULL DEFAULT 'exact'` |  |
| `metadata` | `jsonb NOT NULL DEFAULT '{}'::jsonb` |  |
| `inserted_at` | `timestamp without time zone NOT NULL DEFAULT now()` |  |
| `updated_at` | `timestamp without time zone NOT NULL DEFAULT now()` |  |

### `monetarie_settlement.reconciliation_runs`

Execuções de conciliação.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618120000_create_settlement_runtime_tables.exs` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/reconciliation/reconciliation_run.ex:34`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid PRIMARY KEY DEFAULT gen_random_uuid()` |  |
| `session_id` | `uuid NOT NULL REFERENCES monetarie_settlement.settlement_sessions(id) ON DELETE CASCADE` |  |
| `status` | `varchar(48) NOT NULL DEFAULT 'pending'` |  |
| `started_at` | `timestamp without time zone` |  |
| `completed_at` | `timestamp without time zone` |  |
| `total_transactions` | `integer NOT NULL DEFAULT 0` |  |
| `matched_count` | `integer NOT NULL DEFAULT 0` |  |
| `discrepancy_count` | `integer NOT NULL DEFAULT 0` |  |
| `error_message` | `text` |  |
| `metadata` | `jsonb NOT NULL DEFAULT '{}'::jsonb` |  |
| `inserted_at` | `timestamp without time zone NOT NULL DEFAULT now()` |  |
| `updated_at` | `timestamp without time zone NOT NULL DEFAULT now()` |  |

### `monetarie_settlement.report_schedules`

Agendamento recorrente de geração de relatórios.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618120000_create_settlement_runtime_tables.exs` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/reports/schedule.ex:33`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `:binary_id` | default `fragment("gen_random_uuid()")`; PK |
| `name` | `:string` | NOT NULL |
| `report_type` | `:string` | NOT NULL |
| `params` | `:map` | NOT NULL; default `%{}` |
| `frequency` | `:string` | NOT NULL |
| `active` | `:boolean` | NOT NULL; default `true` |
| `last_run_at` | `:utc_datetime_usec` |  |
| `next_run_at` | `:utc_datetime_usec` |  |
| `created_by` | `:binary_id` |  |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |

Constraints e índices: `INDEX [:active, :next_run_at]`.

### `monetarie_settlement.settlement_sessions`

Sessões de liquidação.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618120000_create_settlement_runtime_tables.exs` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/sessions/session.ex:40`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `:binary_id` | PK |
| `type` | `:string` | NOT NULL |
| `status` | `:string` | NOT NULL; default `"scheduled"` |
| `settlement_date` | `:date` | NOT NULL |
| `scheduled_at` | `:utc_datetime_usec` |  |
| `opened_at` | `:utc_datetime_usec` |  |
| `closed_at` | `:utc_datetime_usec` |  |
| `finalized_at` | `:utc_datetime_usec` |  |
| `cancelled_at` | `:utc_datetime_usec` |  |
| `cancellation_reason` | `:text` |  |
| `total_transactions` | `:integer` | NOT NULL; default `0` |
| `total_amount` | `:decimal` | NOT NULL; default `0` |
| `participant_count` | `:integer` | NOT NULL; default `0` |
| `metadata` | `:map` | NOT NULL; default `%{}` |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime |

Constraints e índices: `UNIQUE INDEX [:type, :settlement_date]`.

### `monetarie_settlement.settlement_transactions`

Transações dentro de uma sessão de liquidação.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618120000_create_settlement_runtime_tables.exs` | Ecto: `pix/backend/apps/settlement_service/lib/settlement_service/sessions/transaction.ex:36`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid PRIMARY KEY DEFAULT gen_random_uuid()` |  |
| `session_id` | `uuid NOT NULL REFERENCES monetarie_settlement.settlement_sessions(id) ON DELETE CASCADE` |  |
| `end_to_end_id` | `varchar(64) NOT NULL` |  |
| `participant_ispb` | `varchar(8) NOT NULL` |  |
| `counterparty_ispb` | `varchar(8) NOT NULL` |  |
| `direction` | `varchar(16) NOT NULL` |  |
| `amount` | `numeric(18,2) NOT NULL` |  |
| `currency` | `varchar(3) NOT NULL DEFAULT 'BRL'` |  |
| `status` | `varchar(32) NOT NULL DEFAULT 'pending'` |  |
| `original_payment_id` | `varchar(128)` |  |
| `metadata` | `jsonb NOT NULL DEFAULT '{}'::jsonb` |  |
| `inserted_at` | `timestamp without time zone NOT NULL DEFAULT now()` |  |
| `updated_at` | `timestamp without time zone NOT NULL DEFAULT now()` |  |

## Schema `monetarie_audit`

Auditoria de tráfego BACEN.

### `monetarie_audit.audit_daily_summary`

Agregado diário de tráfego por tipo/direção (contagens, bytes, latências p95/p99).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1119`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `summary_date` | `date` | NOT NULL |
| `ispb` | `character varying(8)` | NOT NULL |
| `message_type` | `character varying(50)` | NOT NULL |
| `direction` | `character varying(10)` | NOT NULL |
| `total_count` | `integer` | NOT NULL; default `0` |
| `success_count` | `integer` | NOT NULL; default `0` |
| `error_count` | `integer` | NOT NULL; default `0` |
| `total_xml_bytes` | `bigint` | NOT NULL; default `0` |
| `avg_xml_bytes` | `integer` | NOT NULL; default `0` |
| `avg_response_time_ms` | `integer` |  |
| `min_response_time_ms` | `integer` |  |
| `max_response_time_ms` | `integer` |  |
| `p95_response_time_ms` | `integer` |  |
| `p99_response_time_ms` | `integer` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_audit_daily_key (summary_date, ispb, message_type, direction)`.

### `monetarie_audit.bacen_api_validations`

Resultados de validação das chamadas às APIs do BACEN.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1144` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/audit/bacen_validation.ex:17`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `audit_log_id` | `uuid` |  |
| `operation_id` | `bigint` |  |
| `message_type` | `character varying(20)` | NOT NULL |
| `direction` | `character varying(10)` | NOT NULL |
| `validation_type` | `character varying(20)` | NOT NULL |
| `validation_result` | `character varying(10)` | NOT NULL |
| `xsd_version` | `character varying(20)` |  |
| `error_code` | `character varying(50)` |  |
| `error_details` | `text` |  |
| `header_values` | `jsonb` | default `'{}'::jsonb` |
| `xml_hash` | `character varying(128)` |  |
| `validated_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `inserted_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `FK (audit_log_id) REFERENCES monetarie_audit.xml_audit_logs(id)`; `INDEX idx_audit_validations_log (audit_log_id)`; `INDEX idx_audit_validations_result (validation_result)`; `INDEX idx_audit_validations_time (validated_at DESC)`; `INDEX idx_audit_validations_type (message_type)`.

### `monetarie_audit.operation_types`

Catálogo de tipos de operação com prazo de retenção (anos) e flag financeira.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1166`

| Coluna | Tipo | Observações |
|---|---|---|
| `code` | `character varying(20)` | NOT NULL |
| `description` | `character varying(255)` | NOT NULL |
| `retention_years` | `integer` | NOT NULL |
| `is_financial` | `boolean` | NOT NULL; default `false` |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (code)`.

### `monetarie_audit.retention_jobs`

Execuções de expurgo/arquivamento conforme política de retenção.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1276`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `job_type` | `character varying(20)` | NOT NULL |
| `status` | `character varying(20)` | NOT NULL |
| `target_date` | `date` | NOT NULL |
| `retention_years` | `integer` | NOT NULL |
| `records_processed` | `integer` | default `0` |
| `records_archived` | `integer` | default `0` |
| `records_purged` | `integer` | default `0` |
| `archive_path` | `character varying(500)` |  |
| `error_message` | `text` |  |
| `retry_count` | `integer` | default `0` |
| `scheduled_at` | `timestamp with time zone` | NOT NULL |
| `started_at` | `timestamp with time zone` |  |
| `completed_at` | `timestamp with time zone` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `INDEX idx_audit_retjobs_scheduled (scheduled_at)`; `INDEX idx_audit_retjobs_status (status)`.

### `monetarie_audit.xml_audit_logs`

Auditoria de todo XML trafegado com o BACEN; fonte do Monitor de operações (agrupamento por E2E).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1179` | Ecto: `pix/backend/apps/shared/lib/shared/schemas/audit/xml_audit_log.ex:17`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `message_type` | `character varying(50)` | NOT NULL |
| `direction` | `character varying(10)` | NOT NULL |
| `full_xml` | `text` | NOT NULL |
| `xml_size_bytes` | `integer` | NOT NULL |
| `signature_id` | `character varying(255)` |  |
| `signature_algorithm` | `character varying(100)` |  |
| `signature_valid` | `boolean` |  |
| `certificate_thumbprint` | `character varying(128)` |  |
| `headers` | `jsonb` | NOT NULL; default `'{}'::jsonb` |
| `pi_resource_id` | `character varying(255)` |  |
| `pi_requesting_participant` | `character varying(20)` |  |
| `pi_payer_id` | `character varying(100)` |  |
| `pi_end_to_end_id` | `character varying(50)` |  |
| `ispb_sender` | `character varying(8)` | NOT NULL |
| `ispb_receiver` | `character varying(8)` | NOT NULL |
| `end_to_end_id` | `character varying(50)` |  |
| `tx_id` | `character varying(50)` |  |
| `correlation_id` | `character varying(100)` |  |
| `http_method` | `character varying(10)` |  |
| `http_path` | `character varying(500)` |  |
| `http_status_code` | `integer` |  |
| `response_time_ms` | `integer` |  |
| `error_code` | `character varying(50)` |  |
| `error_message` | `text` |  |
| `retention_years` | `integer` | NOT NULL; default `10` |
| `retention_expires_at` | `timestamp with time zone` | NOT NULL |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `received_at` | `timestamp with time zone` |  |
| `processed_at` | `timestamp with time zone` |  |
| `archived_at` | `timestamp with time zone` |  |
| `archived_to` | `character varying(500)` |  |

Constraints e índices: `PK (id)`; `INDEX idx_audit_xml_corr (correlation_id)`; `INDEX idx_audit_xml_created (created_at DESC)`; `INDEX idx_audit_xml_direction (direction)`; `INDEX idx_audit_xml_e2e (end_to_end_id)`; `INDEX idx_audit_xml_http (http_status_code)`; `INDEX idx_audit_xml_receiver (ispb_receiver)`; `INDEX idx_audit_xml_retention (retention_expires_at)`; `INDEX idx_audit_xml_sender (ispb_sender)`; `INDEX idx_audit_xml_txid (tx_id)`; `INDEX idx_audit_xml_type (message_type)`.

## Schema `monetarie_auth`

Autenticação, RBAC e administração.

### `monetarie_auth.activity_log` (PARTICIONADA: RANGE `created_at`)

Log de atividade de usuários (ação, entidade, diff, IP).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1299`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `user_id` | `bigint` |  |
| `action` | `character varying(255)` | NOT NULL |
| `entity_type` | `character varying(255)` |  |
| `entity_id` | `uuid` |  |
| `changes` | `jsonb` |  |
| `ip_address` | `inet` |  |
| `user_agent` | `text` |  |
| `created_at` | `timestamp(6) without time zone` | NOT NULL; default `(now() AT TIME ZONE 'utc'::text)` |

Constraints e índices: `PK (id, created_at)`; `FK (user_id) REFERENCES monetarie_auth.users(id) ON DELETE SET NULL`; `INDEX activity_log_action_index (action)`; `INDEX activity_log_created_at_index (created_at)`; `INDEX activity_log_entity_type_entity_id_index (entity_type, entity_id)`; `INDEX activity_log_user_id_index (user_id)`.

Partições filhas no dump: activity_log_2026_01, activity_log_2026_02, activity_log_2026_03, activity_log_2026_04, activity_log_default (novos filhos mensais criados pelo `Shared.PartitionManager`).

### `monetarie_auth.audit_logs`

Trilha de auditoria de ações administrativas.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1402` | Ecto: `pix/backend/apps/shared/lib/shared/auth/audit_log.ex:17`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `entity_id` | `uuid` |  |
| `user_id` | `uuid` |  |
| `session_id` | `uuid` |  |
| `action` | `character varying(255)` | NOT NULL |
| `resource_type` | `character varying(255)` | NOT NULL |
| `resource_id` | `uuid` |  |
| `ip_address` | `character varying(255)` |  |
| `user_agent` | `character varying(255)` |  |
| `request_data` | `jsonb` |  |
| `response_status` | `integer` |  |
| `created_at` | `timestamp(0) without time zone` |  |

Constraints e índices: `PK (id)`; `INDEX audit_logs_action_index (action)`; `INDEX audit_logs_created_at_index (created_at)`; `INDEX audit_logs_resource_type_index (resource_type)`; `INDEX audit_logs_user_id_index (user_id)`.

### `monetarie_auth.branches`

Agências da instituição.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1422`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `institution_id` | `uuid` | NOT NULL |
| `code` | `character varying(255)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `address` | `text` |  |
| `city` | `character varying(255)` |  |
| `state` | `character varying(255)` |  |
| `postal_code` | `character varying(255)` |  |
| `phone` | `character varying(255)` |  |
| `is_active` | `boolean` | NOT NULL; default `true` |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `FK (institution_id) REFERENCES monetarie_auth.institutions(id) ON DELETE CASCADE`; `UNIQUE INDEX branches_institution_id_code_index (institution_id, code)`; `INDEX branches_is_active_index (is_active)`.

### `monetarie_auth.entities`

Entidades organizacionais.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1443`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `code` | `character varying(255)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `description` | `text` |  |
| `entity_type` | `character varying(255)` |  |
| `is_active` | `boolean` | NOT NULL; default `true` |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `UNIQUE INDEX entities_code_index (code)`.

### `monetarie_auth.entity_systems`

Vínculo entidade-sistema.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1460`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `entity_id` | `uuid` | NOT NULL |
| `system_id` | `uuid` | NOT NULL |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `FK (entity_id) REFERENCES monetarie_auth.entities(id) ON DELETE CASCADE`; `FK (system_id) REFERENCES monetarie_auth.systems(id) ON DELETE CASCADE`; `UNIQUE INDEX entity_systems_entity_id_system_id_index (entity_id, system_id)`; `INDEX entity_systems_system_id_index (system_id)`.

### `monetarie_auth.features`

Features RBAC (páginas/funcionalidades dentro de um módulo).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1474` | Ecto: `pix/backend/apps/shared/lib/shared/auth/feature.ex:14`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `module_id` | `uuid` | NOT NULL |
| `code` | `character varying(255)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `description` | `text` |  |
| `feature_type` | `character varying(255)` |  |
| `route_path` | `character varying(255)` |  |
| `component` | `character varying(255)` |  |
| `icon` | `character varying(255)` |  |
| `display_order` | `integer` | default `0` |
| `is_active` | `boolean` | NOT NULL; default `true` |
| `requires_permission` | `boolean` | NOT NULL; default `true` |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `FK (module_id) REFERENCES monetarie_auth.modules(id) ON DELETE CASCADE`; `UNIQUE INDEX features_code_index (code)`; `INDEX features_display_order_index (display_order)`; `INDEX features_module_id_index (module_id)`.

### `monetarie_auth.group_features`

Junção grupo-feature com 7 flags de ação (visualizar, criar, editar, excluir, aprovar, exportar, executar).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1497` | Ecto: `pix/backend/apps/shared/lib/shared/auth/group_feature.ex:15`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `group_id` | `uuid` | NOT NULL |
| `feature_id` | `uuid` | NOT NULL |
| `can_view` | `boolean` | NOT NULL; default `true` |
| `can_create` | `boolean` | NOT NULL; default `false` |
| `can_update` | `boolean` | NOT NULL; default `false` |
| `can_delete` | `boolean` | NOT NULL; default `false` |
| `can_approve` | `boolean` | NOT NULL; default `false` |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `FK (feature_id) REFERENCES monetarie_auth.features(id) ON DELETE CASCADE`; `FK (group_id) REFERENCES monetarie_auth.groups(id) ON DELETE CASCADE`; `INDEX group_features_feature_id_index (feature_id)`; `UNIQUE INDEX group_features_group_id_feature_id_index (group_id, feature_id)`.

### `monetarie_auth.group_institutions`

Vínculo grupo-instituição.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1516`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `group_id` | `uuid` | NOT NULL |
| `institution_id` | `uuid` | NOT NULL |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `FK (group_id) REFERENCES monetarie_auth.groups(id) ON DELETE CASCADE`; `FK (institution_id) REFERENCES monetarie_auth.institutions(id) ON DELETE CASCADE`; `UNIQUE INDEX group_institutions_group_id_institution_id_index (group_id, institution_id)`; `INDEX group_institutions_institution_id_index (institution_id)`.

### `monetarie_auth.groups`

Grupos RBAC de usuários.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1530` | Ecto: `pix/backend/apps/shared/lib/shared/auth/group.ex:15`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `code` | `character varying(255)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `description` | `text` |  |
| `is_system` | `boolean` | NOT NULL; default `false` |
| `is_active` | `boolean` | NOT NULL; default `true` |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `UNIQUE INDEX groups_code_index (code)`; `INDEX groups_is_active_index (is_active)`.

### `monetarie_auth.institutions`

Instituições (tenants) da cabine.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1547` | Ecto: `pix/backend/apps/shared/lib/shared/auth/institution.ex:19`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `code` | `character varying(255)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `full_name` | `character varying(255)` |  |
| `document_number` | `character varying(255)` |  |
| `participant_code` | `character varying(255)` |  |
| `is_active` | `boolean` | NOT NULL; default `true` |
| `is_direct_participant` | `boolean` | NOT NULL; default `false` |
| `institution_type` | `character varying(255)` |  |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |
| `category` | `character varying(1)` | default `'H'::character varying` |
| `ispb` | `character varying(8)` |  |

Constraints e índices: `PK (id)`; `INDEX institutions_category_index (category)`; `UNIQUE INDEX institutions_code_index (code)`; `INDEX institutions_is_active_index (is_active)`; `UNIQUE INDEX institutions_ispb_index (ispb)`; `INDEX institutions_participant_code_index (participant_code)`.

### `monetarie_auth.login_history` (PARTICIONADA: RANGE `logged_in_at`)

Histórico de logins (sucesso/falha, IP, user agent).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1569`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `user_id` | `bigint` |  |
| `logged_in_at` | `timestamp(6) without time zone` | NOT NULL; default `(now() AT TIME ZONE 'utc'::text)` |
| `logged_out_at` | `timestamp(6) without time zone` |  |
| `ip_address` | `inet` |  |
| `user_agent` | `text` |  |
| `session_token` | `character varying(255)` |  |
| `login_method` | `character varying(50)` |  |
| `is_successful` | `boolean` | default `true` |
| `failure_reason` | `text` |  |
| `metadata` | `jsonb` |  |

Constraints e índices: `PK (id, logged_in_at)`; `FK (user_id) REFERENCES monetarie_auth.users(id) ON DELETE CASCADE`; `INDEX login_history_is_successful_index (is_successful)`; `INDEX login_history_logged_in_at_index (logged_in_at)`; `INDEX login_history_session_token_index (session_token)`; `INDEX login_history_user_id_index (user_id)`.

Partições filhas no dump: login_history_2026_01, login_history_2026_02, login_history_2026_03, login_history_2026_04, login_history_default (novos filhos mensais criados pelo `Shared.PartitionManager`).

### `monetarie_auth.mfa_configurations`

Política de MFA por instituição (métodos permitidos, grupos obrigados).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1684`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `institution_id` | `integer` | NOT NULL |
| `mfa_required` | `boolean` | NOT NULL; default `false` |
| `mfa_grace_period_hours` | `integer` | default `72` |
| `allowed_methods` | `character varying(255)[]` | default `ARRAY['totp'::character varying]` |
| `require_for_groups` | `character varying(255)[]` | default `ARRAY[]::character varying[]` |
| `inserted_at` | `timestamp(0) without time zone` | NOT NULL |
| `updated_at` | `timestamp(0) without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `UNIQUE INDEX mfa_configurations_institution_id_index (institution_id)`.

### `monetarie_auth.mfa_events`

Eventos de MFA por usuário.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1719`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `user_id` | `bigint` | NOT NULL |
| `event_type` | `character varying(255)` | NOT NULL |
| `ip_address` | `character varying(255)` |  |
| `user_agent` | `character varying(255)` |  |
| `metadata` | `jsonb` | default `'{}'::jsonb` |
| `created_at` | `timestamp(0) without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX mfa_events_user_id_created_at_index (user_id, created_at)`.

### `monetarie_auth.modules`

Módulos RBAC (seções de topo: transações, chaves, segurança...).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1753` | Ecto: `pix/backend/apps/shared/lib/shared/auth/module.ex:13`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `code` | `character varying(255)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `description` | `text` |  |
| `icon` | `character varying(255)` |  |
| `display_order` | `integer` | default `0` |
| `is_active` | `boolean` | NOT NULL; default `true` |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `UNIQUE INDEX modules_code_index (code)`; `INDEX modules_display_order_index (display_order)`.

### `monetarie_auth.parameter_groups`

Grupos de parâmetros de configuração.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1771`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `code` | `character varying(255)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `description` | `text` |  |
| `display_order` | `integer` | default `0` |
| `is_active` | `boolean` | NOT NULL; default `true` |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `UNIQUE INDEX parameter_groups_code_index (code)`.

### `monetarie_auth.parameters`

Parâmetros de configuração (com cifragem opcional e regras de validação).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1788`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `parameter_group_id` | `uuid` |  |
| `code` | `character varying(255)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `description` | `text` |  |
| `value` | `text` |  |
| `value_type` | `character varying(255)` |  |
| `default_value` | `text` |  |
| `is_encrypted` | `boolean` | NOT NULL; default `false` |
| `is_system` | `boolean` | NOT NULL; default `false` |
| `is_active` | `boolean` | NOT NULL; default `true` |
| `validation_rules` | `jsonb` |  |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `FK (parameter_group_id) REFERENCES monetarie_auth.parameter_groups(id) ON DELETE CASCADE`; `UNIQUE INDEX parameters_code_index (code)`; `INDEX parameters_parameter_group_id_index (parameter_group_id)`.

### `monetarie_auth.pending_operations`

Operações administrativas pendentes de aprovação (princípio dos 4 olhos).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1811`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `operation_type` | `character varying(255)` | NOT NULL |
| `entity_type` | `character varying(255)` | NOT NULL |
| `entity_id` | `uuid` |  |
| `operation_data` | `jsonb` | NOT NULL |
| `requested_by` | `bigint` |  |
| `requested_at` | `timestamp without time zone` | NOT NULL |
| `approved_by` | `bigint` |  |
| `approved_at` | `timestamp without time zone` |  |
| `rejected_by` | `bigint` |  |
| `rejected_at` | `timestamp without time zone` |  |
| `rejection_reason` | `text` |  |
| `status` | `character varying(255)` | NOT NULL; default `'pending'::character varying` |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `FK (approved_by) REFERENCES monetarie_auth.users(id) ON DELETE SET NULL`; `FK (rejected_by) REFERENCES monetarie_auth.users(id) ON DELETE SET NULL`; `FK (requested_by) REFERENCES monetarie_auth.users(id) ON DELETE SET NULL`; `INDEX pending_operations_entity_type_index (entity_type)`; `INDEX pending_operations_operation_type_index (operation_type)`; `INDEX pending_operations_requested_by_index (requested_by)`; `INDEX pending_operations_status_index (status)`.

### `monetarie_auth.permission_definitions`

Definições de permissão (recurso + ação).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1835`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `code` | `character varying(255)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `description` | `text` |  |
| `resource_type` | `character varying(255)` |  |
| `action` | `character varying(255)` |  |
| `is_active` | `boolean` | NOT NULL; default `true` |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `UNIQUE INDEX permission_definitions_code_index (code)`.

### `monetarie_auth.system_logs`

Logs de sistema persistidos (nível, componente, stack).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1853`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `level` | `character varying(255)` | NOT NULL |
| `message` | `text` | NOT NULL |
| `component` | `character varying(255)` |  |
| `function_name` | `character varying(255)` |  |
| `metadata` | `jsonb` |  |
| `stack_trace` | `text` |  |
| `logged_at` | `timestamp without time zone` | NOT NULL |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX system_logs_component_index (component)`; `INDEX system_logs_level_index (level)`; `INDEX system_logs_logged_at_index (logged_at)`.

### `monetarie_auth.systems`

Sistemas registrados na plataforma.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1871`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `code` | `character varying(255)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `description` | `text` |  |
| `is_active` | `boolean` | NOT NULL; default `true` |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `UNIQUE INDEX systems_code_index (code)`.

### `monetarie_auth.user_groups`

Junção usuário-grupo.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1887` | Ecto: `pix/backend/apps/shared/lib/shared/auth/user_group.ex:12`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `user_id` | `bigint` | NOT NULL |
| `group_id` | `uuid` | NOT NULL |
| `is_primary` | `boolean` | NOT NULL; default `false` |
| `metadata` | `jsonb` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `FK (group_id) REFERENCES monetarie_auth.groups(id) ON DELETE CASCADE`; `FK (user_id) REFERENCES monetarie_auth.users(id) ON DELETE CASCADE`; `INDEX idx_user_groups_group_id (group_id)`; `INDEX idx_user_groups_user_id (user_id)`; `INDEX user_groups_group_id_index (group_id)`; `UNIQUE INDEX user_groups_user_id_group_id_index (user_id, group_id)`.

### `monetarie_auth.users`

Usuários da cabine (login, senha, MFA, must_change_password).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1902` | Ecto: `pix/backend/apps/shared/lib/shared/auth/user.ex:15`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `bigint` | NOT NULL |
| `username` | `character varying(255)` | NOT NULL |
| `email` | `character varying(255)` |  |
| `full_name` | `character varying(255)` |  |
| `password_hash` | `character varying(255)` |  |
| `is_blocked` | `boolean` | default `false` |
| `is_active` | `boolean` | default `true` |
| `last_login` | `timestamp(0) without time zone` |  |
| `password_expires` | `timestamp(0) without time zone` |  |
| `login_attempts` | `integer` | default `0` |
| `keycloak_id` | `character varying(255)` |  |
| `institution_id` | `integer` |  |
| `branch_id` | `integer` |  |
| `created_at` | `timestamp(0) without time zone` |  |
| `updated_at` | `timestamp(0) without time zone` |  |
| `mfa_secret` | `bytea` |  |
| `mfa_enabled` | `boolean` | NOT NULL; default `false` |
| `mfa_verified_at` | `timestamp(0) without time zone` |  |
| `mfa_backup_codes` | `character varying(255)[]` | default `'{}'::character varying[]` |

Constraints e índices: `PK (id)`; `INDEX users_institution_id_index (institution_id)`; `UNIQUE INDEX users_username_index (username)`.

### `monetarie_auth.api_clients`

Credenciais OAuth2 client_credentials para consumidores da API PIX (parceiros).

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618130000_create_api_clients_and_scheduled_message_jobs.exs` | Ecto: `pix/backend/apps/shared/lib/shared/auth/api_client.ex:17`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `:uuid` | NOT NULL; PK |
| `client_id` | `:string` | NOT NULL |
| `client_secret_hash` | `:string` | NOT NULL |
| `name` | `:string` | NOT NULL |
| `ispb` | `:string` | NOT NULL |
| `status` | `:string` | NOT NULL; default `"active"` |
| `description` | `:text` |  |
| `created_by_user_id` | `:bigint` |  |
| `last_used_at` | `:utc_datetime_usec` |  |
| `last_rotated_at` | `:utc_datetime_usec` |  |
| `inserted_at / updated_at` | `timestamps Ecto` | type: :utc_datetime_usec |
| `client_id` | `varchar` | adicionada por `20260618131000_ensure_api_clients_and_scheduled_message_jobs.exs` |

Constraints e índices: `UNIQUE INDEX [:client_id]`; `INDEX [:status]`; `INDEX [:ispb]`.

## Schema `monetarie_webhook`

Webhooks (infra de dados; dispatch é do Core).

### `monetarie_webhook.delivery_log`

Log de entregas de webhook a participantes (request/response, tentativas, erro). Sem produtor ativo na cabine hoje (o dispatch a parceiros é do Core).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6736`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `participant_ispb` | `character varying(8)` | NOT NULL |
| `event_id` | `character varying(50)` | NOT NULL |
| `event_type` | `character varying(50)` | NOT NULL |
| `endpoint` | `character varying(500)` | NOT NULL |
| `request_body` | `jsonb` |  |
| `request_headers` | `jsonb` |  |
| `request_timestamp` | `timestamp with time zone` | NOT NULL |
| `response_status` | `integer` |  |
| `response_body` | `text` |  |
| `response_timestamp` | `timestamp with time zone` |  |
| `status` | `character varying(20)` | NOT NULL; default `'PENDING'::character varying` |
| `attempt_count` | `integer` | NOT NULL; default `0` |
| `last_error` | `text` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |

Constraints e índices: `PK (id)`; `INDEX idx_webhook_delivery_event (event_type)`; `INDEX idx_webhook_delivery_ispb (participant_ispb)`; `INDEX idx_webhook_delivery_status (status)`; `INDEX idx_webhook_delivery_time (created_at DESC)`.

### `monetarie_webhook.participants`

Cadastro de participantes de webhook (endpoints por evento payin/payout/refund/infraction, segredo, mTLS, rate limit).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6759`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `ispb` | `character varying(8)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `secret_key_hash` | `character varying(255)` | NOT NULL |
| `enabled` | `boolean` | NOT NULL; default `true` |
| `endpoint_payin` | `character varying(500)` |  |
| `endpoint_payout` | `character varying(500)` |  |
| `endpoint_refund` | `character varying(500)` |  |
| `endpoint_infraction` | `character varying(500)` |  |
| `rate_limit_per_minute` | `integer` | NOT NULL; default `1000` |
| `mtls_enabled` | `boolean` | NOT NULL; default `false` |
| `mtls_cert_fingerprint` | `character varying(64)` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `now()` |
| `created_by` | `character varying(100)` |  |
| `updated_by` | `character varying(100)` |  |

Constraints e índices: `PK (id)`; `UNIQUE INDEX idx_webhook_part_ispb (ispb)`.

## Schema `bacen_simulator`

Simulador BACEN (apenas dev/homolog; `SIMULATOR_ENABLED=false` nos ambientes reais).

### `bacen_simulator.async_responses`

Respostas assíncronas programadas do simulador BACEN.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:596` | Ecto: `pix/backend/apps/shared/lib/shared/bacen/simulator/schemas.ex:265`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `message_exchange_id` | `uuid` | NOT NULL |
| `response_type` | `character varying(50)` | NOT NULL |
| `scheduled_at` | `timestamp with time zone` | NOT NULL |
| `sent_at` | `timestamp with time zone` |  |
| `status` | `character varying(50)` | NOT NULL; default `'PENDING'::character varying` |
| `response_data` | `jsonb` | NOT NULL |
| `error_message` | `text` |  |
| `retry_count` | `integer` | NOT NULL; default `0` |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `FK (message_exchange_id) REFERENCES bacen_simulator.message_exchanges(id) ON DELETE CASCADE`; `INDEX async_responses_scheduled_at_index (scheduled_at)`; `INDEX async_responses_status_index (status)`; `CONSTRAINT async_responses_status_check CHECK (((status)::text = ANY ((ARRAY['PENDING'::character varying, 'SENT'::character varying, 'FAILED'::character varying, 'CANCELLED'::character varying])::text[])))`.

### `bacen_simulator.bacen_reason_codes`

Catálogo de reason codes usado pelo simulador.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:615`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `reason_code` | `character varying(50)` | NOT NULL |
| `message_type` | `character varying(50)` | NOT NULL |
| `description` | `text` | NOT NULL |
| `is_active` | `boolean` | NOT NULL; default `true` |
| `severity` | `character varying(50)` | NOT NULL |
| `category` | `character varying(100)` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX bacen_reason_codes_reason_code_message_type_index (reason_code, message_type)`; `CONSTRAINT bacen_reason_codes_severity_check CHECK (((severity)::text = ANY ((ARRAY['ERROR'::character varying, 'WARNING'::character varying, 'INFO'::character varying])::text[])))`.

### `bacen_simulator.dict_claims`

Reivindicações simuladas no DICT fake.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:632`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `claim_id` | `character varying(100)` | NOT NULL |
| `key` | `character varying(255)` | NOT NULL |
| `claim_type` | `character varying(50)` | NOT NULL |
| `donor_ispb` | `character varying(8)` | NOT NULL |
| `claimer_ispb` | `character varying(8)` | NOT NULL |
| `status` | `character varying(50)` | NOT NULL; default `'OPEN'::character varying` |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `donor_deadline` | `timestamp with time zone` |  |
| `claimer_deadline` | `timestamp with time zone` |  |
| `confirmed_at` | `timestamp with time zone` |  |
| `completed_at` | `timestamp with time zone` |  |

Constraints e índices: `PK (id)`; `UNIQUE INDEX dict_claims_claim_id_index (claim_id)`; `INDEX dict_claims_key_index (key)`; `INDEX dict_claims_status_index (status)`; `CONSTRAINT dict_claims_claim_type_check CHECK (((claim_type)::text = ANY ((ARRAY['OWNERSHIP'::character varying, 'PORTABILITY'::character varying])::text[])))`; `CONSTRAINT dict_claims_status_check CHECK (((status)::text = ANY ((ARRAY['OPEN'::character varying, 'WAITING_RESOLUTION'::character varying, 'CONFIRMED'::character varying, 'COMPLETED'::character varying, 'CANCELLED'::character varying])::text[])))`.

### `bacen_simulator.dict_entries`

Vínculos (chaves) simulados no DICT fake.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:654` | Ecto: `pix/backend/apps/shared/lib/shared/bacen/simulator/schemas.ex:293`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `key` | `character varying(255)` | NOT NULL |
| `key_type` | `character varying(50)` | NOT NULL |
| `account_type` | `character varying(50)` | NOT NULL |
| `ispb` | `character varying(8)` | NOT NULL |
| `branch` | `character varying(10)` | NOT NULL |
| `account_number` | `character varying(20)` | NOT NULL |
| `tax_id` | `character varying(14)` | NOT NULL |
| `owner_name` | `character varying(255)` | NOT NULL |
| `status` | `character varying(50)` | NOT NULL; default `'ACTIVE'::character varying` |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `INDEX dict_entries_ispb_index (ispb)`; `UNIQUE INDEX dict_entries_key_index (key)`; `INDEX dict_entries_tax_id_index (tax_id)`; `CONSTRAINT dict_entries_account_type_check CHECK (((account_type)::text = ANY ((ARRAY['CACC'::character varying, 'SLRY'::character varying, 'SVGS'::character varying, 'TRAN'::character varying])::text[])))`; `CONSTRAINT dict_entries_key_type_check CHECK (((key_type)::text = ANY ((ARRAY['CPF'::character varying, 'CNPJ'::character varying, 'PHONE'::character varying, 'EMAIL'::character varying, 'EVP'::character varying])::text[])))`; `CONSTRAINT dict_entries_status_check CHECK (((status)::text = ANY ((ARRAY['ACTIVE'::character varying, 'INACTIVE'::character varying, 'BLOCKED'::character varying])::text[])))`.

### `bacen_simulator.dict_query_metrics`

Métricas de consulta do DICT simulado.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:677`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `ispb` | `character varying(8)` | NOT NULL |
| `query_date` | `date` | NOT NULL |
| `total_queries` | `integer` | NOT NULL; default `0` |
| `not_found_queries` | `integer` | NOT NULL; default `0` |
| `not_found_ratio` | `numeric(5,4)` | NOT NULL; default `0.0` |
| `alert_triggered` | `boolean` | NOT NULL; default `false` |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `INDEX dict_query_metrics_alert_triggered_index (alert_triggered)`; `UNIQUE INDEX dict_query_metrics_ispb_query_date_index (ispb, query_date)`.

### `bacen_simulator.dict_token_buckets`

Buckets de rate limit do DICT simulado.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:694`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `ispb` | `character varying(8)` | NOT NULL |
| `participant_capacity` | `integer` | NOT NULL |
| `participant_tokens` | `integer` | NOT NULL |
| `participant_refill_rate` | `integer` | NOT NULL |
| `last_refill` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX dict_token_buckets_ispb_index (ispb)`.

### `bacen_simulator.funds_recoveries`

Recuperações de fundos (MED) simuladas.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:710`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `recovery_id` | `character varying(100)` | NOT NULL |
| `status` | `character varying(50)` | NOT NULL; default `'CREATED'::character varying` |
| `fraud_type` | `character varying(50)` | NOT NULL |
| `victim_ispb` | `character varying(8)` | NOT NULL |
| `fraudster_ispb` | `character varying(8)` |  |
| `total_amount` | `numeric(15,2)` | NOT NULL |
| `recovered_amount` | `numeric(15,2)` | NOT NULL; default `0.0` |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX funds_recoveries_recovery_id_index (recovery_id)`; `INDEX funds_recoveries_status_index (status)`; `CONSTRAINT funds_recoveries_fraud_type_check CHECK (((fraud_type)::text = ANY ((ARRAY['FRAUDULENT_ACCESS'::character varying, 'SCAM'::character varying, 'ACCOUNT_TAKEOVER'::character varying, 'OTHER'::character varying])::text[])))`; `CONSTRAINT funds_recoveries_status_check CHECK (((status)::text = ANY ((ARRAY['CREATED'::character varying, 'TRACKED'::character varying, 'AWAITING_ANALYSIS'::character varying, 'ANALYSED'::character varying, 'REFUNDING'::character varying, 'COMPLETED'::character varying, 'CANCELLED'::character varying])::text[])))`.

### `bacen_simulator.infraction_reports`

Relatos de infração simulados.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:730`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `funds_recovery_id` | `uuid` | NOT NULL |
| `report_id` | `character varying(100)` | NOT NULL |
| `reported_ispb` | `character varying(8)` | NOT NULL |
| `infraction_type` | `character varying(50)` | NOT NULL |
| `description` | `text` | NOT NULL |
| `status` | `character varying(50)` | NOT NULL; default `'REPORTED'::character varying` |
| `reported_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `analysed_at` | `timestamp with time zone` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `FK (funds_recovery_id) REFERENCES bacen_simulator.funds_recoveries(id) ON DELETE CASCADE`; `INDEX infraction_reports_funds_recovery_id_index (funds_recovery_id)`; `UNIQUE INDEX infraction_reports_report_id_index (report_id)`; `INDEX infraction_reports_reported_ispb_index (reported_ispb)`; `CONSTRAINT infraction_reports_status_check CHECK (((status)::text = ANY ((ARRAY['REPORTED'::character varying, 'UNDER_ANALYSIS'::character varying, 'CONFIRMED'::character varying, 'REJECTED'::character varying, 'CLOSED'::character varying])::text[])))`.

### `bacen_simulator.message_exchanges`

Troca de mensagens simuladas (request/response por tipo).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:749` | Ecto: `pix/backend/apps/shared/lib/shared/bacen/simulator/schemas.ex:178`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `message_id` | `character varying(100)` | NOT NULL |
| `message_type` | `character varying(50)` | NOT NULL |
| `direction` | `character varying(50)` | NOT NULL |
| `sender_ispb` | `character varying(8)` | NOT NULL |
| `receiver_ispb` | `character varying(8)` | NOT NULL |
| `request_xml` | `text` | NOT NULL |
| `response_xml` | `text` |  |
| `status` | `character varying(50)` | NOT NULL; default `'PENDING'::character varying` |
| `http_status` | `integer` |  |
| `response_time_ms` | `integer` |  |
| `error_code` | `character varying(50)` |  |
| `error_message` | `text` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `completed_at` | `timestamp with time zone` |  |

Constraints e índices: `PK (id)`; `INDEX message_exchanges_created_at_index (created_at)`; `UNIQUE INDEX message_exchanges_message_id_index (message_id)`; `INDEX message_exchanges_message_type_index (message_type)`; `INDEX message_exchanges_sender_ispb_index (sender_ispb)`; `CONSTRAINT message_exchanges_direction_check CHECK (((direction)::text = ANY ((ARRAY['INBOUND'::character varying, 'OUTBOUND'::character varying])::text[])))`; `CONSTRAINT message_exchanges_status_check CHECK (((status)::text = ANY ((ARRAY['PENDING'::character varying, 'PROCESSING'::character varying, 'COMPLETED'::character varying, 'FAILED'::character varying])::text[])))`.

### `bacen_simulator.message_validations`

Resultados de validação de mensagens no simulador.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:774` | Ecto: `pix/backend/apps/shared/lib/shared/bacen/simulator/schemas.ex:215`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `message_exchange_id` | `uuid` | NOT NULL |
| `validation_type` | `character varying(50)` | NOT NULL |
| `field_path` | `character varying(255)` | NOT NULL |
| `validation_rule` | `text` | NOT NULL |
| `is_valid` | `boolean` | NOT NULL |
| `error_message` | `text` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `FK (message_exchange_id) REFERENCES bacen_simulator.message_exchanges(id) ON DELETE CASCADE`; `INDEX message_validations_is_valid_index (is_valid)`; `INDEX message_validations_message_exchange_id_index (message_exchange_id)`; `CONSTRAINT message_validations_validation_type_check CHECK (((validation_type)::text = ANY ((ARRAY['SCHEMA'::character varying, 'BUSINESS_RULE'::character varying, 'FIELD_FORMAT'::character varying, 'SIGNATURE'::character varying])::text[])))`.

### `bacen_simulator.refund_requests`

Pedidos de devolução simulados.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:791`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `funds_recovery_id` | `uuid` | NOT NULL |
| `refund_id` | `character varying(100)` | NOT NULL |
| `from_ispb` | `character varying(8)` | NOT NULL |
| `to_ispb` | `character varying(8)` | NOT NULL |
| `amount` | `numeric(15,2)` | NOT NULL |
| `status` | `character varying(50)` | NOT NULL; default `'REQUESTED'::character varying` |
| `requested_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `completed_at` | `timestamp with time zone` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `FK (funds_recovery_id) REFERENCES bacen_simulator.funds_recoveries(id) ON DELETE CASCADE`; `INDEX refund_requests_funds_recovery_id_index (funds_recovery_id)`; `UNIQUE INDEX refund_requests_refund_id_index (refund_id)`; `INDEX refund_requests_status_index (status)`; `CONSTRAINT refund_requests_status_check CHECK (((status)::text = ANY ((ARRAY['REQUESTED'::character varying, 'PROCESSING'::character varying, 'COMPLETED'::character varying, 'FAILED'::character varying, 'CANCELLED'::character varying])::text[])))`.

### `bacen_simulator.response_cache`

Cache de respostas do simulador.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:810`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `cache_key` | `character varying(255)` | NOT NULL |
| `response_data` | `jsonb` | NOT NULL |
| `expires_at` | `timestamp with time zone` | NOT NULL |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX response_cache_cache_key_index (cache_key)`; `INDEX response_cache_expires_at_index (expires_at)`.

### `bacen_simulator.response_templates`

Templates de resposta por tipo de mensagem.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:823` | Ecto: `pix/backend/apps/shared/lib/shared/bacen/simulator/schemas.ex:240`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `message_type` | `character varying(50)` | NOT NULL |
| `response_status` | `character varying(50)` | NOT NULL |
| `template_name` | `character varying(100)` | NOT NULL |
| `template_xml` | `text` | NOT NULL |
| `is_default` | `boolean` | NOT NULL; default `false` |
| `description` | `text` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `INDEX response_templates_message_type_index (message_type)`; `UNIQUE INDEX response_templates_message_type_response_status_template_name_i (message_type, response_status, template_name)`.

### `bacen_simulator.scenario_steps`

Passos de cenários de teste roteirizados.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:840` | Ecto: `pix/backend/apps/shared/lib/shared/bacen/simulator/schemas.ex:69`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `scenario_id` | `uuid` | NOT NULL |
| `step_order` | `integer` | NOT NULL |
| `action_type` | `character varying(50)` | NOT NULL |
| `action_config` | `jsonb` | NOT NULL |
| `expected_outcome` | `jsonb` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `FK (scenario_id) REFERENCES bacen_simulator.scenarios(id) ON DELETE CASCADE`; `INDEX scenario_steps_scenario_id_step_order_index (scenario_id, step_order)`.

### `bacen_simulator.scenario_variables`

Variáveis dos cenários.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:855` | Ecto: `pix/backend/apps/shared/lib/shared/bacen/simulator/schemas.ex:95`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `scenario_id` | `uuid` | NOT NULL |
| `variable_name` | `character varying(100)` | NOT NULL |
| `variable_value` | `text` | NOT NULL |
| `variable_type` | `character varying(50)` | NOT NULL |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `FK (scenario_id) REFERENCES bacen_simulator.scenarios(id) ON DELETE CASCADE`; `UNIQUE INDEX scenario_variables_scenario_id_variable_name_index (scenario_id, variable_name)`.

### `bacen_simulator.scenarios`

Cenários de teste do simulador.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:869` | Ecto: `pix/backend/apps/shared/lib/shared/bacen/simulator/schemas.ex:38`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `name` | `character varying(100)` | NOT NULL |
| `description` | `text` |  |
| `is_active` | `boolean` | NOT NULL; default `false` |
| `trigger_type` | `character varying(50)` | NOT NULL |
| `trigger_condition` | `jsonb` |  |
| `priority` | `integer` | NOT NULL; default `0` |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `INDEX scenarios_is_active_index (is_active)`; `UNIQUE INDEX scenarios_name_index (name)`; `INDEX scenarios_priority_index (priority)`.

### `bacen_simulator.simulator_config`

Configuração do simulador (latência, modo).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:886` | Ecto: `pix/backend/apps/shared/lib/shared/bacen/simulator/schemas.ex:14`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `key` | `character varying(100)` | NOT NULL |
| `value` | `text` | NOT NULL |
| `description` | `text` |  |
| `value_type` | `character varying(50)` | NOT NULL |
| `is_encrypted` | `boolean` | NOT NULL; default `false` |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX simulator_config_key_index (key)`; `INDEX simulator_config_value_type_index (value_type)`.

### `bacen_simulator.spi_balances`

Saldos SPI simulados.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:902` | Ecto: `pix/backend/apps/shared/lib/shared/bacen/simulator/schemas.ex:324`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `ispb` | `character varying(8)` | NOT NULL |
| `account_balance` | `numeric(15,2)` | NOT NULL; default `0.0` |
| `settlement_balance` | `numeric(15,2)` | NOT NULL; default `0.0` |
| `blocked_amount` | `numeric(15,2)` | NOT NULL; default `0.0` |
| `available_balance` | `numeric(15,2)` | NOT NULL; default `0.0` |
| `last_updated` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `UNIQUE INDEX spi_balances_ispb_index (ispb)`.

### `bacen_simulator.supported_dict_operations`

Operações DICT suportadas declaradas pelo simulador.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:919`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `operation_name` | `character varying(100)` | NOT NULL |
| `http_method` | `character varying(10)` | NOT NULL |
| `endpoint_path` | `character varying(255)` | NOT NULL |
| `is_enabled` | `boolean` | NOT NULL; default `true` |
| `description` | `text` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `INDEX supported_dict_operations_http_method_index (http_method)`; `UNIQUE INDEX supported_dict_operations_operation_name_index (operation_name)`; `CONSTRAINT supported_dict_operations_http_method_check CHECK (((http_method)::text = ANY ((ARRAY['GET'::character varying, 'POST'::character varying, 'PUT'::character varying, 'PATCH'::character varying, 'DELETE'::character varying])::text[])))`.

### `bacen_simulator.supported_message_types`

Tipos de mensagem suportados pelo simulador.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:935`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `message_type` | `character varying(50)` | NOT NULL |
| `message_category` | `character varying(50)` | NOT NULL |
| `is_enabled` | `boolean` | NOT NULL; default `true` |
| `description` | `text` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `INDEX supported_message_types_message_category_index (message_category)`; `UNIQUE INDEX supported_message_types_message_type_index (message_type)`; `CONSTRAINT supported_message_types_message_category_check CHECK (((message_category)::text = ANY ((ARRAY['SPI'::character varying, 'DICT'::character varying, 'MED'::character varying])::text[])))`.

### `bacen_simulator.test_results`

Resultados individuais de testes do simulador.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:950` | Ecto: `pix/backend/apps/shared/lib/shared/bacen/simulator/schemas.ex:150`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `test_run_id` | `uuid` | NOT NULL |
| `step_order` | `integer` | NOT NULL |
| `message_type` | `character varying(50)` | NOT NULL |
| `request_data` | `jsonb` | NOT NULL |
| `response_data` | `jsonb` |  |
| `status` | `character varying(50)` | NOT NULL |
| `execution_time_ms` | `integer` |  |
| `error_message` | `text` |  |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `FK (test_run_id) REFERENCES bacen_simulator.test_runs(id) ON DELETE CASCADE`; `INDEX test_results_status_index (status)`; `INDEX test_results_test_run_id_step_order_index (test_run_id, step_order)`; `CONSTRAINT test_results_status_check CHECK (((status)::text = ANY ((ARRAY['SUCCESS'::character varying, 'FAILURE'::character varying, 'SKIPPED'::character varying])::text[])))`.

### `bacen_simulator.test_runs`

Execuções de suítes de teste do simulador.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:969` | Ecto: `pix/backend/apps/shared/lib/shared/bacen/simulator/schemas.ex:118`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `scenario_id` | `uuid` |  |
| `name` | `character varying(100)` | NOT NULL |
| `description` | `text` |  |
| `status` | `character varying(50)` | NOT NULL; default `'RUNNING'::character varying` |
| `started_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `completed_at` | `timestamp with time zone` |  |
| `total_messages` | `integer` | NOT NULL; default `0` |
| `successful_messages` | `integer` | NOT NULL; default `0` |
| `failed_messages` | `integer` | NOT NULL; default `0` |
| `created_by` | `character varying(100)` |  |

Constraints e índices: `PK (id)`; `FK (scenario_id) REFERENCES bacen_simulator.scenarios(id) ON DELETE RESTRICT`; `INDEX test_runs_started_at_index (started_at)`; `INDEX test_runs_status_index (status)`; `CONSTRAINT test_runs_status_check CHECK (((status)::text = ANY ((ARRAY['RUNNING'::character varying, 'COMPLETED'::character varying, 'FAILED'::character varying, 'CANCELLED'::character varying])::text[])))`.

### `bacen_simulator.tracking_graph_hops`

Saltos do grafo de rastreamento simulado.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:989`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `tracking_graph_id` | `uuid` | NOT NULL |
| `hop_number` | `integer` | NOT NULL |
| `from_ispb` | `character varying(8)` | NOT NULL |
| `to_ispb` | `character varying(8)` | NOT NULL |
| `amount` | `numeric(15,2)` | NOT NULL |
| `transaction_id` | `character varying(100)` | NOT NULL |
| `timestamp` | `timestamp with time zone` | NOT NULL |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `FK (tracking_graph_id) REFERENCES bacen_simulator.tracking_graphs(id) ON DELETE CASCADE`; `INDEX tracking_graph_hops_tracking_graph_id_hop_number_index (tracking_graph_id, hop_number)`.

### `bacen_simulator.tracking_graphs`

Grafos de rastreamento simulados.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:1006`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL; default `gen_random_uuid()` |
| `funds_recovery_id` | `uuid` | NOT NULL |
| `graph_id` | `character varying(100)` | NOT NULL |
| `total_hops` | `integer` | NOT NULL; default `0` |
| `total_transactions` | `integer` | NOT NULL; default `0` |
| `max_hop_depth` | `integer` | NOT NULL; default `5` |
| `created_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |
| `updated_at` | `timestamp with time zone` | NOT NULL; default `CURRENT_TIMESTAMP` |

Constraints e índices: `PK (id)`; `FK (funds_recovery_id) REFERENCES bacen_simulator.funds_recoveries(id) ON DELETE CASCADE`; `INDEX tracking_graphs_funds_recovery_id_index (funds_recovery_id)`; `UNIQUE INDEX tracking_graphs_graph_id_index (graph_id)`.

### `bacen_simulator.cid_events`

Eventos CID simulados.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618110000_extend_bacen_simulator_med_cid_fraud.exs`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid PRIMARY KEY DEFAULT gen_random_uuid()` |  |
| `file_id` | `uuid NOT NULL REFERENCES bacen_simulator.cid_files(id) ON DELETE CASCADE` |  |
| `event_type` | `varchar(20) NOT NULL` |  |
| `cid` | `varchar(64) NOT NULL` |  |
| `timestamp` | `timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP` |  |
| `created_at` | `timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP` |  |

Constraints e índices: `CONSTRAINT cid_events_type_check CHECK (event_type IN ('ADDED', 'REMOVED', 'UPDATED'))`.

### `bacen_simulator.cid_files`

Arquivos CID simulados.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618110000_extend_bacen_simulator_med_cid_fraud.exs`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid PRIMARY KEY DEFAULT gen_random_uuid()` |  |
| `file_id` | `varchar(100) NOT NULL` |  |
| `participant` | `varchar(8) NOT NULL` |  |
| `key_type` | `varchar(50) NOT NULL` |  |
| `status` | `varchar(50) NOT NULL DEFAULT 'REQUESTED'` |  |
| `request_time` | `timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP` |  |
| `creation_time` | `timestamptz` |  |
| `url` | `text` |  |
| `bytes` | `integer` |  |
| `sha256` | `varchar(64)` |  |
| `created_at` | `timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP` |  |
| `updated_at` | `timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP` |  |

Constraints e índices: `CONSTRAINT cid_files_status_check CHECK (status IN ('REQUESTED', 'PROCESSING', 'AVAILABLE', 'FAILED'))`.

### `bacen_simulator.fraud_markers`

Marcadores de fraude simulados.

- Migration: `pix/backend/apps/shared/priv/repo/migrations/20260618110000_extend_bacen_simulator_med_cid_fraud.exs`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid PRIMARY KEY DEFAULT gen_random_uuid()` |  |
| `fraud_marker_id` | `varchar(100) NOT NULL` |  |
| `participant_ispb` | `varchar(8) NOT NULL` |  |
| `tax_id_number` | `varchar(14) NOT NULL` |  |
| `key_value` | `varchar(255)` |  |
| `fraud_type` | `varchar(50) NOT NULL` |  |
| `details` | `text` |  |
| `request_id` | `varchar(100)` |  |
| `status` | `varchar(50) NOT NULL DEFAULT 'REGISTERED'` |  |
| `created_at` | `timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP` |  |
| `updated_at` | `timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP` |  |
| `cancelled_at` | `timestamptz` |  |

Constraints e índices: `CONSTRAINT fraud_markers_status_check CHECK (status IN ('REGISTERED', 'CANCELLED'))`.

## Schema `public`

Schema public: MED 2.0, limites e Oban.

### `public.med_chain_blocks`

Bloqueios em cadeia MED 2.0 (bloqueio cautelar encadeado).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6783` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/med/chain_block.ex:14`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `claim_id` | `uuid` | NOT NULL |
| `account_id` | `character varying(255)` | NOT NULL |
| `blocked_amount_cents` | `bigint` | NOT NULL |
| `hop_depth` | `integer` | NOT NULL |
| `source_e2e_id` | `character varying(255)` | NOT NULL |
| `status` | `character varying(255)` | NOT NULL; default `'blocked'::character varying` |
| `blocked_at` | `timestamp without time zone` | NOT NULL |
| `released_at` | `timestamp without time zone` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `FK (claim_id) REFERENCES public.med_claims(id) ON DELETE RESTRICT`; `INDEX med_chain_blocks_account_id_index (account_id)`; `INDEX med_chain_blocks_claim_id_index (claim_id)`; `INDEX med_chain_blocks_source_e2e_id_index (source_e2e_id)`; `INDEX med_chain_blocks_status_index (status)`.

### `public.med_claims`

Reivindicações MED 2.0 (Mecanismo Especial de Devolução) no lado SPI.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6802` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/med/claim.ex:14`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `original_e2e_id` | `character varying(255)` | NOT NULL |
| `original_transaction_id` | `uuid` |  |
| `claim_type` | `character varying(255)` | NOT NULL |
| `status` | `character varying(255)` | NOT NULL; default `'open'::character varying` |
| `amount_cents` | `bigint` | NOT NULL |
| `reason_code` | `character varying(255)` | NOT NULL |
| `claimant_ispb` | `character varying(255)` | NOT NULL |
| `respondent_ispb` | `character varying(255)` | NOT NULL |
| `claimant_account` | `character varying(255)` |  |
| `respondent_account` | `character varying(255)` |  |
| `description` | `text` |  |
| `evidence` | `jsonb` | default `'{}'::jsonb` |
| `cautelar_blocked_at` | `timestamp without time zone` |  |
| `cautelar_expires_at` | `timestamp without time zone` |  |
| `claim_deadline` | `timestamp without time zone` |  |
| `resolved_at` | `timestamp without time zone` |  |
| `resolution_notes` | `text` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |
| `opening_reported_at` | `timestamp without time zone` |  |
| `response_deadline` | `timestamp without time zone` |  |
| `monitoring_expires_at` | `timestamp without time zone` |  |
| `escalated` | `boolean` | default `false` |
| `escalation_reason` | `character varying(255)` |  |

Constraints e índices: `PK (id)`; `INDEX med_claims_cautelar_expires_at_index (cautelar_expires_at)`; `INDEX med_claims_claim_deadline_index (claim_deadline)`; `INDEX med_claims_claimant_ispb_index (claimant_ispb)`; `INDEX med_claims_original_e2e_id_index (original_e2e_id)`; `INDEX med_claims_respondent_ispb_index (respondent_ispb)`; `INDEX med_claims_status_index (status)`.

### `public.med_notifications`

Notificações MED 2.0.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6835` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/med/notification.ex:18`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `med_claim_id` | `uuid` | NOT NULL |
| `notification_type` | `character varying(255)` | NOT NULL |
| `direction` | `character varying(255)` | NOT NULL |
| `payload` | `jsonb` | NOT NULL |
| `status` | `character varying(255)` | default `'sent'::character varying` |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `FK (med_claim_id) REFERENCES public.med_claims(id) ON DELETE RESTRICT`; `INDEX med_notifications_med_claim_id_index (med_claim_id)`.

### `public.pix_limits`

Limites transacionais PIX por cliente (Resolução BCB 402: diurno/noturno, cooling de 24h para aumento).

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6851` | Ecto: `pix/backend/apps/spi_service/lib/spi_service/limits/pix_limit.ex:13`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `account_id` | `bigint` | NOT NULL |
| `limit_type` | `character varying(255)` | NOT NULL |
| `amount_cents` | `bigint` | NOT NULL |
| `period` | `character varying(255)` | NOT NULL |
| `active` | `boolean` | default `true` |
| `requested_at` | `timestamp without time zone` |  |
| `effective_at` | `timestamp without time zone` |  |
| `inserted_at` | `timestamp without time zone` | NOT NULL |
| `updated_at` | `timestamp without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `INDEX pix_limits_account_id_index (account_id)`; `UNIQUE INDEX pix_limits_account_id_limit_type_period_index (account_id, limit_type, period)`.

### `public.pix_participants`

Participantes PIX (entidades) no modelo compartilhado.

- DDL: `pix/backend/apps/shared/priv/repo/sql/mon_pix_schema_clean.sql:6869` | Ecto: `pix/backend/apps/shared/lib/shared/participants/participant.ex:14`

| Coluna | Tipo | Observações |
|---|---|---|
| `id` | `uuid` | NOT NULL |
| `ispb` | `character varying(8)` | NOT NULL |
| `name` | `character varying(255)` | NOT NULL |
| `role` | `character varying(255)` | NOT NULL |
| `liquidante_ispb` | `character varying(8)` |  |
| `settlement_account_id` | `bigint` |  |
| `entity_type` | `character varying(255)` | NOT NULL |
| `status` | `character varying(255)` | NOT NULL; default `'active'::character varying` |
| `metadata` | `jsonb` | default `'{}'::jsonb` |
| `inserted_at` | `timestamp(0) without time zone` | NOT NULL |
| `updated_at` | `timestamp(0) without time zone` | NOT NULL |

Constraints e índices: `PK (id)`; `UNIQUE INDEX pix_participants_ispb_index (ispb)`; `INDEX pix_participants_liquidante_ispb_index (liquidante_ispb)`; `INDEX pix_participants_role_index (role)`; `INDEX pix_participants_status_index (status)`.

### `public.oban_jobs` e `public.oban_peers`

Fila de jobs do Oban (outbox NATS `Shared.Workers.Nats.PublishJob`, crons e workers dos 3 apps). Criadas por `Oban.Migrations.up(version: 13)` (`pix/backend/apps/shared/priv/repo/migrations/20260426204500_create_oban_jobs.exs:4`; no-op idempotente em `pix/backend/apps/settlement_service/priv/repo/migrations/20260505000000_create_oban_jobs_settlement.exs:19`). Estrutura padrão Oban v13 (queue, worker, args jsonb, state, attempted_at, scheduled_at etc.); as 3 instâncias Oban (`config :spi_service, Oban` / `:settlement_service, Oban` / `:shared, Oban`, `pix/backend/config/config.exs:69,135,164`) compartilham as mesmas tabelas no prefixo `public`.

---

Total de tabelas lógicas documentadas: 222 (partições filhas mensais contadas junto da tabela-mãe; inclui `oban_jobs`/`oban_peers` e a removida `xsd_schemas`).
