Implements automated onboarding emails to encourage user engagement: - Post-verification welcome email with 5 tips (sent after email verification) - "No Residence" email (2+ days after registration with no property) - "No Tasks" email (5+ days after first residence with no tasks) Key features: - Each onboarding email type sent only once per user (enforced by unique constraint) - Email open tracking via tracking pixel endpoint - Daily scheduled job at 10:00 AM UTC to process eligible users - Admin panel UI for viewing sent emails, stats, and manual sending - Admin can send any email type to users from the user detail Testing section New files: - internal/models/onboarding_email.go - Database model with tracking - internal/services/onboarding_email_service.go - Business logic and eligibility queries - internal/handlers/tracking_handler.go - Email open tracking endpoint - internal/admin/handlers/onboarding_handler.go - Admin API endpoints - admin/src/app/(dashboard)/onboarding-emails/ - Admin UI pages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
35 lines
1.4 KiB
Go
35 lines
1.4 KiB
Go
package models
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// OnboardingEmailType represents the type of onboarding email
|
|
type OnboardingEmailType string
|
|
|
|
const (
|
|
// OnboardingEmailNoResidence is sent when a user has not created a residence after 2 days
|
|
OnboardingEmailNoResidence OnboardingEmailType = "no_residence"
|
|
// OnboardingEmailNoTasks is sent when a user has created a residence but no tasks after 5 days
|
|
OnboardingEmailNoTasks OnboardingEmailType = "no_tasks"
|
|
)
|
|
|
|
// OnboardingEmail tracks sent onboarding emails per user
|
|
// Each email type can only be sent once per user (enforced by unique constraint on user_id + email_type)
|
|
type OnboardingEmail struct {
|
|
ID uint `gorm:"primaryKey" json:"id"`
|
|
UserID uint `gorm:"not null;index" json:"user_id"`
|
|
User User `gorm:"foreignKey:UserID" json:"user,omitempty"`
|
|
EmailType OnboardingEmailType `gorm:"type:varchar(50);not null;index" json:"email_type"`
|
|
SentAt time.Time `gorm:"not null" json:"sent_at"`
|
|
OpenedAt *time.Time `json:"opened_at"`
|
|
TrackingID string `gorm:"type:varchar(64);uniqueIndex" json:"tracking_id"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
// TableName returns the table name for OnboardingEmail
|
|
func (OnboardingEmail) TableName() string {
|
|
return "onboarding_emails"
|
|
}
|