@slotchain/sdk 1.1.3 → 1.2.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/src/types/api.ts CHANGED
@@ -59,23 +59,35 @@ export interface TenantBranding {
59
59
  */
60
60
  export interface ServiceItem {
61
61
  id: string;
62
- serviceId: string;
62
+ service_id: string;
63
63
  name: string;
64
64
  description?: string;
65
65
  price?: number;
66
66
  duration?: number;
67
- available?: boolean;
68
- // TODO: Add actual service item properties
67
+ is_available?: boolean;
68
+ sort_order?: number;
69
+ created_at: string;
70
+ updated_at: string;
69
71
  }
70
72
 
71
73
  /**
72
- * Enhanced Service type with nested service items
74
+ * Enhanced Service type with nested service items (for tenant endpoint)
75
+ * Uses 'serviceItems' property name
73
76
  */
74
77
  export interface ServiceWithItems extends Service {
75
78
  /** Array of service items nested within this service (optional, may be empty array) */
76
79
  serviceItems?: ServiceItem[];
77
80
  }
78
81
 
82
+ /**
83
+ * Service with items for slot endpoint
84
+ * Uses 'items' property name (different from tenant endpoint)
85
+ */
86
+ export interface SlotServiceWithItems extends Service {
87
+ /** Array of service items nested within this service (always included for slot endpoint) */
88
+ items: ServiceItem[];
89
+ }
90
+
79
91
  /**
80
92
  * Service item with parent service reference
81
93
  */
@@ -148,12 +160,16 @@ export interface ListBookingsOptions {
148
160
 
149
161
  export interface Service {
150
162
  id: string;
151
- tenantId: string;
163
+ tenant_id: string;
164
+ slot_id?: string; // Present but not used in queries
152
165
  name: string;
153
166
  description?: string;
167
+ category?: string;
168
+ is_active?: boolean;
154
169
  duration?: number;
155
170
  price?: number;
156
- // TODO: Add actual service properties
171
+ created_at: string;
172
+ updated_at: string;
157
173
  }
158
174
 
159
175
  export interface Slot {
@@ -167,13 +183,99 @@ export interface Slot {
167
183
  updated_at: string;
168
184
  }
169
185
 
186
+ /**
187
+ * Customer record — matches the `customers` table.
188
+ */
170
189
  export interface Customer {
171
190
  id: string;
191
+ tenant_id: string;
192
+ customer_type: 'individual' | 'organization';
193
+ name: string;
194
+ email: string;
195
+ phone?: string;
196
+ address?: string;
197
+ city?: string;
198
+ state?: string;
199
+ zip_code?: string;
200
+ is_guest?: boolean;
201
+ metadata?: Record<string, unknown>;
202
+ created_at: string;
203
+ updated_at: string;
204
+ }
205
+
206
+ /**
207
+ * A row in `customer_users` — links an IDP user (Clerk userId, Auth0 sub, etc.) to a Customer.
208
+ */
209
+ export interface CustomerIdentity {
210
+ id: string;
211
+ customer_id: string;
212
+ idp_id: string;
213
+ role: 'owner' | 'admin' | 'member';
214
+ is_primary: boolean;
215
+ created_at: string;
216
+ updated_at: string;
217
+ }
218
+
219
+ /**
220
+ * Customer with their associated IDP identities (from `customer_users` join).
221
+ */
222
+ export interface CustomerWithIdentities extends Customer {
223
+ identities?: CustomerIdentity[];
224
+ }
225
+
226
+ /**
227
+ * Notification preferences stored in `customer.metadata.notification_preferences`.
228
+ */
229
+ export interface NotificationPreferences {
230
+ email?: boolean;
231
+ sms?: boolean;
232
+ push?: boolean;
233
+ booking_confirmation?: boolean;
234
+ booking_reminder?: boolean;
235
+ booking_cancellation?: boolean;
236
+ marketing?: boolean;
237
+ [key: string]: boolean | undefined;
238
+ }
239
+
240
+ /**
241
+ * Customer with their bookings, as returned by GET /api/v1/customers/bookings.
242
+ */
243
+ export interface CustomerWithBookings {
244
+ customer: Customer;
245
+ bookings: Booking[];
246
+ /** Bookings organised by slot ID → array of bookings */
247
+ groupedBySlot: Record<string, Booking[]>;
248
+ total: number;
249
+ total_slots: number;
250
+ }
251
+
252
+ /**
253
+ * Options for resolving a customer from an IDP identity or email.
254
+ * At least one of `idpId` or `email` must be provided.
255
+ */
256
+ export interface ResolveCustomerOptions {
172
257
  tenantId: string;
258
+ /** IDP user ID (Clerk userId, Auth0 sub, etc.) — checked first */
259
+ idpId?: string;
260
+ /** Email address — used as fallback if idpId lookup returns nothing */
173
261
  email?: string;
262
+ }
263
+
264
+ /**
265
+ * Options for atomic customer upsert (find or create by email within a tenant).
266
+ */
267
+ export interface FindOrCreateCustomerOptions {
268
+ tenant_id: string;
269
+ email: string;
174
270
  name?: string;
175
271
  phone?: string;
176
- // TODO: Add actual customer properties
272
+ address?: string;
273
+ city?: string;
274
+ state?: string;
275
+ zip_code?: string;
276
+ customer_type?: 'individual' | 'organization';
277
+ is_guest?: boolean;
278
+ metadata?: Record<string, unknown>;
177
279
  }
178
280
 
179
281
  export interface Flow {
@@ -249,6 +351,69 @@ export interface GetOrganizationOptions {
249
351
  is_public?: boolean;
250
352
  }
251
353
 
354
+ /**
355
+ * Artifact / document attached to a customer or booking
356
+ */
357
+ export type ArtifactEntityType = 'customer' | 'booking' | 'slot' | 'service' | 'tenant';
358
+
359
+ export type ArtifactMimeCategory = 'pdf' | 'document' | 'image' | 'spreadsheet' | 'video' | 'audio' | 'other';
360
+
361
+ export interface Artifact {
362
+ id: string;
363
+ tenant_id: string;
364
+ /** The Slotly entity this file is attached to */
365
+ related_entity_type: ArtifactEntityType;
366
+ related_entity_id: string;
367
+ /** Original filename supplied by the uploader */
368
+ original_filename: string;
369
+ /** Storage path within the tenant bucket (opaque — use url/signed_url to access) */
370
+ storage_path: string;
371
+ /** MIME category, derived server-side */
372
+ mime_category: ArtifactMimeCategory;
373
+ mime_type?: string;
374
+ size_bytes?: number;
375
+ /** Optional label, e.g. "CV", "Invoice", "Contract" */
376
+ label?: string;
377
+ metadata?: Record<string, unknown>;
378
+ uploaded_by_user_id?: string;
379
+ created_at: string;
380
+ updated_at: string;
381
+ }
382
+
383
+ /**
384
+ * Artifact with a short-lived signed download URL (returned from getUrl / list with signed=true)
385
+ */
386
+ export interface ArtifactWithUrl extends Artifact {
387
+ signed_url: string;
388
+ /** Unix timestamp (seconds) when the signed_url expires */
389
+ signed_url_expires_at: number;
390
+ }
391
+
392
+ export interface ListArtifactsOptions {
393
+ related_entity_type?: ArtifactEntityType;
394
+ related_entity_id?: string;
395
+ /** Include signed download URLs in each result (adds latency) */
396
+ signed?: boolean;
397
+ mime_category?: ArtifactMimeCategory;
398
+ label?: string;
399
+ page?: number;
400
+ limit?: number;
401
+ }
402
+
403
+ export interface UploadArtifactOptions {
404
+ /** The file binary */
405
+ file: Blob | Buffer | ArrayBuffer;
406
+ /** Original filename */
407
+ filename: string;
408
+ /** The entity this artifact belongs to */
409
+ related_entity_type: ArtifactEntityType;
410
+ related_entity_id: string;
411
+ /** Optional label for the UI, e.g. "CV", "Invoice" */
412
+ label?: string;
413
+ mime_type?: string;
414
+ metadata?: Record<string, unknown>;
415
+ }
416
+
252
417
  /**
253
418
  * Full tenant configuration including branding, services, and service items
254
419
  * Service items are nested within each service object (not as a separate top-level array)
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Minimal ambient declarations for Next.js types used in validateSlotlyRequest.
3
+ * This prevents a hard devDependency on the full `next` package just to typecheck
4
+ * the middleware file. Replace with `import type {...} from 'next'` if next is
5
+ * available in the host project.
6
+ */
7
+ declare module 'next' {
8
+ import type { IncomingMessage, ServerResponse } from 'http';
9
+
10
+ interface NextApiRequest extends IncomingMessage {
11
+ query: Record<string, string | string[]>;
12
+ cookies: Record<string, string>;
13
+ body: any;
14
+ env: Record<string, string>;
15
+ headers: Record<string, string | string[] | undefined>;
16
+ method?: string;
17
+ url?: string;
18
+ }
19
+
20
+ interface NextApiResponse<T = any> extends ServerResponse {
21
+ send(body: T): void;
22
+ json(body: T): void;
23
+ status(code: number): NextApiResponse<T>;
24
+ redirect(url: string): void;
25
+ redirect(status: number, url: string): void;
26
+ setHeader(name: string, value: string | string[]): void;
27
+ end(data?: string | Buffer): void;
28
+ }
29
+ }