@scryme/sdk 0.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.
Files changed (2) hide show
  1. package/README.md +410 -0
  2. package/package.json +27 -0
package/README.md ADDED
@@ -0,0 +1,410 @@
1
+ # Scryme V3 SDK
2
+
3
+ The official TypeScript SDK for the **Scryme V3 API**β€”engineered for scalability, security, and developer convenience. This SDK provides complete, type-safe coverage of all Scryme V3 services, allowing developers to seamlessly integrate their applications with the Scryme ecosystem.
4
+
5
+ ## πŸš€ Features
6
+
7
+ - **End-to-End Type Safety**: Direct compilation from the core OpenAPI 3.0 specification.
8
+ - **Axios-Based Client**: Built-in support for request/response interceptors, customizable base URLs, and timeout configurations.
9
+ - **Comprehensive API Coverage**:
10
+ - **Auth**: Token exchange (Client Credentials Flow) & OAuth2 proxy support.
11
+ - **Inventory**: Stock queries, multi-branch listings, batch tracking (trace, split, merge), B2B availability checks, and integrity verify/fix logic.
12
+ - **Orders & B2B**: Quote requests, quote-to-order conversions, and order management.
13
+ - **CRM & Customers**: Customer registration (Zitadel), custom CRM definitions, custom fields, relationships, associations, notes, and activity timelines.
14
+ - **Loyalty**: Loyalty status (tiers & points), voucher validation, and reward redemption.
15
+ - **Finance**: Corporate expenses, utility account tracking, and petty cash fund management (allocations, transactions, top-ups).
16
+ - **POS**: POS device provisioning, staff login, and petty cash expense logging.
17
+ - **Members & Roles**: Staff rosters, custom roles, permission sets, departments, and attendance logging (check-in/check-out).
18
+ - **Services & Bookings**: Resource utilization, booking funnel, public-facing OTP-verified booking, shifts, and materials consumption.
19
+ - **Integrations & Webhooks**: Subscription management and Strapi E-commerce integration (storefront customer registration, storefront token exchange, sync queues).
20
+
21
+ ---
22
+
23
+ ## πŸ“¦ Installation
24
+
25
+ To use the Scryme V3 SDK in your project, install it from the workspace repository:
26
+
27
+ ```bash
28
+ pnpm add @scryme/sdk
29
+ ```
30
+
31
+ ---
32
+
33
+ ## πŸ”‘ Authentication
34
+
35
+ The Scryme V3 API uses **OAuth2 Client Credentials Flow** to authorize external applications and integrations.
36
+
37
+ ### Step 1: Exchange Credentials for an Access Token
38
+ To retrieve an access token, pass your `clientId` and `clientSecret` (generated during device/app provisioning) to the token exchange endpoint:
39
+
40
+ ```typescript
41
+ import axios from "axios";
42
+ import { authExchangeToken } from "@scryme/sdk";
43
+
44
+ // Initialize the global axios configuration if needed
45
+ axios.defaults.baseURL = "https://api.scryme.tech";
46
+
47
+ async function authenticate() {
48
+ try {
49
+ const response = await authExchangeToken({
50
+ clientId: "your_client_id_123",
51
+ clientSecret: "your_client_secret_456"
52
+ });
53
+
54
+ const { accessToken, expiresIn } = response.data;
55
+ console.log(`Authenticated successfully! Token expires in ${expiresIn}s.`);
56
+ return accessToken;
57
+ } catch (error) {
58
+ console.error("Authentication failed:", error);
59
+ throw error;
60
+ }
61
+ }
62
+ ```
63
+
64
+ ### Step 2: Configure Authenticated Client Calls
65
+ Once you have the `accessToken`, register an Axios request interceptor to automatically attach the bearer token to all outgoing requests:
66
+
67
+ ```typescript
68
+ import axios from "axios";
69
+
70
+ function setupAuthenticatedClient(token: string) {
71
+ axios.interceptors.request.use((config) => {
72
+ config.headers.Authorization = `Bearer ${token}`;
73
+ return config;
74
+ });
75
+ }
76
+ ```
77
+
78
+ ---
79
+
80
+ ## πŸ› οΈ Domain Modules & Usage Examples
81
+
82
+ Below are comprehensive examples showing how to interact with the key V3 modules.
83
+
84
+ ### πŸ“¦ 1. V3 Inventory Management
85
+ Query stock levels, trace/merge/split batches, and check availability for B2B accounts.
86
+
87
+ ```typescript
88
+ import {
89
+ inventoryGetInventory,
90
+ inventoryVerifyIntegrity,
91
+ inventoryMergeBatches,
92
+ inventorySplitBatch
93
+ } from "@scryme/sdk";
94
+
95
+ const orgSlug = "scryme-hq";
96
+ const locationId = "loc_nairobi_001";
97
+
98
+ // 1. Get current stock levels at a specific location
99
+ async function checkStock() {
100
+ const response = await inventoryGetInventory(orgSlug, {
101
+ locationId,
102
+ limit: 50,
103
+ offset: 0
104
+ });
105
+ console.log("Stock Inventory:", response.data);
106
+ }
107
+
108
+ // 2. Verify stock integrity and run discrepancy checks
109
+ async function runIntegrityCheck() {
110
+ const result = await inventoryVerifyIntegrity(orgSlug);
111
+ console.log("Integrity Report:", result.data);
112
+ }
113
+
114
+ // 3. Merge multiple stock batches into a single parent batch
115
+ async function consolidateBatches() {
116
+ await inventoryMergeBatches(orgSlug, {
117
+ // Merge parameters
118
+ });
119
+ }
120
+ ```
121
+
122
+ ### πŸ›’ 2. Orders & B2B Sales
123
+ Submit quotes, verify B2B item stock availability, and convert approved quotes to orders.
124
+
125
+ ```typescript
126
+ import {
127
+ ordersCreateOrder,
128
+ ordersRequestB2BQuote,
129
+ ordersConvertQuoteToOrder,
130
+ ordersGetOrders
131
+ } from "@scryme/sdk";
132
+
133
+ // 1. Request a pricing and availability quote for B2B items
134
+ async function createQuote() {
135
+ const quote = await ordersRequestB2BQuote(orgSlug, {
136
+ customerId: "cust_999",
137
+ businessAccountId: "biz_acme_corp",
138
+ locationId: "loc_nairobi_001",
139
+ items: [
140
+ { variantId: "var_espresso_beans_01", quantity: 15 }
141
+ ],
142
+ notes: "Requires delivery before Friday"
143
+ });
144
+ console.log("Quote Requested:", quote.data);
145
+ }
146
+
147
+ // 2. Convert an approved quote directly into a sales order
148
+ async function approveAndOrder(quoteId: string) {
149
+ const order = await ordersConvertQuoteToOrder(quoteId, orgSlug);
150
+ console.log("Sales Order Created:", order.data);
151
+ }
152
+ ```
153
+
154
+ ### πŸ‘₯ 3. Customers & CRM
155
+ Create and query contacts, build custom CRM records with schemas, and manage timelines.
156
+
157
+ ```typescript
158
+ import {
159
+ customersGetCustomers,
160
+ crmControllerCreateRecord,
161
+ crmControllerCreateNote,
162
+ crmControllerGetTimeline
163
+ } from "@scryme/sdk";
164
+
165
+ // 1. Fetch organization-scoped customers
166
+ async function listCustomers() {
167
+ const customers = await customersGetCustomers(orgSlug, { limit: 10 });
168
+ console.log("Customers list:", customers.data);
169
+ }
170
+
171
+ // 2. Create custom CRM fields and records
172
+ async function logDealRecord() {
173
+ // Create a record under the 'deal' definition
174
+ const record = await crmControllerCreateRecord(orgSlug, {
175
+ objectId: "def_deal_id",
176
+ ownerId: "member_sales_rep_01",
177
+ data: {
178
+ title: "Enterprise Upgrade 2026",
179
+ amount: 450000,
180
+ stage: "discovery",
181
+ expectedCloseDate: "2026-12-31"
182
+ }
183
+ });
184
+
185
+ const recordId = record.data.id;
186
+
187
+ // Add rich markdown notes to the deal's timeline
188
+ await crmControllerCreateNote(orgSlug, {
189
+ recordId,
190
+ content: "# Kickoff Meeting Notes\n- Client loved the POS speed.\n- Wants M-Pesa automated routing.",
191
+ timelineDate: new Date().toISOString()
192
+ });
193
+
194
+ // Fetch unified timelines containing all activities and notes
195
+ const timeline = await crmControllerGetTimeline(recordId, orgSlug);
196
+ console.log("Deal Timeline:", timeline.data);
197
+ }
198
+ ```
199
+
200
+ ### 🎫 4. Loyalty & Marketing
201
+ Track customer rewards, redeem points for discounts, and validate vouchers at Checkout.
202
+
203
+ ```typescript
204
+ import {
205
+ loyaltyGetCustomerStatus,
206
+ loyaltyRedeemReward,
207
+ loyaltyValidateVoucher
208
+ } from "@scryme/sdk";
209
+
210
+ // 1. Get customer points balance, tier level, and available rewards
211
+ async function checkLoyalty(customerId: string) {
212
+ const status = await loyaltyGetCustomerStatus(customerId, orgSlug);
213
+ console.log(`Tier: ${status.data.tier}, Balance: ${status.data.points} pts`);
214
+ }
215
+
216
+ // 2. Validate voucher code and check customer eligibility
217
+ async function processDiscount(code: string, customerId: string) {
218
+ try {
219
+ const validation = await loyaltyValidateVoucher(orgSlug, {
220
+ code,
221
+ customerId
222
+ });
223
+ console.log("Voucher Approved:", validation.data);
224
+ } catch (error) {
225
+ console.error("Invalid voucher code:", error);
226
+ }
227
+ }
228
+ ```
229
+
230
+ ### πŸ’΅ 5. Finance, Petty Cash, & Expenses
231
+ Track spending, top up petty cash drawers, and map payments to utility accounts.
232
+
233
+ ```typescript
234
+ import {
235
+ expenseControllerCreateExpense,
236
+ pettyCashControllerCreateFund,
237
+ pettyCashControllerTopUpFund,
238
+ utilityAccountControllerCreateAccount
239
+ } from "@scryme/sdk";
240
+
241
+ // 1. Create a physical utility tracking account
242
+ async function setupElectricityMeter() {
243
+ const account = await utilityAccountControllerCreateAccount({
244
+ name: "HQ Power - Meter A",
245
+ provider: "Kenya Power",
246
+ accountNumber: "22334455-01",
247
+ meterNumber: "M-778899",
248
+ type: "ELECTRICITY"
249
+ });
250
+ return account.data.id;
251
+ }
252
+
253
+ // 2. Record a direct corporate expense
254
+ async function logExpense(utilityAccountId: string) {
255
+ await expenseControllerCreateExpense({
256
+ description: "HQ Monthly Electricity Bill",
257
+ amount: 14500,
258
+ categoryId: "cat_utilities_01",
259
+ paymentMethod: "MPESA",
260
+ utilityAccountId,
261
+ isReimbursable: false,
262
+ isBillable: false
263
+ });
264
+ }
265
+ ```
266
+
267
+ ### 🏒 6. Staff, Shifts, & Attendance
268
+ Log clock-ins, check rosters, and manage custom permission sets and roles.
269
+
270
+ ```typescript
271
+ import {
272
+ attendanceControllerCheckIn,
273
+ attendanceControllerCheckOut,
274
+ roleManagementControllerCreateCustomRole,
275
+ membersControllerGetMembers
276
+ } from "@scryme/sdk";
277
+
278
+ // 1. Employee Clock-In with notes and location validation
279
+ async function clockIn(memberId: string) {
280
+ await attendanceControllerCheckIn(orgSlug, {
281
+ locationId: "loc_nairobi_001",
282
+ notes: "Starting morning shift at register 02"
283
+ });
284
+ }
285
+
286
+ // 2. Create high-security roles with customized permissions
287
+ async function setupManagerRole() {
288
+ const role = await roleManagementControllerCreateCustomRole(orgSlug, {
289
+ name: "Vault Auditor",
290
+ description: "Access to petty cash floats and inventory adjustments",
291
+ permissions: [
292
+ "finance:manage-floats",
293
+ "inventory:adjust"
294
+ ]
295
+ });
296
+ console.log("Audit Role Created:", role.data);
297
+ }
298
+ ```
299
+
300
+ ### πŸ“… 7. Services, Scheduling, & Bookings
301
+ Manage appointments, track resource utilization, and deduct materials automatically upon completion.
302
+
303
+ ```typescript
304
+ import {
305
+ servicesControllerCreateBooking,
306
+ servicesControllerCompleteBooking,
307
+ publicServicesControllerRequestOtp,
308
+ publicServicesControllerVerifyOtp
309
+ } from "@scryme/sdk";
310
+
311
+ // 1. Book an appointment for a customer with specific staff/resources
312
+ async function bookAppointment() {
313
+ const booking = await servicesControllerCreateBooking(orgSlug, {
314
+ serviceId: "srv_coffee_cupping_01",
315
+ customerId: "cust_123",
316
+ locationId: "loc_nairobi_001",
317
+ scheduledStartTime: "2026-10-15T09:00:00Z",
318
+ staffIds: ["member_barista_expert_01"],
319
+ resourceIds: ["res_cupping_lab_A"],
320
+ notes: "VIP tasting session"
321
+ });
322
+ console.log("Appointment Booked:", booking.data);
323
+ }
324
+
325
+ // 2. Complete a booking and auto-deduct standard raw materials
326
+ async function checkoutBooking(bookingId: string) {
327
+ await servicesControllerCompleteBooking(bookingId, orgSlug, {
328
+ actualStartTime: "2026-10-15T09:02:00Z",
329
+ actualEndTime: "2026-10-15T10:15:00Z",
330
+ materials: [
331
+ { variantId: "var_specialty_beans_cupping", quantity: 0.25 } // 250g beans consumed
332
+ ]
333
+ });
334
+ console.log("Booking closed and inventory updated.");
335
+ }
336
+ ```
337
+
338
+ ### πŸ”— 8. Webhooks & Event Subscriptions
339
+ Subscribe to system events and safely verify incoming signatures.
340
+
341
+ ```typescript
342
+ import { webhooksCreate } from "@scryme/sdk";
343
+
344
+ // 1. Register a webhook callback to sync orders to an external ERP
345
+ async function setupWebhook() {
346
+ const webhook = await webhooksCreate(orgSlug, {
347
+ name: "External ERP Sync",
348
+ url: "https://erp.mycompany.com/webhooks/scryme",
349
+ events: ["order.created", "inventory.updated"]
350
+ });
351
+
352
+ // Use the secret to verify signatures in your endpoint (see Best Practices below)
353
+ console.log("Webhook Registered. HMAC Secret:", webhook.data.secret);
354
+ }
355
+ ```
356
+
357
+ ---
358
+
359
+ ## πŸ”’ Best Practices
360
+
361
+ ### Multi-tenant Organization Scoping
362
+ All core resources are strictly isolated by organization. Ensure you always pass the correct `orgSlug` parameter as required by the endpoints. Passing an invalid or unauthorized `orgSlug` will yield a `401 Unauthorized` or `404 Not Found` response.
363
+
364
+ ### Secure Webhook Verification
365
+ When receiving webhook callbacks from Scryme, always verify the webhook signature before processing the payload to prevent spoofing attacks.
366
+
367
+ ```typescript
368
+ import * as crypto from "crypto";
369
+
370
+ function verifySignature(
371
+ payload: string,
372
+ signature: string,
373
+ webhookSecret: string
374
+ ): boolean {
375
+ // Generate the expected HMAC signature
376
+ const hmac = crypto.createHmac("sha256", webhookSecret);
377
+ const expectedSignature = hmac.update(payload).digest("hex");
378
+
379
+ // Constant-time comparison to prevent timing attacks
380
+ return crypto.timingSafeEqual(
381
+ Buffer.from(signature, "hex"),
382
+ Buffer.from(expectedSignature, "hex")
383
+ );
384
+ }
385
+ ```
386
+
387
+ ### Robust Error Handling
388
+ Scryme V3 API returns standardized error structures. Always wrap your SDK calls in `try/catch` blocks and parse the error fields to display helpful messages to users.
389
+
390
+ ```typescript
391
+ import { isAxiosError } from "axios";
392
+
393
+ try {
394
+ await checkStock();
395
+ } catch (error) {
396
+ if (isAxiosError(error) && error.response) {
397
+ const apiError = error.response.data;
398
+ console.error(`Error (${apiError.error.code}): ${apiError.error.message}`);
399
+ console.error("Details:", apiError.error.details);
400
+ } else {
401
+ console.error("Unexpected Error:", error);
402
+ }
403
+ }
404
+ ```
405
+
406
+ ---
407
+
408
+ ## πŸ“„ License
409
+
410
+ This package is proprietary software belonging to Scryme Ltd. All rights reserved.
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@scryme/sdk",
3
+ "version": "0.1.0",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "main": "./dist/index.js",
11
+ "module": "./dist/index.mjs",
12
+ "types": "./dist/index.d.ts",
13
+ "dependencies": {
14
+ "axios": "^1.18.1"
15
+ },
16
+ "devDependencies": {
17
+ "orval": "^8.23.0",
18
+ "tsup": "^8.5.1",
19
+ "typescript": "5.7.3",
20
+ "@repo/typescript-config": "0.0.0"
21
+ },
22
+ "scripts": {
23
+ "generate": "orval",
24
+ "build": "tsup src/index.ts --format cjs,esm --dts",
25
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch"
26
+ }
27
+ }