Skip to content

Horshare/Backend

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 

Repository files navigation

HorShare - Sistema de Registro Equino

Sistema completo para registro, gestão e tokenização de cavalos Campolina com integração blockchain na Scroll Sepolia Testnet.


Visão Geral

O HorShare é um sistema de registro equino que permite gerenciar:

  • Usuários (pessoas físicas ou jurídicas)
  • Haras/Fazendas (propriedades rurais)
  • Cavalos e sua genealogia completa
  • Registros oficiais (provisórios e definitivos)
  • Mensurações técnicas realizadas por profissionais
  • Tokenização blockchain - NFTs (ERC-721) e tokens de cotas (ERC-20)

Stack Tecnológica

Backend

  • NestJS - Framework Node.js progressivo e modular
  • TypeScript - Linguagem com tipagem estática
  • Prisma ORM - ORM type-safe para acesso ao banco de dados
  • SQLite - Banco de dados relacional (MVP - migra para PostgreSQL em produção)

Autenticação & Segurança

  • JWT (JSON Web Tokens) - Autenticação stateless
  • Passport - Middleware de autenticação
  • bcrypt - Hash seguro de senhas

Validação & Qualidade

  • class-validator - Validação de DTOs
  • class-transformer - Transformação de objetos
  • ESLint - Linter para qualidade de código
  • Prettier - Formatação consistente

Blockchain (Scroll Sepolia)

  • ethers.js v6 - Biblioteca para interação com Ethereum/EVM
  • Scroll Sepolia Testnet - Layer 2 otimista para Ethereum
  • ERC-721 - Padrão NFT para representar cavalos únicos
  • ERC-20 - Padrão de token fungível para cotas de cavalos

Arquitetura da Integração Blockchain

┌─────────────────────────────────────────────────────────────┐
│                    FRONTEND (React + Web3)                   │
│  - Usuário conecta MetaMask                                  │
│  - Preenche formulário de registro                           │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│                  BACKEND API (NestJS + Prisma)               │
│  - Valida dados do cavalo                                    │
│  - Salva no banco de dados SQLite                           │
│  - Gera hashes (microchip + registro)                       │
│  - Backend assina transação (REGISTRAR_ROLE)                │
│  - NFT mintado para carteira do usuário                     │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│             BLOCKCHAIN (Scroll Sepolia Testnet)             │
│  - HorseRegistry (0x4f7d...6A3B) - NFTs ERC-721             │
│  - HorseSharesFactory (0x1223...c815) - Factory ERC-20      │
│  - Hashes imutáveis de microchip e registro                 │
└─────────────────────────────────────────────────────────────┘

Fluxo de Mint de NFT

  1. Usuário registra cavalo → Dados salvos no banco de dados
  2. Backend valida → Verifica registro definitivo + mensuração
  3. Backend gera hashes:
    • microchipHash = keccak256(microchip)
    • registroHash = keccak256(JSON canônico do registro + mensuração)
  4. Backend assina transação → Carteira com REGISTRAR_ROLE paga gas fees
  5. NFT mintado on-chain → Enviado diretamente para carteira MetaMask do usuário
  6. Backend atualiza DB → Salva tokenId, txHash e contractAddress

Modelo de Dados

Entidades Principais

User

Representa usuários do sistema, incluindo proprietários, criadores e responsáveis por registros.

Schema:

model User {
  id              String    @id @default(uuid())
  nome            String
  sobrenome       String
  cpf             String    @unique
  dataNascimento  DateTime
  email           String    @unique
  senhaHash       String
  criadoEm        DateTime  @default(now())
}

Haras

Representa propriedades rurais (haras ou fazendas) vinculadas a um proprietário.

Schema:

model Haras {
  id              String  @id @default(uuid())
  nome            String
  proprietarioId  String
  cidade          String
  estado          String
  cep             String
  
  proprietario    User    @relation(fields: [proprietarioId])
}

Cavalo

Entidade central do sistema, representando os equinos registrados com campos blockchain.

Schema:

model Cavalo {
  id                     String    @id @default(uuid())
  nome                   String
  microchip              String    @unique
  sexo                   String    // "M" ou "F"
  dataNascimento         DateTime
  
  // Blockchain Integration
  nftTokenId             String?   @unique
  nftContractAddress     String?
  nftBlockchainDbId      Int?      @unique  // ID numérico para blockchain
  sharesContractAddress  String?
  sharesTokenSymbol      String?
  sharesTotalSupply      Int?
  
  // Relações
  harasNascimentoId      String
  harasAtualId           String
  criadorId              String
  proprietarioAtualId    String
  paiId                  String?
  maeId                  String?
  
  harasNascimento        Haras     @relation("HarasNascimento")
  harasAtual             Haras     @relation("HarasAtual")
  criador                User      @relation("Criador")
  proprietarioAtual      User      @relation("Proprietario")
  registros              Registro[]
  pai                    Cavalo?   @relation("Pai")
  mae                    Cavalo?   @relation("Mae")
}

