Skip to content

Try to retain users who did not subscribe#485

Merged
Blaumaus merged 3 commits intomainfrom
subscribe-reminder
Mar 11, 2026
Merged

Try to retain users who did not subscribe#485
Blaumaus merged 3 commits intomainfrom
subscribe-reminder

Conversation

@Blaumaus
Copy link
Member

@Blaumaus Blaumaus commented Mar 10, 2026

Changes

If applicable, please describe what changes were made in this pull request.

Community Edition support

  • Your feature is implemented for the Swetrix Community Edition
  • This PR only updates the Cloud (Enterprise) Edition code (e.g. Paddle webhooks, blog, payouts, etc.)

Database migrations

  • Clickhouse / MySQL migrations added for this PR
  • No table schemas changed in this PR

Documentation

  • You have updated the documentation according to your PR
  • This PR did not change any publicly documented endpoints

Summary by CodeRabbit

  • New Features
    • Automated subscription reminders: eligible users now receive a 14-day trial invitation email highlighting key benefits (web analytics without cookie banners, error tracking, custom events/funnels/goals, privacy-first reCAPTCHA alternative).
    • Daily reminder scheduling with tracking to avoid duplicate sends and record when reminders are dispatched.

@Blaumaus Blaumaus self-assigned this Mar 10, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1891ab05-8bc4-4b03-9f7d-14631bf56f87

📥 Commits

Reviewing files that changed from the base of the PR and between 657ad2c and a7e8499.

📒 Files selected for processing (1)
  • backend/migrations/mysql/2026_03_10_subscribe_reminder.sql
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/migrations/mysql/2026_03_10_subscribe_reminder.sql

📝 Walkthrough

Walkthrough

Introduces a subscribe-reminder email system: new HTML template and mailer metadata, a daily cron job that emails eligible free-plan users in their first post-onboarding week, a nullable subscribeReminderSentOn user field, and a migration adding the corresponding DB column.

Changes

Cohort / File(s) Summary
Email Template & Mailer
backend/apps/cloud/src/common/templates/en/subscribe-reminder.html, backend/apps/cloud/src/mailer/letter.ts, backend/apps/cloud/src/mailer/mailer.service.ts
Adds new HTML email template inviting a 14-day free trial. Adds SubscribeReminder to LetterTemplate and registers subject metadata ("Your Swetrix trial is waiting for you").
Scheduled Task & Reminder Logic
backend/apps/cloud/src/task-manager/task-manager.service.ts
Adds remindUsersToSubscribe() cron (daily at 10:00) to query free-plan users within a 1-week window post-onboarding, send SubscribeReminder emails with concurrency control, update subscribeReminderSentOn, and log per-user failures. Refines another reminder to exclude free-plan users.
Data Model & Migration
backend/apps/cloud/src/user/entities/user.entity.ts, backend/migrations/mysql/2026_03_10_subscribe_reminder.sql
Adds nullable subscribeReminderSentOn timestamp to User entity and creates the corresponding user table column via migration.

Sequence Diagram

sequenceDiagram
    participant Scheduler as Cron Scheduler
    participant TaskMgr as TaskManager Service
    participant DB as Database
    participant Mailer as Mailer Service
    participant UserSvc as User Service

    Scheduler->>TaskMgr: invoke remindUsersToSubscribe() @ 10:00
    TaskMgr->>DB: Query users (PlanCode.none, onboarded, created ~1 week, no subscribeReminderSentOn)
    DB-->>TaskMgr: return user list
    alt users found
        loop per user (bounded concurrency)
            TaskMgr->>Mailer: send SubscribeReminder(email, subscribeUrl)
            Mailer-->>TaskMgr: success / failure
            alt success
                TaskMgr->>UserSvc: set subscribeReminderSentOn(timestamp)
                UserSvc->>DB: persist timestamp
            else failure
                TaskMgr->>TaskMgr: log error for user
            end
        end
    else no users
        TaskMgr->>TaskMgr: exit early
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through code to spread the news,

A trial awaits — no cards to lose.
Cron wakes at ten to send the rhyme,
One field, one migration, one reminder time.
Hooray for trials and tidy queues!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main objective of the changeset: implementing a subscribe reminder system to retain users who haven't subscribed to a paid plan.
Description check ✅ Passed The description follows the template structure with appropriate checkboxes marked, confirming this is Cloud Edition code with database migrations. However, the 'Changes' section is empty, omitting details about what modifications were implemented.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch subscribe-reminder

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/apps/cloud/src/user/entities/user.entity.ts`:
- Around line 277-279: The entity property subscribeReminderSentOn is declared
with type: 'timestamp' but the migration creates the column as DATETIME; change
the column definition in the migration that adds the subscribe_reminder (the
2026_03_10_subscribe_reminder.sql migration) to use TIMESTAMP (or TIMESTAMP
NULL) instead of DATETIME so it matches the User entity's
subscribeReminderSentOn and the pattern used by
evWarningSentOn/noEventsReminderSentOn; ensure NULLability and any default
clauses in the SQL match the entity declaration.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3fdfaa84-b1be-46a6-9037-a5bed4393b5d

📥 Commits

Reviewing files that changed from the base of the PR and between fc1ff8f and 657ad2c.

📒 Files selected for processing (6)
  • backend/apps/cloud/src/common/templates/en/subscribe-reminder.html
  • backend/apps/cloud/src/mailer/letter.ts
  • backend/apps/cloud/src/mailer/mailer.service.ts
  • backend/apps/cloud/src/task-manager/task-manager.service.ts
  • backend/apps/cloud/src/user/entities/user.entity.ts
  • backend/migrations/mysql/2026_03_10_subscribe_reminder.sql

@Blaumaus Blaumaus merged commit 2c856dd into main Mar 11, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant