Prepara versao dev 1.0
This commit is contained in:
268
backend/internal/repository/tenant_repository.go
Normal file
268
backend/internal/repository/tenant_repository.go
Normal file
@@ -0,0 +1,268 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"aggios-app/backend/internal/domain"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// TenantRepository handles database operations for tenants
|
||||
type TenantRepository struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
// NewTenantRepository creates a new tenant repository
|
||||
func NewTenantRepository(db *sql.DB) *TenantRepository {
|
||||
return &TenantRepository{db: db}
|
||||
}
|
||||
|
||||
// Create creates a new tenant
|
||||
func (r *TenantRepository) Create(tenant *domain.Tenant) error {
|
||||
query := `
|
||||
INSERT INTO tenants (
|
||||
id, name, domain, subdomain, cnpj, razao_social, email, website,
|
||||
address, city, state, zip, description, industry, created_at, updated_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
|
||||
RETURNING id, created_at, updated_at
|
||||
`
|
||||
|
||||
now := time.Now()
|
||||
tenant.ID = uuid.New()
|
||||
tenant.CreatedAt = now
|
||||
tenant.UpdatedAt = now
|
||||
|
||||
return r.db.QueryRow(
|
||||
query,
|
||||
tenant.ID,
|
||||
tenant.Name,
|
||||
tenant.Domain,
|
||||
tenant.Subdomain,
|
||||
tenant.CNPJ,
|
||||
tenant.RazaoSocial,
|
||||
tenant.Email,
|
||||
tenant.Website,
|
||||
tenant.Address,
|
||||
tenant.City,
|
||||
tenant.State,
|
||||
tenant.Zip,
|
||||
tenant.Description,
|
||||
tenant.Industry,
|
||||
tenant.CreatedAt,
|
||||
tenant.UpdatedAt,
|
||||
).Scan(&tenant.ID, &tenant.CreatedAt, &tenant.UpdatedAt)
|
||||
}
|
||||
|
||||
// FindByID finds a tenant by ID
|
||||
func (r *TenantRepository) FindByID(id uuid.UUID) (*domain.Tenant, error) {
|
||||
query := `
|
||||
SELECT id, name, domain, subdomain, cnpj, razao_social, email, phone, website,
|
||||
address, city, state, zip, description, industry, is_active, created_at, updated_at
|
||||
FROM tenants
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
tenant := &domain.Tenant{}
|
||||
var cnpj, razaoSocial, email, phone, website, address, city, state, zip, description, industry sql.NullString
|
||||
|
||||
err := r.db.QueryRow(query, id).Scan(
|
||||
&tenant.ID,
|
||||
&tenant.Name,
|
||||
&tenant.Domain,
|
||||
&tenant.Subdomain,
|
||||
&cnpj,
|
||||
&razaoSocial,
|
||||
&email,
|
||||
&phone,
|
||||
&website,
|
||||
&address,
|
||||
&city,
|
||||
&state,
|
||||
&zip,
|
||||
&description,
|
||||
&industry,
|
||||
&tenant.IsActive,
|
||||
&tenant.CreatedAt,
|
||||
&tenant.UpdatedAt,
|
||||
)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Handle nullable fields
|
||||
if cnpj.Valid {
|
||||
tenant.CNPJ = cnpj.String
|
||||
}
|
||||
if razaoSocial.Valid {
|
||||
tenant.RazaoSocial = razaoSocial.String
|
||||
}
|
||||
if email.Valid {
|
||||
tenant.Email = email.String
|
||||
}
|
||||
if phone.Valid {
|
||||
tenant.Phone = phone.String
|
||||
}
|
||||
if website.Valid {
|
||||
tenant.Website = website.String
|
||||
}
|
||||
if address.Valid {
|
||||
tenant.Address = address.String
|
||||
}
|
||||
if city.Valid {
|
||||
tenant.City = city.String
|
||||
}
|
||||
if state.Valid {
|
||||
tenant.State = state.String
|
||||
}
|
||||
if zip.Valid {
|
||||
tenant.Zip = zip.String
|
||||
}
|
||||
if description.Valid {
|
||||
tenant.Description = description.String
|
||||
}
|
||||
if industry.Valid {
|
||||
tenant.Industry = industry.String
|
||||
}
|
||||
|
||||
return tenant, nil
|
||||
}
|
||||
|
||||
// FindBySubdomain finds a tenant by subdomain
|
||||
func (r *TenantRepository) FindBySubdomain(subdomain string) (*domain.Tenant, error) {
|
||||
query := `
|
||||
SELECT id, name, domain, subdomain, created_at, updated_at
|
||||
FROM tenants
|
||||
WHERE subdomain = $1
|
||||
`
|
||||
|
||||
tenant := &domain.Tenant{}
|
||||
err := r.db.QueryRow(query, subdomain).Scan(
|
||||
&tenant.ID,
|
||||
&tenant.Name,
|
||||
&tenant.Domain,
|
||||
&tenant.Subdomain,
|
||||
&tenant.CreatedAt,
|
||||
&tenant.UpdatedAt,
|
||||
)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return tenant, err
|
||||
}
|
||||
|
||||
// SubdomainExists checks if a subdomain is already taken
|
||||
func (r *TenantRepository) SubdomainExists(subdomain string) (bool, error) {
|
||||
var exists bool
|
||||
query := `SELECT EXISTS(SELECT 1 FROM tenants WHERE subdomain = $1)`
|
||||
err := r.db.QueryRow(query, subdomain).Scan(&exists)
|
||||
return exists, err
|
||||
}
|
||||
|
||||
// FindAll returns all tenants
|
||||
func (r *TenantRepository) FindAll() ([]*domain.Tenant, error) {
|
||||
query := `
|
||||
SELECT id, name, domain, subdomain, is_active, created_at, updated_at
|
||||
FROM tenants
|
||||
ORDER BY created_at DESC
|
||||
`
|
||||
|
||||
rows, err := r.db.Query(query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var tenants []*domain.Tenant
|
||||
for rows.Next() {
|
||||
tenant := &domain.Tenant{}
|
||||
err := rows.Scan(
|
||||
&tenant.ID,
|
||||
&tenant.Name,
|
||||
&tenant.Domain,
|
||||
&tenant.Subdomain,
|
||||
&tenant.IsActive,
|
||||
&tenant.CreatedAt,
|
||||
&tenant.UpdatedAt,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tenants = append(tenants, tenant)
|
||||
}
|
||||
|
||||
if tenants == nil {
|
||||
return []*domain.Tenant{}, nil
|
||||
}
|
||||
|
||||
return tenants, nil
|
||||
}
|
||||
|
||||
// Delete removes a tenant (and cascades to related data)
|
||||
func (r *TenantRepository) Delete(id uuid.UUID) error {
|
||||
result, err := r.db.Exec(`DELETE FROM tenants WHERE id = $1`, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rows, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if rows == 0 {
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateProfile updates tenant profile information
|
||||
func (r *TenantRepository) UpdateProfile(id uuid.UUID, updates map[string]interface{}) error {
|
||||
query := `
|
||||
UPDATE tenants SET
|
||||
name = COALESCE($1, name),
|
||||
cnpj = COALESCE($2, cnpj),
|
||||
razao_social = COALESCE($3, razao_social),
|
||||
email = COALESCE($4, email),
|
||||
phone = COALESCE($5, phone),
|
||||
website = COALESCE($6, website),
|
||||
address = COALESCE($7, address),
|
||||
city = COALESCE($8, city),
|
||||
state = COALESCE($9, state),
|
||||
zip = COALESCE($10, zip),
|
||||
description = COALESCE($11, description),
|
||||
industry = COALESCE($12, industry),
|
||||
updated_at = $13
|
||||
WHERE id = $14
|
||||
`
|
||||
|
||||
_, err := r.db.Exec(
|
||||
query,
|
||||
updates["name"],
|
||||
updates["cnpj"],
|
||||
updates["razao_social"],
|
||||
updates["email"],
|
||||
updates["phone"],
|
||||
updates["website"],
|
||||
updates["address"],
|
||||
updates["city"],
|
||||
updates["state"],
|
||||
updates["zip"],
|
||||
updates["description"],
|
||||
updates["industry"],
|
||||
time.Now(),
|
||||
id,
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user