@gravity-rail/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.
package/README.md ADDED
@@ -0,0 +1,423 @@
1
+ # @gravity-rail/sdk
2
+
3
+ TypeScript SDK for [Gravity Rail](https://gravityrail.com) — the AI-native operating system for organizations that communicate with people at scale.
4
+
5
+ Build AI assistants that handle voice calls, SMS, web chat, email, Discord, and Slack — all backed by configurable workflows, structured data collection, and real-time streaming. One SDK, every channel.
6
+
7
+ ## Installation
8
+
9
+ ```sh
10
+ npm install @gravity-rail/sdk
11
+ # or
12
+ yarn add @gravity-rail/sdk
13
+ # or
14
+ pnpm add @gravity-rail/sdk
15
+ ```
16
+
17
+ Zod schemas are available as an optional peer dependency:
18
+
19
+ ```sh
20
+ npm install zod # optional, for runtime validation
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```typescript
26
+ import { GravityRailClient } from '@gravity-rail/sdk';
27
+
28
+ const client = new GravityRailClient(
29
+ process.env.GRAVITY_RAIL_API_KEY,
30
+ 'https://api.gravityrail.com'
31
+ );
32
+
33
+ // List all workflows in a workspace
34
+ const workflows = await client.getWorkflows(workspaceId);
35
+
36
+ // Get active chats across every channel
37
+ const chats = await client.getChats(workspaceId);
38
+
39
+ // Create a new member
40
+ const member = await client.createWorkspaceMember(workspaceId, {
41
+ first_name: 'Jane',
42
+ last_name: 'Doe',
43
+ email: 'jane@example.com',
44
+ role_id: roleId,
45
+ });
46
+ ```
47
+
48
+ ## Authentication
49
+
50
+ ### API Key
51
+
52
+ Scoped API keys are the simplest way to authenticate. Create one from workspace settings or via the SDK:
53
+
54
+ ```typescript
55
+ const client = new GravityRailClient(
56
+ 'your-api-key',
57
+ 'https://api.gravityrail.com'
58
+ );
59
+ ```
60
+
61
+ Keys can be scoped to specific permissions (read-only, workspace-limited, time-expiring) using the [granular scope system](#scopes--permissions).
62
+
63
+ ### OAuth2 with PKCE
64
+
65
+ For browser-based applications:
66
+
67
+ ```typescript
68
+ const client = new GravityRailClient(undefined, 'https://api.gravityrail.com');
69
+
70
+ // Handle step-up authentication when the API requires it
71
+ client.setEnhancedAuthHandler(async (authInfo) => {
72
+ // Redirect to login or show auth modal
73
+ });
74
+ ```
75
+
76
+ ### Member Identity Switching
77
+
78
+ Act on behalf of a specific workspace member:
79
+
80
+ ```typescript
81
+ client.setActingMember(memberUuid);
82
+ // All subsequent requests use this member's identity
83
+ const myChats = await client.getChats(workspaceId);
84
+ client.setActingMember(undefined); // reset
85
+ ```
86
+
87
+ ## Core Concepts
88
+
89
+ Every Gravity Rail workspace is a self-contained environment with isolated data, workflows, and configuration. The SDK organizes its 500+ methods by domain:
90
+
91
+ | Domain | What it covers |
92
+ |---|---|
93
+ | **Workflows** | Multi-step conversational processes with branching logic, task assignment, and templates |
94
+ | **Assistants** | AI personas with configurable models, voices, and a two-tier supervisor system |
95
+ | **Agents** | Autonomous AI workspace members with their own identity, config, and multi-channel presence |
96
+ | **Chats** | Conversations across all channels — labels, filters, summaries, message history, and export |
97
+ | **Members** | Contacts and team — roles, labels, filters, custom fields, import/export, anonymous resolution |
98
+ | **Data Types** | Schema-driven forms (14 field types) with computed fields and conversational collection |
99
+ | **Events** | Trigger-based automation with [CEL expressions](https://github.com/google/cel-spec) |
100
+ | **Calendars** | Scheduling, availability, event types, Google Calendar sync, and iCal feeds |
101
+ | **Files** | Folder hierarchy with semantic search, role-based sharing, and public access |
102
+ | **Sites** | Customer-facing portals with custom domains, page builder, and web crawling |
103
+ | **Communications** | Phone numbers, SMS, email inboxes, and notification rules |
104
+ | **Toolkits** | Custom tools, MCP server integrations, and AI model configuration |
105
+ | **Operator Groups** | Live human routing with presence tracking and configurable strategies |
106
+ | **Qualifications** | Skills evaluation with expression-based and rubric-based scoring |
107
+ | **Billing** | API keys, subscriptions, and usage reports (AI, voice, SMS, storage) |
108
+ | **Integrations** | Discord, Slack, Monday.com, FHIR, and OAuth app connections |
109
+
110
+ ## Usage Examples
111
+
112
+ ### Workflows & Assistants
113
+
114
+ ```typescript
115
+ // Create a multi-step workflow
116
+ const workflow = await client.createWorkflow(workspaceId, {
117
+ name: 'Customer Onboarding',
118
+ description: 'Guide new customers through setup',
119
+ });
120
+
121
+ // Create an AI assistant
122
+ const assistant = await client.createAssistant(workspaceId, {
123
+ name: 'Onboarding Guide',
124
+ model: 'claude-sonnet-4-20250514',
125
+ bio: 'A friendly assistant that helps new customers get started.',
126
+ });
127
+
128
+ // Add a supervisor for quality assurance
129
+ const supervisor = await client.createSupervisor(workspaceId, {
130
+ name: 'QA Reviewer',
131
+ model: 'claude-sonnet-4-20250514',
132
+ instructions: 'Review assistant responses for accuracy and tone.',
133
+ });
134
+
135
+ // Build from templates
136
+ const templates = await client.getWorkflowTemplates(workspaceId);
137
+ await client.createWorkflowFromTemplate(workspaceId, {
138
+ template_id: templates[0].id,
139
+ });
140
+ ```
141
+
142
+ ### Chat Operations
143
+
144
+ ```typescript
145
+ // Get conversations across all channels
146
+ const chats = await client.getChats(workspaceId);
147
+
148
+ // Full message history with tool calls
149
+ const messages = await client.getChatMessages(workspaceId, chatId);
150
+ const toolCalls = await client.getChatToolCallMessages(workspaceId, chatId);
151
+
152
+ // Trigger an AI response
153
+ await client.sendAssistantMessage(workspaceId, chatId);
154
+
155
+ // Direct messaging between members
156
+ const dm = await client.findOrCreateDMChat(workspaceId, { member_id: targetMemberId });
157
+ await client.sendChatMessage(workspaceId, dm.id, { content: 'Hey!' });
158
+
159
+ // Export for analysis
160
+ const exported = await client.exportChat(workspaceId, chatId);
161
+
162
+ // Organize with labels and filters
163
+ await client.createChatLabel(workspaceId, { name: 'VIP', color: '#FFD700' });
164
+ await client.createChatFilter(workspaceId, { name: 'Unresolved', conditions: { needs_response: true } });
165
+ ```
166
+
167
+ ### Structured Data Collection
168
+
169
+ ```typescript
170
+ // Define a schema — AI assistants collect this conversationally
171
+ const dataType = await client.createDataType(workspaceId, {
172
+ name: 'Contact Form',
173
+ slug: 'contact-form',
174
+ is_collection: true,
175
+ fields: [
176
+ { name: 'Full Name', field_type: 'text', required: true },
177
+ { name: 'Email', field_type: 'email', required: true },
178
+ { name: 'Priority', field_type: 'dropdown', options: ['Low', 'Medium', 'High'] },
179
+ { name: 'Score', field_type: 'formula', formula: 'Priority == "High" ? 100 : 50' },
180
+ ],
181
+ });
182
+
183
+ // Or create records programmatically
184
+ const record = await client.createDataRecord(workspaceId, dataType.id, {
185
+ field_values: { 'Full Name': 'Alice Chen', 'Email': 'alice@example.com', 'Priority': 'High' },
186
+ });
187
+
188
+ // Query and upsert
189
+ const records = await client.getDataRecords(workspaceId, dataType.id);
190
+ await client.upsertDataRecord(workspaceId, dataType.id, {
191
+ match_field: 'Email',
192
+ field_values: { 'Email': 'alice@example.com', 'Priority': 'Medium' },
193
+ });
194
+ ```
195
+
196
+ ### Communication Channels
197
+
198
+ ```typescript
199
+ // Phone — initiate an outbound AI voice call
200
+ const numbers = await client.getPhoneNumbers(workspaceId);
201
+ await client.initiateCall(workspaceId, {
202
+ phone_number_id: numbers[0].id,
203
+ to_number: '+15551234567',
204
+ workflow_id: workflowId,
205
+ });
206
+
207
+ // Email — manage inboxes and threads
208
+ const inboxes = await client.getInboxes(workspaceId);
209
+ const threads = await client.getInboxThreads(workspaceId, inboxes[0].id);
210
+ const emails = await client.getThreadEmails(workspaceId, inboxes[0].id, threadId);
211
+
212
+ // Notifications
213
+ await client.createNotificationRule(workspaceId, {
214
+ name: 'New chat alert',
215
+ event_type: 'chat.created',
216
+ channel: 'email',
217
+ });
218
+ ```
219
+
220
+ ### Toolkits & MCP Servers
221
+
222
+ ```typescript
223
+ // Connect an MCP server for custom AI tool capabilities
224
+ const server = await client.createMcpServer(workspaceId, {
225
+ name: 'Internal Tools',
226
+ url: 'https://tools.example.com/mcp',
227
+ });
228
+ await client.testMcpServerConnection(workspaceId, server.id);
229
+
230
+ // Discover tools, resources, and prompts
231
+ const tools = await client.getMcpServerTools(workspaceId, server.id);
232
+ const resources = await client.getMcpServerResources(workspaceId, server.id);
233
+
234
+ // Or build custom tools directly
235
+ await client.createCustomTool(workspaceId, toolkitId, {
236
+ name: 'lookup_order',
237
+ description: 'Look up an order by ID',
238
+ input_schema: {
239
+ type: 'object',
240
+ properties: { order_id: { type: 'string' } },
241
+ required: ['order_id'],
242
+ },
243
+ });
244
+ ```
245
+
246
+ ### Calendar & Scheduling
247
+
248
+ ```typescript
249
+ const calendar = await client.createCalendar(workspaceId, { name: 'Appointments' });
250
+
251
+ // Check availability and book
252
+ const slots = await client.getAvailableSlots(workspaceId, calendar.id, {
253
+ start_date: '2025-03-01',
254
+ end_date: '2025-03-07',
255
+ duration_minutes: 30,
256
+ });
257
+
258
+ await client.createCalendarEvent(workspaceId, calendar.id, {
259
+ title: 'Consultation',
260
+ start_time: slots[0].start,
261
+ end_time: slots[0].end,
262
+ attendees: [{ member_id: memberId }],
263
+ });
264
+
265
+ // Sync with Google Calendar
266
+ await client.linkCalendarToGoogle(workspaceId, calendar.id, {
267
+ google_calendar_id: 'primary',
268
+ });
269
+ ```
270
+
271
+ ### Event Automation
272
+
273
+ ```typescript
274
+ // Trigger-based automation with CEL conditions
275
+ await client.createEventRule(workspaceId, {
276
+ name: 'VIP Follow-up',
277
+ trigger: 'task.exited',
278
+ condition: '"vip" in member.labels',
279
+ actions: [{
280
+ type: 'send_ai_message',
281
+ delay_minutes: 60,
282
+ config: { message: 'Thank you for your time today.' },
283
+ }],
284
+ });
285
+
286
+ // Scheduled events (CRON)
287
+ const event = await client.createEvent(workspaceId, {
288
+ name: 'Daily Check-in',
289
+ schedule: '0 9 * * *',
290
+ target_filter: { labels: ['active'] },
291
+ });
292
+
293
+ // Trigger manually
294
+ await client.runEvent(workspaceId, event.id);
295
+ ```
296
+
297
+ ### Operator Groups & Live Handoff
298
+
299
+ ```typescript
300
+ // Route conversations to live human operators
301
+ const group = await client.createOperatorGroup(workspaceId, {
302
+ name: 'Support Team',
303
+ routing_strategy: 'round_robin',
304
+ timeout_seconds: 30, // falls back to AI if no one accepts
305
+ });
306
+
307
+ await client.addGroupMember(workspaceId, group.id, { member_id: agentMemberId });
308
+ const operators = await client.getLiveOperators(workspaceId);
309
+ ```
310
+
311
+ ### Sites & Portals
312
+
313
+ ```typescript
314
+ // Build customer-facing portals with AI chat built in
315
+ const site = await client.createSite(workspaceId, {
316
+ name: 'Help Center',
317
+ slug: 'help',
318
+ domain: 'help.example.com',
319
+ });
320
+
321
+ await client.createPage(workspaceId, site.id, {
322
+ title: 'Getting Started',
323
+ slug: 'getting-started',
324
+ content: '# Welcome\nHere is how to get started...',
325
+ });
326
+
327
+ // Import existing documentation automatically
328
+ await client.crawlSite(workspaceId, site.id, { url: 'https://docs.example.com' });
329
+ ```
330
+
331
+ ### Workspace Management
332
+
333
+ ```typescript
334
+ // Export/import full workspace configuration
335
+ const config = await client.exportWorkspace(workspaceId);
336
+ const preview = await client.previewWorkspaceImport(targetId, config);
337
+ await client.importWorkspace(targetId, config);
338
+
339
+ // White-label: provision client workspaces
340
+ const clientWs = await client.createClientWorkspace(workspaceId, {
341
+ name: 'Acme Corp',
342
+ product_id: productId,
343
+ });
344
+ await client.provisionClientWorkspace(workspaceId, clientWs.id);
345
+ ```
346
+
347
+ ## Type System
348
+
349
+ Full TypeScript types for every API entity:
350
+
351
+ ```typescript
352
+ import type {
353
+ Workspace, Member, Chat, Task, Workflow, Assistant,
354
+ DataType, DataRecord, EventRule, Calendar, Site,
355
+ PhoneNumber, Inbox, OperatorGroup, Qualification,
356
+ Subscription, ApiKey, Agent, MemberRole,
357
+ } from '@gravity-rail/sdk';
358
+ ```
359
+
360
+ ### Zod Schemas
361
+
362
+ Runtime validation schemas via a separate import (requires `zod`):
363
+
364
+ ```typescript
365
+ import { taskSchema, memberSchema, workflowSchema } from '@gravity-rail/sdk/schemas';
366
+
367
+ const task = taskSchema.parse(apiResponse);
368
+
369
+ const result = memberSchema.safeParse(formData);
370
+ if (!result.success) {
371
+ console.error(result.error.flatten());
372
+ }
373
+ ```
374
+
375
+ ## Scopes & Permissions
376
+
377
+ The SDK includes the complete scope system for building OAuth apps and managing API key permissions:
378
+
379
+ ```typescript
380
+ import { SCOPES, ScopeCategory, ScopeManager, SCOPE_PRESETS } from '@gravity-rail/sdk';
381
+
382
+ // Browse available scopes by category
383
+ const chatScopes = Object.values(SCOPES).filter(
384
+ (s) => s.category === ScopeCategory.CHATS
385
+ );
386
+ ```
387
+
388
+ 22 scope categories covering every domain: workspace, members, chats, DMs, assistants, workflows, assignments, automations, data types, records, files, sites, agents, calendars, inboxes, phones, webhooks, apps, labels, analytics, operator, and org.
389
+
390
+ ## Error Handling
391
+
392
+ ```typescript
393
+ import { GravityRailClient, ApiError } from '@gravity-rail/sdk';
394
+
395
+ try {
396
+ const task = await client.getTask(workspaceId, taskId);
397
+ } catch (error) {
398
+ if (error instanceof ApiError) {
399
+ console.error(`${error.status}: ${error.message}`);
400
+ // 403 → check API key scopes
401
+ // 404 → verify workspace and entity IDs
402
+ // 429 → rate limited, back off
403
+ }
404
+ }
405
+ ```
406
+
407
+ ## Compliance
408
+
409
+ Gravity Rail is built for HIPAA compliance. The SDK enforces:
410
+
411
+ - **Data isolation** — every workspace has a dedicated database schema
412
+ - **Scoped access** — API keys enforce granular permissions at the scope level
413
+ - **Feature flags** — workspaces can enable `HIPAA_COMPLIANCE` for stricter data handling
414
+ - **Audit trails** — all operations are logged for compliance reporting
415
+
416
+ ## Related
417
+
418
+ - [`@gravity-rail/cli`](https://www.npmjs.com/package/@gravity-rail/cli) — Command-line interface for interactive workspace management
419
+ - [Developer Docs](https://developer.gravityrail.com) — Full API reference and guides
420
+
421
+ ## License
422
+
423
+ MIT
@@ -0,0 +1,88 @@
1
+ // ../client/dist/chunk-KQW7D2GX.mjs
2
+ var DataFieldType = /* @__PURE__ */ ((DataFieldType2) => {
3
+ DataFieldType2["ENUM"] = "enum";
4
+ DataFieldType2["EMAIL"] = "email";
5
+ DataFieldType2["PHONE"] = "phone";
6
+ DataFieldType2["TEXT"] = "text";
7
+ DataFieldType2["LONGTEXT"] = "longtext";
8
+ DataFieldType2["NUMBER"] = "number";
9
+ DataFieldType2["DATE"] = "date";
10
+ DataFieldType2["DATETIME"] = "datetime";
11
+ DataFieldType2["TIME_OF_DAY"] = "time_of_day";
12
+ DataFieldType2["US_ZIP_CODE"] = "us_zip_code";
13
+ DataFieldType2["INTEGER"] = "integer";
14
+ DataFieldType2["BOOLEAN"] = "boolean";
15
+ DataFieldType2["ARRAY"] = "array";
16
+ DataFieldType2["OBJECT"] = "object";
17
+ DataFieldType2["FUNCTION"] = "function";
18
+ return DataFieldType2;
19
+ })(DataFieldType || {});
20
+ var IndexStatus = /* @__PURE__ */ ((IndexStatus2) => {
21
+ IndexStatus2["NONE"] = "none";
22
+ IndexStatus2["PENDING"] = "pending";
23
+ IndexStatus2["CREATING"] = "creating";
24
+ IndexStatus2["REMOVING"] = "removing";
25
+ IndexStatus2["READY"] = "ready";
26
+ IndexStatus2["ERROR"] = "error";
27
+ return IndexStatus2;
28
+ })(IndexStatus || {});
29
+ var CalendarPermissionType = /* @__PURE__ */ ((CalendarPermissionType2) => {
30
+ CalendarPermissionType2["NONE"] = "NONE";
31
+ CalendarPermissionType2["FREE_BUSY"] = "FREE_BUSY";
32
+ CalendarPermissionType2["READ"] = "READ";
33
+ CalendarPermissionType2["WRITE"] = "WRITE";
34
+ CalendarPermissionType2["ADMIN"] = "ADMIN";
35
+ return CalendarPermissionType2;
36
+ })(CalendarPermissionType || {});
37
+ var CalendarSource = /* @__PURE__ */ ((CalendarSource2) => {
38
+ CalendarSource2["INTERNAL"] = "internal";
39
+ CalendarSource2["GOOGLE"] = "google";
40
+ CalendarSource2["OUTLOOK"] = "outlook";
41
+ return CalendarSource2;
42
+ })(CalendarSource || {});
43
+ var CalendarScheduleRecurrence = /* @__PURE__ */ ((CalendarScheduleRecurrence2) => {
44
+ CalendarScheduleRecurrence2["ONCE"] = "ONCE";
45
+ CalendarScheduleRecurrence2["DAILY"] = "DAILY";
46
+ CalendarScheduleRecurrence2["WEEKLY"] = "WEEKLY";
47
+ CalendarScheduleRecurrence2["MONTHLY"] = "MONTHLY";
48
+ CalendarScheduleRecurrence2["CUSTOM"] = "CUSTOM";
49
+ return CalendarScheduleRecurrence2;
50
+ })(CalendarScheduleRecurrence || {});
51
+ var CalendarScheduleAvailabilityType = /* @__PURE__ */ ((CalendarScheduleAvailabilityType2) => {
52
+ CalendarScheduleAvailabilityType2["AVAILABLE"] = "AVAILABLE";
53
+ CalendarScheduleAvailabilityType2["UNAVAILABLE"] = "UNAVAILABLE";
54
+ return CalendarScheduleAvailabilityType2;
55
+ })(CalendarScheduleAvailabilityType || {});
56
+ var CalendarEventStatus = /* @__PURE__ */ ((CalendarEventStatus2) => {
57
+ CalendarEventStatus2["TENTATIVE"] = "TENTATIVE";
58
+ CalendarEventStatus2["CONFIRMED"] = "CONFIRMED";
59
+ CalendarEventStatus2["CANCELLED"] = "CANCELLED";
60
+ CalendarEventStatus2["NO_SHOW"] = "NO_SHOW";
61
+ CalendarEventStatus2["COMPLETED"] = "COMPLETED";
62
+ return CalendarEventStatus2;
63
+ })(CalendarEventStatus || {});
64
+ var AttendeeStatus = /* @__PURE__ */ ((AttendeeStatus2) => {
65
+ AttendeeStatus2["REQUIRED"] = "REQUIRED";
66
+ AttendeeStatus2["OPTIONAL"] = "OPTIONAL";
67
+ return AttendeeStatus2;
68
+ })(AttendeeStatus || {});
69
+ var AttendeeResponseStatus = /* @__PURE__ */ ((AttendeeResponseStatus2) => {
70
+ AttendeeResponseStatus2["PENDING"] = "PENDING";
71
+ AttendeeResponseStatus2["ACCEPTED"] = "ACCEPTED";
72
+ AttendeeResponseStatus2["DECLINED"] = "DECLINED";
73
+ AttendeeResponseStatus2["TENTATIVE"] = "TENTATIVE";
74
+ return AttendeeResponseStatus2;
75
+ })(AttendeeResponseStatus || {});
76
+
77
+ export {
78
+ DataFieldType,
79
+ IndexStatus,
80
+ CalendarPermissionType,
81
+ CalendarSource,
82
+ CalendarScheduleRecurrence,
83
+ CalendarScheduleAvailabilityType,
84
+ CalendarEventStatus,
85
+ AttendeeStatus,
86
+ AttendeeResponseStatus
87
+ };
88
+ //# sourceMappingURL=chunk-KQJR26B5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../client/src/types/dataTypes.ts","../../client/src/types/calendarTypes.ts"],"sourcesContent":["// Data-related types extracted from main types.ts file\n// This file contains all types related to data types, data records, data fields, and data integrity management\n\nimport type { AccountReportItem } from './accountTypes';\nimport type { MemberReportItem } from './memberTypes';\n\n// ===== DATA FIELD TYPES =====\n\nexport enum DataFieldType {\n ENUM = 'enum',\n EMAIL = 'email',\n PHONE = 'phone',\n TEXT = 'text',\n LONGTEXT = 'longtext',\n NUMBER = 'number',\n DATE = 'date',\n DATETIME = 'datetime',\n TIME_OF_DAY = 'time_of_day',\n US_ZIP_CODE = 'us_zip_code',\n INTEGER = 'integer',\n BOOLEAN = 'boolean',\n ARRAY = 'array',\n OBJECT = 'object',\n FUNCTION = 'function',\n}\n\nexport enum IndexStatus {\n NONE = 'none',\n PENDING = 'pending',\n CREATING = 'creating',\n REMOVING = 'removing',\n READY = 'ready',\n ERROR = 'error',\n}\n\nexport interface DataField {\n id?: number;\n name: string;\n slug: string;\n description?: string;\n required: boolean;\n fieldType: DataFieldType;\n options?: EnumOption[];\n referencedTypeId?: number;\n shouldIndex?: boolean;\n indexStatus?: IndexStatus;\n adminOnly?: boolean;\n defaultValue?: any;\n order: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface DataFieldFormData {\n name: string;\n slug: string;\n description?: string;\n required: boolean;\n fieldType: DataFieldType;\n options?: EnumOption[];\n referencedTypeId?: number;\n shouldIndex?: boolean;\n indexStatus?: IndexStatus;\n adminOnly?: boolean;\n defaultValue?: any;\n}\n\n// ===== SCHEMA FIELD TYPES =====\n// Strongly-typed field definitions (canonical representation)\n\n/**\n * Label-value pair for enum field options.\n * Allows enum fields to have user-friendly labels while storing clean values\n * (e.g., numbers for scoring calculations in CEL expressions).\n */\nexport interface EnumOption {\n /** Display label shown to users */\n label: string;\n /** Stored value (can be string or number) */\n value: string | number;\n /**\n * CEL expression that must return true for this option to be visible.\n * Uses record.data.<field_slug> syntax to reference other field values.\n * CONSTRAINT: Can only reference non-FUNCTION fields.\n */\n visibleWhen?: string;\n}\n\n/**\n * SchemaField is the canonical representation of a data type field.\n * This is the type returned by the API and stored in the database.\n * Display order is determined by array position, not the order field.\n */\nexport interface SchemaField {\n /** Unique field identifier */\n slug: string;\n /** Display name for the field */\n name: string;\n /** Optional field description */\n description?: string;\n /** Field type (text, email, enum, etc.) */\n fieldType: DataFieldType;\n /** Whether field is required */\n required: boolean;\n /** @deprecated Display order is now determined by array position */\n order?: number;\n /** Options for enum fields as {label, value} objects. */\n options?: EnumOption[];\n /** Referenced DataType ID for reference fields */\n referencedTypeId?: number;\n /** Whether to index this field */\n shouldIndex?: boolean;\n /** Whether only admins can see this field */\n adminOnly?: boolean;\n /** Default value for the field */\n defaultValue?: any;\n /** CEL expression that computes this field's value from other fields */\n celFunction?: string;\n /**\n * CEL expression for cross-field validation.\n * Context: 'value' (current field value), 'record.data.<field_slug>' (other fields).\n * Returns: true if valid, or a string error message if invalid.\n * CONSTRAINT: Can only reference non-FUNCTION fields.\n */\n validateCel?: string;\n}\n\n// ===== DATA TYPE TYPES =====\n\nexport interface DataType {\n id: number;\n name: string;\n slug: string;\n uuid: string;\n description?: string;\n prompt?: string;\n isCollection: boolean;\n pinned?: boolean;\n archived: boolean;\n ownerId: number | null;\n createdAt: string;\n updatedAt: string;\n /** Typed field definitions */\n fields: SchemaField[];\n}\n\nexport interface DataTypeFormData {\n name: string;\n slug: string;\n description?: string;\n prompt?: string;\n isCollection: boolean;\n pinned?: boolean;\n /** Typed field definitions */\n fields: SchemaField[];\n ownerId?: number | null;\n}\n\n// ===== DATA RECORD TYPES =====\n\nexport interface DataRecord {\n id: number;\n dataTypeId: number;\n memberId: number;\n fieldValues: Record<string, any>;\n externalId?: string;\n assignmentTaskId?: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface DataRecordFormData {\n memberId?: number;\n /** Member external ID (alternative to memberId). Cannot be used with memberId. */\n memberExternalId?: string;\n fieldValues: Record<string, any>;\n externalId?: string;\n assignmentTaskId?: number;\n}\n\n// ===== DATA RECORD AUDIT TRAIL =====\n\nexport interface DataRecordUpdate {\n id: number;\n dataRecordId: number;\n memberId: number;\n fieldName: string;\n oldValue?: string | null;\n newValue?: string | null;\n createdAt: string;\n updatedAt: string;\n assignmentTaskId?: number | null;\n memberName?: string | null;\n}\n\n// ===== DATA RECORD PAGINATION =====\n\nexport interface DataRecordsPaginatedResponse {\n records: DataRecord[];\n pagination: {\n page: number;\n page_size: number;\n total_count: number;\n total_pages: number;\n has_next: boolean;\n has_prev: boolean;\n };\n}\n\n// ===== DATA RECORD ACCESS MODE TYPES =====\n// Used by Assignment data record associations\n\nexport interface DataRecordWithAccessMode extends DataRecord {\n accessMode: number;\n}\n\nexport interface DataRecordAssociationFormData {\n id: number;\n accessMode: number;\n}\n\n// ===== DATA INTEGRITY TYPES =====\n\nexport interface DataRecordReportItem {\n id: number;\n data_type_id: number;\n data_type_name: string;\n data_type_slug: string;\n values: Record<string, any>;\n created_at: string;\n updated_at: string;\n external_id?: string | null;\n}\n\nexport interface DataIntegrityReportItem {\n member: MemberReportItem;\n account: AccountReportItem;\n data_records: DataRecordReportItem[];\n possible_matches: DataIntegrityReportItem[];\n issues: string[];\n normalized_phone?: string | null;\n}\n\n// ===== DATA EXPORT/IMPORT TYPES =====\n\nexport interface DataTypeExportItem {\n uuid: string;\n name: string;\n description: string | null;\n}\n\nexport interface TaskExportDataTypeRelation {\n taskUuid: string;\n dataTypeUuid: string;\n accessMode: number;\n}\n\n// ===== BULK IMPORT TYPES =====\n\n/**\n * Result for a single record in a bulk import operation.\n */\nexport interface BulkRecordResult {\n index: number;\n status: 'created' | 'updated' | 'failed';\n recordId?: number | null;\n externalId?: string | null;\n error?: string | null;\n}\n\n/**\n * Response for bulk create data records operation.\n */\nexport interface BulkCreateDataRecordResponse {\n importedCount: number;\n totalCount: number;\n success: boolean;\n results: BulkRecordResult[];\n errors?: string[] | null;\n}\n\n/**\n * Request body for bulk create data records.\n */\nexport interface BulkCreateDataRecordRequest {\n records: DataRecordFormData[];\n upsert?: boolean;\n}\n","/**\n * Calendar-related types for the Gravity Rail calendar and appointment booking system.\n */\n\n// Calendar Permission Types\nexport enum CalendarPermissionType {\n NONE = 'NONE',\n FREE_BUSY = 'FREE_BUSY',\n READ = 'READ',\n WRITE = 'WRITE',\n ADMIN = 'ADMIN',\n}\n\nexport enum CalendarSource {\n INTERNAL = 'internal',\n GOOGLE = 'google',\n OUTLOOK = 'outlook',\n}\n\n// Calendar types\nexport interface Calendar {\n id: number;\n uuid: string;\n templateUuid: string | null;\n name: string;\n slug: string;\n description: string | null;\n timezone: string;\n color: string | null;\n isPublic: boolean;\n ownerId: number;\n ownerName: string | null;\n remoteCalendarId?: string | null;\n syncStatus?: string | null;\n syncError?: string | null;\n lastSyncedAt?: string | null;\n calendarSource: CalendarSource;\n eventTypeIds: number[];\n schedules: CalendarSchedule[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CalendarFormData {\n name: string;\n slug?: string;\n description?: string | null;\n timezone?: string;\n color?: string | null;\n isPublic?: boolean;\n eventTypeIds?: number[];\n}\n\nexport interface CalendarSchedule {\n id: number;\n uuid: string;\n name: string;\n description: string | null;\n availabilityType: CalendarScheduleAvailabilityType;\n recurrenceType: CalendarScheduleRecurrence;\n startTime: string;\n endTime: string;\n recurrenceRule: Record<string, any> | null;\n recurrenceEndDate: string | null;\n daysOfWeek: string[] | null;\n priority: number;\n eventTypeIds: number[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CalendarScheduleFormData {\n name: string;\n description?: string | null;\n availabilityType: CalendarScheduleAvailabilityType;\n recurrenceType: CalendarScheduleRecurrence;\n startTime: string;\n endTime: string;\n recurrenceRule?: Record<string, any> | null;\n recurrenceEndDate?: string | null;\n daysOfWeek?: string[] | null;\n priority?: number;\n eventTypeIds?: number[] | null;\n}\n\nexport enum CalendarScheduleRecurrence {\n ONCE = 'ONCE',\n DAILY = 'DAILY',\n WEEKLY = 'WEEKLY',\n MONTHLY = 'MONTHLY',\n CUSTOM = 'CUSTOM',\n}\n\nexport enum CalendarScheduleAvailabilityType {\n AVAILABLE = 'AVAILABLE',\n UNAVAILABLE = 'UNAVAILABLE',\n}\n\n// Event type types\nexport interface CalendarEventType {\n id: number;\n uuid: string;\n templateUuid: string | null;\n name: string;\n slug: string;\n description: string | null;\n defaultDurationMinutes: number;\n bufferBeforeMinutes: number;\n bufferAfterMinutes: number;\n minAttendees: number;\n maxAttendees: number | null;\n color: string | null;\n active: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CalendarEventTypeFormData {\n name: string;\n slug?: string;\n description?: string | null;\n defaultDurationMinutes: number;\n bufferBeforeMinutes?: number;\n bufferAfterMinutes?: number;\n minAttendees?: number;\n maxAttendees?: number | null;\n color?: string | null;\n active?: boolean;\n}\n\n// Event types\nexport interface CalendarEvent {\n id: number;\n uuid: string;\n calendarId: number;\n calendarName: string;\n eventTypeId: number;\n eventTypeName: string;\n eventTypeColor: string | null;\n title: string;\n description: string | null;\n location: string | null;\n startTime: string;\n endTime: string;\n status: CalendarEventStatus;\n creatorMemberId: number | null;\n creatorAssistantId: number | null;\n workflowId: number | null;\n taskId: number | null;\n assignmentId: number | null;\n chatId: number | null;\n messageId: number | null;\n cancelledAt: string | null;\n cancelledByMemberId: number | null;\n cancellationReason: string | null;\n recurrenceRule: string | null;\n recurringEventId: string | null;\n isRecurringInstance: boolean;\n originalStartTime: string | null;\n remoteEventId: string | null;\n attendees: CalendarEventAttendee[];\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CalendarEventFormData {\n calendarId: number;\n eventTypeId: number;\n title: string;\n description?: string | null;\n location?: string | null;\n startTime: string;\n attendeeIds: number[];\n workflowId?: number | null;\n taskId?: number | null;\n assignmentId?: number | null;\n}\n\nexport enum CalendarEventStatus {\n TENTATIVE = 'TENTATIVE',\n CONFIRMED = 'CONFIRMED',\n CANCELLED = 'CANCELLED',\n NO_SHOW = 'NO_SHOW',\n COMPLETED = 'COMPLETED',\n}\n\nexport interface CalendarEventAttendee {\n id: number;\n memberId: number;\n status: AttendeeStatus;\n responseStatus: AttendeeResponseStatus;\n responseAt: string | null;\n note: string | null;\n}\n\nexport enum AttendeeStatus {\n REQUIRED = 'REQUIRED',\n OPTIONAL = 'OPTIONAL',\n}\n\nexport enum AttendeeResponseStatus {\n PENDING = 'PENDING',\n ACCEPTED = 'ACCEPTED',\n DECLINED = 'DECLINED',\n TENTATIVE = 'TENTATIVE',\n}\n\n// iCal Feed Types\nexport interface ICalFeedTokenResponse {\n feedUrl: string;\n tokenGeneratedAt: string; // ISO 8601 datetime\n calendarId: number;\n calendarUuid: string;\n}\n\nexport interface ICalFeedUrlResponse {\n feedUrl: string | null;\n hasToken: boolean;\n tokenGeneratedAt: string | null; // ISO 8601 datetime\n}\n\nexport interface UpdateAttendeeRequest {\n responseStatus: AttendeeResponseStatus;\n note?: string | null;\n}\n\n// Availability types\nexport interface AvailabilityCheck {\n eventTypeId: number;\n startTime: string;\n endTime?: string | null;\n}\n\nexport interface AvailabilityResponse {\n available: boolean;\n reason?: string | null;\n}\n\nexport interface AvailableSlotsRequest {\n eventTypeId: number;\n startDate: string;\n endDate: string;\n slotIntervalMinutes?: number;\n}\n\nexport interface AvailableSlotsResponse {\n slots: string[];\n eventTypeId: number;\n calendarId: number;\n}\n\n// Query params\nexport interface CalendarEventsQueryParams {\n calendarId?: number;\n startDate?: string;\n endDate?: string;\n status?: CalendarEventStatus;\n memberId?: number;\n limit?: number;\n offset?: number;\n}\n\n// Google Calendar Integration Types\nexport interface GoogleCalendarInfo {\n id: string;\n summary: string;\n description?: string;\n timeZone: string;\n backgroundColor?: string;\n accessRole: string;\n primary: boolean;\n}\n\nexport interface GoogleCalendarStatusResponse {\n connected: boolean;\n email?: string;\n calendars: GoogleCalendarInfo[];\n insufficientScopes?: boolean;\n}\n\nexport interface GoogleCalendarInsufficientScopesResponse {\n connected: boolean;\n insufficientScopes: true;\n email?: string;\n reAuthUrl: string;\n}\n\nexport interface LinkCalendarRequest {\n googleCalendarId: string;\n}\n\nexport interface LinkCalendarResponse {\n status: string;\n message: string;\n googleCalendarId: string;\n googleCalendarName?: string;\n}\n\nexport interface UnlinkCalendarResponse {\n status: string;\n message: string;\n}\n\nexport interface SyncCalendarResponse {\n status: string;\n message: string;\n created: number;\n updated: number;\n errors: Array<{ event_id: string; error: string }>;\n}\n"],"mappings":";AAQO,IAAK,gBAAL,kBAAKA,mBAAL;AACJA,iBAAA,MAAA,IAAO;AACPA,iBAAA,OAAA,IAAQ;AACRA,iBAAA,OAAA,IAAQ;AACRA,iBAAA,MAAA,IAAO;AACPA,iBAAA,UAAA,IAAW;AACXA,iBAAA,QAAA,IAAS;AACTA,iBAAA,MAAA,IAAO;AACPA,iBAAA,UAAA,IAAW;AACXA,iBAAA,aAAA,IAAc;AACdA,iBAAA,aAAA,IAAc;AACdA,iBAAA,SAAA,IAAU;AACVA,iBAAA,SAAA,IAAU;AACVA,iBAAA,OAAA,IAAQ;AACRA,iBAAA,QAAA,IAAS;AACTA,iBAAA,UAAA,IAAW;AAfF,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AAkBL,IAAK,cAAL,kBAAKC,iBAAL;AACJA,eAAA,MAAA,IAAO;AACPA,eAAA,SAAA,IAAU;AACVA,eAAA,UAAA,IAAW;AACXA,eAAA,UAAA,IAAW;AACXA,eAAA,OAAA,IAAQ;AACRA,eAAA,OAAA,IAAQ;AANC,SAAAA;AAAA,GAAA,eAAA,CAAA,CAAA;ACrBL,IAAK,yBAAL,kBAAKC,4BAAL;AACJA,0BAAA,MAAA,IAAO;AACPA,0BAAA,WAAA,IAAY;AACZA,0BAAA,MAAA,IAAO;AACPA,0BAAA,OAAA,IAAQ;AACRA,0BAAA,OAAA,IAAQ;AALC,SAAAA;AAAA,GAAA,0BAAA,CAAA,CAAA;AAQL,IAAK,iBAAL,kBAAKC,oBAAL;AACJA,kBAAA,UAAA,IAAW;AACXA,kBAAA,QAAA,IAAS;AACTA,kBAAA,SAAA,IAAU;AAHD,SAAAA;AAAA,GAAA,kBAAA,CAAA,CAAA;AAwEL,IAAK,6BAAL,kBAAKC,gCAAL;AACJA,8BAAA,MAAA,IAAO;AACPA,8BAAA,OAAA,IAAQ;AACRA,8BAAA,QAAA,IAAS;AACTA,8BAAA,SAAA,IAAU;AACVA,8BAAA,QAAA,IAAS;AALA,SAAAA;AAAA,GAAA,8BAAA,CAAA,CAAA;AAQL,IAAK,mCAAL,kBAAKC,sCAAL;AACJA,oCAAA,WAAA,IAAY;AACZA,oCAAA,aAAA,IAAc;AAFL,SAAAA;AAAA,GAAA,oCAAA,CAAA,CAAA;AAqFL,IAAK,sBAAL,kBAAKC,yBAAL;AACJA,uBAAA,WAAA,IAAY;AACZA,uBAAA,WAAA,IAAY;AACZA,uBAAA,WAAA,IAAY;AACZA,uBAAA,SAAA,IAAU;AACVA,uBAAA,WAAA,IAAY;AALH,SAAAA;AAAA,GAAA,uBAAA,CAAA,CAAA;AAiBL,IAAK,iBAAL,kBAAKC,oBAAL;AACJA,kBAAA,UAAA,IAAW;AACXA,kBAAA,UAAA,IAAW;AAFF,SAAAA;AAAA,GAAA,kBAAA,CAAA,CAAA;AAKL,IAAK,yBAAL,kBAAKC,4BAAL;AACJA,0BAAA,SAAA,IAAU;AACVA,0BAAA,UAAA,IAAW;AACXA,0BAAA,UAAA,IAAW;AACXA,0BAAA,WAAA,IAAY;AAJH,SAAAA;AAAA,GAAA,0BAAA,CAAA,CAAA;","names":["DataFieldType","IndexStatus","CalendarPermissionType","CalendarSource","CalendarScheduleRecurrence","CalendarScheduleAvailabilityType","CalendarEventStatus","AttendeeStatus","AttendeeResponseStatus"]}