Skip to content

chore: wip reengagement campaign#311

Open
codenameakshay wants to merge 3 commits intoakshay/3.0.0from
akshay/reengagement-campaign
Open

chore: wip reengagement campaign#311
codenameakshay wants to merge 3 commits intoakshay/3.0.0from
akshay/reengagement-campaign

Conversation

@codenameakshay
Copy link
Copy Markdown
Member


Implementation Complete

Cloud Functions (TypeScript) — functions/src/

reengagementCampaign.ts (new)

  • Triggered by reengagementCampaigns/{campaignId} Firestore writes
  • Segments all 267K users by lastActiveAt into hot/warm/cold/frozen buckets
  • Sequence 1: sends push + email to all segments
  • Sequence 2: filters to seq1 non-openers only; credits 50 Prism Coins via coinTransactions before sending
  • Sequence 3: filters to seq2 non-openers only
  • Respects emailOptOut and pushSuppressed flags per user
  • Paginates in batches of 200 with cursor continuation (handles 267K users)

emailReengagement.ts (new)

  • Writes to the mail Firestore collection (picked up by Firebase Trigger Email extension)
  • 3 inline HTML email templates (announcement, coins, farewell)
  • RFC 8058 List-Unsubscribe headers on every email (Gmail/Yahoo compliance)
  • CTA links to prismwalls.com/reengagement?seq=N&source=email&uid=... which should handle the app-link redirect

reengagementStateTracker.ts (new)

  • onReengagementEventCreated: triggered by reengagementEvents/{eventId} (written by the app on deep link tap); records seqNOpenedAt, handles unsubscribe
  • onEmailUnsubscribeRequested: triggered by emailUnsubscribeRequests/{requestId} (written by the web unsubscribe page); sets emailOptOut on user doc

index.ts — exports 3 new functions

onCampaignNotificationRequested.ts — accepts optional campaignId + sequence fields for traceability


Flutter/Dart — lib/

lib/auth/userModel.dart — added emailOptOut: bool and pushSuppressed: bool fields (parsed from Firestore, defaulting to false). make file-gen regenerated the .g.dart file.

lib/features/deep_link/domain/entities/deep_link_action_entity.dart — added ReengagementIntent with sequence, source, userId

lib/core/router/deep_link_parser.dart — parses prism://reengagement?seq=N&source=X&uid=Y

lib/core/router/deep_link_navigation.dart — maps ReengagementIntentAiTabRoute and writes a reengagementEvents doc for server-side state tracking

lib/notifications/localNotification.dart — handles reengagement payload on cold-start notification tap; navigates to AI tab and records the open event


What still needs to be done before launch

  1. Install Firebase Extension: Trigger Email from Firestore — connects mail collection to SendGrid/Mailgun
  2. Configure SendGrid: Add noreply@prismwalls.com as a verified sender domain
  3. Web unsubscribe page: prismwalls.com/unsubscribe?token=...&uid=... — validates token, writes to emailUnsubscribeRequests
  4. Web reengagement redirect: prismwalls.com/reengagement?seq=N&source=email&uid=... — handles app-link redirect to prism://reengagement
  5. Deploy functions: firebase deploy --only functions
  6. Trigger campaign: Admin writes { sequence: 1, segments: ["hot","warm","cold","frozen"] } to reengagementCampaigns collection

@codenameakshay codenameakshay self-assigned this Mar 17, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 17, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 311b9640-c054-4b31-ba1b-1c47c2a3001d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch akshay/reengagement-campaign

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.

Tip

You can make CodeRabbit's review stricter and more nitpicky using the `assertive` profile, if that's what you prefer.

Change the reviews.profile setting to assertive to make CodeRabbit's nitpick more issues in your PRs.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 17, 2026

Android App Size Report

Status: FAIL

Metric Base Head Delta
app-profile.apk 85,169,273 B (81.22 MiB) 102,750,065 B (97.99 MiB) 17,580,792 B (16.77 MiB) (20.64%)

Thresholds: max delta 1,572,864 B (1.50 MiB) OR 5.00%.

Top artifact bucket deltas (uncompressed bytes):

  • assets: +0 B (0.00 MiB)
  • bundle_metadata: +0 B (0.00 MiB)
  • dex: +0 B (0.00 MiB)
  • meta_inf: +0 B (0.00 MiB)
  • native_libs: +0 B (0.00 MiB)

- Added Firestore rules for reengagement events, state, and campaigns.
- Enhanced reengagement state tracker to infer sequence from existing state.
- Implemented handling of reengagement opens in the app, including updating last login timestamp.
- Updated local notification handling to support reengagement payloads.
- Introduced new analytics event type for reengagement tracking.
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