# Modelo de Domínio e Dados

## Convenções

- PK interna: `BIGINT UNSIGNED`.
- Identificador público: UUID/ULID único, nunca sequência previsível isolada.
- FKs obrigatórias e indexadas.
- `created_at`, `updated_at`; `deleted_at` apenas onde restauração faz sentido.
- documentos confirmados usam status/estorno, não soft delete.
- dinheiro: `DECIMAL(19,4)` e currency.
- quantidade: `DECIMAL(20,6)`.
- percentuais: `DECIMAL(9,6)`.
- códigos e enums validados no domínio e por constraints quando possível.
- JSON apenas para payload externo, snapshot e configuração validada.

## Contexto organizacional

Tabelas principais:

- `groups`
- `companies`
- `establishments`
- `warehouses`
- `warehouse_locations`
- `company_modules`
- `document_sequences`
- `cost_centers`
- `projects`

`document_sequences` deve ser bloqueada transacionalmente e possuir empresa, estabelecimento, tipo, série, próximo número e versão.

## Identidade e acesso

- `users`
- `user_sessions`
- `group_memberships`
- `membership_companies`
- `membership_establishments`
- `roles`
- `permissions`
- `role_permissions`
- `membership_roles`
- `membership_permission_overrides`
- `mfa_methods`
- `audit_events`

## Pessoas e parceiros

Usar uma entidade `parties` com papéis, evitando duplicar cliente/fornecedor:

- `parties`
- `party_person_details`
- `party_company_details`
- `party_roles`
- `party_addresses`
- `party_contacts`
- `party_documents`
- `party_bank_accounts`
- `party_company_settings`

Uma mesma pessoa pode ser cliente, fornecedor, transportadora e industrializador. Configurações comerciais/fiscais específicas pertencem à relação com a empresa.

## Catálogo

- `products`
- `product_variants`
- `product_identifiers` (SKU, EAN, código fornecedor)
- `product_categories`
- `brands`
- `units`
- `product_unit_conversions`
- `attribute_definitions`
- `attribute_values`
- `product_variant_attributes`
- `product_images`
- `product_company_settings`
- `product_fiscal_profiles`
- `price_lists`
- `price_list_items`
- `kits`
- `kit_components`

`products` define o conceito; `product_variants` é o item estocável/vendável. Exemplo: produto Tecido Oxford; variante Azul 1,50 m.

Tipos previstos: mercadoria, matéria-prima, insumo, embalagem, intermediário, acabado, componente, serviço, ativo, subproduto.

## Estoque

- `inventory_transactions`
- `inventory_movements`
- `inventory_balance_snapshots`
- `inventory_reservations`
- `inventory_lots`
- `serial_numbers`
- `stock_statuses`
- `inventory_counts`
- `inventory_count_items`
- `stock_transfers`
- `stock_transfer_items`
- `stock_ownerships`

### Ledger

`inventory_transactions` agrupa o documento; `inventory_movements` contém débitos/créditos de quantidade por depósito/local/status/lote/proprietário.

Um movimento contém:

- produto/variante;
- empresa proprietária;
- estabelecimento;
- depósito/local;
- lote/série;
- status de estoque;
- quantidade assinada;
- unidade e fator congelado;
- custo unitário/base;
- origem e ID;
- idempotency key;
- usuário/data.

Saldo atual é projeção. `inventory_balance_snapshots` acelera leitura, mas deve poder ser reconstruído e reconciliado com o ledger.

Status iniciais: disponível, reservado, bloqueado, qualidade, em trânsito, com terceiro, produção em processo, avariado.

## Vendas

- `quotes`, `quote_versions`, `quote_items`
- `sales_orders`, `sales_order_items`
- `sales_order_status_history`
- `sales_order_payments`
- `sales_order_allocations`
- `sales_returns`, `sales_return_items`
- `shipments`, `shipment_items`
- `packages`, `package_items`, `package_labels`

Separar status: comercial, atendimento, estoque, expedição, financeiro e fiscal. Não usar um único status para representar tudo.

## Compras

- `purchase_requests`
- `supplier_quotes`
- `purchase_orders`, `purchase_order_items`
- `goods_receipts`, `goods_receipt_items`
- `purchase_returns`
- `supplier_invoices` como preparação fiscal/financeira.

