@chatarmin/os 1.0.0 → 1.1.0
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.
- package/README.md +750 -80
- package/dist/index.d.ts +205 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +114 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,167 +1,837 @@
|
|
|
1
|
-
# @chatarmin/os
|
|
1
|
+
# @chatarmin/os
|
|
2
2
|
|
|
3
|
-
Type-safe SDK for ChatarminOS -
|
|
3
|
+
> Type-safe SDK for ChatarminOS — the all-in-one platform for B2B SaaS to manage customers, subscriptions, feature access, and billing.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@chatarmin/os)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
## Features
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
- 🏢 **Company Management** — Create, link, and manage customer companies
|
|
11
|
+
- 🎫 **Subscription Tiers** — Define tiers with features and Stripe pricing
|
|
12
|
+
- ✨ **Feature Access** — Check entitlements and enforce usage limits
|
|
13
|
+
- 📊 **Usage Tracking** — Metered billing with idempotency support
|
|
14
|
+
- 💳 **Stripe Integration** — Claim checkout sessions, link subscriptions
|
|
15
|
+
- 🔗 **Smart Linking** — Intelligent company matching by domain/name/email
|
|
16
|
+
- 👥 **Contact Sync** — Bulk upsert contacts for each company
|
|
17
|
+
- 🚀 **Unified Onboarding** — Complete setup in a single API call
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
---
|
|
12
20
|
|
|
13
|
-
|
|
14
|
-
# .npmrc
|
|
15
|
-
@chatarmin:registry=https://registry.npmjs.org/
|
|
16
|
-
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
|
|
17
|
-
```
|
|
21
|
+
## Table of Contents
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
- [Installation](#installation)
|
|
24
|
+
- [Quick Start](#quick-start)
|
|
25
|
+
- [API Reference](#api-reference)
|
|
26
|
+
- [Companies](#companies)
|
|
27
|
+
- [Contacts](#contacts)
|
|
28
|
+
- [Features](#features)
|
|
29
|
+
- [Billing](#billing)
|
|
30
|
+
- [Subscriptions & Tiers](#subscriptions--tiers)
|
|
31
|
+
- [Links](#links)
|
|
32
|
+
- [Onboarding](#onboarding)
|
|
33
|
+
- [Common Patterns](#common-patterns)
|
|
34
|
+
- [TypeScript Support](#typescript-support)
|
|
35
|
+
- [Configuration](#configuration)
|
|
36
|
+
- [Error Handling](#error-handling)
|
|
20
37
|
|
|
21
|
-
|
|
22
|
-
# .env (for local development)
|
|
23
|
-
NPM_TOKEN=npm_yourtokenhere
|
|
38
|
+
---
|
|
24
39
|
|
|
25
|
-
|
|
26
|
-
export NPM_TOKEN=npm_yourtokenhere
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
**For CI/CD**: Add `NPM_TOKEN` as a secret in your deployment platform (GitHub Actions, Vercel, etc.)
|
|
30
|
-
|
|
31
|
-
### 2. Install the Package
|
|
40
|
+
## Installation
|
|
32
41
|
|
|
33
42
|
```bash
|
|
34
|
-
|
|
43
|
+
pnpm add @chatarmin/os
|
|
35
44
|
# or
|
|
36
|
-
|
|
45
|
+
npm install @chatarmin/os
|
|
37
46
|
# or
|
|
38
|
-
yarn add @chatarmin/os
|
|
47
|
+
yarn add @chatarmin/os
|
|
39
48
|
```
|
|
40
49
|
|
|
41
|
-
|
|
50
|
+
---
|
|
42
51
|
|
|
43
52
|
## Quick Start
|
|
44
53
|
|
|
45
54
|
```typescript
|
|
46
|
-
import { ChatarminOS } from "@chatarmin/os
|
|
55
|
+
import { ChatarminOS } from "@chatarmin/os"
|
|
47
56
|
|
|
48
57
|
const os = new ChatarminOS({
|
|
49
|
-
apiKey: process.env.
|
|
58
|
+
apiKey: process.env.OS_API_KEY!,
|
|
50
59
|
// Optional: custom base URL for self-hosted
|
|
51
60
|
// baseUrl: 'https://your-os.example.com/api/v1'
|
|
52
61
|
})
|
|
62
|
+
|
|
63
|
+
// Onboard a new customer (single call does everything!)
|
|
64
|
+
const result = await os.onboard({
|
|
65
|
+
externalOrgId: "org_abc123", // Your product's org ID
|
|
66
|
+
hints: {
|
|
67
|
+
companyName: "Acme Inc",
|
|
68
|
+
domain: "acme.com",
|
|
69
|
+
},
|
|
70
|
+
tierCode: "free",
|
|
71
|
+
contactEmail: "admin@acme.com",
|
|
72
|
+
contactName: "John Doe",
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
console.log(result.companyId) // Use this for all future API calls
|
|
76
|
+
console.log(result.linkStatus) // 'created' | 'linked' | 'already_linked'
|
|
53
77
|
```
|
|
54
78
|
|
|
55
|
-
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## API Reference
|
|
56
82
|
|
|
57
83
|
### Companies
|
|
58
84
|
|
|
85
|
+
Manage customer companies and their links to your product.
|
|
86
|
+
|
|
87
|
+
#### `companies.getByProductLink(input)`
|
|
88
|
+
|
|
89
|
+
Look up a company by your external organization ID.
|
|
90
|
+
|
|
59
91
|
```typescript
|
|
60
|
-
// Find company by your external org ID
|
|
61
92
|
const company = await os.companies.getByProductLink({
|
|
62
|
-
externalOrgId: "
|
|
93
|
+
externalOrgId: "org_abc123",
|
|
63
94
|
})
|
|
64
95
|
|
|
65
|
-
|
|
66
|
-
|
|
96
|
+
if (company) {
|
|
97
|
+
console.log(`Found: ${company.name} (${company.id})`)
|
|
98
|
+
} else {
|
|
99
|
+
console.log("Company not linked yet")
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### `companies.create(input)`
|
|
104
|
+
|
|
105
|
+
Create a new company and link it to your product.
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
const company = await os.companies.create({
|
|
67
109
|
name: "Acme Inc",
|
|
68
110
|
domain: "acme.com",
|
|
69
|
-
externalOrgId: "
|
|
70
|
-
contactEmail: "
|
|
111
|
+
externalOrgId: "org_abc123",
|
|
112
|
+
contactEmail: "admin@acme.com",
|
|
71
113
|
contactName: "John Doe",
|
|
114
|
+
createdAt: "2024-01-15T10:30:00.000Z", // Optional: historical date
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
console.log(company.id) // UUID
|
|
118
|
+
console.log(company.shortId) // e.g., "acme-inc"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### `companies.update(input)`
|
|
122
|
+
|
|
123
|
+
Update company metadata (e.g., backfill historical dates).
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
await os.companies.update({
|
|
127
|
+
companyId: "uuid-here",
|
|
128
|
+
createdAt: "2023-06-01T00:00:00.000Z",
|
|
72
129
|
})
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### `companies.smartLink(input)`
|
|
73
133
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
134
|
+
Intelligently find and link a company using hints.
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
const result = await os.companies.smartLink({
|
|
138
|
+
externalOrgId: "org_abc123",
|
|
77
139
|
hints: {
|
|
78
|
-
companyName: "Acme",
|
|
140
|
+
companyName: "Acme Inc",
|
|
79
141
|
domain: "acme.com",
|
|
80
142
|
emails: ["john@acme.com", "jane@acme.com"],
|
|
81
143
|
},
|
|
82
|
-
minConfidence: 0.
|
|
144
|
+
minConfidence: 0.7, // Default: 0.6
|
|
83
145
|
})
|
|
146
|
+
|
|
147
|
+
switch (result.status) {
|
|
148
|
+
case "already_linked":
|
|
149
|
+
console.log("Already linked to your product")
|
|
150
|
+
break
|
|
151
|
+
case "linked":
|
|
152
|
+
console.log(
|
|
153
|
+
`Auto-linked to ${result.customerName} (${result.confidence}% confidence)`
|
|
154
|
+
)
|
|
155
|
+
break
|
|
156
|
+
case "suggestions":
|
|
157
|
+
console.log("Multiple matches found:", result.suggestions)
|
|
158
|
+
break
|
|
159
|
+
case "no_match":
|
|
160
|
+
console.log("No matching company found")
|
|
161
|
+
break
|
|
162
|
+
}
|
|
84
163
|
```
|
|
85
164
|
|
|
86
|
-
|
|
165
|
+
**Matching priority:**
|
|
166
|
+
|
|
167
|
+
1. Domain match → 95% confidence
|
|
168
|
+
2. Name match → up to 80% confidence
|
|
169
|
+
3. Email domain match → 70% confidence
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
### Contacts
|
|
174
|
+
|
|
175
|
+
Manage people associated with companies.
|
|
176
|
+
|
|
177
|
+
#### `contacts.create(input)`
|
|
178
|
+
|
|
179
|
+
Create or update a single contact.
|
|
87
180
|
|
|
88
181
|
```typescript
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
182
|
+
const contact = await os.contacts.create({
|
|
183
|
+
companyId: "comp_xxx",
|
|
184
|
+
email: "john@acme.com",
|
|
185
|
+
name: "John Doe",
|
|
186
|
+
role: "CEO",
|
|
187
|
+
isPrimary: true,
|
|
188
|
+
avatarUrl: "https://example.com/avatar.jpg",
|
|
189
|
+
metadata: { slackId: "U123" },
|
|
92
190
|
})
|
|
93
191
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
192
|
+
if (contact.isNew) {
|
|
193
|
+
console.log("Created new contact")
|
|
194
|
+
} else {
|
|
195
|
+
console.log("Updated existing contact")
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
#### `contacts.bulkUpsert(input)`
|
|
200
|
+
|
|
201
|
+
Bulk create or update multiple contacts. **Recommended for onboarding.**
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
const result = await os.contacts.bulkUpsert({
|
|
205
|
+
companyId: "comp_xxx",
|
|
206
|
+
contacts: [
|
|
207
|
+
{ email: "ceo@acme.com", name: "Alice", role: "CEO", isPrimary: true },
|
|
208
|
+
{ email: "cto@acme.com", name: "Bob", role: "CTO" },
|
|
209
|
+
{ email: "dev@acme.com", name: "Charlie", role: "Engineer" },
|
|
210
|
+
],
|
|
100
211
|
})
|
|
101
212
|
|
|
102
|
-
|
|
103
|
-
|
|
213
|
+
console.log(`Created: ${result.created}, Updated: ${result.updated}`)
|
|
214
|
+
// result.contacts contains individual results with IDs
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
#### `contacts.list(companyId, primaryOnly?)`
|
|
104
218
|
|
|
105
|
-
|
|
106
|
-
|
|
219
|
+
List contacts for a company.
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// Get all contacts
|
|
223
|
+
const contacts = await os.contacts.list("comp_xxx")
|
|
224
|
+
|
|
225
|
+
// Get only the primary contact
|
|
226
|
+
const [primary] = await os.contacts.list("comp_xxx", true)
|
|
107
227
|
```
|
|
108
228
|
|
|
109
|
-
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
### Features
|
|
232
|
+
|
|
233
|
+
Check and manage feature access for companies.
|
|
234
|
+
|
|
235
|
+
#### `features.check(input)`
|
|
236
|
+
|
|
237
|
+
Check if a company has access to a specific feature.
|
|
110
238
|
|
|
111
239
|
```typescript
|
|
112
|
-
// Check if company has access to a feature
|
|
113
240
|
const access = await os.features.check({
|
|
114
|
-
companyId:
|
|
115
|
-
featureCode: "
|
|
241
|
+
companyId: "comp_xxx",
|
|
242
|
+
featureCode: "ai_credit",
|
|
116
243
|
})
|
|
117
244
|
|
|
118
|
-
|
|
119
|
-
|
|
245
|
+
console.log({
|
|
246
|
+
enabled: access.isEnabled, // Feature is turned on
|
|
247
|
+
canUse: access.canUse, // Can use right now (not at limit)
|
|
248
|
+
hasQuantity: access.hasQuantity, // Is a quantity-based feature
|
|
249
|
+
usage: access.currentUsage, // Current usage count
|
|
250
|
+
limit: access.quantityLimit, // Max allowed (null = unlimited)
|
|
251
|
+
included: access.includedQuantity, // Free tier before billing
|
|
252
|
+
remaining: access.remaining, // How many left (null = unlimited)
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
if (!access.canUse) {
|
|
256
|
+
throw new Error("Upgrade required")
|
|
120
257
|
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### `features.listAccess(companyId)`
|
|
261
|
+
|
|
262
|
+
List all features and their access status for a company.
|
|
121
263
|
|
|
122
|
-
|
|
123
|
-
const
|
|
264
|
+
```typescript
|
|
265
|
+
const features = await os.features.listAccess("comp_xxx")
|
|
266
|
+
|
|
267
|
+
for (const f of features) {
|
|
268
|
+
console.log(`${f.featureName}: ${f.isEnabled ? "✓" : "✗"}`)
|
|
269
|
+
if (f.quantityLimit) {
|
|
270
|
+
console.log(` Usage: ${f.currentUsage} / ${f.quantityLimit}`)
|
|
271
|
+
}
|
|
272
|
+
}
|
|
124
273
|
```
|
|
125
274
|
|
|
126
|
-
|
|
275
|
+
#### `features.setAccess(input)`
|
|
276
|
+
|
|
277
|
+
Update feature access with **partial config merge**.
|
|
127
278
|
|
|
128
279
|
```typescript
|
|
129
|
-
//
|
|
130
|
-
await os.
|
|
131
|
-
companyId:
|
|
132
|
-
featureCode: "
|
|
280
|
+
// Update by company ID
|
|
281
|
+
await os.features.setAccess({
|
|
282
|
+
companyId: "comp_xxx",
|
|
283
|
+
featureCode: "ai_credit",
|
|
284
|
+
isEnabled: true,
|
|
285
|
+
quantityLimit: 1000,
|
|
286
|
+
includedQuantity: 100,
|
|
287
|
+
config: {
|
|
288
|
+
model: "gpt-4",
|
|
289
|
+
maxTokens: 4096,
|
|
290
|
+
},
|
|
291
|
+
source: "manual", // 'subscription' | 'manual' | 'trial' | 'api'
|
|
292
|
+
validUntil: new Date("2025-12-31"), // null for no expiration
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
// Update by external org ID
|
|
296
|
+
await os.features.setAccess({
|
|
297
|
+
externalOrgId: "org_abc123",
|
|
298
|
+
featureCode: "team_seats",
|
|
299
|
+
config: { maxSeats: 50 }, // Only updates maxSeats, preserves other config
|
|
300
|
+
})
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
#### `features.getAccessByExternalOrgId(externalOrgId)`
|
|
304
|
+
|
|
305
|
+
Get all features using your product's external org ID.
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
const result = await os.features.getAccessByExternalOrgId("org_abc123")
|
|
309
|
+
|
|
310
|
+
console.log(`Company: ${result.companyId}`)
|
|
311
|
+
for (const f of result.features) {
|
|
312
|
+
console.log(`${f.featureCode}: ${f.isEnabled}`)
|
|
313
|
+
console.log(" Config:", f.configValues)
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
#### `features.checkByExternalOrgId(externalOrgId, featureCode)`
|
|
318
|
+
|
|
319
|
+
Check a specific feature using your external org ID.
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
const access = await os.features.checkByExternalOrgId("org_abc123", "ai_credit")
|
|
323
|
+
|
|
324
|
+
if (access.canUse) {
|
|
325
|
+
console.log(`Remaining: ${access.remaining}`)
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
### Billing
|
|
332
|
+
|
|
333
|
+
Track usage, claim subscriptions, and manage billing.
|
|
334
|
+
|
|
335
|
+
#### `billing.trackUsage(input)`
|
|
336
|
+
|
|
337
|
+
Track usage for a metered feature.
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
const result = await os.billing.trackUsage({
|
|
341
|
+
companyId: "comp_xxx",
|
|
342
|
+
featureCode: "ai_credit",
|
|
133
343
|
quantity: 5,
|
|
134
|
-
idempotencyKey:
|
|
135
|
-
metadata: { model: "gpt-4" },
|
|
344
|
+
idempotencyKey: `request_${requestId}`, // Prevents double-counting
|
|
345
|
+
metadata: { model: "gpt-4", tokens: 1500 },
|
|
346
|
+
})
|
|
347
|
+
|
|
348
|
+
console.log({
|
|
349
|
+
currentUsage: result.currentUsage,
|
|
350
|
+
remaining: result.remaining,
|
|
351
|
+
billable: result.billableQuantity, // Amount beyond included tier
|
|
352
|
+
isAtLimit: result.isAtLimit,
|
|
136
353
|
})
|
|
137
354
|
```
|
|
138
355
|
|
|
139
|
-
|
|
356
|
+
#### `billing.claimCheckout(input)`
|
|
357
|
+
|
|
358
|
+
Claim a subscription from a completed Stripe Checkout Session.
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
// In your Stripe checkout success handler
|
|
362
|
+
const result = await os.billing.claimCheckout({
|
|
363
|
+
companyId: "comp_xxx",
|
|
364
|
+
checkoutSessionId: "cs_test_xxx", // From Stripe callback
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
if (result.alreadyClaimed) {
|
|
368
|
+
console.log("Subscription was already claimed")
|
|
369
|
+
} else {
|
|
370
|
+
console.log(`Claimed subscription: ${result.subscriptionId}`)
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
#### `billing.linkSubscription(input)`
|
|
375
|
+
|
|
376
|
+
Link an existing Stripe subscription to a company.
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
// When you create subscriptions on YOUR Stripe account
|
|
380
|
+
const result = await os.billing.linkSubscription({
|
|
381
|
+
companyId: "comp_xxx",
|
|
382
|
+
stripeSubscriptionId: "sub_xxx",
|
|
383
|
+
stripeCustomerId: "cus_xxx", // Optional: fetched from subscription if omitted
|
|
384
|
+
tierCode: "pro", // Apply tier features
|
|
385
|
+
displayName: "Pro Plan",
|
|
386
|
+
})
|
|
387
|
+
|
|
388
|
+
console.log({
|
|
389
|
+
subscriptionId: result.subscriptionId,
|
|
390
|
+
isNew: !result.alreadyLinked,
|
|
391
|
+
featuresApplied: result.featuresApplied,
|
|
392
|
+
})
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
#### `billing.getStatus(companyId)`
|
|
396
|
+
|
|
397
|
+
Get billing status overview for a company.
|
|
398
|
+
|
|
399
|
+
```typescript
|
|
400
|
+
const status = await os.billing.getStatus("comp_xxx")
|
|
401
|
+
|
|
402
|
+
console.log({
|
|
403
|
+
hasBilling: status.hasBillingProfile,
|
|
404
|
+
subscriptions: status.activeSubscriptions.length,
|
|
405
|
+
features: status.enabledFeaturesCount,
|
|
406
|
+
})
|
|
407
|
+
|
|
408
|
+
// Check active tier
|
|
409
|
+
if (status.activeSubscriptions[0]?.tier) {
|
|
410
|
+
console.log(`Current tier: ${status.activeSubscriptions[0].tier.name}`)
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
### Subscriptions & Tiers
|
|
417
|
+
|
|
418
|
+
Manage subscription tiers and apply features.
|
|
419
|
+
|
|
420
|
+
#### `tiers.list()`
|
|
421
|
+
|
|
422
|
+
List all available tiers for your product.
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
const tiers = await os.tiers.list()
|
|
426
|
+
|
|
427
|
+
for (const tier of tiers) {
|
|
428
|
+
console.log(`${tier.name} (${tier.code})`)
|
|
429
|
+
}
|
|
430
|
+
// ['Free', 'Pro', 'Enterprise']
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
#### `tiers.get(tierCode)`
|
|
434
|
+
|
|
435
|
+
Get detailed tier information including Stripe prices.
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
const tier = await os.tiers.get("pro")
|
|
439
|
+
|
|
440
|
+
// Check base fee
|
|
441
|
+
if (tier.baseFee) {
|
|
442
|
+
console.log(`Base fee: ${tier.baseFee.stripe.unitAmount / 100}€/mo`)
|
|
443
|
+
console.log(`Price ID: ${tier.baseFee.stripe.priceId}`)
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Access features
|
|
447
|
+
for (const feature of tier.features) {
|
|
448
|
+
console.log(`${feature.code}:`, feature.configValues)
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Get all Stripe price IDs (base fee + feature prices)
|
|
452
|
+
console.log("Stripe prices:", tier.stripePriceIds)
|
|
453
|
+
// ['price_base', 'price_feature1', 'price_feature2']
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
#### `tiers.apply(tierCode, options)`
|
|
457
|
+
|
|
458
|
+
Apply a tier's features to a company (without Stripe).
|
|
459
|
+
|
|
460
|
+
```typescript
|
|
461
|
+
// Apply free tier
|
|
462
|
+
await os.tiers.apply("free", {
|
|
463
|
+
companyId: "comp_xxx",
|
|
464
|
+
})
|
|
465
|
+
|
|
466
|
+
// Apply with custom limits
|
|
467
|
+
await os.tiers.apply("trial", {
|
|
468
|
+
companyId: "comp_xxx",
|
|
469
|
+
features: {
|
|
470
|
+
ai_credit: { included_quantity: 100 },
|
|
471
|
+
seats: { max_quantity: 10 },
|
|
472
|
+
},
|
|
473
|
+
})
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
#### `subscriptions.create(tierCode, options)`
|
|
477
|
+
|
|
478
|
+
Alias for `tiers.apply()` — apply a subscription tier.
|
|
479
|
+
|
|
480
|
+
```typescript
|
|
481
|
+
await os.subscriptions.create("pro", {
|
|
482
|
+
companyId: "comp_xxx",
|
|
483
|
+
features: {
|
|
484
|
+
ai_credit: { included_quantity: 500 },
|
|
485
|
+
},
|
|
486
|
+
})
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
---
|
|
490
|
+
|
|
491
|
+
### Links
|
|
492
|
+
|
|
493
|
+
Manually manage product links.
|
|
494
|
+
|
|
495
|
+
#### `links.create(input)`
|
|
496
|
+
|
|
497
|
+
Create a manual link between your external org ID and an existing company.
|
|
140
498
|
|
|
141
499
|
```typescript
|
|
142
|
-
// Link an external org ID to an existing company
|
|
143
500
|
await os.links.create({
|
|
501
|
+
companyId: "comp_xxx",
|
|
502
|
+
externalOrgId: "org_abc123",
|
|
503
|
+
label: "Store Vienna", // Optional: display label
|
|
504
|
+
externalUserId: "user_xyz", // Optional: user who created the link
|
|
505
|
+
})
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
#### `links.reset(options?)`
|
|
509
|
+
|
|
510
|
+
Delete all product links for your product. Use before re-importing.
|
|
511
|
+
|
|
512
|
+
```typescript
|
|
513
|
+
// Basic reset (links only)
|
|
514
|
+
const result = await os.links.reset()
|
|
515
|
+
console.log(`Deleted ${result.linksDeleted} links`)
|
|
516
|
+
|
|
517
|
+
// Full reset (links + contacts + MRR)
|
|
518
|
+
const result = await os.links.reset({
|
|
519
|
+
deleteContacts: true,
|
|
520
|
+
resetMrr: true,
|
|
521
|
+
})
|
|
522
|
+
console.log(
|
|
523
|
+
`Deleted ${result.linksDeleted} links, ${result.contactsDeleted} contacts`
|
|
524
|
+
)
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
---
|
|
528
|
+
|
|
529
|
+
### Onboarding
|
|
530
|
+
|
|
531
|
+
Complete customer onboarding in a single API call.
|
|
532
|
+
|
|
533
|
+
The `onboard()` method handles:
|
|
534
|
+
|
|
535
|
+
1. Smart company matching/creation
|
|
536
|
+
2. Product linking
|
|
537
|
+
3. Subscription claiming/linking
|
|
538
|
+
4. Tier feature application
|
|
539
|
+
|
|
540
|
+
#### Basic Usage
|
|
541
|
+
|
|
542
|
+
```typescript
|
|
543
|
+
const result = await os.onboard({
|
|
544
|
+
externalOrgId: "org_abc123", // Your product's org ID (required)
|
|
545
|
+
hints: {
|
|
546
|
+
companyName: "Acme Inc",
|
|
547
|
+
domain: "acme.com",
|
|
548
|
+
emails: ["john@acme.com"],
|
|
549
|
+
},
|
|
550
|
+
tierCode: "free",
|
|
551
|
+
contactEmail: "admin@acme.com",
|
|
552
|
+
contactName: "John Doe",
|
|
553
|
+
createdAt: "2024-01-15T10:30:00.000Z", // Optional: historical date
|
|
554
|
+
})
|
|
555
|
+
|
|
556
|
+
console.log({
|
|
557
|
+
companyId: result.companyId,
|
|
558
|
+
companyName: result.companyName,
|
|
559
|
+
linkStatus: result.linkStatus, // 'created' | 'linked' | 'already_linked'
|
|
560
|
+
tierApplied: result.billingStatus?.tierApplied,
|
|
561
|
+
})
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
#### Scenario 1: User Completed Stripe Checkout
|
|
565
|
+
|
|
566
|
+
```typescript
|
|
567
|
+
const result = await os.onboard({
|
|
568
|
+
externalOrgId: "org_abc123",
|
|
569
|
+
hints: { companyName: "Acme Inc", domain: "acme.com" },
|
|
570
|
+
checkoutSessionId: "cs_test_xxx", // From Stripe checkout callback
|
|
571
|
+
})
|
|
572
|
+
|
|
573
|
+
// result.billingStatus.claimed = true
|
|
574
|
+
// result.billingStatus.subscriptionId = 'sub_xxx'
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
#### Scenario 2: Free Tier Signup
|
|
578
|
+
|
|
579
|
+
```typescript
|
|
580
|
+
const result = await os.onboard({
|
|
581
|
+
externalOrgId: "org_abc123",
|
|
582
|
+
hints: { companyName: "Acme Inc" },
|
|
583
|
+
tierCode: "free",
|
|
584
|
+
contactEmail: "admin@acme.com",
|
|
585
|
+
})
|
|
586
|
+
|
|
587
|
+
// result.billingStatus.tierApplied = true
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
#### Scenario 3: You Create Stripe Subscription
|
|
591
|
+
|
|
592
|
+
```typescript
|
|
593
|
+
// 1. Get tier prices
|
|
594
|
+
const tier = await os.tiers.get("pro")
|
|
595
|
+
|
|
596
|
+
// 2. Create subscription on YOUR Stripe account
|
|
597
|
+
const stripeSub = await stripe.subscriptions.create({
|
|
598
|
+
customer: stripeCustomerId,
|
|
599
|
+
items: tier.stripePriceIds.map((price) => ({ price })),
|
|
600
|
+
})
|
|
601
|
+
|
|
602
|
+
// 3. Onboard with the subscription
|
|
603
|
+
const result = await os.onboard({
|
|
604
|
+
externalOrgId: "org_abc123",
|
|
605
|
+
hints: { companyName: "Acme Inc" },
|
|
606
|
+
stripeSubscriptionId: stripeSub.id,
|
|
607
|
+
stripeCustomerId: stripeCustomerId,
|
|
608
|
+
tierCode: "pro",
|
|
609
|
+
})
|
|
610
|
+
|
|
611
|
+
// result.billingStatus.linked = true
|
|
612
|
+
// result.billingStatus.tierApplied = true
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
#### Handling Existing Customers
|
|
616
|
+
|
|
617
|
+
```typescript
|
|
618
|
+
const result = await os.onboard({
|
|
619
|
+
externalOrgId: "org_abc123",
|
|
620
|
+
hints: { companyName: "Acme Inc" },
|
|
621
|
+
})
|
|
622
|
+
|
|
623
|
+
switch (result.linkStatus) {
|
|
624
|
+
case "already_linked":
|
|
625
|
+
console.log("Welcome back!")
|
|
626
|
+
break
|
|
627
|
+
case "linked":
|
|
628
|
+
console.log("Found existing company, linked!")
|
|
629
|
+
break
|
|
630
|
+
case "created":
|
|
631
|
+
console.log("New company created!")
|
|
632
|
+
break
|
|
633
|
+
}
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
## Common Patterns
|
|
639
|
+
|
|
640
|
+
### Feature Gating
|
|
641
|
+
|
|
642
|
+
```typescript
|
|
643
|
+
async function checkFeatureAccess(orgId: string, feature: string) {
|
|
644
|
+
const access = await os.features.checkByExternalOrgId(orgId, feature)
|
|
645
|
+
|
|
646
|
+
if (!access.isEnabled) {
|
|
647
|
+
throw new Error(`Feature ${feature} is not available on your plan`)
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
if (!access.canUse) {
|
|
651
|
+
throw new Error(`Usage limit reached for ${feature}. Please upgrade.`)
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
return access
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// Usage
|
|
658
|
+
await checkFeatureAccess("org_abc123", "ai_credit")
|
|
659
|
+
await performAIOperation()
|
|
660
|
+
await os.billing.trackUsage({
|
|
144
661
|
companyId: company.id,
|
|
145
|
-
|
|
146
|
-
|
|
662
|
+
featureCode: "ai_credit",
|
|
663
|
+
quantity: 1,
|
|
147
664
|
})
|
|
148
665
|
```
|
|
149
666
|
|
|
150
|
-
|
|
667
|
+
### Stripe Subscription Flow
|
|
668
|
+
|
|
669
|
+
```typescript
|
|
670
|
+
// 1. User selects a plan → Get tier prices
|
|
671
|
+
const tier = await os.tiers.get("pro")
|
|
672
|
+
|
|
673
|
+
// 2. Create Stripe Checkout Session with tier prices
|
|
674
|
+
const session = await stripe.checkout.sessions.create({
|
|
675
|
+
customer: customerId,
|
|
676
|
+
line_items: tier.stripePriceIds.map((price) => ({
|
|
677
|
+
price,
|
|
678
|
+
quantity: 1,
|
|
679
|
+
})),
|
|
680
|
+
success_url: `${baseUrl}/success?session_id={CHECKOUT_SESSION_ID}`,
|
|
681
|
+
cancel_url: `${baseUrl}/cancel`,
|
|
682
|
+
})
|
|
683
|
+
|
|
684
|
+
// 3. After checkout completes → Claim subscription
|
|
685
|
+
const result = await os.onboard({
|
|
686
|
+
externalOrgId: "org_abc123",
|
|
687
|
+
checkoutSessionId: session.id,
|
|
688
|
+
})
|
|
689
|
+
```
|
|
151
690
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
691
|
+
### Backfilling Historical Data
|
|
692
|
+
|
|
693
|
+
```typescript
|
|
694
|
+
import { ChatarminOS } from "@chatarmin/os"
|
|
695
|
+
import historicalData from "./migration-data.json"
|
|
696
|
+
|
|
697
|
+
const os = new ChatarminOS({ apiKey: process.env.OS_API_KEY! })
|
|
698
|
+
|
|
699
|
+
for (const org of historicalData) {
|
|
700
|
+
// Create company with historical date
|
|
701
|
+
const result = await os.onboard({
|
|
702
|
+
externalOrgId: org.id,
|
|
703
|
+
hints: {
|
|
704
|
+
companyName: org.name,
|
|
705
|
+
domain: org.domain,
|
|
706
|
+
},
|
|
707
|
+
tierCode: org.plan,
|
|
708
|
+
contactEmail: org.adminEmail,
|
|
709
|
+
createdAt: org.createdAt, // Historical timestamp
|
|
710
|
+
})
|
|
711
|
+
|
|
712
|
+
// Sync contacts
|
|
713
|
+
await os.contacts.bulkUpsert({
|
|
714
|
+
companyId: result.companyId,
|
|
715
|
+
contacts: org.users.map((u) => ({
|
|
716
|
+
email: u.email,
|
|
717
|
+
name: u.name,
|
|
718
|
+
role: u.role,
|
|
719
|
+
})),
|
|
720
|
+
})
|
|
721
|
+
}
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
---
|
|
156
725
|
|
|
157
726
|
## TypeScript Support
|
|
158
727
|
|
|
159
|
-
The SDK is fully typed
|
|
728
|
+
The SDK is fully typed with comprehensive TypeScript definitions.
|
|
729
|
+
|
|
730
|
+
### Importing Types
|
|
731
|
+
|
|
732
|
+
```typescript
|
|
733
|
+
import { ChatarminOS } from "@chatarmin/os"
|
|
734
|
+
import type {
|
|
735
|
+
ChatarminOSConfig,
|
|
736
|
+
CreateCompanyInput,
|
|
737
|
+
SmartLinkInput,
|
|
738
|
+
SmartLinkResult,
|
|
739
|
+
ContactInput,
|
|
740
|
+
FeatureCheckInput,
|
|
741
|
+
FeatureSetAccessInput,
|
|
742
|
+
TrackUsageInput,
|
|
743
|
+
OnboardInput,
|
|
744
|
+
OnboardResult,
|
|
745
|
+
ApplyTierInput,
|
|
746
|
+
ClaimCheckoutInput,
|
|
747
|
+
LinkSubscriptionInput,
|
|
748
|
+
} from "@chatarmin/os"
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
### Router Types
|
|
752
|
+
|
|
753
|
+
```typescript
|
|
754
|
+
import type { AppRouter } from "@chatarmin/os"
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
---
|
|
758
|
+
|
|
759
|
+
## Configuration
|
|
760
|
+
|
|
761
|
+
| Option | Type | Required | Default | Description |
|
|
762
|
+
| --------- | -------- | -------- | --------------------------------- | --------------------------- |
|
|
763
|
+
| `apiKey` | `string` | ✅ | — | API key from OS admin panel |
|
|
764
|
+
| `baseUrl` | `string` | — | `https://os.chatarmin.com/api/v1` | API endpoint |
|
|
160
765
|
|
|
161
766
|
```typescript
|
|
162
|
-
|
|
767
|
+
const os = new ChatarminOS({
|
|
768
|
+
apiKey: process.env.OS_API_KEY!,
|
|
769
|
+
baseUrl: "https://os.chatarmin.com/api/v1", // Default
|
|
770
|
+
})
|
|
771
|
+
|
|
772
|
+
// Local development
|
|
773
|
+
const osLocal = new ChatarminOS({
|
|
774
|
+
apiKey: process.env.OS_API_KEY!,
|
|
775
|
+
baseUrl: "http://localhost:3001/api/v1",
|
|
776
|
+
})
|
|
163
777
|
```
|
|
164
778
|
|
|
779
|
+
### Getting Your API Key
|
|
780
|
+
|
|
781
|
+
1. Go to ChatarminOS → **Settings** → **Developers** → **API Keys**
|
|
782
|
+
2. Click "Create API Key"
|
|
783
|
+
3. Copy the key (format: `os_sk_xxxxxxxxxxxx`)
|
|
784
|
+
4. Store in environment variables
|
|
785
|
+
|
|
786
|
+
---
|
|
787
|
+
|
|
788
|
+
## Error Handling
|
|
789
|
+
|
|
790
|
+
The SDK uses tRPC under the hood. Errors include structured information:
|
|
791
|
+
|
|
792
|
+
```typescript
|
|
793
|
+
try {
|
|
794
|
+
await os.billing.trackUsage({
|
|
795
|
+
companyId: "comp_xxx",
|
|
796
|
+
featureCode: "ai_credit",
|
|
797
|
+
quantity: 1000,
|
|
798
|
+
})
|
|
799
|
+
} catch (error) {
|
|
800
|
+
if (error instanceof TRPCClientError) {
|
|
801
|
+
console.error("Code:", error.data?.code) // e.g., 'FORBIDDEN'
|
|
802
|
+
console.error("Message:", error.message) // Human-readable message
|
|
803
|
+
console.error("HTTP Status:", error.data?.httpStatus)
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
### Common Error Codes
|
|
809
|
+
|
|
810
|
+
| Code | Description |
|
|
811
|
+
| --------------------- | -------------------------- |
|
|
812
|
+
| `UNAUTHORIZED` | Invalid or missing API key |
|
|
813
|
+
| `FORBIDDEN` | No access to this resource |
|
|
814
|
+
| `NOT_FOUND` | Company/feature not found |
|
|
815
|
+
| `BAD_REQUEST` | Invalid input parameters |
|
|
816
|
+
| `PRECONDITION_FAILED` | Usage limit exceeded |
|
|
817
|
+
|
|
818
|
+
---
|
|
819
|
+
|
|
820
|
+
## Related Documentation
|
|
821
|
+
|
|
822
|
+
- **[QUICKSTART.md](./QUICKSTART.md)** — Quick publishing & installation guide
|
|
823
|
+
- **[PUBLISHING.md](./PUBLISHING.md)** — Detailed publishing instructions
|
|
824
|
+
- **[test-sdk.ts](./test-sdk.ts)** — Complete usage examples
|
|
825
|
+
|
|
826
|
+
---
|
|
827
|
+
|
|
828
|
+
## Support
|
|
829
|
+
|
|
830
|
+
- **Email**: hello@chatarmin.com
|
|
831
|
+
- **Documentation**: https://os.chatarmin.com/docs
|
|
832
|
+
|
|
833
|
+
---
|
|
834
|
+
|
|
165
835
|
## License
|
|
166
836
|
|
|
167
837
|
MIT © Chatarmin GmbH
|
package/dist/index.d.ts
CHANGED
|
@@ -113,7 +113,7 @@ export interface FeatureSetAccessInput {
|
|
|
113
113
|
validUntil?: Date | null;
|
|
114
114
|
}
|
|
115
115
|
/**
|
|
116
|
-
* Input for tracking feature usage.
|
|
116
|
+
* Input for tracking feature usage (increment operation).
|
|
117
117
|
*/
|
|
118
118
|
export interface TrackUsageInput {
|
|
119
119
|
/** Company ID */
|
|
@@ -121,7 +121,7 @@ export interface TrackUsageInput {
|
|
|
121
121
|
/** Feature code to track */
|
|
122
122
|
featureCode: string;
|
|
123
123
|
/**
|
|
124
|
-
* Quantity to track.
|
|
124
|
+
* Quantity to track (must be positive).
|
|
125
125
|
* @default 1
|
|
126
126
|
*/
|
|
127
127
|
quantity?: number;
|
|
@@ -130,9 +130,67 @@ export interface TrackUsageInput {
|
|
|
130
130
|
* Use a unique ID per operation (e.g., message ID).
|
|
131
131
|
*/
|
|
132
132
|
idempotencyKey?: string;
|
|
133
|
-
/**
|
|
133
|
+
/**
|
|
134
|
+
* Additional metadata for the usage event.
|
|
135
|
+
* Store external references here (e.g., { externalId: "msg_123", type: "message" })
|
|
136
|
+
*/
|
|
137
|
+
metadata?: Record<string, unknown>;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Input for setting usage to an absolute value.
|
|
141
|
+
* Use for corrections when you know what the total usage SHOULD be.
|
|
142
|
+
*/
|
|
143
|
+
export interface SetUsageInput {
|
|
144
|
+
/** Company ID */
|
|
145
|
+
companyId: string;
|
|
146
|
+
/** Feature code */
|
|
147
|
+
featureCode: string;
|
|
148
|
+
/** The absolute value to set usage to (must be >= 0) */
|
|
149
|
+
absoluteValue: number;
|
|
150
|
+
/** Reason for the set operation (required for audit trail) */
|
|
151
|
+
reason: string;
|
|
152
|
+
/** Admin user who performed the operation */
|
|
153
|
+
performedBy?: string;
|
|
154
|
+
/** Additional metadata (e.g., { ticketId: "SUPPORT-123" }) */
|
|
155
|
+
metadata?: Record<string, unknown>;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Input for adjusting usage by a delta.
|
|
159
|
+
* Use for explicit corrections - supports negative values for refunds.
|
|
160
|
+
*/
|
|
161
|
+
export interface AdjustUsageInput {
|
|
162
|
+
/** Company ID */
|
|
163
|
+
companyId: string;
|
|
164
|
+
/** Feature code */
|
|
165
|
+
featureCode: string;
|
|
166
|
+
/** The delta to apply (can be negative for refunds) */
|
|
167
|
+
delta: number;
|
|
168
|
+
/** Reason for the adjustment (required for audit trail) */
|
|
169
|
+
reason: string;
|
|
170
|
+
/** Reference to original event being adjusted (for Stripe cancellations) */
|
|
171
|
+
adjustsEventId?: string;
|
|
172
|
+
/** Admin user who performed the operation */
|
|
173
|
+
performedBy?: string;
|
|
174
|
+
/** Additional metadata (e.g., { ticketId: "REFUND-456" }) */
|
|
134
175
|
metadata?: Record<string, unknown>;
|
|
135
176
|
}
|
|
177
|
+
/**
|
|
178
|
+
* Result from usage operations (track, set, adjust).
|
|
179
|
+
*/
|
|
180
|
+
export interface UsageResult {
|
|
181
|
+
success: boolean;
|
|
182
|
+
featureCode: string;
|
|
183
|
+
previousUsage: number;
|
|
184
|
+
currentUsage: number;
|
|
185
|
+
delta: number;
|
|
186
|
+
quantityLimit: number | null;
|
|
187
|
+
remaining: number | null;
|
|
188
|
+
isAtLimit: boolean;
|
|
189
|
+
includedQuantity: number;
|
|
190
|
+
billableQuantity: number;
|
|
191
|
+
meterId: string;
|
|
192
|
+
eventId: string | null;
|
|
193
|
+
}
|
|
136
194
|
/**
|
|
137
195
|
* Input for claiming a Stripe checkout subscription.
|
|
138
196
|
*/
|
|
@@ -401,11 +459,11 @@ export declare class ChatarminOS {
|
|
|
401
459
|
getByProductLink: (input: {
|
|
402
460
|
externalOrgId: string;
|
|
403
461
|
}) => Promise<{
|
|
462
|
+
external_org_id: string;
|
|
463
|
+
external_user_id: string | null;
|
|
404
464
|
name: string;
|
|
405
465
|
id: string;
|
|
406
466
|
domain: string | null;
|
|
407
|
-
external_org_id: string;
|
|
408
|
-
external_user_id: string | null;
|
|
409
467
|
} | null>;
|
|
410
468
|
/**
|
|
411
469
|
* Create a new company and link it to your product.
|
|
@@ -563,8 +621,8 @@ export declare class ChatarminOS {
|
|
|
563
621
|
created_at: Date;
|
|
564
622
|
updated_at: Date;
|
|
565
623
|
company_id: string | null;
|
|
566
|
-
short_id: string | null;
|
|
567
624
|
is_primary: boolean;
|
|
625
|
+
short_id: string | null;
|
|
568
626
|
avatar_url: string | null;
|
|
569
627
|
}>;
|
|
570
628
|
/**
|
|
@@ -619,8 +677,8 @@ export declare class ChatarminOS {
|
|
|
619
677
|
created_at: Date;
|
|
620
678
|
updated_at: Date;
|
|
621
679
|
company_id: string | null;
|
|
622
|
-
short_id: string | null;
|
|
623
680
|
is_primary: boolean;
|
|
681
|
+
short_id: string | null;
|
|
624
682
|
avatar_url: string | null;
|
|
625
683
|
}[]>;
|
|
626
684
|
};
|
|
@@ -923,6 +981,142 @@ export declare class ChatarminOS {
|
|
|
923
981
|
billableQuantity: number;
|
|
924
982
|
meterId: string;
|
|
925
983
|
}>;
|
|
984
|
+
/**
|
|
985
|
+
* Set usage to an absolute value.
|
|
986
|
+
*
|
|
987
|
+
* Use this for corrections when you know what the total usage SHOULD be.
|
|
988
|
+
* Creates a snapshot for audit trail. The delta (difference) is calculated
|
|
989
|
+
* automatically and synced to Stripe.
|
|
990
|
+
*
|
|
991
|
+
* @param input - Set usage parameters
|
|
992
|
+
* @returns Result with previous and new usage values
|
|
993
|
+
*
|
|
994
|
+
* @example Correct usage to 100 (was 150)
|
|
995
|
+
* ```typescript
|
|
996
|
+
* const result = await os.billing.setUsage({
|
|
997
|
+
* companyId: 'comp_xxx',
|
|
998
|
+
* featureCode: 'ai_credit',
|
|
999
|
+
* absoluteValue: 100,
|
|
1000
|
+
* reason: 'Corrected after customer support review',
|
|
1001
|
+
* performedBy: 'admin@company.com'
|
|
1002
|
+
* })
|
|
1003
|
+
*
|
|
1004
|
+
* console.log({
|
|
1005
|
+
* previousUsage: result.previousUsage, // 150
|
|
1006
|
+
* currentUsage: result.currentUsage, // 100
|
|
1007
|
+
* delta: result.delta // -50
|
|
1008
|
+
* })
|
|
1009
|
+
* ```
|
|
1010
|
+
*/
|
|
1011
|
+
setUsage: (input: SetUsageInput) => Promise<UsageResult>;
|
|
1012
|
+
/**
|
|
1013
|
+
* Adjust usage by a delta (positive or negative).
|
|
1014
|
+
*
|
|
1015
|
+
* Use this for explicit corrections. Supports negative values for
|
|
1016
|
+
* refunds or error corrections. Creates an audit trail and syncs
|
|
1017
|
+
* to Stripe (including meter event adjustments when possible).
|
|
1018
|
+
*
|
|
1019
|
+
* @param input - Adjustment parameters
|
|
1020
|
+
* @returns Result with previous and new usage values
|
|
1021
|
+
*
|
|
1022
|
+
* @example Refund 50 units
|
|
1023
|
+
* ```typescript
|
|
1024
|
+
* const result = await os.billing.adjustUsage({
|
|
1025
|
+
* companyId: 'comp_xxx',
|
|
1026
|
+
* featureCode: 'ai_credit',
|
|
1027
|
+
* delta: -50,
|
|
1028
|
+
* reason: 'Refund for failed API calls',
|
|
1029
|
+
* performedBy: 'support@company.com'
|
|
1030
|
+
* })
|
|
1031
|
+
* ```
|
|
1032
|
+
*
|
|
1033
|
+
* @example Add bonus units
|
|
1034
|
+
* ```typescript
|
|
1035
|
+
* const result = await os.billing.adjustUsage({
|
|
1036
|
+
* companyId: 'comp_xxx',
|
|
1037
|
+
* featureCode: 'ai_credit',
|
|
1038
|
+
* delta: 100,
|
|
1039
|
+
* reason: 'Promotional bonus for beta testers'
|
|
1040
|
+
* })
|
|
1041
|
+
* ```
|
|
1042
|
+
*/
|
|
1043
|
+
adjustUsage: (input: AdjustUsageInput) => Promise<UsageResult>;
|
|
1044
|
+
/**
|
|
1045
|
+
* Get usage event history for a feature.
|
|
1046
|
+
*
|
|
1047
|
+
* Returns the history of usage events including increments, sets,
|
|
1048
|
+
* and adjustments. Useful for auditing and debugging.
|
|
1049
|
+
*
|
|
1050
|
+
* @param companyId - Company ID
|
|
1051
|
+
* @param featureCode - Feature code to get history for
|
|
1052
|
+
* @param options - Query options
|
|
1053
|
+
* @returns Array of usage events
|
|
1054
|
+
*
|
|
1055
|
+
* @example
|
|
1056
|
+
* ```typescript
|
|
1057
|
+
* const history = await os.billing.getUsageHistory(
|
|
1058
|
+
* 'comp_xxx',
|
|
1059
|
+
* 'ai_credit',
|
|
1060
|
+
* { limit: 20, eventType: 'adjustment' }
|
|
1061
|
+
* )
|
|
1062
|
+
*
|
|
1063
|
+
* for (const event of history) {
|
|
1064
|
+
* console.log(`${event.event_type}: ${event.quantity} at ${event.event_time}`)
|
|
1065
|
+
* if (event.adjustment_reason) {
|
|
1066
|
+
* console.log(` Reason: ${event.adjustment_reason}`)
|
|
1067
|
+
* }
|
|
1068
|
+
* }
|
|
1069
|
+
* ```
|
|
1070
|
+
*/
|
|
1071
|
+
getUsageHistory: (companyId: string, featureCode: string, options?: {
|
|
1072
|
+
limit?: number;
|
|
1073
|
+
includeDelivered?: boolean;
|
|
1074
|
+
eventType?: "increment" | "set" | "adjustment";
|
|
1075
|
+
}) => Promise<{
|
|
1076
|
+
id: string;
|
|
1077
|
+
metadata: unknown;
|
|
1078
|
+
quantity: number;
|
|
1079
|
+
source: string;
|
|
1080
|
+
created_at: Date;
|
|
1081
|
+
company_id: string;
|
|
1082
|
+
billing_profile_id: string;
|
|
1083
|
+
meter_code: string;
|
|
1084
|
+
available_product_id: string;
|
|
1085
|
+
event_time: Date;
|
|
1086
|
+
event_type: string;
|
|
1087
|
+
previous_value: number | null;
|
|
1088
|
+
adjustment_reason: string | null;
|
|
1089
|
+
adjusts_event_id: string | null;
|
|
1090
|
+
idempotency_key: string;
|
|
1091
|
+
stripe_delivery_status: string;
|
|
1092
|
+
stripe_event_id: string | null;
|
|
1093
|
+
stripe_delivery_error: string | null;
|
|
1094
|
+
delivered_at: Date | null;
|
|
1095
|
+
}[]>;
|
|
1096
|
+
/**
|
|
1097
|
+
* Get usage snapshots for a feature.
|
|
1098
|
+
*
|
|
1099
|
+
* Returns audit snapshots created by set operations and reconciliations.
|
|
1100
|
+
* Useful for understanding historical usage corrections.
|
|
1101
|
+
*
|
|
1102
|
+
* @param companyId - Company ID
|
|
1103
|
+
* @param featureCode - Feature code
|
|
1104
|
+
* @param limit - Max number of snapshots to return
|
|
1105
|
+
* @returns Array of usage snapshots
|
|
1106
|
+
*/
|
|
1107
|
+
getUsageSnapshots: (companyId: string, featureCode: string, limit?: number) => Promise<{
|
|
1108
|
+
id: string;
|
|
1109
|
+
metadata: unknown;
|
|
1110
|
+
reason: string | null;
|
|
1111
|
+
created_at: Date;
|
|
1112
|
+
company_id: string;
|
|
1113
|
+
meter_code: string;
|
|
1114
|
+
created_by: string | null;
|
|
1115
|
+
absolute_value: number;
|
|
1116
|
+
billable_value: number;
|
|
1117
|
+
snapshot_type: string;
|
|
1118
|
+
trigger_event_id: string | null;
|
|
1119
|
+
}[]>;
|
|
926
1120
|
/**
|
|
927
1121
|
* Claim a subscription from a completed Stripe Checkout Session.
|
|
928
1122
|
*
|
|
@@ -1086,16 +1280,16 @@ export declare class ChatarminOS {
|
|
|
1086
1280
|
}) => Promise<{
|
|
1087
1281
|
id: string;
|
|
1088
1282
|
metadata: unknown;
|
|
1089
|
-
label: string | null;
|
|
1090
1283
|
confidence: number | null;
|
|
1284
|
+
label: string | null;
|
|
1091
1285
|
created_at: Date;
|
|
1092
1286
|
updated_at: Date;
|
|
1093
1287
|
company_id: string;
|
|
1094
1288
|
product_id: string;
|
|
1095
1289
|
external_org_id: string;
|
|
1096
1290
|
external_user_id: string | null;
|
|
1097
|
-
link_type: string;
|
|
1098
1291
|
sync_status: string;
|
|
1292
|
+
link_type: string;
|
|
1099
1293
|
} | undefined>;
|
|
1100
1294
|
/**
|
|
1101
1295
|
* Delete all product links for this product.
|
|
@@ -1223,9 +1417,9 @@ export declare class ChatarminOS {
|
|
|
1223
1417
|
description: string | null;
|
|
1224
1418
|
code: string;
|
|
1225
1419
|
is_active: boolean;
|
|
1226
|
-
display_order: number;
|
|
1227
1420
|
created_at: Date;
|
|
1228
1421
|
updated_at: Date;
|
|
1422
|
+
display_order: number;
|
|
1229
1423
|
product_id: string;
|
|
1230
1424
|
}[]>;
|
|
1231
1425
|
/**
|
|
@@ -1341,9 +1535,9 @@ export declare class ChatarminOS {
|
|
|
1341
1535
|
description: string | null;
|
|
1342
1536
|
code: string;
|
|
1343
1537
|
is_active: boolean;
|
|
1344
|
-
display_order: number;
|
|
1345
1538
|
created_at: Date;
|
|
1346
1539
|
updated_at: Date;
|
|
1540
|
+
display_order: number;
|
|
1347
1541
|
product_id: string;
|
|
1348
1542
|
}[]>;
|
|
1349
1543
|
/**
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAQ/C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAA;IAEd;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAA;IACrB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,4BAA4B;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAA;IACrB,6CAA6C;IAC7C,KAAK,EAAE;QACL,oCAAoC;QACpC,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,2CAA2C;QAC3C,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,yCAAyC;QACzC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KAClB,CAAA;IACD;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,MAAM,EAAE,gBAAgB,GAAG,QAAQ,GAAG,UAAU,GAAG,aAAa,CAAA;IAChE,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,6BAA6B;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iEAAiE;IACjE,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,UAAU,EAAE,MAAM,CAAA;QAClB,YAAY,EAAE,MAAM,CAAA;QACpB,UAAU,EAAE,MAAM,CAAA;QAClB,MAAM,EAAE,MAAM,CAAA;KACf,CAAC,CAAA;CACH;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,oCAAoC;IACpC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,kCAAkC;IAClC,MAAM,CAAC,EAAE,cAAc,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAA;IACpD,uDAAuD;IACvD,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,wDAAwD;IACxD,aAAa,EAAE,MAAM,CAAA;IACrB,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAA;IACd,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAA;IACb,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAA;IACd,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,SAAS,EAAE,OAAO,CAAA;IAClB,gBAAgB,EAAE,MAAM,CAAA;IACxB,gBAAgB,EAAE,MAAM,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAA;IACjB,0CAA0C;IAC1C,iBAAiB,EAAE,MAAM,CAAA;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAA;IACjB,uCAAuC;IACvC,oBAAoB,EAAE,MAAM,CAAA;IAC5B,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACnD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAA;IACb,mBAAmB;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,0CAA0C;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,iBAAiB;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,UAAU,EAAE,OAAO,CAAA;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,KAAK,EAAE,OAAO,CAAA;CACf;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,iCAAiC;IACjC,QAAQ,EAAE,KAAK,CAAC;QACd,KAAK,EAAE,MAAM,CAAA;QACb,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,OAAO,CAAA;KACf,CAAC,CAAA;CACH;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,8DAA8D;IAC9D,aAAa,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,KAAK,CAAC,EAAE;QACN,oCAAoC;QACpC,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,2CAA2C;QAC3C,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,yCAAyC;QACzC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KAClB,CAAA;IAED;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAE1B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAE7B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAEzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAA;IAEjB,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAA;IAEnB;;;;;OAKG;IACH,UAAU,EAAE,gBAAgB,GAAG,QAAQ,GAAG,SAAS,CAAA;IAEnD,8DAA8D;IAC9D,aAAa,CAAC,EAAE;QACd,yCAAyC;QACzC,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,qDAAqD;QACrD,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,sCAAsC;QACtC,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,yCAAyC;QACzC,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,6DAA6D;QAC7D,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;CACF;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAgD;IAE9D;;;;;;;;;;;;;;;OAeG;gBACS,MAAM,EAAE,iBAAiB;IAoBrC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,IAAI,SAAS;QAGT;;;;;;;;;;;;;;;;;;;;;;WAsBG;kCACuB;YAAE,aAAa,EAAE,MAAM,CAAA;SAAE;;;;;;;QAGnD;;;;;;;;;;;;;;;;;;;;;;WAsBG;wBACa,kBAAkB;;;;;;QAGlC;;;;;;;;;;;;;;;WAeG;wBACa;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE;;;QAGzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAmCG;2BACgB,cAAc,KAAG,OAAO,CAAC,eAAe,CAAC;MAG/D;IAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,IAAI,QAAQ;QAGR;;;;;;;;;;;;;;;;;;;;;;;;;WAyBG;wBACa;YAAE,SAAS,EAAE,MAAM,CAAA;SAAE,GAAG,YAAY;;;;;;;;;;;;;;QAGpD;;;;;;;;;;;;;;;;;;;;;;WAsBG;4BACiB;YAClB,SAAS,EAAE,MAAM,CAAA;YACjB,QAAQ,EAAE,YAAY,EAAE,CAAA;SACzB,KAAG,OAAO,CAAC,iBAAiB,CAAC;QAG9B;;;;;;;;;;;;;;;WAeG;0BACe,MAAM;;;;;;;;;;;;;MAG3B;IAMD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,IAAI,QAAQ;QAGR;;;;;;;;;;;;;;;;;;;;;;;;;;;WA2BG;uBACY,iBAAiB;;;;;;;;;;;QAEhC;;;;;;;;;;;;;;;;;;;;;WAqBG;gCACqB,MAAM;;;;;;;;;;;QAG9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA0CG;2BACgB,qBAAqB;;;;;;;;;;;;;QAGxC;;;;;;;;;;;;;;;;;;;WAmBG;kDACuC,MAAM;;;;;;;;;;;;;;;;QAGhD;;;;;;;;;;;;;;;;;;;WAmBG;8CACmC,MAAM,eAAe,MAAM;;;;;;;;;;;;;;MAMpE;IAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;IACH,IAAI,OAAO;QAGP;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA4BG;4BACiB,eAAe;;;;;;;;;;;QAGnC;;;;;;;;;;;;;;;;;;;;;;;;;;WA0BG;0BACe,aAAa,KAAG,OAAO,CAAC,WAAW,CAAC;QAMtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA8BG;6BACkB,gBAAgB,KAAG,OAAO,CAAC,WAAW,CAAC;QAM5D;;;;;;;;;;;;;;;;;;;;;;;;;;WA0BG;qCAEU,MAAM,eACJ,MAAM,YACT;YACR,KAAK,CAAC,EAAE,MAAM,CAAA;YACd,gBAAgB,CAAC,EAAE,OAAO,CAAA;YAC1B,SAAS,CAAC,EAAE,WAAW,GAAG,KAAK,GAAG,YAAY,CAAA;SAC/C;;;;;;;;;;;;;;;;;;;;;QAQH;;;;;;;;;;WAUG;uCAEU,MAAM,eACJ,MAAM,UACX,MAAM;;;;;;;;;;;;;QAQhB;;;;;;;;;;;;;;;;;;;;;;;WAuBG;+BACoB,kBAAkB;;;;;;;;;;;QAGzC;;;;;;;;;;;;;;;;;;;;;;;;;;WA0BG;kCACuB,qBAAqB;;;;;;;;;;;;;;;QAG/C;;;;;;;;;;;;;;;;;;;;;;;;WAwBG;+BACoB,MAAM;;;;;;;;;;;;;;;;MAGhC;IAMD;;;;;;;;;;;;;;;OAeG;IACH,IAAI,KAAK;QAGL;;;;;;;;;;;;;;;;;;WAkBG;wBACa;YACd,SAAS,EAAE,MAAM,CAAA;YACjB,aAAa,EAAE,MAAM,CAAA;YACrB,KAAK,CAAC,EAAE,MAAM,CAAA;YACd,cAAc,CAAC,EAAE,MAAM,CAAA;SACxB;;;;;;;;;;;;;;QAQD;;;;;;;;;;;;;;;;;;;;;;;;;;WA0BG;0BACe;YAAE,cAAc,CAAC,EAAE,OAAO,CAAC;YAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;SAAE;;;;;MAGrE;IAMD;;;;;;;;;;;;;;;;;;;OAmBG;IACH,IAAI,aAAa;QAGb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA6BG;2BACgB,MAAM,WAAW,cAAc;;;;;QAOlD;;;;;;;;;;;;;;;;;;;WAmBG;;;;;;;;;;;;;;;;;;;;QAIH;;;;;;;;;;;;;;;;;;;;;;;WAuBG;4BACiB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAG7B;IAMD;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,IAAI,KAAK;QAGL;;;;;;;;;;;WAWG;;;;;;;;;;;;;;;;;;;;QAGH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAsCG;wBACa,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAGtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA8BG;0BACe,MAAM,WAAW,cAAc;;;;;MAOpD;IAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuFG;IACG,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;CAoF3D;AAGD,YAAY,EAAE,SAAS,EAAE,CAAA;AAGzB,eAAe,WAAW,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -555,6 +555,120 @@ export class ChatarminOS {
|
|
|
555
555
|
* ```
|
|
556
556
|
*/
|
|
557
557
|
trackUsage: (input) => client.billing.trackUsage.mutate(input),
|
|
558
|
+
/**
|
|
559
|
+
* Set usage to an absolute value.
|
|
560
|
+
*
|
|
561
|
+
* Use this for corrections when you know what the total usage SHOULD be.
|
|
562
|
+
* Creates a snapshot for audit trail. The delta (difference) is calculated
|
|
563
|
+
* automatically and synced to Stripe.
|
|
564
|
+
*
|
|
565
|
+
* @param input - Set usage parameters
|
|
566
|
+
* @returns Result with previous and new usage values
|
|
567
|
+
*
|
|
568
|
+
* @example Correct usage to 100 (was 150)
|
|
569
|
+
* ```typescript
|
|
570
|
+
* const result = await os.billing.setUsage({
|
|
571
|
+
* companyId: 'comp_xxx',
|
|
572
|
+
* featureCode: 'ai_credit',
|
|
573
|
+
* absoluteValue: 100,
|
|
574
|
+
* reason: 'Corrected after customer support review',
|
|
575
|
+
* performedBy: 'admin@company.com'
|
|
576
|
+
* })
|
|
577
|
+
*
|
|
578
|
+
* console.log({
|
|
579
|
+
* previousUsage: result.previousUsage, // 150
|
|
580
|
+
* currentUsage: result.currentUsage, // 100
|
|
581
|
+
* delta: result.delta // -50
|
|
582
|
+
* })
|
|
583
|
+
* ```
|
|
584
|
+
*/
|
|
585
|
+
setUsage: (input) => client.billing.setUsage.mutate({
|
|
586
|
+
...input,
|
|
587
|
+
source: "api",
|
|
588
|
+
}),
|
|
589
|
+
/**
|
|
590
|
+
* Adjust usage by a delta (positive or negative).
|
|
591
|
+
*
|
|
592
|
+
* Use this for explicit corrections. Supports negative values for
|
|
593
|
+
* refunds or error corrections. Creates an audit trail and syncs
|
|
594
|
+
* to Stripe (including meter event adjustments when possible).
|
|
595
|
+
*
|
|
596
|
+
* @param input - Adjustment parameters
|
|
597
|
+
* @returns Result with previous and new usage values
|
|
598
|
+
*
|
|
599
|
+
* @example Refund 50 units
|
|
600
|
+
* ```typescript
|
|
601
|
+
* const result = await os.billing.adjustUsage({
|
|
602
|
+
* companyId: 'comp_xxx',
|
|
603
|
+
* featureCode: 'ai_credit',
|
|
604
|
+
* delta: -50,
|
|
605
|
+
* reason: 'Refund for failed API calls',
|
|
606
|
+
* performedBy: 'support@company.com'
|
|
607
|
+
* })
|
|
608
|
+
* ```
|
|
609
|
+
*
|
|
610
|
+
* @example Add bonus units
|
|
611
|
+
* ```typescript
|
|
612
|
+
* const result = await os.billing.adjustUsage({
|
|
613
|
+
* companyId: 'comp_xxx',
|
|
614
|
+
* featureCode: 'ai_credit',
|
|
615
|
+
* delta: 100,
|
|
616
|
+
* reason: 'Promotional bonus for beta testers'
|
|
617
|
+
* })
|
|
618
|
+
* ```
|
|
619
|
+
*/
|
|
620
|
+
adjustUsage: (input) => client.billing.adjustUsage.mutate({
|
|
621
|
+
...input,
|
|
622
|
+
source: "api",
|
|
623
|
+
}),
|
|
624
|
+
/**
|
|
625
|
+
* Get usage event history for a feature.
|
|
626
|
+
*
|
|
627
|
+
* Returns the history of usage events including increments, sets,
|
|
628
|
+
* and adjustments. Useful for auditing and debugging.
|
|
629
|
+
*
|
|
630
|
+
* @param companyId - Company ID
|
|
631
|
+
* @param featureCode - Feature code to get history for
|
|
632
|
+
* @param options - Query options
|
|
633
|
+
* @returns Array of usage events
|
|
634
|
+
*
|
|
635
|
+
* @example
|
|
636
|
+
* ```typescript
|
|
637
|
+
* const history = await os.billing.getUsageHistory(
|
|
638
|
+
* 'comp_xxx',
|
|
639
|
+
* 'ai_credit',
|
|
640
|
+
* { limit: 20, eventType: 'adjustment' }
|
|
641
|
+
* )
|
|
642
|
+
*
|
|
643
|
+
* for (const event of history) {
|
|
644
|
+
* console.log(`${event.event_type}: ${event.quantity} at ${event.event_time}`)
|
|
645
|
+
* if (event.adjustment_reason) {
|
|
646
|
+
* console.log(` Reason: ${event.adjustment_reason}`)
|
|
647
|
+
* }
|
|
648
|
+
* }
|
|
649
|
+
* ```
|
|
650
|
+
*/
|
|
651
|
+
getUsageHistory: (companyId, featureCode, options) => client.billing.getUsageHistory.query({
|
|
652
|
+
companyId,
|
|
653
|
+
featureCode,
|
|
654
|
+
...options,
|
|
655
|
+
}),
|
|
656
|
+
/**
|
|
657
|
+
* Get usage snapshots for a feature.
|
|
658
|
+
*
|
|
659
|
+
* Returns audit snapshots created by set operations and reconciliations.
|
|
660
|
+
* Useful for understanding historical usage corrections.
|
|
661
|
+
*
|
|
662
|
+
* @param companyId - Company ID
|
|
663
|
+
* @param featureCode - Feature code
|
|
664
|
+
* @param limit - Max number of snapshots to return
|
|
665
|
+
* @returns Array of usage snapshots
|
|
666
|
+
*/
|
|
667
|
+
getUsageSnapshots: (companyId, featureCode, limit) => client.billing.getUsageSnapshots.query({
|
|
668
|
+
companyId,
|
|
669
|
+
featureCode,
|
|
670
|
+
limit,
|
|
671
|
+
}),
|
|
558
672
|
/**
|
|
559
673
|
* Claim a subscription from a completed Stripe Checkout Session.
|
|
560
674
|
*
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chatarmin/os",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Type-safe SDK for ChatarminOS - Customer & Subscription Management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
7
|
-
"access": "
|
|
7
|
+
"access": "public"
|
|
8
8
|
},
|
|
9
9
|
"main": "./dist/index.js",
|
|
10
10
|
"types": "./dist/index.d.ts",
|