Skip to content

Canalize Data Service (canalizeds) is a lightweight, provider-agnostic data access layer designed for modular backends such as Canalize-GW and the Kubex ecosystem. It provides a unified interface for CRUD, query, and health operations across different providers (Supabase, Postgres, Memory, File).

License

Notifications You must be signed in to change notification settings

canalize-prm/canalizeds

Canalize DB - Database Layer

Data Access Layer para o sistema Canalize PRM

License Go Version PostgreSQL

📋 Visão Geral

Canalizedb é a camada de acesso a dados do sistema Canalize PRM. Fornece models GORM, repositories, services e migrations para PostgreSQL.

Principais Funcionalidades

  • 📦 Models GORM: Mapeamento ORM para PostgreSQL
  • 🗄️ Repositories: Padrão Repository para acesso a dados
  • 💼 Services: Lógica de negócio e validações
  • 🏭 Factory: Exports públicos e dependency injection
  • 🔄 Migrations: Scripts SQL de inicialização
  • 🔐 Multi-tenant: Isolamento por company_id

🏗️ Arquitetura

canalizedb/
├── internal/
│   ├── models/
│   │   ├── prm/                    # Partner Relationship Management
│   │   │   ├── partner_model.go    # ✅ Partner models
│   │   │   ├── partner_repo.go     # ✅ Partner repository
│   │   │   ├── partner_service.go  # ✅ Partner service
│   │   │   ├── wizard_models.go    # ✅ Wizard models
│   │   │   ├── wizard_service.go   # ✅ Wizard service
│   │   │   ├── commission_rule_repo.go
│   │   │   ├── company_repo.go
│   │   │   ├── pipeline_repo.go
│   │   │   └── ...
│   │   ├── clients/                # Clientes/Customers
│   │   ├── oauth/                  # OAuth/Auth
│   │   └── notification/           # Notificações
│   ├── bootstrap/
│   │   └── embedded/               # SQL migrations
│   │       ├── 001_init.sql
│   │       ├── 002_hardening.sql
│   │       ├── 003_create_invites.sql
│   │       └── 004_wizard_and_missing_schema.sql
│   └── services/                   # Shared services
├── factory/                        # Public API
│   ├── partner.go                  # ✅ Partner exports
│   ├── wizard.go                   # ✅ Wizard exports
│   └── ...
├── go.mod
└── README.md                       # This file

Padrões de Design

  1. Repository Pattern: Abstração de acesso a dados
  2. Service Layer: Lógica de negócio separada
  3. Factory Pattern: Dependency injection e exports públicos
  4. DTO Pattern: Data Transfer Objects para APIs

🚀 Quick Start

Instalação

# Clone o repositório
git clone https://github.com/canalize-prm/canalizedb.git
cd canalizedb

# Instale dependências
go mod download

Uso Básico

import (
    "github.com/canalize-prm/canalizedb/factory"
    "gorm.io/gorm"
)

// Conectar ao banco
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})

// Criar service via factory
partnerService := factory.NewPartnerService(db)

// Criar um parceiro
dto := &factory.CreatePartnerDTO{
    Email: "partner@example.com",
    Name:  "João Silva",
    Role:  factory.RolePartner,
}
partner, err := partnerService.CreatePartner(ctx, dto)

📦 Módulos Disponíveis

1. Partners (✅ Completo)

Gerenciamento de parceiros/usuários do sistema.

Models: Partner, CreatePartnerDTO, UpdatePartnerDTO Repository: IPartnerRepo Service: IPartnerService Factory: factory.NewPartnerService(db)

📖 Documentação: internal/models/prm/PARTNERS_README.md

Exemplo:

// Listar parceiros ativos
filters := &factory.PartnerFilterParams{
    Status: ptr(factory.PartnerStatusActive),
    Page:   1,
    Limit:  20,
}
result, err := partnerService.ListPartners(ctx, filters)

2. Wizard (✅ Completo)

Sistema de onboarding guiado para novas empresas.

Models: OnboardingStatus, Pipeline, CommissionRule, SmtpSettings Repository: 8 repositories (onboarding, smtp, templates, etc) Service: IWizardService Factory: factory.NewWizardService(db)

Funcionalidades:

  • ✅ Status de onboarding
  • ✅ Configuração de empresa (CNPJ + logo)
  • ✅ Criação de pipeline com stages
  • ✅ Configuração de comissão
  • ✅ Configuração SMTP com teste

Exemplo:

// Inicializar onboarding
wizardService := factory.NewWizardService(db)
status, err := wizardService.InitializeOnboarding(ctx, companyID)

// Atualizar info da empresa
err = wizardService.UpdateCompanyCNPJAndLogo(ctx, companyID, "12.345.678/0001-90", logoBlob)

3. Clients (✅ Completo)

Gerenciamento de clientes/customers.

Models: ClientDetailed Repository: IClientRepo Service: IClientService

Exemplo:

clientRepo := clients.NewClientRepo(ctx, dbService)
client, err := clientRepo.FindOne("id = ?", clientID)

4. OAuth (✅ Parcial)

Autenticação e autorização OAuth2.

Models: OAuthClient, AuthCode Repository: OAuth repositories Service: OAuth services


🗄️ Database Schema

Tabelas Principais

Tabela Descrição Module
profiles Parceiros/Usuários PRM
companies Empresas PRM
pipelines Pipelines de vendas PRM
pipeline_stages Estágios do pipeline PRM
leads Leads/Oportunidades PRM
commissions Comissões de parceiros PRM
commission_rules Regras de comissão PRM
smtp_settings Configurações SMTP PRM
notification_templates Templates de notificação PRM
onboarding_status Status de onboarding PRM
user_invitations Convites de usuários Auth

