Developer Review Document

Credit Logic Review

Goal: align backend behavior with the product promise that credits are based on contacts and campaigns, not raw AI token spend.

Current vs Expected Logic

Area How It Works Now How It Should Work
Core credit meaning Backend is inconsistent. Credits are consumed in campaign assignment flows and also constrained in AI reply flows through remainingCredits. 1 credit = 1 unique contact activated in the billing cycle.
Campaign setup When a campaign is created or launched and leads are assigned, credits are consumed there, but not through a clean cycle-aware ledger. Campaign usage should consume 1 credit only when that campaign activates a contact that has not yet been credited under the intended rule.
Campaign lead assignment Current backend can deduct credits per lead added to a campaign, even without a proper monthly/cycle credit record. On campaign activation, check a credit ledger first. If the contact is billable under policy, deduct 1. Otherwise deduct 0.
New inbound WhatsApp lead Inbound WhatsApp can still fall into token-based AI reply blocking. First inbound WhatsApp contact in the billing cycle should consume 1 credit, then conversation stays free for that cycle.
New inbound Email lead Email inbound is not consistently tied to the same contact-credit rule. First inbound Email contact in the billing cycle should consume 1 credit, then conversation stays free for that cycle.
AI replies after first contact Replies can still be blocked because each AI turn is treated like spendable budget in reply generation/validation. No visible contact credit deduction per AI reply. After first credit usage, replies should be free for the rest of the cycle.
Same contact, same cycle Can still cost the system again and eventually stop replying due to low token budget. If the contact is already covered in the current billing cycle, no more visible credits should be deducted.
Same contact, different campaign Current behavior is inconsistent and partly campaign-driven. If business rule remains same contact, different campaign = 1, then deduct 1 again for that new campaign. If not, keep it free across campaigns in the cycle. This must be explicit.
Same contact, next billing cycle No clean cycle reset rule is enforced end-to-end. On the next billing cycle, the same contact can consume 1 credit again.
Billing window Not cleanly tied to the customer subscription cycle. Use subscription billing cycle start and end dates as the reset window.
remainingCredits Acts partly like a token bucket. Should represent remaining contact credits for the active billing cycle.
Token usage Used as live enforcement in WhatsApp reply paths. Keep token usage for internal reporting, margin analysis, alerts, and abuse protection only.
Low-credit behavior Replies can be silently suppressed when a single AI turn needs more tokens than remainingCredits. Existing covered conversations should keep working. Internal token caps should protect the platform without breaking the customer-facing credit promise.
User-facing expectation Pricing page says contact-based credits, but backend does not fully enforce that. Backend must exactly match the pricing page and sales explanation.
Source of truth No dedicated ledger exists for contact-level credit usage across channels and campaigns. Add a credit usage ledger keyed by billing cycle and normalized contact identity.

Recommended Business Rule

Event Recommended Credit Usage
New inbound WhatsApp lead Consume 1 credit.
New inbound Email lead Consume 1 credit.
Campaign activates a new contact Consume 1 credit.
Follow-up messages to same contact in same campaign and cycle 0 extra credits.
Same contact keeps chatting in same cycle 0 extra credits.
Same contact in another campaign in same cycle If product rule stays as shown on pricing page, consume 1 more credit.
Same contact next billing cycle Consume 1 new credit again.

Implementation Notes for Developers

Item Required Change
Credit ledger Create a ledger collection with fields such as userId, channel, contactKey, campaignId, billingCycleKey, creditConsumed, creditedAt, source.
Contact identity Use normalized phone number for WhatsApp and normalized lowercase email for Email.
Billing cycle key Derive from the active subscription cycle, not a floating 30-day window from last message.
Reply-token charging Remove visible customer credit deduction from WhatsApp and Email AI reply flows.
Internal cost tracking Keep prompt/completion/validator token logging for analytics only.
Existing threads Do not block an already-covered conversation because of token spend. Use internal alerts/limits instead.
Policy choice Lock one explicit rule for same contact, different campaign and enforce it consistently everywhere.

Prepared for internal engineering review. This document summarizes product promise vs backend enforcement and the required alignment work.