package repository import ( "context" "database/sql" "encoding/json" "fmt" "aggios-app/backend/internal/domain" "github.com/google/uuid" ) type SignupTemplateRepository struct { db *sql.DB } func NewSignupTemplateRepository(db *sql.DB) *SignupTemplateRepository { return &SignupTemplateRepository{db: db} } // Create cria um novo template de cadastro func (r *SignupTemplateRepository) Create(ctx context.Context, template *domain.SignupTemplate) error { formFieldsJSON, err := json.Marshal(template.FormFields) if err != nil { return fmt.Errorf("error marshaling form_fields: %w", err) } modulesJSON, err := json.Marshal(template.EnabledModules) if err != nil { return fmt.Errorf("error marshaling enabled_modules: %w", err) } query := ` INSERT INTO signup_templates ( name, description, slug, form_fields, enabled_modules, redirect_url, success_message, custom_logo_url, custom_primary_color, is_active, created_by ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id, created_at, updated_at ` err = r.db.QueryRowContext( ctx, query, template.Name, template.Description, template.Slug, formFieldsJSON, modulesJSON, template.RedirectURL, template.SuccessMessage, template.CustomLogoURL, template.CustomPrimaryColor, template.IsActive, template.CreatedBy, ).Scan(&template.ID, &template.CreatedAt, &template.UpdatedAt) if err != nil { return fmt.Errorf("error creating signup template: %w", err) } return nil } // FindBySlug busca um template pelo slug func (r *SignupTemplateRepository) FindBySlug(ctx context.Context, slug string) (*domain.SignupTemplate, error) { query := ` SELECT id, name, description, slug, form_fields, enabled_modules, redirect_url, success_message, custom_logo_url, custom_primary_color, is_active, usage_count, created_by, created_at, updated_at FROM signup_templates WHERE slug = $1 AND is_active = true ` var template domain.SignupTemplate var formFieldsJSON, modulesJSON []byte var redirectURL, successMessage, customLogoURL, customPrimaryColor sql.NullString err := r.db.QueryRowContext(ctx, query, slug).Scan( &template.ID, &template.Name, &template.Description, &template.Slug, &formFieldsJSON, &modulesJSON, &redirectURL, &successMessage, &customLogoURL, &customPrimaryColor, &template.IsActive, &template.UsageCount, &template.CreatedBy, &template.CreatedAt, &template.UpdatedAt, ) if redirectURL.Valid { template.RedirectURL = redirectURL.String } if successMessage.Valid { template.SuccessMessage = successMessage.String } if customLogoURL.Valid { template.CustomLogoURL = customLogoURL.String } if customPrimaryColor.Valid { template.CustomPrimaryColor = customPrimaryColor.String } if err == sql.ErrNoRows { return nil, fmt.Errorf("signup template not found") } if err != nil { return nil, fmt.Errorf("error finding signup template: %w", err) } if err := json.Unmarshal(formFieldsJSON, &template.FormFields); err != nil { return nil, fmt.Errorf("error unmarshaling form_fields: %w", err) } if err := json.Unmarshal(modulesJSON, &template.EnabledModules); err != nil { return nil, fmt.Errorf("error unmarshaling enabled_modules: %w", err) } return &template, nil } // FindByID busca um template pelo ID func (r *SignupTemplateRepository) FindByID(ctx context.Context, id uuid.UUID) (*domain.SignupTemplate, error) { query := ` SELECT id, name, description, slug, form_fields, enabled_modules, redirect_url, success_message, custom_logo_url, custom_primary_color, is_active, usage_count, created_by, created_at, updated_at FROM signup_templates WHERE id = $1 ` var template domain.SignupTemplate var formFieldsJSON, modulesJSON []byte var redirectURL, successMessage, customLogoURL, customPrimaryColor sql.NullString err := r.db.QueryRowContext(ctx, query, id).Scan( &template.ID, &template.Name, &template.Description, &template.Slug, &formFieldsJSON, &modulesJSON, &redirectURL, &successMessage, &customLogoURL, &customPrimaryColor, &template.IsActive, &template.UsageCount, &template.CreatedBy, &template.CreatedAt, &template.UpdatedAt, ) if redirectURL.Valid { template.RedirectURL = redirectURL.String } if successMessage.Valid { template.SuccessMessage = successMessage.String } if customLogoURL.Valid { template.CustomLogoURL = customLogoURL.String } if customPrimaryColor.Valid { template.CustomPrimaryColor = customPrimaryColor.String } if err == sql.ErrNoRows { return nil, fmt.Errorf("signup template not found") } if err != nil { return nil, fmt.Errorf("error finding signup template: %w", err) } if err := json.Unmarshal(formFieldsJSON, &template.FormFields); err != nil { return nil, fmt.Errorf("error unmarshaling form_fields: %w", err) } if err := json.Unmarshal(modulesJSON, &template.EnabledModules); err != nil { return nil, fmt.Errorf("error unmarshaling enabled_modules: %w", err) } return &template, nil } // List lista todos os templates func (r *SignupTemplateRepository) List(ctx context.Context) ([]*domain.SignupTemplate, error) { query := ` SELECT id, name, description, slug, form_fields, enabled_modules, redirect_url, success_message, custom_logo_url, custom_primary_color, is_active, usage_count, created_by, created_at, updated_at FROM signup_templates ORDER BY created_at DESC ` rows, err := r.db.QueryContext(ctx, query) if err != nil { return nil, fmt.Errorf("error listing signup templates: %w", err) } defer rows.Close() var templates []*domain.SignupTemplate for rows.Next() { var template domain.SignupTemplate var formFieldsJSON, modulesJSON []byte var redirectURL, successMessage, customLogoURL, customPrimaryColor sql.NullString err := rows.Scan( &template.ID, &template.Name, &template.Description, &template.Slug, &formFieldsJSON, &modulesJSON, &redirectURL, &successMessage, &customLogoURL, &customPrimaryColor, &template.IsActive, &template.UsageCount, &template.CreatedBy, &template.CreatedAt, &template.UpdatedAt, ) if err != nil { return nil, fmt.Errorf("error scanning signup template: %w", err) } if redirectURL.Valid { template.RedirectURL = redirectURL.String } if successMessage.Valid { template.SuccessMessage = successMessage.String } if customLogoURL.Valid { template.CustomLogoURL = customLogoURL.String } if customPrimaryColor.Valid { template.CustomPrimaryColor = customPrimaryColor.String } if err := json.Unmarshal(formFieldsJSON, &template.FormFields); err != nil { return nil, fmt.Errorf("error unmarshaling form_fields: %w", err) } if err := json.Unmarshal(modulesJSON, &template.EnabledModules); err != nil { return nil, fmt.Errorf("error unmarshaling enabled_modules: %w", err) } templates = append(templates, &template) } return templates, nil } // IncrementUsageCount incrementa o contador de uso func (r *SignupTemplateRepository) IncrementUsageCount(ctx context.Context, id uuid.UUID) error { query := `UPDATE signup_templates SET usage_count = usage_count + 1 WHERE id = $1` _, err := r.db.ExecContext(ctx, query, id) return err } // Update atualiza um template func (r *SignupTemplateRepository) Update(ctx context.Context, template *domain.SignupTemplate) error { formFieldsJSON, err := json.Marshal(template.FormFields) if err != nil { return fmt.Errorf("error marshaling form_fields: %w", err) } modulesJSON, err := json.Marshal(template.EnabledModules) if err != nil { return fmt.Errorf("error marshaling enabled_modules: %w", err) } query := ` UPDATE signup_templates SET name = $1, description = $2, slug = $3, form_fields = $4, enabled_modules = $5, redirect_url = $6, success_message = $7, custom_logo_url = $8, custom_primary_color = $9, is_active = $10 WHERE id = $11 ` _, err = r.db.ExecContext( ctx, query, template.Name, template.Description, template.Slug, formFieldsJSON, modulesJSON, template.RedirectURL, template.SuccessMessage, template.CustomLogoURL, template.CustomPrimaryColor, template.IsActive, template.ID, ) if err != nil { return fmt.Errorf("error updating signup template: %w", err) } return nil } // Delete deleta um template func (r *SignupTemplateRepository) Delete(ctx context.Context, id uuid.UUID) error { query := `DELETE FROM signup_templates WHERE id = $1` _, err := r.db.ExecContext(ctx, query, id) if err != nil { return fmt.Errorf("error deleting signup template: %w", err) } return nil }