Novos Campos Blockchain:

  • nftTokenId: ID do token ERC-721 na blockchain
  • nftContractAddress: Endereço do contrato HorseRegistry
  • nftBlockchainDbId: ID numérico sequencial usado no contrato
  • sharesContractAddress: Endereço do token ERC-20 de cotas (se criado)
  • sharesTokenSymbol: Símbolo do token de cotas (ex: "SPIRIT")
  • sharesTotalSupply: Total de cotas emitidas

Registro

Representa atos oficiais relacionados ao cavalo, como registro provisório ou definitivo.

Schema:

model Registro {
  id              String      @id @default(uuid())
  data            DateTime    @default(now())
  tipo            String      // "PROVISORIO" ou "DEFINITIVO"
  numeroRegistro  String      @unique
  userId          String
  cavaloId        String
  
  user            User        @relation(fields: [userId])
  cavalo          Cavalo      @relation(fields: [cavaloId])
  mensuracao      Mensuracao?
}

Mensuração

Armazena dados técnicos e morfológicos do cavalo, vinculados a um registro específico.

Schema:

model Mensuracao {
  id                        String   @id @default(uuid())
  registroId                String   @unique
  veterinarioResponsavel    String
  pelagem                   String?
  particularidades          String?
  marcasSinais              String?
  alturaCernelha            Float?
  alturaDorso               Float?
  alturaGarupa              Float?
  alturaCostados            Float?
  perimetroCanela           Float?
  perimetroTorax            Float?
  comprimentoCabeca         Float?
  comprimentoPescoco        Float?
  comprimentoDorsoLombo     Float?
  comprimentoGarupa         Float?
  comprimentoEspadua        Float?
  comprimentoCorpo          Float?
  larguraCabeca             Float?
  larguraAncas              Float?
  larguraPeito              Float?
  
  registro                  Registro @relation(fields: [registroId])
}

Smart Contracts (Scroll Sepolia)

HorseRegistry (ERC-721)

Endereço: 0x4f7dBB2F9353Bfdd95BD153912405c2559Bb6A3B

Contrato principal para NFTs de cavalos.

Funções Principais:

  • mintHorseFromDb() - Mintar NFT (apenas REGISTRAR_ROLE)
  • updateRegistroHash() - Atualizar hash do registro
  • updateTokenURI() - Atualizar metadata URI
  • setActive() - Ativar/desativar cavalo
  • ownerOf() - Consultar dono do NFT
  • tokenURI() - Consultar metadata URI

Roles & Permissões:

  • DEFAULT_ADMIN_ROLE - Pode conceder/revogar outras roles
  • REGISTRAR_ROLE - Pode mintar NFTs e atualizar registros
  • PAUSER_ROLE - Pode pausar/despausar o contrato

HorseSharesFactory

Endereço: 0x1223aFa91995e88a838c0080c8fd9414C808c815

Factory para criar tokens ERC-20 de cotas de cavalos.

Função Principal:

  • createShares() - Criar token de cotas (apenas dono do NFT)

Regra de Negócio:

  • Apenas o proprietário do NFT pode criar o token de cotas
  • Cada cavalo pode ter apenas um token de cotas
  • O supply inicial vai para o dono do NFT

Como Rodar o Servidor

1. Pré-requisitos

  • Node.js 20+ instalado
  • npm ou yarn

2. Instalar Dependências

cd src
npm install

3. Configurar Variáveis de Ambiente

Crie um arquivo .env na pasta src/:

# Database
DATABASE_URL="file:./prisma/dev.db"

# JWT
JWT_SECRET="seu-secret-key-aqui-mude-em-producao"

# Server
PORT=3001
FRONTEND_URL="http://localhost:3000"

# Blockchain - Scroll Sepolia Testnet
BLOCKCHAIN_RPC_URL="https://sepolia-rpc.scroll.io"
BLOCKCHAIN_CHAIN_ID="534351"

# Contratos Deployados
ERC721_CONTRACT_ADDRESS="0x4f7dBB2F9353Bfdd95BD153912405c2559Bb6A3B"
ERC20_FACTORY_ADDRESS="0x1223aFa91995e88a838c0080c8fd9414C808c815"

