> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devmob.app.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Cooperative and Company Relationship

> Relação 1:N entre cooperativas e empresas de transporte.

## Overview

Uma **Cooperative** representa a organização administradora. Uma **Company** representa a empresa de transporte que opera frota, rotas, viagens, vendas e billing.

A relação é **1:N**:

* Uma `Cooperative` pode administrar zero ou mais `Company`.
* Uma `Company` pertence obrigatoriamente a uma única `Cooperative`.
* O vínculo é persistido em `Company.cooperativeId`.

```mermaid theme={null}
erDiagram
    Organization ||--o| Cooperative : "type COOPERATIVE"
    Organization ||--o| Company : "type COMPANY"
    Cooperative ||--o{ Company : "administra"

    Cooperative {
        UUID cooperativeId
        UUID organizationId
    }

    Company {
        UUID companyId
        UUID organizationId
        UUID cooperativeId
        string anttCode
    }
```

## Responsabilidades

| Entidade       | Responsabilidade                                                                            |
| -------------- | ------------------------------------------------------------------------------------------- |
| `Cooperative`  | Agrupa e administra empresas afiliadas. É o escopo de coordenação e governança.             |
| `Company`      | Opera transporte. É dona de frota, motoristas vinculados, rotas, viagens, vendas e billing. |
| `Organization` | Fornece identidade de tenant, dados cadastrais, roles, memberships e convites.              |

<Info>
  Mesmo vinculada a uma cooperativa, a `Company` continua sendo a unidade operacional e financeira. Dados como `Vehicle`, `Route`, `Trip`, `Order`, `Payment`, `Receivable`, `Transfer`, `BankAccount` e `CompanyPaymentSettings` pertencem à empresa.
</Info>

## Lifecycle

```mermaid theme={null}
flowchart TD
    BACKOFFICE[BackOffice cria Organization COOPERATIVE] --> COOP[Cooperative criada]
    COOP --> COOP_OWNER[Owner recebe Membership na Organization da Cooperative]
    BACKOFFICE_COMPANY[BackOffice cria Organization COMPANY] --> SELECT[Cooperative existente é selecionada]
    SELECT --> COMPANY[Company criada com cooperativeId]
    COMPANY --> COMPANY_OWNER[Owner recebe Membership na Organization da Company]
    COMPANY --> OPS[Company opera frota, rotas, viagens e vendas]
```

1. A cooperativa nasce como uma `Organization` com `type=COOPERATIVE` e extensão `Cooperative`.
2. A empresa nasce como uma `Organization` com `type=COMPANY` e extensão `Company`.
3. A criação da empresa exige uma `Cooperative` ativa.
4. O `cooperativeId` da empresa define a afiliação administrativa.
5. O owner da cooperativa recebe `Membership` na organização da cooperativa.
6. O owner da empresa recebe `Membership` na organização da empresa.

## Regras de negócio

| Regra              | Descrição                                                                                                        |
| ------------------ | ---------------------------------------------------------------------------------------------------------------- |
| Cardinalidade      | Uma cooperativa pode ter N empresas. Uma empresa tem exatamente uma cooperativa.                                 |
| Obrigatoriedade    | `Company.cooperativeId` é obrigatório. Não existe Company órfã.                                                  |
| Tenant próprio     | Cooperative e Company têm `Organization` próprias. Elas não compartilham `organizationId`.                       |
| Escopo operacional | Frota, motoristas, rotas, viagens, tickets e pedidos são sempre filtrados por `companyId`.                       |
| Escopo financeiro  | Billing pertence à Company. Cooperative não recebe pagamentos, recebíveis ou transferências diretamente.         |
| Administração      | Usuários da Cooperative podem administrar empresas afiliadas apenas por capacidades explicitamente permitidas.   |
| Auditoria          | Criação, troca de afiliação, bloqueio ou remoção de Company deve registrar ator, data e motivo quando aplicável. |

## Escopo de acesso

Memberships continuam sendo avaliadas no contexto da `Organization` ativa do usuário.

| Contexto ativo                | Pode acessar                                                                                |
| ----------------------------- | ------------------------------------------------------------------------------------------- |
| `Organization` da Cooperative | Dados administrativos da cooperativa e empresas afiliadas conforme permissions disponíveis. |
| `Organization` da Company     | Operação da própria empresa: frota, rotas, viagens, vendas e billing.                       |
| Sem Membership no contexto    | Nenhum dado privado da cooperativa ou da empresa.                                           |

Quando uma tela de cooperativa lista empresas afiliadas, a consulta deve filtrar por:

```txt theme={null}
Company.cooperativeId = Cooperative.cooperativeId do contexto ativo
```

Quando uma tela operacional da empresa busca recursos, a consulta deve filtrar por:

```txt theme={null}
resource.companyId = Company.companyId do contexto ativo
```

## Mudança de afiliação

A troca de `Company.cooperativeId` é uma operação sensível. O comportamento recomendado é tratar a troca como rotina administrativa controlada, não como edição comum de cadastro.

| Ponto            | Regra                                                                                                |
| ---------------- | ---------------------------------------------------------------------------------------------------- |
| Autorização      | Exigir permission administrativa compatível com BackOffice ou Cooperative.                           |
| Integridade      | A nova Cooperative deve existir, estar ativa e não estar removida.                                   |
| Dados históricos | Registros já criados continuam apontando para a mesma Company. Não reescrever `companyId` histórico. |
| Billing          | Não alterar ownership financeiro. Billing continua pertencendo à Company.                            |
| Auditoria        | Registrar `oldCooperativeId`, `newCooperativeId`, ator, data e motivo.                               |

## Padrões de consulta

### Listar empresas da cooperativa

```txt theme={null}
SELECT Company
WHERE Company.cooperativeId = :activeCooperativeId
  AND Company.deletedAt IS NULL
ORDER BY Company.createdAt DESC
```

### Resolver cooperativa de uma empresa

```txt theme={null}
SELECT Cooperative
JOIN Company ON Company.cooperativeId = Cooperative.cooperativeId
WHERE Company.companyId = :companyId
```

### Validar se uma empresa pertence à cooperativa ativa

```txt theme={null}
EXISTS Company
WHERE Company.companyId = :companyId
  AND Company.cooperativeId = :activeCooperativeId
  AND Company.deletedAt IS NULL
```

## Modelagem relacionada

* [Cooperative](/data-modelling/tenant/cooperative)
* [Company](/data-modelling/tenant/company)
* [Organization](/data-modelling/tenant/organization)
* [Membership](/data-modelling/tenant/membership)
* [Roles & Permissions](/domain/authorization/roles-and-permissions)