## Financeiro

- `financial_accounts`
- `financial_categories`
- `financial_titles`
- `financial_installments`
- `financial_settlements`
- `cash_transactions`
- `bank_statement_imports`
- `bank_statement_lines`
- `reconciliations`
- `allocations`

Título mantém origem, contraparte, competência, emissão, vencimento, moeda e empresa. Baixas são registros separados; saldo é valor original acrescido/reduzido por eventos válidos.

## Produção

- `bill_of_materials`
- `bom_versions`
- `bom_components`
- `routings`
- `routing_operations`
- `work_centers`
- `production_orders`
- `production_order_materials`
- `production_order_operations`
- `material_issues`
- `production_outputs`
- `production_losses`
- `production_costs`

BOM e roteiro são versionados; a OP guarda snapshot da versão liberada. Alterar ficha futura não altera OP em andamento.

## Industrialização externa

- `outsourcing_orders`
- `outsourcing_order_inputs`
- `outsourcing_expected_outputs`
- `outsourcing_shipments`
- `outsourcing_shipment_items`
- `outsourcing_receipts`
- `outsourcing_receipt_inputs`
- `outsourcing_receipt_outputs`
- `outsourcing_losses`
- `outsourcing_service_costs`

O retorno deve reconciliar:

`enviado = consumido + devolvido sem transformação + perda aceita + pendente com terceiro`.

O produto resultante recebe lote novo com genealogia para os lotes consumidos.

## Marketplace

- `marketplace_connections`
- `marketplace_accounts`
- `marketplace_category_mappings`
- `marketplace_attribute_mappings`
- `marketplace_listings`
- `marketplace_listing_variants`
- `marketplace_orders`
- `marketplace_order_items`
- `marketplace_shipments`
- `marketplace_sync_states`
- `marketplace_webhook_events`
- `integration_attempts`

Guardar IDs externos e snapshots, mas a entidade externa nunca substitui Pedido de Venda interno. A importação cria/vincula o pedido interno de forma idempotente.

## Fiscal

- `fiscal_profiles`
- `tax_rules`
- `operation_natures`
- `fiscal_certificates`
- `fiscal_documents`
- `fiscal_document_items`
- `fiscal_document_events`
- `fiscal_xml_files`
- `fiscal_number_reservations`

Dados usados na emissão devem ser snapshot: emitente, destinatário, produto, tributos, totais, transporte e pagamento. Nunca depender do cadastro atual para reconstruir uma nota histórica.

## Plataforma e integrações

- `outbox_events`
- `queue_jobs`
- `dead_letter_jobs`
- `idempotency_keys`
- `webhook_receipts`
- `files`
- `notifications`
- `scheduled_tasks`
- `system_settings`
- `integration_credentials` criptografada.

## Índices essenciais

- todos os escopos começam por `group_id` e, quando pertinente, `company_id`;
- únicos devem incluir tenant: `(group_id, code)`;
- ledger: `(group_id, company_id, variant_id, warehouse_id, lot_id, occurred_at)`;
- pedidos externos: `(connection_id, external_order_id)` único;
- idempotência: `(group_id, scope, idempotency_key)` único;
- filas: `(status, queue, available_at)`;
- outbox: `(status, occurred_at)`;
- auditoria: `(group_id, created_at, resource_type, resource_id)`.

## Regras de integridade

- empresa pertence ao grupo informado;
- estabelecimento pertence à empresa;
- depósito pertence ao estabelecimento ou tem vínculo explícito;
- todos os itens de documento compartilham grupo e empresa do cabeçalho;
- produto inativo não entra em novo documento, mas permanece histórico;
- quantidade de série é compatível com unidade inteira;
- lote obrigatório conforme configuração do produto;
- somatório de alocações financeiras igual ao valor aplicável;
- documento confirmado exige itens e totais consistentes;
- eventos externos únicos por conta e ID.

## Migrations

Cada arquivo possui número sequencial, descrição, `up()` e `down()` quando seguro. Registrar checksum e tempo em `schema_migrations`. Deploys destrutivos seguem expandir/migrar/contrair, nunca renomear/remover em uma única versão.

