@carrierllc/mcp 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/dist/index.d.ts +0 -13
  2. package/dist/index.js +8394 -77
  3. package/dist/index.js.map +1 -1
  4. package/package.json +10 -10
  5. package/dist/.metadata_never_index +0 -0
  6. package/dist/apps/app-state.d.ts +0 -19
  7. package/dist/apps/app-state.d.ts.map +0 -1
  8. package/dist/apps/app-state.js +0 -28
  9. package/dist/apps/app-state.js.map +0 -1
  10. package/dist/apps/balance-topup.d.ts +0 -19
  11. package/dist/apps/balance-topup.d.ts.map +0 -1
  12. package/dist/apps/balance-topup.js +0 -121
  13. package/dist/apps/balance-topup.js.map +0 -1
  14. package/dist/apps/fleet-health-app.d.ts +0 -29
  15. package/dist/apps/fleet-health-app.d.ts.map +0 -1
  16. package/dist/apps/fleet-health-app.js +0 -152
  17. package/dist/apps/fleet-health-app.js.map +0 -1
  18. package/dist/apps/index.d.ts +0 -37
  19. package/dist/apps/index.d.ts.map +0 -1
  20. package/dist/apps/index.js +0 -42
  21. package/dist/apps/index.js.map +0 -1
  22. package/dist/apps/provisioning-wizard.d.ts +0 -11
  23. package/dist/apps/provisioning-wizard.d.ts.map +0 -1
  24. package/dist/apps/provisioning-wizard.js +0 -345
  25. package/dist/apps/provisioning-wizard.js.map +0 -1
  26. package/dist/audit.d.ts +0 -31
  27. package/dist/audit.d.ts.map +0 -1
  28. package/dist/audit.js +0 -42
  29. package/dist/audit.js.map +0 -1
  30. package/dist/billing-thresholds.d.ts +0 -71
  31. package/dist/billing-thresholds.d.ts.map +0 -1
  32. package/dist/billing-thresholds.js +0 -238
  33. package/dist/billing-thresholds.js.map +0 -1
  34. package/dist/billing.d.ts +0 -95
  35. package/dist/billing.d.ts.map +0 -1
  36. package/dist/billing.js +0 -239
  37. package/dist/billing.js.map +0 -1
  38. package/dist/clerk.d.ts +0 -125
  39. package/dist/clerk.d.ts.map +0 -1
  40. package/dist/clerk.js +0 -389
  41. package/dist/clerk.js.map +0 -1
  42. package/dist/client.d.ts +0 -35
  43. package/dist/client.d.ts.map +0 -1
  44. package/dist/client.js +0 -85
  45. package/dist/client.js.map +0 -1
  46. package/dist/credits.d.ts +0 -165
  47. package/dist/credits.d.ts.map +0 -1
  48. package/dist/credits.js +0 -483
  49. package/dist/credits.js.map +0 -1
  50. package/dist/index.d.ts.map +0 -1
  51. package/dist/intelligence.d.ts +0 -4
  52. package/dist/intelligence.d.ts.map +0 -1
  53. package/dist/intelligence.js +0 -977
  54. package/dist/intelligence.js.map +0 -1
  55. package/dist/list-recent-ocs-events.d.ts +0 -48
  56. package/dist/list-recent-ocs-events.d.ts.map +0 -1
  57. package/dist/list-recent-ocs-events.js +0 -160
  58. package/dist/list-recent-ocs-events.js.map +0 -1
  59. package/dist/manus-client.d.ts +0 -429
  60. package/dist/manus-client.d.ts.map +0 -1
  61. package/dist/manus-client.js +0 -401
  62. package/dist/manus-client.js.map +0 -1
  63. package/dist/manus-common.d.ts +0 -5
  64. package/dist/manus-common.d.ts.map +0 -1
  65. package/dist/manus-common.js +0 -5
  66. package/dist/manus-common.js.map +0 -1
  67. package/dist/manus-schedule.d.ts +0 -74
  68. package/dist/manus-schedule.d.ts.map +0 -1
  69. package/dist/manus-schedule.js +0 -213
  70. package/dist/manus-schedule.js.map +0 -1
  71. package/dist/manus-usage.d.ts +0 -32
  72. package/dist/manus-usage.d.ts.map +0 -1
  73. package/dist/manus-usage.js +0 -120
  74. package/dist/manus-usage.js.map +0 -1
  75. package/dist/manus-webhook.d.ts +0 -60
  76. package/dist/manus-webhook.d.ts.map +0 -1
  77. package/dist/manus-webhook.js +0 -361
  78. package/dist/manus-webhook.js.map +0 -1
  79. package/dist/pricing-tools.d.ts +0 -26
  80. package/dist/pricing-tools.d.ts.map +0 -1
  81. package/dist/pricing-tools.js +0 -428
  82. package/dist/pricing-tools.js.map +0 -1
  83. package/dist/projects-tools.d.ts +0 -39
  84. package/dist/projects-tools.d.ts.map +0 -1
  85. package/dist/projects-tools.js +0 -545
  86. package/dist/projects-tools.js.map +0 -1
  87. package/dist/prompts.d.ts +0 -7
  88. package/dist/prompts.d.ts.map +0 -1
  89. package/dist/prompts.js +0 -151
  90. package/dist/prompts.js.map +0 -1
  91. package/dist/stripe-connect-tools.d.ts +0 -33
  92. package/dist/stripe-connect-tools.d.ts.map +0 -1
  93. package/dist/stripe-connect-tools.js +0 -504
  94. package/dist/stripe-connect-tools.js.map +0 -1
  95. package/dist/timing-safe-equal.d.ts +0 -5
  96. package/dist/timing-safe-equal.d.ts.map +0 -1
  97. package/dist/timing-safe-equal.js +0 -13
  98. package/dist/timing-safe-equal.js.map +0 -1
  99. package/dist/tools-backlog.d.ts +0 -37
  100. package/dist/tools-backlog.d.ts.map +0 -1
  101. package/dist/tools-backlog.js +0 -410
  102. package/dist/tools-backlog.js.map +0 -1
  103. package/dist/tools-carrier-ask.d.ts +0 -138
  104. package/dist/tools-carrier-ask.d.ts.map +0 -1
  105. package/dist/tools-carrier-ask.js +0 -913
  106. package/dist/tools-carrier-ask.js.map +0 -1
  107. package/dist/tools-pricing.d.ts +0 -18
  108. package/dist/tools-pricing.d.ts.map +0 -1
  109. package/dist/tools-pricing.js +0 -172
  110. package/dist/tools-pricing.js.map +0 -1
  111. package/dist/tools-ui-agent-ask.d.ts +0 -29
  112. package/dist/tools-ui-agent-ask.d.ts.map +0 -1
  113. package/dist/tools-ui-agent-ask.js +0 -272
  114. package/dist/tools-ui-agent-ask.js.map +0 -1
  115. package/dist/tools-ui-agent-schedule.d.ts +0 -29
  116. package/dist/tools-ui-agent-schedule.d.ts.map +0 -1
  117. package/dist/tools-ui-agent-schedule.js +0 -517
  118. package/dist/tools-ui-agent-schedule.js.map +0 -1
  119. package/dist/tools-ui-agent.d.ts +0 -40
  120. package/dist/tools-ui-agent.d.ts.map +0 -1
  121. package/dist/tools-ui-agent.js +0 -508
  122. package/dist/tools-ui-agent.js.map +0 -1
  123. package/dist/tools.d.ts +0 -60
  124. package/dist/tools.d.ts.map +0 -1
  125. package/dist/tools.js +0 -1384
  126. package/dist/tools.js.map +0 -1
  127. package/dist/types.d.ts +0 -298
  128. package/dist/types.d.ts.map +0 -1
  129. package/dist/types.js +0 -5
  130. package/dist/types.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/credits.d.ts DELETED