# Carteira do Backend (precisa ter REGISTRAR_ROLE e ETH para gas)
# IMPORTANTE: Nunca commitar esta chave! Use secrets em produção
BLOCKCHAIN_PRIVATE_KEY="sua-private-key-sem-0x"

# Metadata
METADATA_BASE_URI="http://localhost:3001/blockchain/metadata"

4. Configurar Banco de Dados

# Gerar Prisma Client
npx prisma generate

# Rodar migrations
npx prisma migrate dev

# (Opcional) Visualizar banco de dados
npx prisma studio

5. Iniciar o Servidor

Modo Desenvolvimento:

npm run start:dev

Modo Produção:

npm run build
npm run start:prod

Servidor disponível em: http://localhost:3001/api


Documentação da API

Autenticação

Login

POST /api/auth/login
Content-Type: application/json

{
  "email": "usuario@email.com",
  "senha": "senha123"
}

Perfil do Usuário (Protegido)

GET /api/auth/profile
Authorization: Bearer {access_token}

Usuários

POST   /api/users          # Criar usuário
GET    /api/users          # Listar usuários
GET    /api/users/:id      # Buscar usuário
PATCH  /api/users/:id      # Atualizar usuário
DELETE /api/users/:id      # Deletar usuário

Haras

POST   /api/haras          # Criar haras
GET    /api/haras          # Listar haras
GET    /api/haras/:id      # Buscar haras
PATCH  /api/haras/:id      # Atualizar haras
DELETE /api/haras/:id      # Deletar haras

Cavalos

POST   /api/horses                  # Criar cavalo
GET    /api/horses                  # Listar cavalos
GET    /api/horses/:id              # Buscar cavalo
GET    /api/horses/:id/genealogy    # Árvore genealógica
GET    /api/horses/:id/descendants  # Descendentes
PATCH  /api/horses/:id              # Atualizar cavalo
DELETE /api/horses/:id              # Deletar cavalo

Registros

POST   /api/registries     # Criar registro
GET    /api/registries     # Listar registros
GET    /api/registries/:id # Buscar registro
PATCH  /api/registries/:id # Atualizar registro
DELETE /api/registries/:id # Deletar registro

Mensurações

POST   /api/measurements     # Criar mensuração
GET    /api/measurements     # Listar mensurações
GET    /api/measurements/:id # Buscar mensuração
PATCH  /api/measurements/:id # Atualizar mensuração
DELETE /api/measurements/:id # Deletar mensuração

Blockchain (Integração Web3)

Informações dos Contratos

GET /api/blockchain/info

Resposta:

{
  "network": "Scroll Sepolia Testnet",
  "blockNumber": 15520882,
  "contracts": {
    "horseRegistry": {
      "address": "0x4f7dBB2F9353Bfdd95BD153912405c2559Bb6A3B",
      "type": "ERC-721",
      "description": "Registro de cavalos (NFTs)"
    },
    "sharesFactory": {
      "address": "0x1223aFa91995e88a838c0080c8fd9414C808c815",
      "type": "Factory",
      "description": "Factory de tokens de cotas (ERC-20)"
    }
  },
  "rpcUrl": "https://sepolia-rpc.scroll.io"
}

Mintar NFT do Cavalo

POST /api/blockchain/nft/mint
Content-Type: application/json

{
  "cavaloId": "uuid-do-cavalo",
  "ownerAddress": "0x..." // Endereço MetaMask do usuário
}

Resposta:

{
  "success": true,
  "cavalo": {
    "id": "5b2ff098-713a-49cf-a88f-42590029669a",
    "nome": "Relâmpago Dourado",
    "microchip": "456789012345678"
  },
  "nft": {
    "tokenId": "3",
    "transactionHash": "0xf8fca9ac192b66b966913a747f8e91bab03750edeea324cff8cd8233695b2a2a",
    "ownerAddress": "0x9B5d0F6CDdCd7f059f681406D8B72eDbC1C0619D",
    "metadataUri": "http://localhost:3001/blockchain/metadata/horse/...",
    "contractAddress": "0x4f7dBB2F9353Bfdd95BD153912405c2559Bb6A3B"
  }
}

Verificar na Blockchain:

https://sepolia.scrollscan.com/tx/0xf8fca9ac192b66b966913a747f8e91bab03750edeea324cff8cd8233695b2a2a

Consultar Proprietário do NFT

GET /api/blockchain/nft/:tokenId/owner

Resposta:

{
  "tokenId": "3",
  "owner": "0x9B5d0F6CDdCd7f059f681406D8B72eDbC1C0619D",
  "metadataUri": "http://localhost:3001/blockchain/metadata/horse/...",
  "cavalo": {
    "id": "...",
    "nome": "Relâmpago Dourado",
    "microchip": "456789012345678"
  },
  "proprietarioAtual": {
    "id": "...",
    "nome": "João",
    "sobrenome": "Silva",
    "email": "joao@email.com"
  }
}

