DuOrigin v2 - React + NestJS + Prisma + EUDR API Integration
This commit is contained in:
209
docs/API-ROUTES.md
Normal file
209
docs/API-ROUTES.md
Normal file
@@ -0,0 +1,209 @@
|
||||
# DuOrigin v2 - API Routes
|
||||
|
||||
## Autenticação
|
||||
|
||||
Todas as rotas (exceto login/registro) requerem autenticação via JWT.
|
||||
Header: `Authorization: Bearer <token>`
|
||||
|
||||
### POST /api/auth/login
|
||||
Login de usuário.
|
||||
```json
|
||||
// Request
|
||||
{ "email": "user@email.com", "password": "senha123" }
|
||||
|
||||
// Response
|
||||
{ "success": true, "data": { "accessToken": "jwt...", "tokenType": "bearer" } }
|
||||
```
|
||||
|
||||
### POST /api/auth/registro
|
||||
Registrar novo usuário.
|
||||
```json
|
||||
// Request
|
||||
{ "email": "user@email.com", "password": "senha123", "fullName": "Nome", "role": "operator" }
|
||||
|
||||
// Response
|
||||
{ "success": true, "data": { "id": 1, "email": "...", "fullName": "...", "role": "operator", "isActive": true, "createdAt": "..." } }
|
||||
```
|
||||
|
||||
### GET /api/auth/me
|
||||
Dados do usuário logado.
|
||||
```json
|
||||
// Response
|
||||
{ "success": true, "data": { "id": 1, "email": "...", "fullName": "...", "role": "...", "isActive": true, "createdAt": "..." } }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Empresas (Companies)
|
||||
|
||||
### GET /api/empresas
|
||||
Lista todas as empresas.
|
||||
|
||||
### POST /api/empresas
|
||||
Criar nova empresa.
|
||||
```json
|
||||
{ "name": "Nome", "cnpj": "12345678000190", "country": "BR", "state": "SP", "city": "São Paulo", "euOperatorId": "EU-001" }
|
||||
```
|
||||
|
||||
### GET /api/empresas/[id]
|
||||
Detalhes de uma empresa.
|
||||
|
||||
### PUT /api/empresas/[id]
|
||||
Atualizar empresa.
|
||||
|
||||
### DELETE /api/empresas/[id]
|
||||
Excluir empresa.
|
||||
|
||||
---
|
||||
|
||||
## Propriedades (Producers)
|
||||
|
||||
### GET /api/propriedades
|
||||
Lista todas as propriedades.
|
||||
Query: `?companyId=1` para filtrar por empresa.
|
||||
|
||||
### POST /api/propriedades
|
||||
Criar nova propriedade.
|
||||
```json
|
||||
{ "name": "Nome", "cpfCnpj": "12345678901", "companyId": 1, "state": "MT", "city": "Cuiabá", "carCode": "MT-123" }
|
||||
```
|
||||
|
||||
### GET /api/propriedades/[id]
|
||||
Detalhes de uma propriedade.
|
||||
|
||||
### PUT /api/propriedades/[id]
|
||||
Atualizar propriedade.
|
||||
|
||||
### DELETE /api/propriedades/[id]
|
||||
Excluir propriedade.
|
||||
|
||||
---
|
||||
|
||||
## Avaliações (Areas)
|
||||
|
||||
### GET /api/avaliacoes
|
||||
Lista todas as avaliações/áreas.
|
||||
Query: `?producerId=1` para filtrar por produtor.
|
||||
|
||||
### POST /api/avaliacoes
|
||||
Criar nova avaliação.
|
||||
```json
|
||||
{ "name": "Nome", "producerId": 1, "geojson": "{...}", "areaHa": 100.5, "biome": "Cerrado", "latCenter": -15.0, "lonCenter": -56.0 }
|
||||
```
|
||||
|
||||
### GET /api/avaliacoes/[id]
|
||||
Detalhes de uma avaliação.
|
||||
|
||||
### PUT /api/avaliacoes/[id]
|
||||
Atualizar avaliação.
|
||||
|
||||
### DELETE /api/avaliacoes/[id]
|
||||
Excluir avaliação.
|
||||
|
||||
### POST /api/avaliacoes/[id]/gerar-dds
|
||||
Gerar Due Diligence Statement para a avaliação.
|
||||
```json
|
||||
// Request (opcional)
|
||||
{ "notes": "Observações adicionais" }
|
||||
|
||||
// Response
|
||||
{ "success": true, "data": { "id": 1, "referenceNumber": "DDS-ABC123", "status": "draft", ... } }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dashboard
|
||||
|
||||
### GET /api/dashboard/stats
|
||||
Estatísticas do sistema.
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"totalEmpresas": 10,
|
||||
"totalPropriedades": 50,
|
||||
"totalAvaliacoes": 100,
|
||||
"totalLotes": 200,
|
||||
"totalDds": 25,
|
||||
"ddsByStatus": { "draft": 5, "submitted": 10, "approved": 8, "rejected": 2 },
|
||||
"riskDistribution": { "low": 70, "medium": 20, "high": 8, "critical": 2 },
|
||||
"recentActivity": [...]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Usuários (Admin Only)
|
||||
|
||||
### GET /api/usuarios
|
||||
Lista todos os usuários. Requer role `admin`.
|
||||
|
||||
### GET /api/usuarios/[id]
|
||||
Detalhes de um usuário.
|
||||
|
||||
### PUT /api/usuarios/[id]
|
||||
Atualizar usuário.
|
||||
```json
|
||||
{ "email": "novo@email.com", "fullName": "Novo Nome", "role": "admin", "isActive": true, "password": "novaSenha" }
|
||||
```
|
||||
|
||||
### DELETE /api/usuarios/[id]
|
||||
Excluir usuário (não pode excluir a si mesmo).
|
||||
|
||||
---
|
||||
|
||||
## Formato de Resposta Padrão
|
||||
|
||||
### Sucesso
|
||||
```json
|
||||
{ "success": true, "data": { ... } }
|
||||
```
|
||||
|
||||
### Erro
|
||||
```json
|
||||
{ "success": false, "error": "Mensagem de erro" }
|
||||
```
|
||||
|
||||
## Códigos de Status HTTP
|
||||
|
||||
- `200` - OK
|
||||
- `201` - Created
|
||||
- `400` - Bad Request
|
||||
- `401` - Unauthorized
|
||||
- `403` - Forbidden
|
||||
- `404` - Not Found
|
||||
- `500` - Internal Server Error
|
||||
|
||||
---
|
||||
|
||||
## Estrutura de Arquivos
|
||||
|
||||
```
|
||||
src/app/api/
|
||||
├── auth/
|
||||
│ ├── login/route.ts # POST - Login
|
||||
│ ├── registro/route.ts # POST - Registro
|
||||
│ └── me/route.ts # GET - Dados do usuário
|
||||
├── empresas/
|
||||
│ ├── route.ts # GET list, POST create
|
||||
│ └── [id]/route.ts # GET, PUT, DELETE
|
||||
├── propriedades/
|
||||
│ ├── route.ts # GET list, POST create
|
||||
│ └── [id]/route.ts # GET, PUT, DELETE
|
||||
├── avaliacoes/
|
||||
│ ├── route.ts # GET list, POST create
|
||||
│ ├── [id]/route.ts # GET, PUT, DELETE
|
||||
│ └── [id]/gerar-dds/route.ts # POST - Gerar DDS
|
||||
├── dashboard/
|
||||
│ └── stats/route.ts # GET - Estatísticas
|
||||
└── usuarios/
|
||||
├── route.ts # GET list (admin)
|
||||
└── [id]/route.ts # GET, PUT, DELETE (admin)
|
||||
```
|
||||
|
||||
## Libs Auxiliares
|
||||
|
||||
- `src/lib/prisma.ts` - Prisma Client singleton
|
||||
- `src/lib/auth.ts` - JWT helpers (createToken, verifyToken, requireAuth, requireAdmin)
|
||||
- `src/lib/password.ts` - bcrypt helpers (hashPassword, verifyPassword)
|
||||
527
docs/EUDR-API-INTEGRATION.md
Normal file
527
docs/EUDR-API-INTEGRATION.md
Normal file
@@ -0,0 +1,527 @@
|
||||
# EUDR API Integration - Documentação Técnica
|
||||
|
||||
> **Versão**: 1.4
|
||||
> **Data**: Fevereiro 2026
|
||||
> **Baseado em**: EUDR API EO Specifications v1.4 (22 Julho 2025)
|
||||
|
||||
## 📋 Índice
|
||||
|
||||
1. [Visão Geral](#visão-geral)
|
||||
2. [Ambientes](#ambientes)
|
||||
3. [Autenticação](#autenticação)
|
||||
4. [Serviços da API](#serviços-da-api)
|
||||
5. [Conformance Tests](#conformance-tests)
|
||||
6. [Estrutura XML/SOAP](#estrutura-xmlsoap)
|
||||
7. [GeoJSON para Geolocalização](#geojson-para-geolocalização)
|
||||
8. [Unidades de Medida](#unidades-de-medida)
|
||||
9. [Regras de Validação](#regras-de-validação)
|
||||
10. [Códigos de Erro](#códigos-de-erro)
|
||||
11. [Fluxo de Integração DuOrigin](#fluxo-de-integração-duorigin)
|
||||
|
||||
---
|
||||
|
||||
## Visão Geral
|
||||
|
||||
A API EUDR permite a submissão e gestão de DDS (Due Diligence Statements) de forma automatizada via **SOAP/WSDL** (machine-to-machine). O DuOrigin atua como intermediário entre o operador e a API oficial da UE.
|
||||
|
||||
### Arquitetura
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ Operador │────▶│ DuOrigin │────▶│ EUDR API │
|
||||
│ (Frontend) │ │ (Backend) │ │ (EU Server) │
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
│ │ │
|
||||
Formulário SOAP Client SOAP/WSDL
|
||||
Web UI NestJS XML Messages
|
||||
```
|
||||
|
||||
### Serviços Disponíveis
|
||||
|
||||
| Serviço | Descrição | Versões |
|
||||
|---------|-----------|---------|
|
||||
| `Echo` | Teste de conexão/autenticação | V1 |
|
||||
| `submitDDS` | Submissão de nova DDS | V1, V2 |
|
||||
| `amendDDS` | Alteração de DDS existente | V1, V2 |
|
||||
| `retractDds` | Cancelar/Retirar DDS | V1, V2 |
|
||||
| `getDDSInfo` | Obter status e referência de DDS | V1, V2 |
|
||||
| `getStatementByIdentifiers` | Obter dados completos de DDS | V1, V2 |
|
||||
| `getReferencedDds` | Obter DDS referenciadas na cadeia | V2 |
|
||||
|
||||
---
|
||||
|
||||
## Ambientes
|
||||
|
||||
### Production (Produção)
|
||||
- **URL Base**: `https://webgate.ec.europa.eu/tracesnt/`
|
||||
- **Uso**: DDS com valor legal
|
||||
- **Requisito**: Passar todos os Conformance Tests (CF1-CF7)
|
||||
|
||||
### Acceptance Cloud (Testes)
|
||||
- **URL Base**: `https://acceptance.eudr.webcloud.ec.europa.eu/tracesnt/`
|
||||
- **Uso**: Testes funcionais e Conformance Tests
|
||||
- **WebServiceClientId de Teste**: `eudr-test`
|
||||
|
||||
### URLs dos WSDLs
|
||||
|
||||
**ACCEPTANCE (Testes):**
|
||||
- Submission WS: `https://acceptance.eudr.webcloud.ec.europa.eu/tracesnt/services/EudrSubmissionServiceV1.wsdl`
|
||||
- Submission V2: `https://acceptance.eudr.webcloud.ec.europa.eu/tracesnt/services/EudrSubmissionServiceV2.wsdl`
|
||||
- Retrieval WS: `https://acceptance.eudr.webcloud.ec.europa.eu/tracesnt/services/EudrRetrievalServiceV1.wsdl`
|
||||
- Retrieval V2: `https://acceptance.eudr.webcloud.ec.europa.eu/tracesnt/services/EudrRetrievalServiceV2.wsdl`
|
||||
- Echo WS: `https://acceptance.eudr.webcloud.ec.europa.eu/tracesnt/services/EudrEchoService.wsdl`
|
||||
|
||||
**PRODUCTION (Produção):**
|
||||
- Submission WS: `https://webgate.ec.europa.eu/tracesnt/services/EudrSubmissionServiceV1.wsdl`
|
||||
- Retrieval WS: `https://webgate.ec.europa.eu/tracesnt/services/EudrRetrievalServiceV1.wsdl`
|
||||
- (Echo não disponível em produção)
|
||||
|
||||
---
|
||||
|
||||
## Autenticação
|
||||
|
||||
A API utiliza **WS-Security UsernameToken com Digest** (HTTPS obrigatório).
|
||||
|
||||
### Estrutura do Header de Segurança
|
||||
|
||||
```xml
|
||||
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
|
||||
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
|
||||
<wsu:Timestamp wsu:Id="TS-xxx">
|
||||
<wsu:Created>2026-02-09T12:00:00.000Z</wsu:Created>
|
||||
<wsu:Expires>2026-02-09T12:05:00.000Z</wsu:Expires>
|
||||
</wsu:Timestamp>
|
||||
<wsse:UsernameToken wsu:Id="UsernameToken-xxx">
|
||||
<wsse:Username>EU_LOGIN_USERNAME</wsse:Username>
|
||||
<wsse:Password Type="...#PasswordDigest">BASE64_DIGEST</wsse:Password>
|
||||
<wsse:Nonce EncodingType="...#Base64Binary">BASE64_NONCE</wsse:Nonce>
|
||||
<wsu:Created>2026-02-09T12:00:00.000Z</wsu:Created>
|
||||
</wsse:UsernameToken>
|
||||
</wsse:Security>
|
||||
```
|
||||
|
||||
### Cálculo do Password Digest
|
||||
|
||||
```
|
||||
Password = Base64( SHA-1( Nonce + Created + AuthenticationKey ) )
|
||||
```
|
||||
|
||||
Onde:
|
||||
- **Nonce**: 16 bytes aleatórios em Base64
|
||||
- **Created**: Timestamp ISO 8601
|
||||
- **AuthenticationKey**: Chave obtida no TRACES NT
|
||||
|
||||
### Campos Obrigatórios no SOAP Envelope
|
||||
|
||||
```xml
|
||||
<v4:WebServiceClientId>eudr-test</v4:WebServiceClientId>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Serviços da API
|
||||
|
||||
### 1. Echo Test (CF1)
|
||||
Teste de conexão - disponível apenas em ambientes de teste.
|
||||
|
||||
**Endpoint**: `{EUDR_URL}/services/EudrEchoService#testEcho`
|
||||
|
||||
**Request:**
|
||||
```xml
|
||||
<eudr:testEchoRequest>
|
||||
<eudr:message>Test message</eudr:message>
|
||||
</eudr:testEchoRequest>
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```xml
|
||||
<eudr:testEchoResponse>
|
||||
<eudr:message>Test message</eudr:message>
|
||||
</eudr:testEchoResponse>
|
||||
```
|
||||
|
||||
### 2. Submit DDS (CF2)
|
||||
Submissão de nova Declaração de Due Diligence.
|
||||
|
||||
**Endpoint**: `{EUDR_URL}/services/EudrSubmissionServiceV2#submitDDS`
|
||||
|
||||
**Request (V2):**
|
||||
```xml
|
||||
<v21:SubmitDDSRequest>
|
||||
<v4:WebServiceClientId>eudr-test</v4:WebServiceClientId>
|
||||
<v21:ActivityType>IMPORT</v21:ActivityType>
|
||||
<v21:ConfidentialityFlag>false</v21:ConfidentialityFlag>
|
||||
<v21:CompanyInternalReference>REF-2026-001</v21:CompanyInternalReference>
|
||||
|
||||
<!-- Para Authorized Representative -->
|
||||
<v21:OnBehalfOfOperator>
|
||||
<v21:Name>Empresa Exemplo Ltda</v21:Name>
|
||||
<v21:StreetNumber>Rua Principal, 100</v21:StreetNumber>
|
||||
<v21:PostalCode>01000-000</v21:PostalCode>
|
||||
<v21:City>São Paulo</v21:City>
|
||||
<v21:CountryCode>BR</v21:CountryCode>
|
||||
<v21:EORI>BR12345678901234</v21:EORI>
|
||||
</v21:OnBehalfOfOperator>
|
||||
|
||||
<v21:Commodity>
|
||||
<v21:HSCode>1201</v21:HSCode>
|
||||
<v21:Description>Soybeans for export</v21:Description>
|
||||
<v21:NetMass>50000</v21:NetMass>
|
||||
<v21:PercentageEstimateOrDeviation>5</v21:PercentageEstimateOrDeviation>
|
||||
|
||||
<v21:Producer>
|
||||
<v21:CountryCode>BR</v21:CountryCode>
|
||||
<v21:ProducerName>Fazenda Exemplo</v21:ProducerName>
|
||||
<v21:GeoLocation>{"type":"FeatureCollection","features":[...]}</v21:GeoLocation>
|
||||
</v21:Producer>
|
||||
</v21:Commodity>
|
||||
</v21:SubmitDDSRequest>
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```xml
|
||||
<v21:SubmitDDSResponse>
|
||||
<v21:UUID>550e8400-e29b-41d4-a716-446655440000</v21:UUID>
|
||||
</v21:SubmitDDSResponse>
|
||||
```
|
||||
|
||||
### 3. Get DDS Info (CF3)
|
||||
Obter status e número de referência.
|
||||
|
||||
**Endpoint**: `{EUDR_URL}/services/EudrRetrievalServiceV2#getDdsInfo`
|
||||
|
||||
**Request por UUID:**
|
||||
```xml
|
||||
<v21:GetDdsInfoRequest>
|
||||
<v4:WebServiceClientId>eudr-test</v4:WebServiceClientId>
|
||||
<v21:UUID>550e8400-e29b-41d4-a716-446655440000</v21:UUID>
|
||||
</v21:GetDdsInfoRequest>
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```xml
|
||||
<v21:GetDdsInfoResponse>
|
||||
<v21:DDSInfo>
|
||||
<v21:UUID>550e8400-e29b-41d4-a716-446655440000</v21:UUID>
|
||||
<v21:Status>AVAILABLE</v21:Status>
|
||||
<v21:ReferenceNumber>EUDR-2026-0001234</v21:ReferenceNumber>
|
||||
<v21:VerificationNumber>VN123456789</v21:VerificationNumber>
|
||||
<v21:InternalReference>REF-2026-001</v21:InternalReference>
|
||||
<v21:CAMessage>...</v21:CAMessage>
|
||||
<v21:RejectionReason>...</v21:RejectionReason>
|
||||
</v21:DDSInfo>
|
||||
</v21:GetDdsInfoResponse>
|
||||
```
|
||||
|
||||
### 4. Amend DDS (CF5)
|
||||
Alterar DDS em status AVAILABLE.
|
||||
|
||||
**Endpoint**: `{EUDR_URL}/services/EudrSubmissionServiceV2#amendDDS`
|
||||
|
||||
**Nota**: A mensagem é semelhante a submitDDS, mas inclui o UUID da DDS a ser alterada.
|
||||
|
||||
### 5. Retract DDS (CF6)
|
||||
Cancelar/Retirar DDS.
|
||||
|
||||
**Endpoint**: `{EUDR_URL}/services/EudrSubmissionServiceV2#retractDds`
|
||||
|
||||
**Request:**
|
||||
```xml
|
||||
<v21:RetractDdsRequest>
|
||||
<v4:WebServiceClientId>eudr-test</v4:WebServiceClientId>
|
||||
<v21:UUID>550e8400-e29b-41d4-a716-446655440000</v21:UUID>
|
||||
</v21:RetractDdsRequest>
|
||||
```
|
||||
|
||||
### 6. Get Statement By Identifiers (CF7)
|
||||
Obter dados completos de uma DDS usando Reference + Verification Number.
|
||||
|
||||
**Endpoint**: `{EUDR_URL}/services/EudrRetrievalServiceV2#getStatementByIdentifiers`
|
||||
|
||||
### 7. Get Referenced DDS (CF7)
|
||||
Obter DDS referenciadas na cadeia de suprimentos (V2 only).
|
||||
|
||||
**Endpoint**: `{EUDR_URL}/services/EudrRetrievalServiceV2#getReferencedDds`
|
||||
|
||||
---
|
||||
|
||||
## Conformance Tests
|
||||
|
||||
Sequência obrigatória para acesso à produção:
|
||||
|
||||
| CF | Nome | Descrição | Obrigatório |
|
||||
|----|------|-----------|-------------|
|
||||
| CF1 | Echo Test | Conexão e autenticação | ✅ |
|
||||
| CF2 | Submit DDS | Submissão de DDS | ✅ |
|
||||
| CF3 | Get DDS Info | Obter referência/status | ✅ |
|
||||
| CF4 | Error Handling | Gestão de erros | ✅ |
|
||||
| CF5 | Amend DDS | Alteração de DDS | Opcional |
|
||||
| CF6 | Retract DDS | Retirada de DDS | Opcional |
|
||||
| CF7 | Get DDS Data | Obter dados completos | Opcional |
|
||||
|
||||
### Fluxo de Certificação
|
||||
|
||||
1. Registrar operador no TRACES NT (Acceptance)
|
||||
2. Obter credenciais de Web Service
|
||||
3. Executar CF1 (Echo) - validar autenticação
|
||||
4. Executar CF2 (Submit) - submeter DDS de teste
|
||||
5. Executar CF3 (Get Info) - obter referência
|
||||
6. Executar CF4 - testar cenários de erro
|
||||
7. Solicitar acesso à produção via email para SANTE-TRACES@ec.europa.eu
|
||||
|
||||
---
|
||||
|
||||
## Estrutura XML/SOAP
|
||||
|
||||
### Envelope SOAP Completo
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:v21="http://ec.europa.eu/tracesnt/eudr/v2.1"
|
||||
xmlns:v4="http://ec.europa.eu/tracesnt/commons/v4">
|
||||
<soap:Header>
|
||||
<wsse:Security>
|
||||
<!-- UsernameToken conforme seção Autenticação -->
|
||||
</wsse:Security>
|
||||
</soap:Header>
|
||||
<soap:Body>
|
||||
<!-- Request específico do serviço -->
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
```
|
||||
|
||||
### Namespaces
|
||||
|
||||
| Prefixo | URI |
|
||||
|---------|-----|
|
||||
| soap | http://schemas.xmlsoap.org/soap/envelope/ |
|
||||
| wsse | http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd |
|
||||
| wsu | http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd |
|
||||
| v21 | http://ec.europa.eu/tracesnt/eudr/v2.1 |
|
||||
| v4 | http://ec.europa.eu/tracesnt/commons/v4 |
|
||||
|
||||
---
|
||||
|
||||
## GeoJSON para Geolocalização
|
||||
|
||||
A geolocalização é enviada como string JSON dentro do campo `GeoLocation`.
|
||||
|
||||
### Estrutura GeoJSON para EUDR
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [-47.123456, -23.456789]
|
||||
},
|
||||
"properties": {
|
||||
"plotId": "PLOT-001",
|
||||
"area": 3.5,
|
||||
"harvestDate": "2025-06-15"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [[
|
||||
[-47.100, -23.400],
|
||||
[-47.100, -23.500],
|
||||
[-47.200, -23.500],
|
||||
[-47.200, -23.400],
|
||||
[-47.100, -23.400]
|
||||
]]
|
||||
},
|
||||
"properties": {
|
||||
"plotId": "PLOT-002"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Regras de Geolocalização
|
||||
|
||||
- **Latitude**: -90 a +90
|
||||
- **Longitude**: -180 a +180
|
||||
- **Precisão máxima**: 6 casas decimais (sistema arredonda automaticamente)
|
||||
- **Área máxima para Point (não-gado)**: 4 hectares
|
||||
- **Área mínima**: 0.1 hectare (0.0001 km²)
|
||||
- **Polígonos**: Mínimo 4 pontos, não podem ter auto-interseção
|
||||
- **Tamanho máximo por DDS**: 25 MB
|
||||
|
||||
---
|
||||
|
||||
## Unidades de Medida
|
||||
|
||||
### Para Import/Export
|
||||
|
||||
| HS Code | Tipo | Descrição |
|
||||
|---------|------|-----------|
|
||||
| 010221, 010229 | NAR (p/st) | Número de itens |
|
||||
| 4011, 4013 | NAR (p/st) | Número de itens |
|
||||
| 4403, 4406, 4408, 4410-4413 | MTQ (m³) | Metro cúbico |
|
||||
| 4701, 4702, 4704, 4705 | KSD (kg 90% sdt) | Kg substância 90% seca |
|
||||
|
||||
**Campos obrigatórios Import/Export:**
|
||||
- Net Mass (Kg): Sempre obrigatório
|
||||
- Supplementary Unit: Obrigatório se HS Code estiver na lista acima
|
||||
|
||||
### Para Domestic/Trade
|
||||
|
||||
Combinações válidas:
|
||||
1. Net Mass + Percentage estimate (0-25%)
|
||||
2. Supplementary unit type + quantity
|
||||
3. Ambos
|
||||
|
||||
**Tipos de Supplementary Unit:**
|
||||
| Código | Display | Descrição |
|
||||
|--------|---------|-----------|
|
||||
| KSD | KSD (kg 90% sdt) | Kg substância 90% seca |
|
||||
| MTK | MTK (m²) | Metro quadrado |
|
||||
| MTQ | MTQ (m³) | Metro cúbico |
|
||||
| MTR | MTR (m) | Metro |
|
||||
| NAR | NAR (p/st) | Número de itens |
|
||||
| NPR | NPR (pa) | Número de pares |
|
||||
|
||||
---
|
||||
|
||||
## Regras de Validação
|
||||
|
||||
### Operador
|
||||
|
||||
| Regra | Descrição |
|
||||
|-------|-----------|
|
||||
| Activity Type | Obrigatório; não pode mudar em amend |
|
||||
| EORI | Obrigatório para IMPORT/EXPORT |
|
||||
| Non-EU Operator | Apenas IMPORT permitido |
|
||||
| Authorized Rep | Deve informar dados do operador representado |
|
||||
|
||||
### Commodities
|
||||
|
||||
| Regra | Descrição |
|
||||
|-------|-----------|
|
||||
| Mínimo | Pelo menos 1 commodity por DDS |
|
||||
| Máximo | 100 commodities por DDS |
|
||||
| Description | Obrigatório para cada commodity |
|
||||
| Net Mass | Obrigatório para IMPORT/EXPORT |
|
||||
| HS Code | Deve ser válido (Annex I EUDR) |
|
||||
| Timber | Requer scientific name + common name |
|
||||
|
||||
### Geolocalização
|
||||
|
||||
| Regra | Descrição |
|
||||
|-------|-----------|
|
||||
| Obrigatória | Se não houver Referenced DDS |
|
||||
| Tamanho máximo | 25 MB por DDS |
|
||||
| Producers por commodity | Máximo 1000 |
|
||||
| Producers por DDS | Máximo 10.000 |
|
||||
| Área para Point | Obrigatória; default 4ha; máx 4ha (não-gado) |
|
||||
|
||||
### DDS Referenciadas
|
||||
|
||||
| Regra | Descrição |
|
||||
|-------|-----------|
|
||||
| Máximo | 2000 por DDS |
|
||||
| Status | Deve estar AVAILABLE ou ARCHIVED |
|
||||
| Auto-referência | DDS não pode referenciar a si mesma |
|
||||
|
||||
---
|
||||
|
||||
## Códigos de Erro
|
||||
|
||||
### Erros de Autenticação/Schema
|
||||
|
||||
| Código HTTP | Descrição |
|
||||
|-------------|-----------|
|
||||
| 401 | Credenciais inválidas |
|
||||
| 403 | Sem permissão |
|
||||
| 500 | Erro de schema XML |
|
||||
|
||||
### Erros de Negócio
|
||||
|
||||
| Código | Descrição |
|
||||
|--------|-----------|
|
||||
| EUDR_WEBSERVICE_USER_NOT_EUDR_OPERATOR | Usuário não registrado como operador EUDR |
|
||||
| EUDR_WEBSERVICE_USER_FROM_MANY_OPERATOR | Usuário pertence a mais de um operador |
|
||||
| EUDR_WEBSERVICE_USER_ACTIVITY_NOT_ALLOWED | Atividade não permitida para o perfil |
|
||||
| EUDR_OPERATOR_EORI_FOR_ACTIVITY_MISSING | EORI obrigatório para IMPORT/EXPORT |
|
||||
| EUDR_BEHALF_OPERATOR_NOT_PROVIDED | Operador representado não informado |
|
||||
| EUDR_BEHALF_OPERATOR_CITY_POSTALCODE_EMPTY_OR_INVALID | Cidade/CEP inválidos |
|
||||
| EUDR_ACTIVITY_TYPE_NOT_COMPATIBLE | Atividade incompatível com perfil |
|
||||
| EUDR_COMMODITIES_HS_CODE_INVALID | HS Code inválido |
|
||||
| EUDR_COMMODITIES_DESCRIPTOR_NET_MASS_EMPTY | Net Mass obrigatório |
|
||||
| EUDR_COMMODITIES_DESCRIPTOR_QUANTITY_MISSING | Quantidade obrigatória |
|
||||
| EUDR_COMMODITITY_PRODUCER_COUNTRY_CODE_INVALID | Código de país inválido |
|
||||
| EUDR_COMMODITIES_PRODUCER_GEO_EMPTY | Geolocalização obrigatória |
|
||||
| EUDR_COMMODITIES_PRODUCER_GEO_INVALID | GeoJSON inválido |
|
||||
| EUDR_COMMODITIES_PRODUCER_GEO_LATITUDE_INVALID | Latitude fora do range |
|
||||
| EUDR_COMMODITIES_PRODUCER_GEO_LONGITUDE_INVALID | Longitude fora do range |
|
||||
| EUDR_COMMODITIES_PRODUCER_GEO_INVALID_GEOMETRY | Geometria inválida |
|
||||
| EUDR_COMMODITIES_PRODUCER_GEO_AREA_INVALID | Área inválida (0.1-4 ha) |
|
||||
| EUDR_MAXIMUM_GEO_SIZE_REACHED | Tamanho máximo excedido (25MB) |
|
||||
| EUDR_REFERENCED_STATEMENT_NOT_FOUND | DDS referenciada não encontrada |
|
||||
| EUDR_MAXIMUM_REFERENCED_DDS_REACHED | Máximo de DDS referenciadas excedido |
|
||||
| EUDR_API_AMEND_ACTIVITY_TYPE_CHANGE_NOT_ALLOWED | Não pode mudar activity type |
|
||||
| EUDR_API_AMEND_OR_WITHDRAW_DDS_NOT_POSSIBLE | DDS referenciada ou prazo expirado |
|
||||
| EUDR_API_AMEND_NOT_ALLOWED_FOR_STATUS | Status não permite alteração |
|
||||
| EUDR_API_NO_DDS | DDS não encontrada |
|
||||
|
||||
---
|
||||
|
||||
## Fluxo de Integração DuOrigin
|
||||
|
||||
### 1. Cadastro de Operador
|
||||
```
|
||||
Operador → DuOrigin UI → Salvar empresa com EORI, endereço, etc.
|
||||
```
|
||||
|
||||
### 2. Submissão de DDS
|
||||
```
|
||||
1. Operador preenche formulário DDS no DuOrigin
|
||||
2. Sistema valida dados localmente
|
||||
3. DuOrigin chama eudr-api.service.submitDDS()
|
||||
4. Recebe UUID e armazena no banco
|
||||
5. Polling getDDSInfo() para obter Reference Number
|
||||
6. Atualiza status no DuOrigin
|
||||
```
|
||||
|
||||
### 3. Acompanhamento
|
||||
```
|
||||
1. DuOrigin faz polling periódico de getDDSInfo()
|
||||
2. Atualiza status (SUBMITTED → AVAILABLE/REJECTED)
|
||||
3. Notifica operador se houver CA message
|
||||
```
|
||||
|
||||
### 4. Alterações
|
||||
```
|
||||
1. Operador solicita alteração
|
||||
2. DuOrigin valida prazo e referências
|
||||
3. Chama amendDDS() com dados completos
|
||||
4. Atualiza registro local
|
||||
```
|
||||
|
||||
### 5. Retirada
|
||||
```
|
||||
1. Operador solicita cancelamento/retirada
|
||||
2. DuOrigin valida status e referências
|
||||
3. Chama retractDds() com UUID
|
||||
4. Atualiza status para WITHDRAWN/CANCELLED
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Contatos
|
||||
|
||||
- **Suporte Técnico**: SANTE-TRACES@ec.europa.eu (título deve começar com "EUDR API")
|
||||
- **Política**: ENV-DEFORESTATION@ec.europa.eu
|
||||
- **Website**: https://environment.ec.europa.eu/topics/forests/deforestation/regulation-implementation_en
|
||||
|
||||
---
|
||||
|
||||
*Documentação gerada para DuOrigin v2 - Fevereiro 2026*
|
||||
Reference in New Issue
Block a user