Skip to content

feat(emails): add KiloClaw purchase confirmation#3049

Merged
evanjacobson merged 5 commits intomainfrom
feat/transactional-emails_kiloclaw
May 5, 2026
Merged

feat(emails): add KiloClaw purchase confirmation#3049
evanjacobson merged 5 commits intomainfrom
feat/transactional-emails_kiloclaw

Conversation

@evanjacobson
Copy link
Copy Markdown
Contributor

@evanjacobson evanjacobson commented May 5, 2026

Summary

KiloClaw purchases now send the transactional confirmation users expect when a subscription becomes active, closing a gap where successful activations were only reflected in-app.

This adds a Mailgun-backed KiloClaw subscription-started email with durable send markers so webhook retries can recover missed sends without double-emailing users. The implementation follows the existing server-rendered email template conventions and extends the current KiloClaw email-log pattern for activation-period dedupe.

#3054 merged into this branch

Implementation notes
  • Adds a new kiloClawSubscriptionStarted transactional email template and sender.
  • Extends kiloclaw_email_log with period_start so subscription-started emails dedupe per activation period rather than forever per instance.
  • Sends on first paid activation, resubscribe, and $0 coupon/promo settlements, while skipping active renewal and dunning recovery settlements.
  • Handles duplicate webhook/retry paths by using persisted subscription change-log state to send once when the first attempt completed activation but missed the email side effect.
  • Clears retryable provider-not-configured markers, while retaining terminal invalid-recipient markers to avoid retry loops.

Verification

  • Not manually verified; this change is primarily webhook/email side-effect behavior and was covered with automated tests rather than a browser flow.

Visual Changes

image

Reviewer Notes

Suggested review focus
  • Activation-period idempotency around webhook retries and duplicate settlements.
  • The kiloclaw_email_log.period_start schema change.
  • Branches that should send versus skip: initial activation, resubscribe, $0 settlement, active renewal, past_due, and unpaid.
  • Provider failure handling: retryable provider_not_configured versus terminal invalid-recipient outcomes.
  • Copy and links in the new transactional email template.

Deployment note: the replacement unique index for kiloclaw_email_log will be created separately outside the Drizzle migration with CREATE UNIQUE INDEX CONCURRENTLY because the table has roughly 260.7K rows and Drizzle migrations run inside a transaction. I will run:

CREATE UNIQUE INDEX CONCURRENTLY "UQ_kiloclaw_email_log_user_instance_type_period"
ON "kiloclaw_email_log" USING btree ("user_id","instance_id","email_type","period_start")
WHERE "kiloclaw_email_log"."instance_id" is not null;

then,

DROP INDEX "UQ_kiloclaw_email_log_user_instance_type"

@evanjacobson evanjacobson marked this pull request as ready for review May 5, 2026 18:06
Comment thread packages/db/src/migrations/0110_nappy_newton_destine.sql Outdated
@kilo-code-bot
Copy link
Copy Markdown
Contributor

kilo-code-bot Bot commented May 5, 2026

Code Review Summary

Status: 1 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/db/src/migrations/0112_nifty_typhoid_mary.sql 3 Replacement unique index is created with plain CREATE UNIQUE INDEX, which can block writes on populated kiloclaw_email_log during deploy.

Fix these issues in Kilo Cloud

Other Observations (not in diff)

Issues found in unchanged code that cannot receive inline comments:

File Line Issue
N/A N/A No new issues found in the incremental diff; the existing migration index-build warning remains active.
Files Reviewed (3 files)
  • apps/web/src/lib/kiloclaw/credit-billing.ts - 0 issues
  • apps/web/src/lib/purchase-emails.test.ts - 0 issues
  • packages/db/src/migrations/0112_nifty_typhoid_mary.sql - 1 carried-forward issue

Reviewed by gpt-5.5-2026-04-23 · 1,333,271 tokens

Comment thread packages/db/src/migrations/0111_little_meteorite.sql Outdated
@evanjacobson evanjacobson force-pushed the feat/transactional-emails_kiloclaw branch from dbfccd0 to 087d9c0 Compare May 5, 2026 18:17
Comment thread packages/db/src/migrations/0111_little_meteorite.sql Outdated
@evanjacobson evanjacobson force-pushed the feat/transactional-emails_kiloclaw branch from 087d9c0 to a3a8cd9 Compare May 5, 2026 18:33
Comment thread packages/db/src/migrations/0111_fantastic_gargoyle.sql Outdated
@evanjacobson evanjacobson changed the title feat(emails): add KiloClaw purchase confirmation feat(emails): add Stripe-based KiloClaw purchase confirmation May 5, 2026
Comment thread packages/db/src/migrations/0111_fantastic_gargoyle.sql Outdated
Comment thread packages/db/src/migrations/0111_fantastic_gargoyle.sql Outdated
@evanjacobson evanjacobson force-pushed the feat/transactional-emails_kiloclaw branch from 74e0fcb to b8fb31e Compare May 5, 2026 20:46
Comment thread packages/db/src/migrations/0112_nifty_typhoid_mary.sql
…ons (#3054)

Adds a Subsciription Started email for credit-based billing
@evanjacobson evanjacobson changed the title feat(emails): add Stripe-based KiloClaw purchase confirmation feat(emails): add KiloClaw purchase confirmation May 5, 2026
@evanjacobson evanjacobson merged commit 23e33c0 into main May 5, 2026
41 checks passed
@evanjacobson evanjacobson deleted the feat/transactional-emails_kiloclaw branch May 5, 2026 21:47
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.

2 participants