Criar Token de Cotas (ERC-20)

POST /api/blockchain/shares/create
Content-Type: application/json

{
  "cavaloId": "uuid-do-cavalo",
  "name": "Cotas Relâmpago Dourado",
  "symbol": "RELAMP",
  "totalSupply": 100,
  "initialOwnerAddress": "0x..." // Endereço do dono do NFT
}

Resposta:

{
  "success": true,
  "cavalo": {
    "id": "...",
    "nome": "Relâmpago Dourado"
  },
  "token": {
    "contractAddress": "0xabc...",
    "name": "Cotas Relâmpago Dourado",
    "symbol": "RELAMP",
    "totalSupply": 100,
    "transactionHash": "0xdef...",
    "initialOwner": "0x..."
  }
}

Consultar Saldo

# Saldo de NFTs (ERC-721)
GET /api/blockchain/balance?address=0x...

# Saldo de cotas de um cavalo específico (ERC-20)
GET /api/blockchain/balance?address=0x...&cavaloId=uuid

Metadata do NFT (OpenSea Compatible)

GET /api/blockchain/metadata/horse/:cavaloId

Resposta:

{
  "name": "Relâmpago Dourado",
  "description": "Cavalo registrado na plataforma HorShare - Microchip: 456789012345678",
  "image": "http://localhost:3001/blockchain/metadata/horse/.../image",
  "external_url": "https://horshare.com/horse/...",
  "attributes": [
    { "trait_type": "Microchip", "value": "456789012345678" },
    { "trait_type": "Sexo", "value": "Macho" },
    { "trait_type": "Data de Nascimento", "value": "2019-08-20" },
    { "trait_type": "Pelagem", "value": "Tordilha" },
    { "trait_type": "Altura na Cernelha", "value": 1.55, "display_type": "number" },
    { "trait_type": "Registro", "value": "DEF-2024-003" },
    { "trait_type": "Haras", "value": "Haras Muiraquitã" }
  ]
}

Testando a Integração Blockchain

Passo a Passo Completo

1. Criar cavalo com registro definitivo

# 1.1 Criar cavalo
curl -X POST http://localhost:3001/api/horses \
  -H "Content-Type: application/json" \
  -d '{
    "nome": "Teste Blockchain",
    "microchip": "111222333444555",
    "sexo": "M",
    "dataNascimento": "2020-01-01",
    "harasNascimentoId": "uuid-haras",
    "harasAtualId": "uuid-haras",
    "criadorId": "uuid-user",
    "proprietarioAtualId": "uuid-user"
  }'

# 1.2 Criar registro definitivo
curl -X POST http://localhost:3001/api/registries \
  -H "Content-Type: application/json" \
  -d '{
    "cavaloId": "uuid-do-cavalo",
    "tipo": "DEFINITIVO",
    "numeroRegistro": "DEF-2024-999",
    "userId": "uuid-user"
  }'

# 1.3 Criar mensuração
curl -X POST http://localhost:3001/api/measurements \
  -H "Content-Type: application/json" \
  -d '{
    "registroId": "uuid-registro",
    "pelagem": "Castanha",
    "alturaCernelha": 1.50,
    "perimetroTorax": 1.75,
    "veterinarioResponsavel": "Dr. Teste"
  }'

2. Mintar NFT para a carteira do usuário

curl -X POST http://localhost:3001/api/blockchain/nft/mint \
  -H "Content-Type: application/json" \
  -d '{
    "cavaloId": "uuid-do-cavalo",
    "ownerAddress": "0xSeuEnderecoMetaMask"
  }'

3. Verificar NFT

# Consultar dono do NFT
curl http://localhost:3001/api/blockchain/nft/3/owner

# Ver saldo de NFTs
curl "http://localhost:3001/api/blockchain/balance?address=0xSeuEndereco"

# Ver metadata
curl http://localhost:3001/api/blockchain/metadata/horse/uuid-do-cavalo

4. Criar e verificar token de cotas

# Criar token de cotas
curl -X POST http://localhost:3001/api/blockchain/shares/create \
  -H "Content-Type: application/json" \
  -d '{
    "cavaloId": "uuid-do-cavalo",
    "name": "Cotas Teste",
    "symbol": "TEST",
    "totalSupply": 100,
    "initialOwnerAddress": "0xSeuEndereco"
  }'

# Ver saldo de cotas
curl "http://localhost:3001/api/blockchain/balance?address=0xSeuEndereco&cavaloId=uuid-do-cavalo"