Migrations

As migrations são executadas automaticamente via embedded SQL files:

internal/bootstrap/embedded/
├── 001_init.sql                    # Schema inicial
├── 002_hardening.sql               # Segurança e índices
├── 003_create_invites.sql          # Sistema de convites
└── 004_wizard_and_missing_schema.sql # Wizard + complementos

🔧 Configuração

Conectar ao Banco

import (
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

dsn := "host=localhost user=postgres password=secret dbname=canalize_prm port=5432 sslmode=disable"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
    Logger: logger.Default.LogMode(logger.Info),
})

Pool de Conexões

sqlDB, _ := db.DB()

// Configurações de pool
sqlDB.SetMaxIdleConns(10)
sqlDB.SetMaxOpenConns(100)
sqlDB.SetConnMaxLifetime(time.Hour)

📊 Factory Pattern

O package factory expõe interfaces e construtores públicos:

Exports Disponíveis

// Partners
factory.NewPartnerService(db) IPartnerService
factory.NewPartnerRepo(db) IPartnerRepo
factory.Partner
factory.CreatePartnerDTO
factory.PartnerStatus
factory.PartnerRole

// Wizard
factory.NewWizardService(db) IWizardService
factory.OnboardingStatus
factory.Pipeline
factory.SmtpSettings

// Clients
factory.ClientDetailed

Dependency Injection

// Gateway layer usa factory
import "github.com/canalize-prm/canalizedb/factory"

func InitServices(db *gorm.DB) {
    partnerService := factory.NewPartnerService(db)
    wizardService := factory.NewWizardService(db)
    // ...
}

🧪 Testes

Executar Testes

# Todos os testes
go test ./...

# Com coverage
go test ./... -cover -coverprofile=coverage.out

# Ver coverage
go tool cover -html=coverage.out

Testes de Integração

Requer PostgreSQL rodando:

# Subir banco para testes
docker run -d \
  -e POSTGRES_PASSWORD=test \
  -e POSTGRES_DB=canalize_test \
  -p 5433:5432 \
  postgres:14

# Executar testes
DB_TEST_PORT=5433 go test ./... -v

📈 Performance

Índices Recomendados

Já criados nas migrations:

-- Profiles (Partners)
CREATE INDEX idx_profiles_email ON profiles(email);
CREATE INDEX idx_profiles_company_id ON profiles(company_id);
CREATE INDEX idx_profiles_status ON profiles(status);

-- Leads
CREATE INDEX idx_leads_company_id ON leads(company_id);
CREATE INDEX idx_leads_stage_id ON leads(stage_id);
CREATE INDEX idx_leads_assigned_to ON leads(assigned_to);

-- Pipelines
CREATE INDEX idx_pipelines_company_id ON pipelines(company_id);
CREATE INDEX idx_pipeline_stages_pipeline_id ON pipeline_stages(pipeline_id);

Query Optimization

  • ✅ GORM usa prepared statements
  • ✅ Eager loading com Preload()
  • ✅ Paginação com Limit() e Offset()
  • ✅ Índices em foreign keys

🔐 Segurança

Multi-tenancy

Isolamento por company_id:

// Repository level
query := db.Where("company_id = ?", companyID)

Row-Level Security (RLS)

PostgreSQL RLS policies (migrations):

-- Exemplo de policy
CREATE POLICY company_isolation ON leads
    USING (company_id = current_setting('app.current_company_id')::uuid);

SQL Injection

  • ✅ GORM sanitiza inputs automaticamente
  • ✅ Prepared statements
  • NUNCA use string concatenation

🐛 Debugging

Enable SQL Logging

db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
    Logger: logger.Default.LogMode(logger.Info),
})

Output:

[2025-10-18 10:30:00] SELECT * FROM "profiles" WHERE email = 'test@example.com'

Profiling

import _ "net/http/pprof"
import "net/http"

go func() {
    http.ListenAndServe("localhost:6060", nil)
}()

Acesse: http://localhost:6060/debug/pprof/


🤝 Contribuindo

Code Style

  1. Repository: Apenas acesso a dados, sem validações
  2. Service: Validações e lógica de negócio
  3. Factory: Exports públicos e construtores
  4. Naming: IXxxRepo, IXxxService, XxxDTO

Adicionando Novo Módulo

  1. Crie internal/models/<module>/:

    • <entity>_model.go
    • <entity>_repo.go
    • <entity>_service.go
  2. Exponha via factory/<module>.go:

    type IXxxService = module.IXxxService
    func NewXxxService(db *gorm.DB) IXxxService {
        repo := module.NewXxxRepo(db)
        return module.NewXxxService(repo)
    }
  3. Documente em README_<MODULE>.md


📝 Changelog

v1.0.0 (2025-10-18)

  • ✅ Partners module completo
  • ✅ Wizard module completo
  • ✅ Clients module completo
  • ✅ Factory exports
  • ✅ Migrations automáticas

v0.9.0 (2025-10-17)

  • ✅ Estrutura inicial
  • ✅ Models básicos
  • ✅ Repository pattern

📄 Licença

MIT License - veja LICENSE para detalhes.


👥 Autores

Rafael Mori


🔗 Links


Database layer built with ❤️ for Canalize PRM

About

Canalize Data Service (canalizeds) is a lightweight, provider-agnostic data access layer designed for modular backends such as Canalize-GW and the Kubex ecosystem. It provides a unified interface for CRUD, query, and health operations across different providers (Supabase, Postgres, Memory, File).

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published