@@ -1,165 +0,0 @@
1
- /**
2
- * Carrier MCP — Credits System v2.0 (Pricing Evolution)
3
- *
4
- * Implements credit-based billing inspired by Stripe's Pricing Model Evolution Guide:
5
- * - Monthly credit allotments per tier (Lovable pattern)
6
- * - Auto-billed overages when base credits exhausted (Warp pattern)
7
- * - Credit rollovers for irregular usage (Lovable pattern)
8
- * - Daily free credits for acquisition (Browserbase/Lovable pattern)
9
- * - Billing thresholds to prevent bill shock (Hex pattern)
10
- * - Volume discounts for high-usage customers
11
- *
12
- * Storage layout (CARRIER_USERS KV):
13
- * key: credits:<sub>:<yyyymm> value: CreditLedger
14
- * key: credits:daily:<sub>:<yyyymmdd> value: DailyFreeCredits
15
- * key: credits:config:<sub> value: CreditConfig (overrides, thresholds)
16
- * key: credits:rollover:<sub> value: RolloverBalance
17
- *
18
- * Credit economy:
19
- * 1 tool call = 1 credit (read scope)
20
- * 1 tool call = 2 credits (write scope)
21
- * 1 tool call = 5 credits (admin scope)
22
- * Intelligence composites = 3 credits each
23
- *
24
- * Stripe integration:
25
- * - Overages reported via Stripe Metered Billing (usage_records API)
26
- * - Billing thresholds trigger Stripe invoice finalization
27
- * - Credit grants created via Stripe Customer Balance Transactions
28
- */
29
- import type { Env } from "./types.js";
30
- import type { Tier, ScopeToken } from "./billing.js";
31
- /** Monthly credit allotments per tier */
32
- export declare const TIER_CREDIT_ALLOTMENTS: Record<Tier, number>;
33
- /** Daily free credits for all users (acquisition driver) */
34
- export declare const DAILY_FREE_CREDITS = 50;
35
- /** Maximum rollover credits (cap at 2x monthly allotment) */
36
- export declare const ROLLOVER_CAP_MULTIPLIER = 2;
37
- /** Credit cost per scope */
38
- export declare const SCOPE_CREDIT_COSTS: Record<ScopeToken | "intelligence", number>;
39
- /** Volume discount tiers (cumulative monthly usage) */
40
- export declare const VOLUME_DISCOUNTS: VolumeDiscountTier[];
41
- /** Default billing threshold (in cents) — triggers invoice at this spend level */
42
- export declare const DEFAULT_BILLING_THRESHOLD_CENTS = 10000;
43
- /** Overage price per credit (in cents) — Pro tier */
44
- export declare const OVERAGE_PRICE_PER_CREDIT_CENTS = 0.1;
45
- export interface VolumeDiscountTier {
46
- threshold: number;
47
- discountPct: number;
48
- }
49
- export interface CreditLedger {
50
- /** Monthly allotment (base + rollover) */
51
- allotment: number;
52
- /** Credits consumed this period */
53
- consumed: number;
54
- /** Credits from rollovers applied this month */
55
- rollover_applied: number;
56
- /** Overage credits consumed beyond allotment */
57
- overage: number;
58
- /** Overage amount billed (cents) */
59
- overage_billed_cents: number;
60
- /** Whether billing threshold was hit this period */
61
- threshold_triggered: boolean;
62
- /** ISO 8601 last updated */
63
- updated_at: string;
64
- }
65
- export interface DailyFreeCredits {
66
- /** Credits granted today */
67
- granted: number;
68
- /** Credits consumed from daily free pool */
69
- consumed: number;
70
- /** ISO date (YYYY-MM-DD) */
71
- date: string;
72
- }
73
- export interface CreditConfig {
74
- /** Custom billing threshold override (cents) */
75
- billing_threshold_cents: number;
76
- /** Whether overages are enabled (Pro+) */
77
- overages_enabled: boolean;
78
- /** Whether rollovers are enabled (Pro+) */
79
- rollovers_enabled: boolean;
80
- /** Custom overage rate override (cents per credit) */
81
- overage_rate_cents: number;
82
- /** Volume discount tier override */
83
- volume_discount_pct: number;
84
- /** Notification preferences */
85
- notify_at_pct: number[];
86
- updated_at: string;
87
- }
88
- export interface RolloverBalance {
89
- /** Unused credits from previous month eligible for rollover */
90
- credits: number;
91
- /** Source month (YYYYMM) */
92
- source_month: string;
93
- /** Expiry — rollovers expire after 1 month */
94
- expires_at: string;
95
- }
96
- export interface CreditCheckResult {
97
- allowed: boolean;
98
- credits_remaining: number;
99
- daily_free_remaining: number;
100
- overage_active: boolean;
101
- overage_amount_cents: number;
102
- threshold_pct: number;
103
- tier: Tier;
104
- volume_discount_pct: number;
105
- reset_at: string;
106
- }
107
- export interface CreditDeductionResult {
108
- success: boolean;
109
- credits_deducted: number;
110
- source: "allotment" | "daily_free" | "overage";
111
- new_balance: number;
112
- overage_triggered: boolean;
113
- threshold_triggered: boolean;
114
- }
115
- /**
116
- * Check if a user has sufficient credits for a tool call.
117
- * Order of credit consumption:
118
- * 1. Daily free credits (if available)
119
- * 2. Monthly allotment (base + rollover)
120
- * 3. Overage (if enabled for tier)
121
- */
122
- export declare function checkCredits(env: Env, sub: string, tier: Tier, scope: ScopeToken | "intelligence"): Promise<CreditCheckResult>;
123
- /**
124
- * Deduct credits for a tool call. Fire-and-forget in the hot path.
125
- *
126
- * Consumption order:
127
- * 1. Daily free credits first (lowest cost to user)
128
- * 2. Monthly allotment
129
- * 3. Overage (auto-billed, Pro+ only)
130
- */
131
- export declare function deductCredits(env: Env, sub: string, tier: Tier, scope: ScopeToken | "intelligence"): void;
132
- /**
133
- * Calculate and apply rollover credits from previous month.
134
- * Called by the monthly cron job (scheduled handler).
135
- *
136
- * Rules:
137
- * - Only Pro+ tiers get rollovers
138
- * - Rollover = min(unused credits, allotment * ROLLOVER_CAP_MULTIPLIER)
139
- * - Rollovers expire after 1 month (use-it-or-lose-it next cycle)
140
- */
141
- export declare function applyMonthlyRollover(env: Env, sub: string, tier: Tier): Promise<RolloverBalance | null>;
142
- /**
143
- * Resolve the applicable volume discount percentage based on cumulative usage.
144
- */
145
- export declare function resolveVolumeDiscount(consumed: number): number;
146
- /**
147
- * Update a user's credit configuration (admin or self-service).
148
- */
149
- export declare function updateCreditConfig(env: Env, sub: string, updates: Partial<CreditConfig>): Promise<CreditConfig>;
150
- /**
151
- * Get credit usage summary for a user (used by billing UI).
152
- */
153
- export declare function getCreditSummary(env: Env, sub: string, tier: Tier): Promise<{
154
- ledger: CreditLedger;
155
- daily_free: DailyFreeCredits;
156
- config: CreditConfig;
157
- rollover: RolloverBalance | null;
158
- volume_discount_pct: number;
159
- }>;
160
- /**
161
- * Issue a credit grant to a customer via Stripe Customer Balance Transactions.
162
- * Used for promotional credits, referral bonuses, and compensation.
163
- */
164
- export declare function issueStripeCredits(env: Env, sub: string, amountCents: number, description: string): Promise<boolean>;
165
- //# sourceMappingURL=credits.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"credits.d.ts","sourceRoot":"","sources":["../src/credits.ts"],"names":[],"mappings":"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"}
package/dist/credits.js DELETED
@@ -1,483 +0,0 @@
1
- /**
2
- * Carrier MCP — Credits System v2.0 (Pricing Evolution)
3
- *
4
- * Implements credit-based billing inspired by Stripe's Pricing Model Evolution Guide:
5
- * - Monthly credit allotments per tier (Lovable pattern)
6
- * - Auto-billed overages when base credits exhausted (Warp pattern)
7
- * - Credit rollovers for irregular usage (Lovable pattern)
8
- * - Daily free credits for acquisition (Browserbase/Lovable pattern)
9
- * - Billing thresholds to prevent bill shock (Hex pattern)
10
- * - Volume discounts for high-usage customers
11
- *
12
- * Storage layout (CARRIER_USERS KV):
13
- * key: credits:<sub>:<yyyymm> value: CreditLedger
14
- * key: credits:daily:<sub>:<yyyymmdd> value: DailyFreeCredits
15
- * key: credits:config:<sub> value: CreditConfig (overrides, thresholds)
16
- * key: credits:rollover:<sub> value: RolloverBalance
17
- *
18
- * Credit economy:
19
- * 1 tool call = 1 credit (read scope)
20
- * 1 tool call = 2 credits (write scope)
21
- * 1 tool call = 5 credits (admin scope)
22
- * Intelligence composites = 3 credits each
23
- *
24
- * Stripe integration:
25
- * - Overages reported via Stripe Metered Billing (usage_records API)
26
- * - Billing thresholds trigger Stripe invoice finalization
27
- * - Credit grants created via Stripe Customer Balance Transactions
28
- */
29
- // ---------------------------------------------------------------------------
30
- // Credit Constants
31
- // ---------------------------------------------------------------------------
32
- /** Monthly credit allotments per tier */
33
- export const TIER_CREDIT_ALLOTMENTS = {
34
- free: 5_000,
35
- pro: 100_000,
36
- enterprise: Infinity,
37
- };
38
- /** Daily free credits for all users (acquisition driver) */
39
- export const DAILY_FREE_CREDITS = 50;
40
- /** Maximum rollover credits (cap at 2x monthly allotment) */
41
- export const ROLLOVER_CAP_MULTIPLIER = 2;
42
- /** Credit cost per scope */
43
- export const SCOPE_CREDIT_COSTS = {
44
- read: 1,
45
- write: 2,
46
- admin: 5,
47
- intelligence: 3,
48
- };
49
- /** Volume discount tiers (cumulative monthly usage) */
50
- export const VOLUME_DISCOUNTS = [
51
- { threshold: 50_000, discountPct: 0 },
52
- { threshold: 100_000, discountPct: 10 },
53
- { threshold: 250_000, discountPct: 15 },
54
- { threshold: 500_000, discountPct: 20 },
55
- { threshold: 1_000_000, discountPct: 25 },
56
- ];
57
- /** Default billing threshold (in cents) — triggers invoice at this spend level */
58
- export const DEFAULT_BILLING_THRESHOLD_CENTS = 10_000; // $100
59
- /** Overage price per credit (in cents) — Pro tier */
60
- export const OVERAGE_PRICE_PER_CREDIT_CENTS = 0.1; // $0.001 per credit
61
- // ---------------------------------------------------------------------------
62
- // Credit Check
63
- // ---------------------------------------------------------------------------
64
- /**
65
- * Check if a user has sufficient credits for a tool call.
66
- * Order of credit consumption:
67
- * 1. Daily free credits (if available)
68
- * 2. Monthly allotment (base + rollover)
69
- * 3. Overage (if enabled for tier)
70
- */
71
- export async function checkCredits(env, sub, tier, scope) {
72
- const cost = SCOPE_CREDIT_COSTS[scope];
73
- const month = currentMonth();
74
- const today = currentDay();
75
- const resetAt = firstDayNextMonth();
76
- // Enterprise always allowed
77
- if (tier === "enterprise") {
78
- return {
79
- allowed: true,
80
- credits_remaining: Infinity,
81
- daily_free_remaining: Infinity,
82
- overage_active: false,
83
- overage_amount_cents: 0,
84
- threshold_pct: 0,
85
- tier,
86
- volume_discount_pct: 0,
87
- reset_at: resetAt,
88
- };
89
- }
90
- // Load ledger
91
- const ledger = await getLedger(env, sub, month, tier);
92
- const dailyFree = await getDailyFreeCredits(env, sub, today);
93
- const config = await getCreditConfig(env, sub, tier);
94
- // Calculate remaining
95
- const monthlyRemaining = Math.max(0, ledger.allotment - ledger.consumed);
96
- const dailyFreeRemaining = Math.max(0, dailyFree.granted - dailyFree.consumed);
97
- const totalRemaining = dailyFreeRemaining + monthlyRemaining;
98
- // Check if allowed
99
- const overageEnabled = config.overages_enabled && tier !== "free";
100
- const allowed = totalRemaining >= cost || overageEnabled;
101
- // Volume discount
102
- const volumeDiscount = resolveVolumeDiscount(ledger.consumed);
103
- // Threshold percentage
104
- const thresholdPct = config.billing_threshold_cents > 0
105
- ? Math.round((ledger.overage_billed_cents / config.billing_threshold_cents) * 100)
106
- : 0;
107
- return {
108
- allowed,
109
- credits_remaining: monthlyRemaining,
110
- daily_free_remaining: dailyFreeRemaining,
111
- overage_active: monthlyRemaining < cost && dailyFreeRemaining < cost && overageEnabled,
112
- overage_amount_cents: ledger.overage_billed_cents,
113
- threshold_pct: thresholdPct,
114
- tier,
115
- volume_discount_pct: volumeDiscount,
116
- reset_at: resetAt,
117
- };
118
- }
119
- // ---------------------------------------------------------------------------
120
- // Credit Deduction
121
- // ---------------------------------------------------------------------------
122
- /**
123
- * Deduct credits for a tool call. Fire-and-forget in the hot path.
124
- *
125
- * Consumption order:
126
- * 1. Daily free credits first (lowest cost to user)
127
- * 2. Monthly allotment
128
- * 3. Overage (auto-billed, Pro+ only)
129
- */
130
- export function deductCredits(env, sub, tier, scope) {
131
- void (async () => {
132
- const cost = SCOPE_CREDIT_COSTS[scope];
133
- const month = currentMonth();
134
- const today = currentDay();
135
- // Enterprise — no deduction needed
136
- if (tier === "enterprise")
137
- return;
138
- // Try daily free credits first
139
- const dailyFree = await getDailyFreeCredits(env, sub, today);
140
- const dailyRemaining = dailyFree.granted - dailyFree.consumed;
141
- if (dailyRemaining >= cost) {
142
- // Deduct from daily free pool
143
- await putDailyFreeCredits(env, sub, today, {
144
- ...dailyFree,
145
- consumed: dailyFree.consumed + cost,
146
- });
147
- return;
148
- }
149
- // Deduct from monthly allotment
150
- const ledger = await getLedger(env, sub, month, tier);
151
- const monthlyRemaining = ledger.allotment - ledger.consumed;
152
- if (monthlyRemaining >= cost) {
153
- await putLedger(env, sub, month, {
154
- ...ledger,
155
- consumed: ledger.consumed + cost,
156
- updated_at: new Date().toISOString(),
157
- });
158
- return;
159
- }
160
- // Overage path (Pro+ only)
161
- const config = await getCreditConfig(env, sub, tier);
162
- if (!config.overages_enabled || tier === "free")
163
- return;
164
- const volumeDiscount = resolveVolumeDiscount(ledger.consumed);
165
- const effectiveRate = OVERAGE_PRICE_PER_CREDIT_CENTS * (1 - volumeDiscount / 100);
166
- const overageCostCents = Math.round(cost * effectiveRate * 100) / 100;
167
- const updatedLedger = {
168
- ...ledger,
169
- consumed: ledger.consumed + cost,
170
- overage: ledger.overage + cost,
171
- overage_billed_cents: ledger.overage_billed_cents + overageCostCents,
172
- updated_at: new Date().toISOString(),
173
- };
174
- // Check billing threshold
175
- if (!ledger.threshold_triggered &&
176
- updatedLedger.overage_billed_cents >= config.billing_threshold_cents) {
177
- updatedLedger.threshold_triggered = true;
178
- // Trigger Stripe invoice finalization (async, non-blocking)
179
- void triggerBillingThreshold(env, sub, updatedLedger.overage_billed_cents);
180
- }
181
- await putLedger(env, sub, month, updatedLedger);
182
- // Push overage to Stripe at every 100-credit boundary
183
- if (updatedLedger.overage % 100 === 0) {
184
- void pushOverageToStripe(env, sub, 100, effectiveRate).catch(() => { });
185
- }
186
- })();
187
- }
188
- // ---------------------------------------------------------------------------
189
- // Credit Grant (Rollover)
190
- // ---------------------------------------------------------------------------
191
- /**
192
- * Calculate and apply rollover credits from previous month.
193
- * Called by the monthly cron job (scheduled handler).
194
- *
195
- * Rules:
196
- * - Only Pro+ tiers get rollovers
197
- * - Rollover = min(unused credits, allotment * ROLLOVER_CAP_MULTIPLIER)
198
- * - Rollovers expire after 1 month (use-it-or-lose-it next cycle)
199
- */
200
- export async function applyMonthlyRollover(env, sub, tier) {
201
- if (tier === "free")
202
- return null;
203
- const prevMonth = previousMonth();
204
- const prevLedger = await getLedger(env, sub, prevMonth, tier);
205
- const unused = Math.max(0, prevLedger.allotment - prevLedger.consumed);
206
- if (unused === 0)
207
- return null;
208
- const maxRollover = TIER_CREDIT_ALLOTMENTS[tier] * ROLLOVER_CAP_MULTIPLIER;
209
- const rolloverAmount = Math.min(unused, maxRollover);
210
- const rollover = {
211
- credits: rolloverAmount,
212
- source_month: prevMonth,
213
- expires_at: firstDayMonthAfterNext(),
214
- };
215
- await env.CARRIER_USERS.put(`credits:rollover:${sub}`, JSON.stringify(rollover), { expirationTtl: 62 * 24 * 60 * 60 });
216
- // Apply to current month's ledger
217
- const currentMo = currentMonth();
218
- const currentLedger = await getLedger(env, sub, currentMo, tier);
219
- await putLedger(env, sub, currentMo, {
220
- ...currentLedger,
221
- allotment: currentLedger.allotment + rolloverAmount,
222
- rollover_applied: rolloverAmount,
223
- updated_at: new Date().toISOString(),
224
- });
225
- return rollover;
226
- }
227
- // ---------------------------------------------------------------------------
228
- // Volume Discounts
229
- // ---------------------------------------------------------------------------
230
- /**
231
- * Resolve the applicable volume discount percentage based on cumulative usage.
232
- */
233
- export function resolveVolumeDiscount(consumed) {
234
- let discount = 0;
235
- for (const tier of VOLUME_DISCOUNTS) {
236
- if (consumed >= tier.threshold) {
237
- discount = tier.discountPct;
238
- }
239
- else {
240
- break;
241
- }
242
- }
243
- return discount;
244
- }
245
- // ---------------------------------------------------------------------------
246
- // Billing Threshold
247
- // ---------------------------------------------------------------------------
248
- /**
249
- * Trigger billing threshold — creates a Stripe invoice for accumulated overages.
250
- * Prevents bill shock by invoicing incrementally (Hex pattern).
251
- */
252
- async function triggerBillingThreshold(env, sub, amountCents) {
253
- const stripeKey = env.STRIPE_SECRET_KEY;
254
- if (!stripeKey)
255
- return;
256
- const customerId = await env.CARRIER_USERS.get(`stripe_customer_id:${sub}`);
257
- if (!customerId)
258
- return;
259
- // Create an invoice item for the threshold amount
260
- const body = new URLSearchParams({
261
- customer: customerId,
262
- amount: String(Math.round(amountCents)),
263
- currency: "usd",
264
- description: `Carrier MCP overage credits (threshold reached)`,
265
- });
266
- const resp = await fetch("https://api.stripe.com/v1/invoiceitems", {
267
- method: "POST",
268
- headers: {
269
- Authorization: `Bearer ${stripeKey}`,
270
- "Content-Type": "application/x-www-form-urlencoded",
271
- },
272
- body: body.toString(),
273
- });
274
- if (!resp.ok)
275
- return;
276
- // Create and finalize the invoice
277
- const invoiceBody = new URLSearchParams({
278
- customer: customerId,
279
- auto_advance: "true", // Auto-finalize and attempt payment
280
- "collection_method": "charge_automatically",
281
- description: "Carrier MCP — Overage billing threshold invoice",
282
- });
283
- await fetch("https://api.stripe.com/v1/invoices", {
284
- method: "POST",
285
- headers: {
286
- Authorization: `Bearer ${stripeKey}`,
287
- "Content-Type": "application/x-www-form-urlencoded",
288
- },
289
- body: invoiceBody.toString(),
290
- });
291
- }
292
- /**
293
- * Push overage usage records to Stripe Metered Billing.
294
- */
295
- async function pushOverageToStripe(env, sub, quantity, ratePerCredit) {
296
- const stripeKey = env.STRIPE_SECRET_KEY;
297
- if (!stripeKey)
298
- return;
299
- const subItemId = await env.CARRIER_USERS.get(`stripe_sub_item_id:${sub}`);
300
- if (!subItemId)
301
- return;
302
- const body = new URLSearchParams({
303
- quantity: String(quantity),
304
- timestamp: String(Math.floor(Date.now() / 1000)),
305
- action: "increment",
306
- });
307
- await fetch(`https://api.stripe.com/v1/subscription_items/${subItemId}/usage_records`, {
308
- method: "POST",
309
- headers: {
310
- Authorization: `Bearer ${stripeKey}`,
311
- "Content-Type": "application/x-www-form-urlencoded",
312
- },
313
- body: body.toString(),
314
- });
315
- // Store rate for reconciliation
316
- await env.CARRIER_USERS.put(`overage_rate:${sub}`, JSON.stringify({ rate_cents: ratePerCredit, updated_at: new Date().toISOString() }), { expirationTtl: 35 * 24 * 60 * 60 });
317
- }
318
- // ---------------------------------------------------------------------------
319
- // KV Helpers
320
- // ---------------------------------------------------------------------------
321
- async function getLedger(env, sub, month, tier) {
322
- const key = `credits:${sub}:${month}`;
323
- const raw = await env.CARRIER_USERS.get(key, "json").catch(() => null);
324
- if (raw && typeof raw === "object" && "allotment" in raw) {
325
- return raw;
326
- }
327
- // Initialize new ledger for the month
328
- const allotment = TIER_CREDIT_ALLOTMENTS[tier];
329
- return {
330
- allotment,
331
- consumed: 0,
332
- rollover_applied: 0,
333
- overage: 0,
334
- overage_billed_cents: 0,
335
- threshold_triggered: false,
336
- updated_at: new Date().toISOString(),
337
- };
338
- }
339
- async function putLedger(env, sub, month, ledger) {
340
- const key = `credits:${sub}:${month}`;
341
- await env.CARRIER_USERS.put(key, JSON.stringify(ledger), {
342
- expirationTtl: 65 * 24 * 60 * 60, // ~2 months
343
- });
344
- }
345
- async function getDailyFreeCredits(env, sub, day) {
346
- const key = `credits:daily:${sub}:${day}`;
347
- const raw = await env.CARRIER_USERS.get(key, "json").catch(() => null);
348
- if (raw && typeof raw === "object" && "granted" in raw) {
349
- return raw;
350
- }
351
- // Initialize daily free credits
352
- return {
353
- granted: DAILY_FREE_CREDITS,
354
- consumed: 0,
355
- date: day,
356
- };
357
- }
358
- async function putDailyFreeCredits(env, sub, day, credits) {
359
- const key = `credits:daily:${sub}:${day}`;
360
- await env.CARRIER_USERS.put(key, JSON.stringify(credits), {
361
- expirationTtl: 2 * 24 * 60 * 60, // 2 days
362
- });
363
- }
364
- async function getCreditConfig(env, sub, tier) {
365
- const key = `credits:config:${sub}`;
366
- const raw = await env.CARRIER_USERS.get(key, "json").catch(() => null);
367
- if (raw && typeof raw === "object" && "billing_threshold_cents" in raw) {
368
- return raw;
369
- }
370
- // Default config
371
- return {
372
- billing_threshold_cents: DEFAULT_BILLING_THRESHOLD_CENTS,
373
- overages_enabled: tier !== "free",
374
- rollovers_enabled: tier !== "free",
375
- overage_rate_cents: OVERAGE_PRICE_PER_CREDIT_CENTS,
376
- volume_discount_pct: 0,
377
- notify_at_pct: [50, 80, 95, 100],
378
- updated_at: new Date().toISOString(),
379
- };
380
- }
381
- // ---------------------------------------------------------------------------
382
- // Admin: Update Credit Config
383
- // ---------------------------------------------------------------------------
384
- /**
385
- * Update a user's credit configuration (admin or self-service).
386
- */
387
- export async function updateCreditConfig(env, sub, updates) {
388
- const tier = await resolveUserTier(env, sub);
389
- const current = await getCreditConfig(env, sub, tier);
390
- const updated = {
391
- ...current,
392
- ...updates,
393
- updated_at: new Date().toISOString(),
394
- };
395
- const key = `credits:config:${sub}`;
396
- await env.CARRIER_USERS.put(key, JSON.stringify(updated));
397
- return updated;
398
- }
399
- /**
400
- * Get credit usage summary for a user (used by billing UI).
401
- */
402
- export async function getCreditSummary(env, sub, tier) {
403
- const month = currentMonth();
404
- const today = currentDay();
405
- const ledger = await getLedger(env, sub, month, tier);
406
- const dailyFree = await getDailyFreeCredits(env, sub, today);
407
- const config = await getCreditConfig(env, sub, tier);
408
- const rolloverRaw = await env.CARRIER_USERS.get(`credits:rollover:${sub}`, "json").catch(() => null);
409
- const rollover = rolloverRaw;
410
- const volumeDiscount = resolveVolumeDiscount(ledger.consumed);
411
- return { ledger, daily_free: dailyFree, config, rollover, volume_discount_pct: volumeDiscount };
412
- }
413
- // ---------------------------------------------------------------------------
414
- // Stripe Credit Grants
415
- // ---------------------------------------------------------------------------
416
- /**
417
- * Issue a credit grant to a customer via Stripe Customer Balance Transactions.
418
- * Used for promotional credits, referral bonuses, and compensation.
419
- */
420
- export async function issueStripeCredits(env, sub, amountCents, description) {
421
- const stripeKey = env.STRIPE_SECRET_KEY;
422
- if (!stripeKey)
423
- return false;
424
- const customerId = await env.CARRIER_USERS.get(`stripe_customer_id:${sub}`);
425
- if (!customerId)
426
- return false;
427
- const body = new URLSearchParams({
428
- amount: String(-Math.abs(amountCents)), // Negative = credit to customer
429
- currency: "usd",
430
- description,
431
- });
432
- const resp = await fetch(`https://api.stripe.com/v1/customers/${customerId}/balance_transactions`, {
433
- method: "POST",
434
- headers: {
435
- Authorization: `Bearer ${stripeKey}`,
436
- "Content-Type": "application/x-www-form-urlencoded",
437
- },
438
- body: body.toString(),
439
- });
440
- return resp.ok;
441
- }
442
- // ---------------------------------------------------------------------------
443
- // Internal Helpers
444
- // ---------------------------------------------------------------------------
445
- async function resolveUserTier(env, sub) {
446
- const raw = await env.CARRIER_USERS.get(`user:${sub}`, "json").catch(() => null);
447
- if (raw && typeof raw === "object" && "tier" in raw) {
448
- const t = raw.tier;
449
- if (t === "pro" || t === "enterprise")
450
- return t;
451
- }
452
- return "free";
453
- }
454
- function currentMonth() {
455
- const now = new Date();
456
- return `${now.getUTCFullYear()}${String(now.getUTCMonth() + 1).padStart(2, "0")}`;
457
- }
458
- function currentDay() {
459
- const now = new Date();
460
- return `${now.getUTCFullYear()}${String(now.getUTCMonth() + 1).padStart(2, "0")}${String(now.getUTCDate()).padStart(2, "0")}`;
461
- }
462
- function previousMonth() {
463
- const now = new Date();
464
- const d = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() - 1, 1));
465
- return `${d.getUTCFullYear()}${String(d.getUTCMonth() + 1).padStart(2, "0")}`;
466
- }
467
- function firstDayNextMonth() {
468
- const now = new Date();
469
- const y = now.getUTCFullYear();
470
- const m = now.getUTCMonth() + 1;
471
- if (m === 12)
472
- return new Date(Date.UTC(y + 1, 0, 1)).toISOString();
473
- return new Date(Date.UTC(y, m, 1)).toISOString();
474
- }
475
- function firstDayMonthAfterNext() {
476
- const now = new Date();
477
- const y = now.getUTCFullYear();
478
- const m = now.getUTCMonth() + 2;
479
- if (m >= 12)
480
- return new Date(Date.UTC(y + 1, m - 12, 1)).toISOString();
481
- return new Date(Date.UTC(y, m, 1)).toISOString();
482
- }
483
- //# sourceMappingURL=credits.js.map