@chatarmin/os 1.5.7 → 1.5.9

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 CHANGED
@@ -31,7 +31,6 @@
31
31
  - [Links](#links)
32
32
  - [Onboarding](#onboarding)
33
33
  - [Common Patterns](#common-patterns)
34
- - [Changelog](#changelog)
35
34
  - [TypeScript Support](#typescript-support)
36
35
  - [Configuration](#configuration)
37
36
  - [Error Handling](#error-handling)
@@ -75,7 +74,7 @@ const result = await os.onboard({
75
74
  })
76
75
 
77
76
  console.log(result.companyId) // Use this for all future API calls
78
- console.log(result.linkStatus) // 'created' | 'linked' | 'already_linked'
77
+ console.log(result.linkStatus) // 'created' | 'already_linked'
79
78
  ```
80
79
 
81
80
  ---
@@ -86,12 +85,12 @@ console.log(result.linkStatus) // 'created' | 'linked' | 'already_linked'
86
85
 
87
86
  Manage customer companies and their links to your product.
88
87
 
89
- #### `companies.getByProductLink(input)`
88
+ #### `companies.get(input)`
90
89
 
91
- Look up a company by your external organization ID.
90
+ Look up a company by your external organization ID or ChatarminOS company ID.
92
91
 
93
92
  ```typescript
94
- const company = await os.companies.getByProductLink({
93
+ const company = await os.companies.get({
95
94
  externalOrgId: "org_abc123",
96
95
  })
97
96
 
@@ -132,48 +131,6 @@ await os.companies.update({
132
131
  })
133
132
  ```
134
133
 
135
- #### `companies.smartLink(input)`
136
-
137
- Intelligently find and link a company using hints.
138
-
139
- ```typescript
140
- const result = await os.companies.smartLink({
141
- externalOrgId: "org_abc123",
142
- label: "My Product", // Display label for the product link (required)
143
- hints: {
144
- companyName: "Acme Inc",
145
- domain: "acme.com",
146
- emails: ["john@acme.com", "jane@acme.com"],
147
- },
148
- minConfidence: 0.7, // Default: 0.8
149
- })
150
-
151
- switch (result.status) {
152
- case "already_linked":
153
- console.log("Already linked to your product")
154
- break
155
- case "linked":
156
- console.log(
157
- `Auto-linked to ${result.customerName} (${result.confidence}% confidence)`
158
- )
159
- break
160
- case "suggestions":
161
- console.log("Multiple matches found:", result.suggestions)
162
- break
163
- case "no_match":
164
- console.log("No matching company found")
165
- break
166
- }
167
- ```
168
-
169
- **Matching priority:**
170
-
171
- 1. Domain match → 95% confidence
172
- 2. Name match → up to 80% confidence
173
- 3. Email domain match → 70% confidence
174
-
175
- ---
176
-
177
134
  ### Contacts
178
135
 
179
136
  Manage people associated with companies.
@@ -276,17 +233,6 @@ for (const f of features) {
276
233
  }
277
234
  ```
278
235
 
279
- #### `features.listForProduct(input?)`
280
-
281
- List **feature definitions** attached to your product (the API key’s product). No company id—use for catalog UI, empty states, or multi-feature shells. Inactive features are omitted unless you pass `{ includeInactive: true }`.
282
-
283
- ```typescript
284
- const defs = await os.features.listForProduct()
285
- for (const f of defs) {
286
- console.log(`${f.code}: ${f.name}${f.hasQuantity ? " (metered)" : ""}`)
287
- }
288
- ```
289
-
290
236
  #### `features.setAccess(input)`
291
237
 
292
238
  Update feature access with **partial config merge**.
@@ -347,34 +293,6 @@ if (access.canUse) {
347
293
 
348
294
  Track usage, claim subscriptions, and manage billing.
349
295
 
350
- #### `billing.getDashboardContext(input)`
351
-
352
- **Recommended** for billing/usage dashboards when you only have your tenant’s `externalOrgId`. One round-trip returns `companyId`, `productLinkId`, and an ordered list of features with usage, limits, optional Stripe `billing`, and `billingDegraded` when usage exists without a linked subscription item.
353
-
354
- Ordering uses `config_values.dashboard_order` or `dashboardOrder` when set; otherwise feature `displayOrder`.
355
-
356
- ```typescript
357
- const ctx = await os.billing.getDashboardContext({
358
- externalOrgId: "org_abc123",
359
- })
360
-
361
- console.log(ctx.companyId, ctx.productLinkId)
362
- for (const f of ctx.features) {
363
- console.log(
364
- f.featureCode,
365
- f.currentUsage,
366
- f.remaining,
367
- f.canUse,
368
- f.billingDegraded ? "(no Stripe period)" : "",
369
- f.billing?.currentPeriodEnd
370
- )
371
- }
372
- ```
373
-
374
- If the tenant is not linked, the call fails with `NOT_FOUND` (same message style as other `externalOrgId` flows).
375
-
376
- See [Changelog](#changelog) for migrating from `getByProductLink` + `listAccess` and hardcoded feature codes.
377
-
378
296
  #### `billing.trackUsage(input)`
379
297
 
380
298
  Track usage for a metered feature.
@@ -600,7 +518,7 @@ const result = await os.onboard({
600
518
  console.log({
601
519
  companyId: result.companyId,
602
520
  companyName: result.companyName,
603
- linkStatus: result.linkStatus, // 'created' | 'linked' | 'already_linked'
521
+ linkStatus: result.linkStatus, // 'created' | 'already_linked'
604
522
  tierApplied: result.billingStatus?.tierApplied,
605
523
  })
606
524
  ```
@@ -672,9 +590,6 @@ switch (result.linkStatus) {
672
590
  case "already_linked":
673
591
  console.log("Welcome back!")
674
592
  break
675
- case "linked":
676
- console.log("Found existing company, linked!")
677
- break
678
593
  case "created":
679
594
  console.log("New company created!")
680
595
  break
@@ -784,15 +699,9 @@ import { ChatarminOS } from "@chatarmin/os"
784
699
  import type {
785
700
  ChatarminOSConfig,
786
701
  CreateCompanyInput,
787
- SmartLinkInput,
788
- SmartLinkResult,
789
702
  ContactInput,
790
703
  FeatureCheckInput,
791
704
  FeatureSetAccessInput,
792
- BillingDashboardContext,
793
- GetBillingDashboardContextInput,
794
- ListProductFeatureCatalogInput,
795
- ProductFeatureCatalogItem,
796
705
  TrackUsageInput,
797
706
  OnboardInput,
798
707
  OnboardResult,
@@ -871,32 +780,6 @@ try {
871
780
 
872
781
  ---
873
782
 
874
- ## Changelog
875
-
876
- Release notes live in **[CHANGELOG.md](./CHANGELOG.md)**.
877
-
878
- ### Dashboard context migration (PRD #194)
879
-
880
- **Before:** Resolve the company, then list access and filter client-side:
881
-
882
- ```typescript
883
- const company = await os.companies.getByProductLink({ externalOrgId })
884
- if (!company) {
885
- /* onboarding */
886
- }
887
- const rows = await os.features.listAccess({
888
- companyId: company.id,
889
- includeBillingDetails: true,
890
- })
891
- // Often: pick one featureCode in code, merge catalog labels manually
892
- ```
893
-
894
- **After:** Single product-key call keyed by tenant id; use `features.listForProduct()` for definition labels and `os.billing.getDashboardContext({ externalOrgId })` for per-tenant state. Server applies link disambiguation, row shape, optional `billing`, `billingDegraded`, and dashboard ordering from OS `config_values`.
895
-
896
- `features.listAccess` / `getAccessByExternalOrgId` remain supported; opt in when you need the new contract.
897
-
898
- ---
899
-
900
783
  ## Related Documentation
901
784
 
902
785
  - **[QUICKSTART.md](./QUICKSTART.md)** — Quick publishing & installation guide
@@ -19,8 +19,8 @@ export declare function createChatarminOsBillingNamespace(call: ChatarminOsBilli
19
19
  metadata: unknown;
20
20
  event_type: string;
21
21
  source: string;
22
- billing_profile_id: string | null;
23
22
  idempotency_key: string;
23
+ billing_profile_id: string | null;
24
24
  subscription_item_id: string | null;
25
25
  feature_access_id: string | null;
26
26
  meter_code: string;
@@ -0,0 +1,8 @@
1
+ import type { AppRouter } from '@chatarmin/api';
2
+ import type { createTRPCClient } from '@trpc/client';
3
+ import type { CompaniesClient } from './types';
4
+ type SdkClient = ReturnType<typeof createTRPCClient<AppRouter>>;
5
+ type SdkCall = <T>(operation: string, action: () => Promise<T>) => Promise<T>;
6
+ export declare function createCompaniesClient(client: SdkClient, call: SdkCall): CompaniesClient;
7
+ export {};
8
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/companies/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,KAAK,EACV,eAAe,EAOhB,MAAM,SAAS,CAAA;AAEhB,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAA;AAC/D,KAAK,OAAO,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;AAE7E,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,OAAO,GACZ,eAAe,CAiBjB"}
@@ -0,0 +1,8 @@
1
+ export function createCompaniesClient(client, call) {
2
+ return {
3
+ get: (input) => call('companies.get', () => client.companies.get.query(input)),
4
+ list: (input) => call('companies.list', () => client.companies.listForProduct.query(input ?? {})),
5
+ create: (input) => call('companies.create', () => client.companies.createWithLink.mutate(input)),
6
+ update: (input) => call('companies.update', () => client.companies.updateCompany.mutate(input)),
7
+ };
8
+ }
@@ -0,0 +1,3 @@
1
+ export { createCompaniesClient } from './client';
2
+ export type { CompaniesClient, CompanyAssignee, CompanyAssignees, CreateCompanyInput, CreateCompanyResult, GetCompanyInput, LinkedCompany, ListCompaniesInput, ListCompaniesResult, ListLinkedCompaniesInput, ListLinkedCompaniesResult, ProductCompany, UpdateCompanyResult, } from './types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/companies/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAChD,YAAY,EACV,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,EACzB,cAAc,EACd,mBAAmB,GACpB,MAAM,SAAS,CAAA"}
@@ -0,0 +1 @@
1
+ export { createCompaniesClient } from './client';
@@ -0,0 +1,66 @@
1
+ export interface CreateCompanyInput {
2
+ name: string;
3
+ domain?: string;
4
+ externalOrgId: string;
5
+ externalUserId?: string;
6
+ label?: string;
7
+ contactEmail?: string;
8
+ contactName?: string;
9
+ createdAt?: string;
10
+ }
11
+ export interface CompanyAssignee {
12
+ memberId: string;
13
+ displayName: string | null;
14
+ email: string | null;
15
+ }
16
+ export interface CompanyAssignees {
17
+ csm: CompanyAssignee | null;
18
+ sales: CompanyAssignee | null;
19
+ }
20
+ export interface ProductCompany {
21
+ id: string;
22
+ name: string;
23
+ shortId: string | null;
24
+ domain: string | null;
25
+ externalOrgId: string;
26
+ label: string | null;
27
+ externalUserId: string | null;
28
+ assignees: CompanyAssignees;
29
+ }
30
+ /** @deprecated Use ProductCompany */
31
+ export type LinkedCompany = ProductCompany;
32
+ export interface GetCompanyInput {
33
+ externalOrgId?: string;
34
+ companyId?: string;
35
+ }
36
+ export interface ListCompaniesInput {
37
+ limit?: number;
38
+ cursor?: string;
39
+ }
40
+ export interface ListCompaniesResult {
41
+ companies: ProductCompany[];
42
+ nextCursor?: string;
43
+ }
44
+ /** @deprecated Use ListCompaniesInput */
45
+ export type ListLinkedCompaniesInput = ListCompaniesInput;
46
+ /** @deprecated Use ListCompaniesResult */
47
+ export type ListLinkedCompaniesResult = ListCompaniesResult;
48
+ export interface CreateCompanyResult {
49
+ id: string;
50
+ shortId: string | null;
51
+ name: string;
52
+ externalOrgId: string;
53
+ }
54
+ export interface UpdateCompanyResult {
55
+ updated: boolean;
56
+ }
57
+ export interface CompaniesClient {
58
+ get: (input: GetCompanyInput) => Promise<ProductCompany | null>;
59
+ list: (input?: ListCompaniesInput) => Promise<ListCompaniesResult>;
60
+ create: (input: CreateCompanyInput) => Promise<CreateCompanyResult>;
61
+ update: (input: {
62
+ companyId: string;
63
+ createdAt?: string;
64
+ }) => Promise<UpdateCompanyResult>;
65
+ }
66
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/companies/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,eAAe,GAAG,IAAI,CAAA;IAC3B,KAAK,EAAE,eAAe,GAAG,IAAI,CAAA;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,SAAS,EAAE,gBAAgB,CAAA;CAC5B;AAED,qCAAqC;AACrC,MAAM,MAAM,aAAa,GAAG,cAAc,CAAA;AAE1C,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,cAAc,EAAE,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,yCAAyC;AACzC,MAAM,MAAM,wBAAwB,GAAG,kBAAkB,CAAA;AAEzD,0CAA0C;AAC1C,MAAM,MAAM,yBAAyB,GAAG,mBAAmB,CAAA;AAE3D,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAA;IAC/D,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,kBAAkB,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAA;IAClE,MAAM,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAA;IACnE,MAAM,EAAE,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAA;CAC3F"}
@@ -0,0 +1 @@
1
+ export {};