Adds CRUD and preview APIs, RBAC permissions, seeded system templates, and migrates OTP email/SMS to template rendering. Co-authored-by: Cursor <cursoragent@cursor.com>
64 lines
1.4 KiB
Go
64 lines
1.4 KiB
Go
package emailtemplates
|
|
|
|
import (
|
|
"Yimaru-Backend/internal/domain"
|
|
"html/template"
|
|
"regexp"
|
|
"strings"
|
|
texttemplate "text/template"
|
|
)
|
|
|
|
var slugPattern = regexp.MustCompile(`^[a-z][a-z0-9_]*$`)
|
|
|
|
func normalizeSlug(slug string) (string, error) {
|
|
value := strings.ToLower(strings.TrimSpace(slug))
|
|
if value == "" {
|
|
return "", errSlugRequired
|
|
}
|
|
if !slugPattern.MatchString(value) {
|
|
return "", errInvalidSlug
|
|
}
|
|
return value, nil
|
|
}
|
|
|
|
func normalizeStatus(status *string) (string, error) {
|
|
if status == nil || strings.TrimSpace(*status) == "" {
|
|
return domain.EmailTemplateStatusActive, nil
|
|
}
|
|
value := strings.ToUpper(strings.TrimSpace(*status))
|
|
switch value {
|
|
case domain.EmailTemplateStatusActive, domain.EmailTemplateStatusInactive:
|
|
return value, nil
|
|
default:
|
|
return "", errInvalidStatus
|
|
}
|
|
}
|
|
|
|
func normalizeVariables(vars []string) []string {
|
|
if len(vars) == 0 {
|
|
return []string{}
|
|
}
|
|
out := make([]string, 0, len(vars))
|
|
seen := make(map[string]struct{}, len(vars))
|
|
for _, variable := range vars {
|
|
trimmed := strings.TrimSpace(variable)
|
|
if trimmed == "" {
|
|
continue
|
|
}
|
|
if _, ok := seen[trimmed]; ok {
|
|
continue
|
|
}
|
|
seen[trimmed] = struct{}{}
|
|
out = append(out, trimmed)
|
|
}
|
|
return out
|
|
}
|
|
|
|
func newTextTemplate(name, content string) (*texttemplate.Template, error) {
|
|
return texttemplate.New(name).Parse(content)
|
|
}
|
|
|
|
func newHTMLTemplate(name, content string) (*template.Template, error) {
|
|
return template.New(name).Parse(content)
|
|
}
|