{"id":37605728,"url":"https://github.com/robertolima-dev/rust_ecommerce","last_synced_at":"2026-01-16T10:08:56.748Z","repository":{"id":309544158,"uuid":"1035457903","full_name":"robertolima-dev/rust_ecommerce","owner":"robertolima-dev","description":"A robust e-commerce study application built with Rust, Actix Web, PostgreSQL, MongoDB, and Elasticsearch. Features product management, user authentication, multi-tenancy, and comprehensive error handling.","archived":false,"fork":false,"pushed_at":"2025-08-21T13:22:53.000Z","size":83,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-21T15:43:04.592Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robertolima-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-10T12:52:30.000Z","updated_at":"2025-08-21T13:22:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"6242b490-a01c-40b9-85f2-44e7064ae559","html_url":"https://github.com/robertolima-dev/rust_ecommerce","commit_stats":null,"previous_names":["robertolima-dev/rust_ecommerce"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/robertolima-dev/rust_ecommerce","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertolima-dev%2Frust_ecommerce","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertolima-dev%2Frust_ecommerce/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertolima-dev%2Frust_ecommerce/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertolima-dev%2Frust_ecommerce/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robertolima-dev","download_url":"https://codeload.github.com/robertolima-dev/rust_ecommerce/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertolima-dev%2Frust_ecommerce/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28478049,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T06:30:42.265Z","status":"ssl_error","status_checked_at":"2026-01-16T06:30:16.248Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-16T10:08:56.622Z","updated_at":"2026-01-16T10:08:56.726Z","avatar_url":"https://github.com/robertolima-dev.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rust E-commerce - Actix Web\n\nUma aplicação de estudo de e-commerce desenvolvida em Rust com Actix Web, PostgreSQL, MongoDB e Elasticsearch. Este projeto demonstra a implementação de uma arquitetura robusta para sistemas de comércio eletrônico, incluindo gestão de produtos, usuários, tenants e autenticação.\n\n## Configuração\n\n### 1. Variáveis de Ambiente\n\nCrie um arquivo `.env` na raiz do projeto com as seguintes variáveis:\n\n```env\n# Configurações do Servidor\nSERVER_HOST=127.0.0.1\nSERVER_PORT=8080\n\n# Ambiente da aplicação\nAPP_ENVIRONMENT=development\n\n# Configurações do Banco de Dados PostgreSQL\nDATABASE_URL=postgresql://username:password@localhost:5432/database_name\nDATABASE_MAX_CONNECTIONS=5\n\n# Configurações do MongoDB\nMONGO_URI=mongodb://localhost:27017\n\n# Configurações do Elasticsearch\nELASTICSEARCH_URL=http://localhost:9200\nELASTICSEARCH_INDEX_PREFIX=app\n\n# Configurações JWT\nJWT_SECRET=your_super_secret_jwt_key_that_is_at_least_32_characters_long\nJWT_EXPIRES_IN=86400\n```\n\n### 2. Dependências Externas\n\nCertifique-se de ter os seguintes serviços rodando:\n\n- **PostgreSQL**: Banco de dados principal\n- **MongoDB**: Banco de dados NoSQL\n- **Elasticsearch**: Motor de busca\n\n### 3. Executando o Projeto\n\n```bash\n# Verificar se compila\ncargo check\n\n# Executar em modo desenvolvimento\ncargo run\n\n# Executar em modo release\ncargo run --release\n```\n\nO servidor estará disponível em `http://127.0.0.1:8080`\n\n## Scripts de Desenvolvimento\n\n### Criando um Novo App\n\nUse o script `start_new_app.sh` para criar rapidamente um novo módulo de aplicação:\n\n```bash\n# Criar um app com migration\n./start_new_app.sh User\n\n# Criar um app sem migration\n./start_new_app.sh Product --no_migrate\n```\n\nO script criará automaticamente:\n- 📁 `src/apps/user/` (diretório do app)\n- 📄 `mod.rs` (declarações de módulos)\n- 📄 `models.rs` (modelos de dados)\n- 📄 `routes.rs` (rotas da API)\n- 📄 `services.rs` (lógica de negócio)\n- 📄 `repositories.rs` (acesso ao banco)\n- 📄 `tests.rs` (testes unitários)\n- 🗄️ `migrations/YYYYMMDDHHMMSS_create_users.sql` (migration do banco)\n\n### Revertendo um App\n\nSe precisar remover um app criado, use o script `revert_new_app.sh`:\n\n```bash\n./revert_new_app.sh User\n```\n\nO script irá:\n- ❌ Remover o diretório do app\n- ❌ Remover as migrations relacionadas\n- ❌ Remover a declaração do módulo\n- ⚠️ Pedir confirmação antes de executar\n\n## 🚀 Melhorias Implementadas no Script\n\n### Arquitetura de Tratamento de Erros\n\nO script agora gera código com uma arquitetura robusta de tratamento de erros em três camadas:\n\n#### 1. **Routes Layer** - `Result\u003cimpl Responder, AppError\u003e`\n\n**Antes:**\n```rust\npub async fn list_items(app_state: web::Data\u003cAppState\u003e) -\u003e impl Responder {\n    HttpResponse::Ok().json(serde_json::json!({\n        \"message\": \"Lista de Item\",\n        \"data\": []\n    }))\n}\n```\n\n**Depois:**\n```rust\npub async fn list_items(app_state: web::Data\u003cAppState\u003e) -\u003e Result\u003cimpl Responder, AppError\u003e {\n    Ok(HttpResponse::Ok().json(serde_json::json!({\n        \"message\": \"Lista de Item\",\n        \"data\": []\n    })))\n}\n```\n\n**Benefícios:**\n- ✅ **Tratamento de erros automático**: Actix Web converte `AppError` em respostas HTTP apropriadas\n- ✅ **Consistência**: Todas as rotas seguem o mesmo padrão de retorno\n- ✅ **Debugging melhorado**: Erros são rastreados até a origem\n- ✅ **Respostas padronizadas**: Erros seguem o formato definido em `AppError`\n\n#### 2. **Services Layer** - `Result\u003cPaginatedResponse\u003cT\u003e, AppError\u003e`\n\n**Antes:**\n```rust\npub async fn list_users(app_state: \u0026AppState) -\u003e Result\u003cVec\u003cUser\u003e, Box\u003cdyn std::error::Error\u003e\u003e {\n    let repository = UserRepository::new(app_state);\n    repository.find_all().await\n}\n```\n\n**Depois:**\n```rust\npub async fn list_items(app_state: \u0026AppState) -\u003e Result\u003cPaginatedResponse\u003cItem\u003e, AppError\u003e {\n    let repository = ItemRepository::new(app_state);\n    let items = repository.find_all().await\n        .map_err(|e| AppError::database_error(e.to_string()))?;\n    \n    Ok(PaginatedResponse {\n        count: items.len() as i64,\n        results: items,\n        limit: 10,\n        offset: 0,\n    })\n}\n```\n\n**Benefícios:**\n- ✅ **Paginação nativa**: Todas as listagens retornam dados paginados\n- ✅ **Metadados úteis**: Inclui `count`, `limit`, `offset` para frontend\n- ✅ **Padrão consistente**: Formato uniforme para todas as APIs de listagem\n- ✅ **Melhor UX**: Frontend pode implementar paginação facilmente\n- ✅ **Conversão de erros**: Erros de banco são convertidos para `AppError`\n\n#### 3. **Repositories Layer** - `Result\u003cT, sqlx::Error\u003e`\n\n**Antes:**\n```rust\npub async fn find_all(\u0026self) -\u003e Result\u003cVec\u003cUser\u003e, Box\u003cdyn std::error::Error\u003e\u003e {\n    // código...\n}\n```\n\n**Depois:**\n```rust\npub async fn find_all(\u0026self) -\u003e Result\u003cVec\u003cUser\u003e, sqlx::Error\u003e {\n    // código...\n}\n```\n\n**Benefícios:**\n- ✅ **Tipagem específica**: Erro específico do SQLx em vez de erro genérico\n- ✅ **Melhor performance**: Evita boxing de erros desnecessário\n- ✅ **Debugging preciso**: Erros de banco são mais específicos e informativos\n- ✅ **Consistência com SQLx**: Usa o tipo de erro nativo da biblioteca\n\n### Fluxo de Erros Atualizado\n\n```\n┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐\n│   Repository    │    │     Service     │    │      Route      │    │   HTTP Client   │\n│                 │    │                 │    │                 │    │                 │\n│ sqlx::Error     │───▶│ AppError        │───▶│ Result\u003cimpl     │───▶│ HTTP Response   │\n│                 │    │                 │    │  Responder,     │    │ (com status     │\n│                 │    │                 │    │  AppError\u003e      │    │  apropriado)    │\n└─────────────────┘    └─────────────────┘    └─────────────────┘    └─────────────────┘\n        │                       │                       │                       │\n        │ map_err()             │ automatic conversion  │ actix-web handles     │\n        ▼                       ▼                       ▼                       ▼\n   Database errors      Business logic errors    Route errors         Client response\n```\n\n### Estruturas de Dados Utilizadas\n\n#### `AppError` - Tratamento Centralizado de Erros\n```rust\npub enum AppError {\n    Conflict(Option\u003cString\u003e),\n    DatabaseError(Option\u003cString\u003e),\n    NotFound(Option\u003cString\u003e),\n    Unauthorized(Option\u003cString\u003e),\n    BadRequest(Option\u003cString\u003e),\n    InternalError(Option\u003cString\u003e),\n}\n```\n\n#### `PaginatedResponse\u003cT\u003e` - Resposta Paginada Padrão\n```rust\npub struct PaginatedResponse\u003cT\u003e {\n    pub count: i64,      // Total de registros\n    pub results: Vec\u003cT\u003e, // Dados da página atual\n    pub limit: i64,      // Limite por página\n    pub offset: i64,     // Offset da página\n}\n```\n\n### Benefícios Gerais da Nova Arquitetura\n\n1. **🔒 Tratamento de Erros Robusto**\n   - Cada camada tem responsabilidade específica\n   - Erros são propagados de forma controlada\n   - Respostas HTTP consistentes\n\n2. **📊 Paginação Padrão**\n   - Todas as listagens são paginadas automaticamente\n   - Metadados úteis para frontend\n   - Performance otimizada para grandes datasets\n\n3. **⚡ Performance Melhorada**\n   - Menos uso de `Box\u003cdyn Error\u003e` genérico\n   - Tipagem específica para erros de banco\n   - Conversões eficientes entre tipos\n\n4. **🛠️ Manutenibilidade**\n   - Código mais previsível e fácil de manter\n   - Padrões consistentes em toda a aplicação\n   - Debugging simplificado\n\n5. **🎯 Experiência do Desenvolvedor**\n   - Script gera código pronto para produção\n   - Menos boilerplate para implementar\n   - Estrutura escalável e profissional\n\n### Exemplo de Uso Completo\n\n```bash\n# Criar um novo app com a nova arquitetura\n./start_new_app.sh Product\n\n# O script gera automaticamente:\n# - Routes com Result\u003cimpl Responder, AppError\u003e\n# - Services com Result\u003cPaginatedResponse\u003cT\u003e, AppError\u003e\n# - Repositories com Result\u003cT, sqlx::Error\u003e\n# - Tratamento de erros em todas as camadas\n# - Paginação automática para listagens\n```\n\n## Estrutura do Projeto\n\n```\nsrc/\n├── app_core/           # Núcleo da aplicação\n│   ├── app_state.rs    # Estado global da aplicação\n│   ├── app_error.rs    # Tratamento centralizado de erros\n│   ├── databases/      # Configurações de banco de dados\n│   ├── app_routes.rs   # Definição de rotas\n│   ├── settings.rs     # Configurações da aplicação\n│   └── ...\n├── apps/               # Módulos da aplicação\n│   ├── user/           # Sistema de usuários e autenticação\n│   │   ├── mod.rs\n│   │   ├── models.rs\n│   │   ├── routes.rs   # Result\u003cimpl Responder, AppError\u003e\n│   │   ├── services.rs # Result\u003cPaginatedResponse\u003cT\u003e, AppError\u003e\n│   │   ├── repositories.rs # Result\u003cT, sqlx::Error\u003e\n│   │   ├── keycloak/   # Integração com Keycloak\n│   │   └── tests.rs\n│   ├── product/        # 🛍️ Sistema de produtos (E-commerce)\n│   │   ├── mod.rs\n│   │   ├── models.rs   # Product, CreateProductRequest, UpdateProductRequest\n│   │   ├── routes.rs   # CRUD completo com tratamento de erros\n│   │   ├── services.rs # Lógica de negócio e validações\n│   │   ├── repositories.rs # Acesso ao banco PostgreSQL\n│   │   └── tests.rs    # Testes abrangentes\n│   ├── tenant/         # Sistema de multi-tenancy\n│   ├── orchestrator/   # Gestão de processos de negócio\n│   ├── sync_app/       # Sistema de sincronização\n│   └── mod.rs\n├── utils/              # Utilitários\n│   ├── pagination.rs   # PaginatedResponse\u003cT\u003e\n│   ├── validation.rs   # Validadores customizados\n│   ├── jwt.rs          # Gestão de tokens JWT\n│   └── ...\n└── main.rs            # Ponto de entrada\n```\n\n## Funcionalidades\n\n### 🏗️ **Arquitetura e Infraestrutura**\n- ✅ Servidor Actix Web configurado\n- ✅ Conexão com PostgreSQL (banco principal)\n- ✅ Conexão com MongoDB (dados NoSQL)\n- ✅ Conexão com Elasticsearch (busca e indexação)\n- ✅ Sistema de configurações por ambiente\n- ✅ Logging com tracing\n- ✅ Estrutura modular escalável\n- ✅ Scripts de automação para criação de apps\n- ✅ Sistema de migrations automático\n\n### 🔧 **Qualidade de Código**\n- ✅ **Tratamento robusto de erros com AppError**\n- ✅ **Paginação automática com PaginatedResponse**\n- ✅ **Tipagem específica para erros de banco**\n- ✅ **Arquitetura em camadas com responsabilidades bem definidas**\n- ✅ **Sistema de gestão de tokens para autenticação e recuperação**\n- ✅ **Validadores customizados para email, senha, telefone, CPF e data**\n\n### 🛍️ **Módulos de E-commerce**\n- ✅ **Sistema de Usuários**: Cadastro, login, perfis e autenticação\n- ✅ **Sistema de Produtos**: CRUD completo com gestão de estoque e preços\n- ✅ **Sistema de Tenants**: Multi-tenancy para diferentes lojas\n- ✅ **Sistema de Orquestradores**: Gestão de processos de negócio\n- ✅ **Sistema de Sincronização**: Produtor/consumidor para eventos\n\n## 🔍 Sistema de Validação Customizada\n\nO projeto inclui validadores customizados para garantir a qualidade dos dados de entrada.\n\n### Validadores Disponíveis\n\n| Validador | Função | Regras |\n|-----------|--------|--------|\n| **Email** | `validate_email` | Regex: `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$` |\n| **Password** | `validate_password` | Mínimo 8 caracteres, letras e números obrigatórios |\n| **Phone** | `validate_phone` | Formato internacional: `+5511999999999` |\n| **Document** | `validate_document` | CPF: `000.000.000-00` |\n| **Birth Date** | `validate_birth_date` | Data: `YYYY-MM-DD` |\n\n### Uso nos Modelos\n\n```rust\nuse crate::utils::validation::{validate_email, validate_password, validate_phone, validate_document, validate_birth_date};\n\n#[derive(Debug, Serialize, Deserialize, Validate)]\npub struct UserRequest {\n    #[validate(custom = \"validate_email\")]\n    pub email: String,\n\n    #[validate(custom = \"validate_password\")]\n    pub password: String,\n}\n\n#[derive(Debug, Deserialize, Validate, Serialize)]\npub struct ProfileRequest {\n    #[validate(custom = \"validate_phone\")]\n    pub phone: Option\u003cString\u003e,\n\n    #[validate(custom = \"validate_document\")]\n    pub document: Option\u003cString\u003e,\n\n    #[validate(custom = \"validate_birth_date\")]\n    pub birth_date: Option\u003cString\u003e,\n}\n```\n\n### Regras de Validação Detalhadas\n\n#### **Email** (`validate_email`)\n- Formato padrão de email\n- Aceita caracteres especiais: `.`, `_`, `%`, `+`, `-`\n- Domínio válido com TLD de pelo menos 2 caracteres\n\n#### **Password** (`validate_password`)\n- **Mínimo 8 caracteres**\n- **Pelo menos uma letra** (maiúscula ou minúscula)\n- **Pelo menos um número**\n- Aceita caracteres especiais: `@`, `$`, `!`, `%`, `*`, `#`, `?`, `\u0026`\n\n#### **Phone** (`validate_phone`)\n- Formato internacional\n- Opcional: `+` no início\n- 1-15 dígitos numéricos\n- Exemplo: `+5511999999999`\n\n#### **Document** (`validate_document`)\n- Formato CPF brasileiro\n- Padrão: `000.000.000-00`\n- Pontos e hífen obrigatórios\n\n#### **Birth Date** (`validate_birth_date`)\n- Formato ISO: `YYYY-MM-DD`\n- Data válida (não aceita datas inexistentes)\n- Exemplo: `1990-12-25`\n\n### Benefícios\n\n- ✅ **Validação consistente** em toda a aplicação\n- ✅ **Mensagens de erro personalizadas** em português\n- ✅ **Regras específicas** para o contexto brasileiro\n- ✅ **Reutilização** em múltiplos modelos\n- ✅ **Manutenibilidade** centralizada\n\n## 🛍️ **Módulo de Produtos (E-commerce)**\n\nO módulo de produtos é o coração do sistema de e-commerce, implementando todas as funcionalidades necessárias para gestão de catálogo de produtos.\n\n### **Funcionalidades do Módulo**\n\n| Operação | Endpoint | Método | Descrição |\n|----------|----------|---------|-----------|\n| **Listar Produtos** | `/api/v1/products/` | `GET` | Lista paginada com filtros (nome, preço, estoque) |\n| **Buscar Produto** | `/api/v1/products/{id}` | `GET` | Busca produto específico por ID |\n| **Criar Produto** | `/api/v1/products/` | `POST` | Cria novo produto com validações |\n| **Atualizar Produto** | `/api/v1/products/{id}` | `PUT` | Atualiza produto existente |\n| **Deletar Produto** | `/api/v1/products/{id}` | `DELETE` | Remove produto (soft delete) |\n\n### **Modelo de Dados**\n\n```rust\n#[derive(Debug, Serialize, Deserialize, Clone)]\npub struct Product {\n    pub id: Uuid,                    // Identificador único\n    pub tenant_id: Uuid,             // ID do tenant/loja\n    pub name: String,                // Nome do produto\n    pub slug: String,                // URL amigável\n    pub short_description: Option\u003cString\u003e, // Descrição curta\n    pub description: Option\u003cString\u003e,       // Descrição completa\n    pub price: BigDecimal,           // Preço em centavos\n    pub stock_quantity: i32,        // Quantidade em estoque\n    pub attributes: Option\u003cserde_json::Value\u003e, // Atributos customizados\n    pub is_active: bool,             // Status ativo/inativo\n    pub dt_created: DateTime\u003cUtc\u003e,   // Data de criação\n    pub dt_updated: DateTime\u003cUtc\u003e,   // Data de atualização\n    pub dt_deleted: Option\u003cDateTime\u003cUtc\u003e\u003e, // Soft delete\n}\n```\n\n### **Validações Implementadas**\n\n- ✅ **Nome**: Obrigatório, não pode ser vazio\n- ✅ **Preço**: Deve ser positivo (em centavos)\n- ✅ **Estoque**: Deve ser não-negativo\n- ✅ **Tenant**: Produtos são isolados por loja\n- ✅ **Slug**: Geração automática baseada no nome\n\n### **Tratamento de Erros**\n\nO módulo implementa tratamento robusto de erros:\n\n```rust\n// Service retorna erro 404 quando produto não é encontrado\npub async fn get_product(app_state: \u0026AppState, id: Uuid) -\u003e Result\u003cProduct, AppError\u003e {\n    let repository = ProductRepository::new(app_state);\n    let product = repository.find_by_id(id).await?;\n\n    match product {\n        Some(product) =\u003e Ok(product),\n        None =\u003e Err(AppError::not_found(\"Produto não encontrado\")),\n    }\n}\n```\n\n### **Respostas HTTP**\n\n| Status | Operação | Body |\n|--------|----------|------|\n| **200** | Listar/Buscar/Atualizar | JSON com dados do produto |\n| **201** | Criar | JSON com mensagem de sucesso e dados |\n| **204** | Deletar | Sem conteúdo (sucesso) |\n| **404** | Produto não encontrado | JSON com mensagem de erro |\n| **400** | Dados inválidos | JSON com detalhes da validação |\n| **500** | Erro interno | JSON com mensagem de erro |\n\n### **Filtros de Listagem**\n\n```rust\n#[derive(Debug, Deserialize)]\npub struct ProductListParams {\n    pub name: Option\u003cString\u003e,        // Filtrar por nome\n    pub min_price: Option\u003ci64\u003e,      // Preço mínimo\n    pub max_price: Option\u003ci64\u003e,      // Preço máximo\n    pub limit: Option\u003ci64\u003e,          // Limite por página\n    pub offset: Option\u003ci64\u003e,         // Offset para paginação\n    pub is_active: Option\u003cbool\u003e,     // Filtrar por status\n}\n```\n\n### **Exemplo de Uso**\n\n```bash\n# Listar produtos ativos com preço entre R$ 10 e R$ 100\nGET /api/v1/products/?min_price=1000\u0026max_price=10000\u0026is_active=true\u0026limit=20\n\n# Buscar produto específico\nGET /api/v1/products/550e8400-e29b-41d4-a716-446655440000\n\n# Criar novo produto\nPOST /api/v1/products/\n{\n    \"name\": \"Smartphone XYZ\",\n    \"short_description\": \"Smartphone de última geração\",\n    \"description\": \"Smartphone com câmera de 48MP...\",\n    \"price\": 199900,  // R$ 1.999,00\n    \"stock_quantity\": 50,\n    \"is_active\": true\n}\n```\n\n### **Testes Implementados**\n\nO módulo inclui testes abrangentes:\n\n- ✅ **Testes de Models**: Validação de criação e atualização\n- ✅ **Testes de Services**: Lógica de negócio e tratamento de erros\n- ✅ **Testes de Validação**: Campos obrigatórios e formatos\n- ✅ **Testes de Integração**: Cenários de erro e sucesso\n- ✅ **Funções Auxiliares**: Dados de teste reutilizáveis\n\n---\n\n## 🔐 Sistema de Gestão de Tokens\n\nO projeto inclui um sistema completo de gestão de tokens para autenticação e recuperação de senha.\n\n### Estrutura do Banco de Dados\n\n```sql\nCREATE TABLE user_tokens (\n    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n    code TEXT NOT NULL,\n    token_type TEXT DEFAULT 'reset_password',\n    expires_at TIMESTAMP NOT NULL,\n    consumed BOOLEAN DEFAULT FALSE,\n    dt_created TIMESTAMP NOT NULL DEFAULT now()\n);\n\nCREATE INDEX idx_user_tokens_user_id ON user_tokens(user_id);\nCREATE INDEX idx_user_tokens_token_type ON user_tokens(token_type);\n```\n\n### Tipos de Tokens\n\n| Tipo | Descrição | Expiração | Uso |\n|------|-----------|-----------|-----|\n| `confirm_email` | Confirmação de email | 1 hora | Cadastro de usuário |\n| `reset_password` | Reset de senha | 1 hora | Recuperação de senha |\n\n### Modelo de Dados\n\n```rust\n#[derive(Debug, Serialize, Deserialize, Clone)]\npub struct UserToken {\n    pub id: Uuid,\n    pub user_id: Uuid,\n    pub code: String,\n    pub token_type: String,\n    pub expires_at: DateTime\u003cUtc\u003e,\n    pub consumed: bool,\n    pub dt_created: DateTime\u003cUtc\u003e,\n}\n```\n\n### Repositório de Tokens\n\nO `TokenRepository` fornece métodos para gerenciar tokens:\n\n```rust\npub struct TokenRepository\u003c'a\u003e {\n    app_state: \u0026'a AppState,\n}\n\nimpl\u003c'a\u003e TokenRepository\u003c'a\u003e {\n    // Criar token para usuário\n    pub async fn create_token(\n        \u0026self,\n        user_id: Uuid,\n        token_type: \u0026str,\n    ) -\u003e Result\u003cUserToken, sqlx::Error\u003e\n\n    // Buscar token válido por user_id e token_type\n    pub async fn find_valid_token(\n        \u0026self,\n        user_id: Uuid,\n        token_type: \u0026str,\n    ) -\u003e Result\u003cOption\u003cUserToken\u003e, sqlx::Error\u003e\n\n    // Buscar token válido por código\n    pub async fn find_valid_token_by_code(\n        \u0026self,\n        code: \u0026str,\n        token_type: \u0026str,\n    ) -\u003e Result\u003cOption\u003cUserToken\u003e, sqlx::Error\u003e\n\n    // Marcar token como consumido\n    pub async fn mark_as_consumed(\u0026self, token_id: Uuid) -\u003e Result\u003c(), sqlx::Error\u003e\n}\n```\n\n### Fluxos Implementados\n\n#### 1. **Cadastro de Usuário com Confirmação de Email**\n\n```rust\n// 1. Criar usuário e perfil\nlet user = User::new(...);\nlet profile = Profile::new(user.id);\n\n// 2. Salvar no banco\nrepository.create_user_with_profile(\u0026user, \u0026profile).await?;\n\n// 3. Criar token de confirmação\nlet confirm_token = token_repo\n    .create_token(user.id, \"confirm_email\")\n    .await?;\n\n// 4. Enviar email (implementação futura)\nprintln!(\"Token de confirmação: {}\", confirm_token.code);\n```\n\n#### 2. **Recuperação de Senha**\n\n```rust\n// 1. Verificar se usuário existe\nlet user = repository.find_by_email(\u0026email).await?;\n\n// 2. Criar token de reset\nlet reset_token = token_repo\n    .create_token(user.id, \"reset_password\")\n    .await?;\n\n// 3. Enviar email (implementação futura)\nprintln!(\"Token de reset: {}\", reset_token.code);\n```\n\n#### 3. **Alteração de Senha com Token**\n\n```rust\n// 1. Validar token\nlet token = token_repo\n    .find_valid_token_by_code(\u0026code, \"reset_password\")\n    .await?\n    .ok_or_else(|| AppError::bad_request(\"Token inválido\"))?;\n\n// 2. Alterar senha\nrepository.update_password(token.user_id, \u0026hashed_password).await?;\n\n// 3. Marcar token como consumido\ntoken_repo.mark_as_consumed(token.id).await?;\n```\n\n#### 4. **Confirmação de Email**\n\n```rust\n// 1. Validar token\nlet token = token_repo\n    .find_valid_token_by_code(\u0026code, \"confirm_email\")\n    .await?\n    .ok_or_else(|| AppError::bad_request(\"Token inválido\"))?;\n\n// 2. Confirmar email\nprofile_repo.confirm_email(token.user_id).await?;\n\n// 3. Marcar token como consumido\ntoken_repo.mark_as_consumed(token.id).await?;\n```\n\n### Endpoints da API\n\n| Método | Endpoint | Descrição |\n|--------|----------|-----------|\n| `POST` | `/api/v1/auth/register/` | Cadastro com token de confirmação |\n| `POST` | `/api/v1/auth/login/` | Login do usuário |\n| `POST` | `/api/v1/auth/forgot-password/` | Solicitar reset de senha |\n| `POST` | `/api/v1/auth/change-password/` | Alterar senha com token |\n| `GET` | `/api/v1/auth/confirm-email/{code}` | Confirmar email com token |\n\n### Segurança\n\n- **Expiração automática**: Tokens expiram em 1 hora\n- **Uso único**: Tokens são marcados como consumidos após uso\n- **Validação de tipo**: Cada token tem um tipo específico\n- **Limpeza automática**: Tokens expirados não são retornados\n- **Índices otimizados**: Busca eficiente por user_id e token_type\n\n### Próximas Implementações\n\n- [ ] **Envio de emails**: Integração com serviço de email\n- [ ] **Rate limiting**: Limitar tentativas de criação de tokens\n- [ ] **Auditoria**: Log de todas as operações com tokens\n- [ ] **Notificações**: Webhooks para eventos de token\n- [ ] **Expiração configurável**: Diferentes tempos por tipo de token\n\n## Próximos Passos\n\n### 🚀 **Funcionalidades de E-commerce**\n1. **Sistema de Categorias**: Organização hierárquica de produtos\n2. **Sistema de Imagens**: Upload e gestão de imagens de produtos\n3. **Sistema de Variações**: Produtos com diferentes opções (cor, tamanho, etc.)\n4. **Sistema de Avaliações**: Comentários e ratings dos clientes\n5. **Sistema de Descontos**: Cupons e promoções\n6. **Sistema de Carrinho**: Gestão de carrinho de compras\n7. **Sistema de Pedidos**: Processamento e gestão de pedidos\n8. **Sistema de Pagamentos**: Integração com gateways de pagamento\n\n### 🔧 **Melhorias Técnicas**\n1. **Configurar paginação dinâmica** (limit/offset via query params)\n2. **Implementar cache** para melhorar performance\n3. **Adicionar documentação OpenAPI/Swagger**\n4. **Implementar busca full-text** com Elasticsearch\n5. **Sistema de notificações** para eventos de produtos\n6. **Logs de auditoria** para todas as operações\n7. **Rate limiting** para APIs públicas\n8. **Métricas e monitoramento** com Prometheus\n\n### 📱 **Frontend e UX**\n1. **Interface administrativa** para gestão de produtos\n2. **API de busca** com filtros avançados\n3. **Sistema de tags** para categorização\n4. **Exportação de dados** (CSV, JSON)\n5. **Importação em lote** de produtos\n6. **Dashboard de métricas** de vendas ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobertolima-dev%2Frust_ecommerce","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobertolima-dev%2Frust_ecommerce","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobertolima-dev%2Frust_ecommerce/lists"}