Estrutura do Projeto

Backend/
├── src/
│   ├── src/
│   │   ├── database/
│   │   │   ├── prisma.module.ts
│   │   │   └── prisma.service.ts
│   │   ├── modules/
│   │   │   ├── auth/              # Autenticação JWT
│   │   │   ├── blockchain/        # Integração Web3
│   │   │   │   ├── blockchain.controller.ts
│   │   │   │   ├── blockchain.service.ts
│   │   │   │   ├── blockchain-contract.service.ts
│   │   │   │   ├── dto/
│   │   │   │   │   └── blockchain.dto.ts
│   │   │   │   └── abis/
│   │   │   │       ├── HorseRegistry.json
│   │   │   │       ├── HorseSharesFactory.json
│   │   │   │       └── HorseShareToken.json
│   │   │   ├── haras/             # Propriedades rurais
│   │   │   ├── horse/             # Cavalos + Genealogia
│   │   │   ├── measurements/      # Mensurações técnicas
│   │   │   ├── registry/          # Registros oficiais
│   │   │   └── user/              # Usuários
│   │   ├── app.module.ts
│   │   └── main.ts
│   ├── prisma/
│   │   ├── schema.prisma          # Schema com campos blockchain
│   │   ├── dev.db
│   │   └── migrations/
│   │       ├── 20251215203753_init/
│   │       └── 20251215214856_add_nft_blockchain_db_id/
│   ├── package.json
│   ├── tsconfig.json
│   └── .env
└── README.md

Links Úteis


Funcionalidades Implementadas

Módulos Backend

  1. UserModule - Gestão completa de usuários
  2. AuthModule - Autenticação JWT com Passport
  3. HarasModule - CRUD de propriedades rurais
  4. HorseModule - CRUD de cavalos + Genealogia
  5. RegistryModule - Registros provisórios e definitivos
  6. MeasurementsModule - Mensurações técnicas
  7. BlockchainModule - NFTs (ERC-721) + Tokens de Cotas (ERC-20)

Blockchain Integration

  1. Mint de NFT - Backend assina, usuário recebe
  2. Consulta de proprietário - Verificação on-chain
  3. Criação de tokens de cotas - ERC-20 por cavalo
  4. Metadata OpenSea compatible - JSON padrão NFT
  5. Hashes de integridade - Microchip + Registro imutáveis
  6. Verificação de saldos - NFTs e tokens de cotas

Segurança e Boas Práticas

Blockchain

  • ✅ Backend usa carteira com REGISTRAR_ROLE para mintar
  • ✅ NFT vai diretamente para carteira do usuário
  • ✅ Hashes de microchip e registro são imutáveis on-chain
  • ✅ Apenas dono do NFT pode criar token de cotas
  • ✅ Contratos têm roles de admin, registrador e pauser

Backend

  • ✅ Senhas hasheadas com bcrypt
  • ✅ Autenticação JWT
  • ✅ Validação de DTOs com class-validator
  • ✅ Private keys em variáveis de ambiente (nunca no código)

Testes

# Testes unitários
npm run test

# Testes e2e
npm run test:e2e

# Cobertura de testes
npm run test:cov

Scripts Úteis

# Desenvolvimento
npm run start:dev

# Build
npm run build

# Produção
npm run start:prod

# Prisma
npx prisma generate       # Gerar client
npx prisma migrate dev    # Criar migration
npx prisma studio         # UI visual do banco

Notas para Produção

Este backend está configurado para Scroll Sepolia Testnet. Para produção:

  1. Banco de Dados: Migrar de SQLite para PostgreSQL
  2. Variáveis de Ambiente: Usar secrets manager (AWS Secrets, HashiCorp Vault)
  3. Blockchain: Usar Scroll Mainnet com carteira segura (multisig recomendado)
  4. Private Keys: NUNCA commitar! Use HSM ou KMS em produção
  5. CORS: Configurar domínios permitidos
  6. Rate Limiting: Implementar para evitar abuso
  7. Logs: Centralizar com CloudWatch, Datadog ou similar
  8. Monitoring: Configurar alertas para transações falhadas

Contribuindo

  1. Fork o projeto
  2. Crie uma branch (git checkout -b feature/nova-feature)
  3. Commit suas mudanças (git commit -m 'Add nova feature')
  4. Push para a branch (git push origin feature/nova-feature)
  5. Abra um Pull Request

📄 Licença

Este projeto está sob a licença MIT.

About

Horshare é sistema completo para registro, gestão e tokenização de cavalos Campolina com integração blockchain na Scroll Sepolia Testnet.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors