Rebrand from Casera/MyCrib to honeyDue
Total rebrand across all Go API source files: - Go module path: casera-api -> honeydue-api - All imports updated (130+ files) - Docker: containers, images, networks renamed - Email templates: support email, noreply, icon URL - Domains: casera.app/mycrib.treytartt.com -> honeyDue.treytartt.com - Bundle IDs: com.tt.casera -> com.tt.honeyDue - IAP product IDs updated - Landing page, admin panel, config defaults - Seeds, CI workflows, Makefile, docs - Database table names preserved (no migration needed) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/config"
|
||||
"github.com/treytartt/honeydue-api/internal/config"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -11,12 +11,12 @@ import (
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/apperrors"
|
||||
"github.com/treytartt/casera-api/internal/config"
|
||||
"github.com/treytartt/casera-api/internal/dto/requests"
|
||||
"github.com/treytartt/casera-api/internal/dto/responses"
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/apperrors"
|
||||
"github.com/treytartt/honeydue-api/internal/config"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/requests"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/responses"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
)
|
||||
|
||||
// Deprecated: Legacy error constants - kept for reference during transition
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/config"
|
||||
"github.com/treytartt/honeydue-api/internal/config"
|
||||
)
|
||||
|
||||
// CacheService provides Redis caching functionality
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/apperrors"
|
||||
"github.com/treytartt/casera-api/internal/dto/requests"
|
||||
"github.com/treytartt/casera-api/internal/dto/responses"
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/apperrors"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/requests"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/responses"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
)
|
||||
|
||||
// Deprecated: Use apperrors.NotFound("error.contractor_not_found") instead
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/dto/requests"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/casera-api/internal/testutil"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/requests"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/testutil"
|
||||
)
|
||||
|
||||
func setupContractorService(t *testing.T) (*ContractorService, *repositories.ContractorRepository, *repositories.ResidenceRepository) {
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/apperrors"
|
||||
"github.com/treytartt/casera-api/internal/dto/requests"
|
||||
"github.com/treytartt/casera-api/internal/dto/responses"
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/apperrors"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/requests"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/responses"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
)
|
||||
|
||||
// Document-related errors
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
"gopkg.in/gomail.v2"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/config"
|
||||
"github.com/treytartt/honeydue-api/internal/config"
|
||||
)
|
||||
|
||||
// EmailService handles sending emails
|
||||
@@ -140,17 +140,17 @@ func (s *EmailService) SendEmailWithEmbeddedImages(to, subject, htmlBody, textBo
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Casera "Warm Sage" Email Design System
|
||||
// Matching the web landing page: casera.app
|
||||
// honeyDue "Warm Sage" Email Design System
|
||||
// Matching the web landing page: honeyDue.treytartt.com
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
// emailIconURL is the URL for the email icon
|
||||
const emailIconURL = "https://casera.app/images/icon.png"
|
||||
const emailIconURL = "https://honeyDue.treytartt.com/images/icon.png"
|
||||
|
||||
// emailFontStack — Outfit via Google Fonts with progressive fallback
|
||||
const emailFontStack = "Outfit, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif"
|
||||
|
||||
// baseEmailTemplate wraps all email content in the Casera shell:
|
||||
// baseEmailTemplate wraps all email content in the honeyDue shell:
|
||||
// cream background → white card with warm shadow → sage brand stripe at top
|
||||
func baseEmailTemplate() string {
|
||||
return `<!DOCTYPE html>
|
||||
@@ -238,10 +238,10 @@ func emailHeader(subtitle string) string {
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td style="vertical-align: middle; padding-right: 14px;">
|
||||
<img src="%s" alt="Casera" width="44" height="44" style="display: block; border-radius: 12px; border: 0;" />
|
||||
<img src="%s" alt="honeyDue" width="44" height="44" style="display: block; border-radius: 12px; border: 0;" />
|
||||
</td>
|
||||
<td style="vertical-align: middle;">
|
||||
<p style="font-family: %s; font-size: 22px; font-weight: 800; color: #2D3436; margin: 0; letter-spacing: -0.5px;">Casera</p>
|
||||
<p style="font-family: %s; font-size: 22px; font-weight: 800; color: #2D3436; margin: 0; letter-spacing: -0.5px;">honeyDue</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -276,8 +276,8 @@ func emailFooter(year int) string {
|
||||
<table role="presentation" width="100%%" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td style="padding: 24px 48px 32px 48px; text-align: center;">
|
||||
<p style="font-family: %s; font-size: 12px; color: #8A8F87; margin: 0;">© %d Casera. All rights reserved.</p>
|
||||
<p style="font-family: %s; font-size: 12px; margin: 8px 0 0 0;"><a href="mailto:support@casera.app" style="color: #6B8F71; text-decoration: none;">support@casera.app</a></p>
|
||||
<p style="font-family: %s; font-size: 12px; color: #8A8F87; margin: 0;">© %d honeyDue. All rights reserved.</p>
|
||||
<p style="font-family: %s; font-size: 12px; margin: 8px 0 0 0;"><a href="mailto:honeydue@treymail.com" style="color: #6B8F71; text-decoration: none;">honeydue@treymail.com</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>`, emailDivider(), emailFontStack, year, emailFontStack)
|
||||
@@ -395,7 +395,7 @@ func emailTipCard(number, title, description, accentColor, bgColor, titleColor s
|
||||
|
||||
// SendWelcomeEmail sends a welcome email with verification code
|
||||
func (s *EmailService) SendWelcomeEmail(to, firstName, code string) error {
|
||||
subject := "Welcome to Casera - Verify Your Email"
|
||||
subject := "Welcome to honeyDue - Verify Your Email"
|
||||
|
||||
name := firstName
|
||||
if name == "" {
|
||||
@@ -413,7 +413,7 @@ func (s *EmailService) SendWelcomeEmail(to, firstName, code string) error {
|
||||
|
||||
%s
|
||||
|
||||
<p style="font-family: %s; font-size: 13px; line-height: 1.6; color: #8A8F87; margin: 16px 0 0 0;">If you didn't create a Casera account, you can safely ignore this email.</p>
|
||||
<p style="font-family: %s; font-size: 13px; line-height: 1.6; color: #8A8F87; margin: 16px 0 0 0;">If you didn't create a honeyDue account, you can safely ignore this email.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -427,7 +427,7 @@ func (s *EmailService) SendWelcomeEmail(to, firstName, code string) error {
|
||||
|
||||
htmlBody := fmt.Sprintf(baseEmailTemplate(), subject, bodyContent)
|
||||
|
||||
textBody := fmt.Sprintf(`Welcome to Casera!
|
||||
textBody := fmt.Sprintf(`Welcome to honeyDue!
|
||||
|
||||
Hi %s,
|
||||
|
||||
@@ -437,9 +437,9 @@ Your verification code: %s
|
||||
|
||||
This code expires in 24 hours.
|
||||
|
||||
If you didn't create a Casera account, you can safely ignore this email.
|
||||
If you didn't create a honeyDue account, you can safely ignore this email.
|
||||
|
||||
- The Casera Team
|
||||
- The honeyDue Team
|
||||
`, name, code)
|
||||
|
||||
return s.SendEmail(to, subject, htmlBody, textBody)
|
||||
@@ -447,7 +447,7 @@ If you didn't create a Casera account, you can safely ignore this email.
|
||||
|
||||
// SendAppleWelcomeEmail sends a welcome email for Apple Sign In users (no verification needed)
|
||||
func (s *EmailService) SendAppleWelcomeEmail(to, firstName string) error {
|
||||
subject := "Welcome to Casera!"
|
||||
subject := "Welcome to honeyDue!"
|
||||
|
||||
name := firstName
|
||||
if name == "" {
|
||||
@@ -471,21 +471,21 @@ func (s *EmailService) SendAppleWelcomeEmail(to, firstName string) error {
|
||||
|
||||
%s
|
||||
|
||||
<p style="font-family: %s; font-size: 13px; line-height: 1.6; color: #8A8F87; margin: 24px 0 0 0;">Questions? Reach out anytime at <a href="mailto:support@casera.app" style="color: #6B8F71; text-decoration: none; font-weight: 600;">support@casera.app</a></p>
|
||||
<p style="font-family: %s; font-size: 13px; line-height: 1.6; color: #8A8F87; margin: 24px 0 0 0;">Questions? Reach out anytime at <a href="mailto:honeydue@treymail.com" style="color: #6B8F71; text-decoration: none; font-weight: 600;">honeydue@treymail.com</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
%s`,
|
||||
emailHeader("Welcome to Casera!"),
|
||||
emailHeader("Welcome to honeyDue!"),
|
||||
emailFontStack, name,
|
||||
emailCalloutBox(features),
|
||||
emailButton("Open Casera", "casera://home", "#C4856A"),
|
||||
emailButton("Open honeyDue", "honeydue://home", "#C4856A"),
|
||||
emailFontStack,
|
||||
emailFooter(time.Now().Year()))
|
||||
|
||||
htmlBody := fmt.Sprintf(baseEmailTemplate(), subject, bodyContent)
|
||||
|
||||
textBody := fmt.Sprintf(`Welcome to Casera!
|
||||
textBody := fmt.Sprintf(`Welcome to honeyDue!
|
||||
|
||||
Hi %s,
|
||||
|
||||
@@ -496,9 +496,9 @@ Your account is ready! Here's what you can do:
|
||||
- Contractor Directory: Keep your trusted pros organized
|
||||
- Document Storage: Store warranties, manuals, and important records
|
||||
|
||||
Questions? Reach out anytime at support@casera.app
|
||||
Questions? Reach out anytime at honeydue@treymail.com
|
||||
|
||||
- The Casera Team
|
||||
- The honeyDue Team
|
||||
`, name)
|
||||
|
||||
return s.SendEmail(to, subject, htmlBody, textBody)
|
||||
@@ -506,7 +506,7 @@ Questions? Reach out anytime at support@casera.app
|
||||
|
||||
// SendGoogleWelcomeEmail sends a welcome email for Google Sign In users (no verification needed)
|
||||
func (s *EmailService) SendGoogleWelcomeEmail(to, firstName string) error {
|
||||
subject := "Welcome to Casera!"
|
||||
subject := "Welcome to honeyDue!"
|
||||
|
||||
name := firstName
|
||||
if name == "" {
|
||||
@@ -530,21 +530,21 @@ func (s *EmailService) SendGoogleWelcomeEmail(to, firstName string) error {
|
||||
|
||||
%s
|
||||
|
||||
<p style="font-family: %s; font-size: 13px; line-height: 1.6; color: #8A8F87; margin: 24px 0 0 0;">Questions? Reach out anytime at <a href="mailto:support@casera.app" style="color: #6B8F71; text-decoration: none; font-weight: 600;">support@casera.app</a></p>
|
||||
<p style="font-family: %s; font-size: 13px; line-height: 1.6; color: #8A8F87; margin: 24px 0 0 0;">Questions? Reach out anytime at <a href="mailto:honeydue@treymail.com" style="color: #6B8F71; text-decoration: none; font-weight: 600;">honeydue@treymail.com</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
%s`,
|
||||
emailHeader("Welcome to Casera!"),
|
||||
emailHeader("Welcome to honeyDue!"),
|
||||
emailFontStack, name,
|
||||
emailCalloutBox(features),
|
||||
emailButton("Open Casera", "casera://home", "#C4856A"),
|
||||
emailButton("Open honeyDue", "honeydue://home", "#C4856A"),
|
||||
emailFontStack,
|
||||
emailFooter(time.Now().Year()))
|
||||
|
||||
htmlBody := fmt.Sprintf(baseEmailTemplate(), subject, bodyContent)
|
||||
|
||||
textBody := fmt.Sprintf(`Welcome to Casera!
|
||||
textBody := fmt.Sprintf(`Welcome to honeyDue!
|
||||
|
||||
Hi %s,
|
||||
|
||||
@@ -555,9 +555,9 @@ Your account is ready! Here's what you can do:
|
||||
- Contractor Directory: Keep your trusted pros organized
|
||||
- Document Storage: Store warranties, manuals, and important records
|
||||
|
||||
Questions? Reach out anytime at support@casera.app
|
||||
Questions? Reach out anytime at honeydue@treymail.com
|
||||
|
||||
- The Casera Team
|
||||
- The honeyDue Team
|
||||
`, name)
|
||||
|
||||
return s.SendEmail(to, subject, htmlBody, textBody)
|
||||
@@ -565,7 +565,7 @@ Questions? Reach out anytime at support@casera.app
|
||||
|
||||
// SendPostVerificationEmail sends a welcome email after user verifies their email address
|
||||
func (s *EmailService) SendPostVerificationEmail(to, firstName string) error {
|
||||
subject := "You're All Set! Getting Started with Casera"
|
||||
subject := "You're All Set! Getting Started with honeyDue"
|
||||
|
||||
name := firstName
|
||||
if name == "" {
|
||||
@@ -584,13 +584,13 @@ func (s *EmailService) SendPostVerificationEmail(to, firstName string) error {
|
||||
<table role="presentation" width="100%%" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td class="email-body" style="padding: 0 48px 40px 48px;">
|
||||
<p style="font-family: %s; font-size: 16px; line-height: 1.7; color: #4B5563; margin: 0 0 24px 0;">Hi %s, your email is verified and you're ready to go! Here's how to get the most out of Casera:</p>
|
||||
<p style="font-family: %s; font-size: 16px; line-height: 1.7; color: #4B5563; margin: 0 0 24px 0;">Hi %s, your email is verified and you're ready to go! Here's how to get the most out of honeyDue:</p>
|
||||
|
||||
%s
|
||||
|
||||
%s
|
||||
|
||||
<p style="font-family: %s; font-size: 13px; line-height: 1.6; color: #8A8F87; margin: 24px 0 0 0;">Questions or feedback? We'd love to hear from you at <a href="mailto:support@casera.app" style="color: #6B8F71; text-decoration: none; font-weight: 600;">support@casera.app</a></p>
|
||||
<p style="font-family: %s; font-size: 13px; line-height: 1.6; color: #8A8F87; margin: 24px 0 0 0;">Questions or feedback? We'd love to hear from you at <a href="mailto:honeydue@treymail.com" style="color: #6B8F71; text-decoration: none; font-weight: 600;">honeydue@treymail.com</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -598,7 +598,7 @@ func (s *EmailService) SendPostVerificationEmail(to, firstName string) error {
|
||||
emailHeader("You're all set!"),
|
||||
emailFontStack, name,
|
||||
tips,
|
||||
emailButton("Get Started", "casera://home", "#C4856A"),
|
||||
emailButton("Get Started", "honeydue://home", "#C4856A"),
|
||||
emailFontStack,
|
||||
emailFooter(time.Now().Year()))
|
||||
|
||||
@@ -608,7 +608,7 @@ func (s *EmailService) SendPostVerificationEmail(to, firstName string) error {
|
||||
|
||||
Hi %s,
|
||||
|
||||
Your email is verified and you're ready to go! Here's how to get the most out of Casera:
|
||||
Your email is verified and you're ready to go! Here's how to get the most out of honeyDue:
|
||||
|
||||
1. ADD YOUR PROPERTY
|
||||
Start by adding your home. You can manage multiple properties and share access with family.
|
||||
@@ -625,9 +625,9 @@ Upload warranties, manuals, insurance policies. Find them instantly instead of d
|
||||
5. SAVE YOUR CONTRACTORS
|
||||
Keep your trusted plumber, electrician, and other pros organized and one tap away.
|
||||
|
||||
Questions? support@casera.app
|
||||
Questions? honeydue@treymail.com
|
||||
|
||||
- The Casera Team
|
||||
- The honeyDue Team
|
||||
`, name)
|
||||
|
||||
return s.SendEmail(to, subject, htmlBody, textBody)
|
||||
@@ -635,7 +635,7 @@ Questions? support@casera.app
|
||||
|
||||
// SendVerificationEmail sends an email verification code
|
||||
func (s *EmailService) SendVerificationEmail(to, firstName, code string) error {
|
||||
subject := "Casera - Verify Your Email"
|
||||
subject := "honeyDue - Verify Your Email"
|
||||
|
||||
name := firstName
|
||||
if name == "" {
|
||||
@@ -677,7 +677,7 @@ This code expires in 24 hours.
|
||||
|
||||
If you didn't request this, you can safely ignore this email.
|
||||
|
||||
- The Casera Team
|
||||
- The honeyDue Team
|
||||
`, name, code)
|
||||
|
||||
return s.SendEmail(to, subject, htmlBody, textBody)
|
||||
@@ -685,7 +685,7 @@ If you didn't request this, you can safely ignore this email.
|
||||
|
||||
// SendPasswordResetEmail sends a password reset email
|
||||
func (s *EmailService) SendPasswordResetEmail(to, firstName, code string) error {
|
||||
subject := "Casera - Password Reset Request"
|
||||
subject := "honeyDue - Password Reset Request"
|
||||
|
||||
name := firstName
|
||||
if name == "" {
|
||||
@@ -727,7 +727,7 @@ This code expires in 15 minutes.
|
||||
|
||||
If you didn't request a password reset, please ignore this email. Your password will remain unchanged.
|
||||
|
||||
- The Casera Team
|
||||
- The honeyDue Team
|
||||
`, name, code)
|
||||
|
||||
return s.SendEmail(to, subject, htmlBody, textBody)
|
||||
@@ -735,7 +735,7 @@ If you didn't request a password reset, please ignore this email. Your password
|
||||
|
||||
// SendPasswordChangedEmail sends a password changed confirmation email
|
||||
func (s *EmailService) SendPasswordChangedEmail(to, firstName string) error {
|
||||
subject := "Casera - Your Password Has Been Changed"
|
||||
subject := "honeyDue - Your Password Has Been Changed"
|
||||
|
||||
name := firstName
|
||||
if name == "" {
|
||||
@@ -761,7 +761,7 @@ func (s *EmailService) SendPasswordChangedEmail(to, firstName string) error {
|
||||
emailHeader("Password changed"),
|
||||
emailFontStack, name,
|
||||
emailFontStack, changeTime,
|
||||
emailAlertBox("Wasn't you?", "If you didn't make this change, contact us immediately at support@casera.app or reset your password right away.", "#C4856A", "#FDF3EE", "#A06B52"),
|
||||
emailAlertBox("Wasn't you?", "If you didn't make this change, contact us immediately at honeydue@treymail.com or reset your password right away.", "#C4856A", "#FDF3EE", "#A06B52"),
|
||||
emailFooter(time.Now().Year()))
|
||||
|
||||
htmlBody := fmt.Sprintf(baseEmailTemplate(), subject, bodyContent)
|
||||
@@ -772,9 +772,9 @@ Hi %s,
|
||||
|
||||
Your password was successfully changed on %s.
|
||||
|
||||
If you didn't make this change, contact us immediately at support@casera.app or reset your password right away.
|
||||
If you didn't make this change, contact us immediately at honeydue@treymail.com or reset your password right away.
|
||||
|
||||
- The Casera Team
|
||||
- The honeyDue Team
|
||||
`, name, changeTime)
|
||||
|
||||
return s.SendEmail(to, subject, htmlBody, textBody)
|
||||
@@ -783,7 +783,7 @@ If you didn't make this change, contact us immediately at support@casera.app or
|
||||
// SendTaskCompletedEmail sends an email notification when a task is completed
|
||||
// images parameter is optional - pass nil or empty slice if no images
|
||||
func (s *EmailService) SendTaskCompletedEmail(to, recipientName, taskTitle, completedByName, residenceName string, images []EmbeddedImage) error {
|
||||
subject := fmt.Sprintf("Casera - Task Completed: %s", taskTitle)
|
||||
subject := fmt.Sprintf("honeyDue - Task Completed: %s", taskTitle)
|
||||
|
||||
name := recipientName
|
||||
if name == "" {
|
||||
@@ -872,7 +872,7 @@ Task: %s
|
||||
Completed by: %s
|
||||
Completed on: %s%s
|
||||
|
||||
- The Casera Team
|
||||
- The honeyDue Team
|
||||
`, name, residenceName, taskTitle, completedByName, completedTime, imagesText)
|
||||
|
||||
// Use embedded images method if we have images, otherwise use simple send
|
||||
@@ -884,7 +884,7 @@ Completed on: %s%s
|
||||
|
||||
// SendTasksReportEmail sends a tasks report email with PDF attachment
|
||||
func (s *EmailService) SendTasksReportEmail(to, recipientName, residenceName string, totalTasks, completed, pending, overdue int, pdfData []byte) error {
|
||||
subject := fmt.Sprintf("Casera - Tasks Report for %s", residenceName)
|
||||
subject := fmt.Sprintf("honeyDue - Tasks Report for %s", residenceName)
|
||||
|
||||
name := recipientName
|
||||
if name == "" {
|
||||
@@ -942,7 +942,7 @@ func (s *EmailService) SendTasksReportEmail(to, recipientName, residenceName str
|
||||
emailHeader("Tasks report"),
|
||||
emailFontStack, name, residenceName,
|
||||
emailCalloutBox(statRow),
|
||||
emailButton("Open Casera", "casera://tasks", "#6B8F71"),
|
||||
emailButton("Open honeyDue", "honeydue://tasks", "#6B8F71"),
|
||||
emailFontStack,
|
||||
emailFooter(time.Now().Year()))
|
||||
|
||||
@@ -958,7 +958,7 @@ Total: %d | Completed: %d | Pending: %d | Overdue: %d
|
||||
|
||||
The full report is attached as a PDF.
|
||||
|
||||
- The Casera Team
|
||||
- The honeyDue Team
|
||||
`, residenceName, name, residenceName, totalTasks, completed, pending, overdue)
|
||||
|
||||
// Create filename with timestamp
|
||||
@@ -978,7 +978,7 @@ The full report is attached as a PDF.
|
||||
|
||||
// SendNoResidenceOnboardingEmail sends an onboarding email to users who haven't created a residence
|
||||
func (s *EmailService) SendNoResidenceOnboardingEmail(to, firstName, baseURL, trackingID string) error {
|
||||
subject := "Get started with Casera - Add your first property"
|
||||
subject := "Get started with honeyDue - Add your first property"
|
||||
|
||||
name := firstName
|
||||
if name == "" {
|
||||
@@ -998,7 +998,7 @@ func (s *EmailService) SendNoResidenceOnboardingEmail(to, firstName, baseURL, tr
|
||||
<table role="presentation" width="100%%" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td class="email-body" style="padding: 0 48px 40px 48px;">
|
||||
<p style="font-family: %s; font-size: 16px; line-height: 1.7; color: #4B5563; margin: 0 0 24px 0;">Hi %s, you haven't added your first property yet. It only takes a minute and unlocks everything Casera has to offer:</p>
|
||||
<p style="font-family: %s; font-size: 16px; line-height: 1.7; color: #4B5563; margin: 0 0 24px 0;">Hi %s, you haven't added your first property yet. It only takes a minute and unlocks everything honeyDue has to offer:</p>
|
||||
|
||||
%s
|
||||
|
||||
@@ -1013,7 +1013,7 @@ func (s *EmailService) SendNoResidenceOnboardingEmail(to, firstName, baseURL, tr
|
||||
emailHeader("Add your first property"),
|
||||
emailFontStack, name,
|
||||
emailCalloutBox(features),
|
||||
emailButton("Add Your First Property", "casera://add-property", "#C4856A"),
|
||||
emailButton("Add Your First Property", "honeydue://add-property", "#C4856A"),
|
||||
emailFontStack,
|
||||
trackingPixel,
|
||||
emailFooter(time.Now().Year()))
|
||||
@@ -1031,9 +1031,9 @@ You haven't added your first property yet. It only takes a minute!
|
||||
- Store important documents
|
||||
- Manage contractors
|
||||
|
||||
Open the Casera app and tap + to get started.
|
||||
Open the honeyDue app and tap + to get started.
|
||||
|
||||
- The Casera Team
|
||||
- The honeyDue Team
|
||||
`, name)
|
||||
|
||||
return s.SendEmail(to, subject, htmlBody, textBody)
|
||||
@@ -1041,7 +1041,7 @@ Open the Casera app and tap + to get started.
|
||||
|
||||
// SendNoTasksOnboardingEmail sends an onboarding email to users who have a property but no tasks
|
||||
func (s *EmailService) SendNoTasksOnboardingEmail(to, firstName, baseURL, trackingID string) error {
|
||||
subject := "Stay on top of home maintenance with Casera"
|
||||
subject := "Stay on top of home maintenance with honeyDue"
|
||||
|
||||
name := firstName
|
||||
if name == "" {
|
||||
@@ -1077,7 +1077,7 @@ func (s *EmailService) SendNoTasksOnboardingEmail(to, firstName, baseURL, tracki
|
||||
emailHeader("Create your first task"),
|
||||
emailFontStack, name,
|
||||
emailCalloutBox(features),
|
||||
emailButton("Create Your First Task", "casera://add-task", "#C4856A"),
|
||||
emailButton("Create Your First Task", "honeydue://add-task", "#C4856A"),
|
||||
emailFontStack,
|
||||
trackingPixel,
|
||||
emailFooter(time.Now().Year()))
|
||||
@@ -1098,7 +1098,7 @@ Great job adding your property! Now set up your first task. Here are some ideas:
|
||||
|
||||
Set up recurring tasks and we'll remind you when they're due.
|
||||
|
||||
- The Casera Team
|
||||
- The honeyDue Team
|
||||
`, name)
|
||||
|
||||
return s.SendEmail(to, subject, htmlBody, textBody)
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/config"
|
||||
"github.com/treytartt/honeydue-api/internal/config"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
"google.golang.org/api/androidpublisher/v3"
|
||||
"google.golang.org/api/option"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/config"
|
||||
"github.com/treytartt/honeydue-api/internal/config"
|
||||
)
|
||||
|
||||
// IAP validation errors
|
||||
|
||||
@@ -9,10 +9,10 @@ import (
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/apperrors"
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/casera-api/internal/push"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/apperrors"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/push"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
)
|
||||
|
||||
// Notification-related errors
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/casera-api/internal/push"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/casera-api/internal/testutil"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/push"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/testutil"
|
||||
)
|
||||
|
||||
func setupNotificationService(t *testing.T) (*NotificationService, *repositories.NotificationRepository) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
)
|
||||
|
||||
// OnboardingEmailService handles sending and tracking onboarding emails
|
||||
|
||||
@@ -165,7 +165,7 @@ func (s *PDFService) GenerateTasksReportPDF(report *TasksReportResponse) ([]byte
|
||||
pdf.SetY(-25)
|
||||
pdf.SetFont("Arial", "I", 9)
|
||||
pdf.SetTextColor(128, 128, 128)
|
||||
pdf.Cell(0, 10, fmt.Sprintf("Casera - Tasks Report for %s", report.ResidenceName))
|
||||
pdf.Cell(0, 10, fmt.Sprintf("honeyDue - Tasks Report for %s", report.ResidenceName))
|
||||
pdf.Ln(5)
|
||||
pdf.Cell(0, 10, fmt.Sprintf("Generated on %s", time.Now().UTC().Format("2006-01-02 15:04:05 UTC")))
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/apperrors"
|
||||
"github.com/treytartt/casera-api/internal/config"
|
||||
"github.com/treytartt/casera-api/internal/dto/requests"
|
||||
"github.com/treytartt/casera-api/internal/dto/responses"
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/casera-api/internal/task/predicates"
|
||||
"github.com/treytartt/honeydue-api/internal/apperrors"
|
||||
"github.com/treytartt/honeydue-api/internal/config"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/requests"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/responses"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/task/predicates"
|
||||
)
|
||||
|
||||
// Common errors (deprecated - kept for reference, now using apperrors package)
|
||||
@@ -383,7 +383,7 @@ func (s *ResidenceService) GetShareCode(residenceID, userID uint) (*responses.Sh
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// GenerateSharePackage generates a share code and returns package metadata for .casera file
|
||||
// GenerateSharePackage generates a share code and returns package metadata for .honeydue file
|
||||
func (s *ResidenceService) GenerateSharePackage(residenceID, userID uint, expiresInHours int) (*responses.SharePackageResponse, error) {
|
||||
// Check ownership (only owners can share residences)
|
||||
isOwner, err := s.residenceRepo.IsOwner(residenceID, userID)
|
||||
|
||||
@@ -11,11 +11,11 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/config"
|
||||
"github.com/treytartt/casera-api/internal/dto/requests"
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/casera-api/internal/testutil"
|
||||
"github.com/treytartt/honeydue-api/internal/config"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/requests"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/testutil"
|
||||
)
|
||||
|
||||
func setupResidenceService(t *testing.T) (*ResidenceService, *repositories.ResidenceRepository, *repositories.UserRepository) {
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/config"
|
||||
"github.com/treytartt/honeydue-api/internal/config"
|
||||
)
|
||||
|
||||
// StorageService handles file uploads to local filesystem
|
||||
|
||||
@@ -13,9 +13,9 @@ import (
|
||||
"github.com/stripe/stripe-go/v81/customer"
|
||||
"github.com/stripe/stripe-go/v81/webhook"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/apperrors"
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/apperrors"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
)
|
||||
|
||||
// StripeService handles Stripe checkout, portal, and webhook processing
|
||||
@@ -412,7 +412,7 @@ func (s *StripeService) getOrCreateStripeCustomer(sub *models.UserSubscription,
|
||||
Email: stripe.String(user.Email),
|
||||
Name: stripe.String(user.GetFullName()),
|
||||
}
|
||||
params.AddMetadata("casera_user_id", fmt.Sprintf("%d", user.ID))
|
||||
params.AddMetadata("honeydue_user_id", fmt.Sprintf("%d", user.ID))
|
||||
|
||||
c, err := customer.New(params)
|
||||
if err != nil {
|
||||
|
||||
@@ -8,10 +8,10 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/apperrors"
|
||||
"github.com/treytartt/casera-api/internal/config"
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/apperrors"
|
||||
"github.com/treytartt/honeydue-api/internal/config"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
)
|
||||
|
||||
// Subscription-related errors
|
||||
@@ -35,10 +35,10 @@ var (
|
||||
// KnownSubscriptionIDs are the product IDs for Pro subscriptions
|
||||
// Update these to match your actual App Store Connect / Google Play Console product IDs
|
||||
var KnownSubscriptionIDs = []string{
|
||||
"com.tt.casera.pro.monthly",
|
||||
"com.tt.casera.pro.yearly",
|
||||
"casera_pro_monthly",
|
||||
"casera_pro_yearly",
|
||||
"com.tt.honeyDue.pro.monthly",
|
||||
"com.tt.honeyDue.pro.yearly",
|
||||
"honeydue_pro_monthly",
|
||||
"honeydue_pro_yearly",
|
||||
}
|
||||
|
||||
// SubscriptionService handles subscription business logic
|
||||
|
||||
@@ -7,9 +7,9 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/casera-api/internal/testutil"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/testutil"
|
||||
)
|
||||
|
||||
// setupSubscriptionService creates a SubscriptionService with the given
|
||||
@@ -140,7 +140,7 @@ func TestProcessGooglePurchase_ClientNil_ReturnsError(t *testing.T) {
|
||||
googleClient: nil, // Not configured
|
||||
}
|
||||
|
||||
_, err := svc.ProcessGooglePurchase(user.ID, "fake-token", "com.tt.casera.pro.monthly")
|
||||
_, err := svc.ProcessGooglePurchase(user.ID, "fake-token", "com.tt.honeyDue.pro.monthly")
|
||||
assert.Error(t, err, "ProcessGooglePurchase should return error when Google IAP client is nil")
|
||||
|
||||
// Verify user was NOT upgraded to Pro
|
||||
|
||||
@@ -3,8 +3,8 @@ package services
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/casera-api/internal/task/predicates"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/task/predicates"
|
||||
)
|
||||
|
||||
// iOS Notification Category Identifiers
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/dto/responses"
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/casera-api/internal/testutil"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/responses"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/testutil"
|
||||
)
|
||||
|
||||
/*
|
||||
|
||||
@@ -12,11 +12,11 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/apperrors"
|
||||
"github.com/treytartt/casera-api/internal/dto/requests"
|
||||
"github.com/treytartt/casera-api/internal/dto/responses"
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/apperrors"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/requests"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/responses"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
)
|
||||
|
||||
// Task-related errors (DEPRECATED - kept for reference, use apperrors instead)
|
||||
|
||||
@@ -10,10 +10,10 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/dto/requests"
|
||||
"github.com/treytartt/casera-api/internal/models"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/casera-api/internal/testutil"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/requests"
|
||||
"github.com/treytartt/honeydue-api/internal/models"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/testutil"
|
||||
)
|
||||
|
||||
func setupTaskService(t *testing.T) (*TaskService, *repositories.TaskRepository, *repositories.ResidenceRepository) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"github.com/treytartt/casera-api/internal/dto/responses"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/responses"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
)
|
||||
|
||||
// TaskTemplateService handles business logic for task templates
|
||||
|
||||
@@ -3,9 +3,9 @@ package services
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/treytartt/casera-api/internal/apperrors"
|
||||
"github.com/treytartt/casera-api/internal/dto/responses"
|
||||
"github.com/treytartt/casera-api/internal/repositories"
|
||||
"github.com/treytartt/honeydue-api/internal/apperrors"
|
||||
"github.com/treytartt/honeydue-api/internal/dto/responses"
|
||||
"github.com/treytartt/honeydue-api/internal/repositories"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
Reference in New Issue
Block a user