@qikdev/mcp 6.6.6 → 6.6.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.
@@ -0,0 +1,1200 @@
1
+ /**
2
+ * Qik API Documentation Integration
3
+ *
4
+ * This module provides comprehensive documentation understanding capabilities
5
+ * for the Qik MCP server, integrating the full API documentation to provide
6
+ * context-aware help, examples, and troubleshooting assistance.
7
+ */
8
+ /**
9
+ * Comprehensive Qik API Documentation
10
+ * Based on the full API documentation PDF
11
+ */
12
+ export const QIK_DOCUMENTATION = {
13
+ authentication: {
14
+ tokenTypes: {
15
+ user: {
16
+ description: "User access tokens are granted when users log in to the platform admin console at https://app.qik.dev. Typically reserved for administration staff, developers or team members.",
17
+ prefix: "ey",
18
+ useCase: "Administrative access, platform management, content creation by staff",
19
+ example: "eyJhbGciOiJIUzI1NiIsIn..."
20
+ },
21
+ persona: {
22
+ description: "Persona access tokens are generated when customers log in to your applications. Branded with your custom domain and business name.",
23
+ prefix: "pa-",
24
+ useCase: "Customer-facing applications, branded experiences, user-specific content",
25
+ example: "pa-123524316234735478345843584358"
26
+ },
27
+ application: {
28
+ description: "Application access tokens are static tokens for every application you create. Useful for public websites or backend integrations.",
29
+ prefix: "at-",
30
+ useCase: "Public websites, search engine indexing, backend integrations, static content",
31
+ example: "at-9x7OK8sT5..."
32
+ }
33
+ },
34
+ methods: {
35
+ bearer: {
36
+ description: "Include the token in the Authorization header using Bearer authentication",
37
+ example: "Authorization: Bearer eyJsadh432kndsfgi45..."
38
+ },
39
+ queryString: {
40
+ description: "Include the token as a URL query parameter",
41
+ example: "https://api.qik.dev/user?access_token=eyJsadh432kndsfgi45..."
42
+ }
43
+ },
44
+ errorCodes: {
45
+ "401": {
46
+ description: "Unauthorized - The request was made without an access token or with an expired/invalid access token",
47
+ commonCauses: [
48
+ "Missing access token",
49
+ "Expired access token",
50
+ "Invalid token format",
51
+ "Token not properly formatted in header"
52
+ ],
53
+ solutions: [
54
+ "Check that QIK_ACCESS_TOKEN environment variable is set",
55
+ "Verify token is not expired",
56
+ "Ensure Bearer prefix is included in Authorization header",
57
+ "Refresh token if using user/persona tokens"
58
+ ]
59
+ },
60
+ "403": {
61
+ description: "Access Denied - The user does not have permission to make the request",
62
+ commonCauses: [
63
+ "Insufficient permissions for the operation",
64
+ "Trying to access content outside permitted scopes",
65
+ "Application token lacks required permissions"
66
+ ],
67
+ solutions: [
68
+ "Check user/application permissions",
69
+ "Verify scope access rights",
70
+ "Contact administrator to grant required permissions",
71
+ "Use a token with appropriate access level"
72
+ ]
73
+ },
74
+ "429": {
75
+ description: "Too many requests - You have exceeded the allowed rate limit",
76
+ commonCauses: [
77
+ "Making requests too quickly",
78
+ "Bulk operations without rate limiting",
79
+ "Multiple concurrent requests"
80
+ ],
81
+ solutions: [
82
+ "Implement exponential backoff",
83
+ "Add delays between requests",
84
+ "Use batch operations where available",
85
+ "Monitor request frequency"
86
+ ]
87
+ }
88
+ }
89
+ },
90
+ endpoints: {
91
+ "/content/:type/create": {
92
+ method: "POST",
93
+ description: "Create new content items of a specified type. Supports file uploads for media content types.",
94
+ parameters: {
95
+ "type": {
96
+ type: "string",
97
+ required: true,
98
+ description: "The key of the content type to create (e.g., 'car', 'blogPost', 'article')",
99
+ example: "article"
100
+ },
101
+ "title": {
102
+ type: "string",
103
+ required: true,
104
+ description: "The title of the content item",
105
+ example: "My New Article"
106
+ },
107
+ "meta": {
108
+ type: "object",
109
+ required: true,
110
+ description: "Meta information including scopes (required)",
111
+ example: { scopes: ["62b59cb573fb4772e7b5fa93"] }
112
+ },
113
+ "data": {
114
+ type: "object",
115
+ required: false,
116
+ description: "Custom field data based on content type definition",
117
+ example: { make: "Toyota", model: "Camry" }
118
+ }
119
+ },
120
+ examples: [
121
+ {
122
+ request: {
123
+ title: "Pathfinder",
124
+ meta: { scopes: ["62b59cb573fb4772e7b5fa93"] },
125
+ data: { make: "Nissan", style: "Ti" }
126
+ },
127
+ response: {
128
+ _id: "62cf66e161ad86b0095ca407",
129
+ title: "Pathfinder",
130
+ meta: {
131
+ created: "2023-07-14T00:44:17.764Z",
132
+ type: "article",
133
+ slug: "pathfinder",
134
+ status: "active"
135
+ },
136
+ data: { make: "Nissan", style: "Ti" }
137
+ },
138
+ description: "Creating a basic content item with custom fields"
139
+ },
140
+ {
141
+ request: {
142
+ title: "Awesome Photo",
143
+ meta: { scopes: ["62b59cb573fb4772e7b5fa93"] },
144
+ mediaIntegrationType: "upload",
145
+ file: {
146
+ url: "https://publicimages.com/landscape.jpg",
147
+ name: "Landscape.jpg"
148
+ },
149
+ data: { caption: "What a lovely landscape" }
150
+ },
151
+ response: {
152
+ _id: "62cf66e161ad86b0095ca408",
153
+ title: "Awesome Photo",
154
+ mediaIntegrationType: "upload",
155
+ fileName: "Landscape.jpg"
156
+ },
157
+ description: "Creating an image by providing external URL for upload"
158
+ }
159
+ ],
160
+ commonErrors: [
161
+ "Missing required 'scopes' in meta object",
162
+ "Invalid content type key",
163
+ "Field placement errors (root vs data object)",
164
+ "Insufficient permissions for the specified scopes"
165
+ ],
166
+ relatedEndpoints: [
167
+ "/content/:type/list",
168
+ "/content/:id",
169
+ "/content/:type/definition"
170
+ ]
171
+ },
172
+ "/content/:type/list": {
173
+ method: "POST",
174
+ description: "Retrieve multiple content items with advanced filtering, sorting, and pagination",
175
+ parameters: {
176
+ "type": {
177
+ type: "string",
178
+ required: true,
179
+ description: "Content type to list",
180
+ example: "profile"
181
+ },
182
+ "search": {
183
+ type: "string",
184
+ required: false,
185
+ description: "Keywords to search within title, tags, and text areas",
186
+ example: "john smith"
187
+ },
188
+ "filter": {
189
+ type: "object",
190
+ required: false,
191
+ description: "Advanced filter criteria with 40+ comparators",
192
+ example: {
193
+ operator: "and",
194
+ filters: [
195
+ { key: "firstName", comparator: "startswith", value: "John" }
196
+ ]
197
+ }
198
+ },
199
+ "sort": {
200
+ type: "object",
201
+ required: false,
202
+ description: "Sorting configuration",
203
+ example: { key: "meta.created", direction: "desc", type: "date" }
204
+ },
205
+ "page": {
206
+ type: "object",
207
+ required: false,
208
+ description: "Pagination settings",
209
+ example: { size: 20, index: 1 }
210
+ }
211
+ },
212
+ examples: [
213
+ {
214
+ request: {
215
+ sort: { direction: "asc", type: "string", key: "title" },
216
+ search: "",
217
+ select: ["title", "data.make"],
218
+ page: { size: 50, index: 1 },
219
+ filter: {
220
+ operator: "and",
221
+ filters: [{
222
+ operator: "and",
223
+ filters: [
224
+ { key: "data.make", comparator: "in", values: ["Toyota", "Nissan"] },
225
+ { key: "title", comparator: "contains", value: "ra" }
226
+ ]
227
+ }]
228
+ }
229
+ },
230
+ response: {
231
+ items: [
232
+ { _id: "62b5a0316143c2335f858ea8", title: "Prado", data: { make: "Toyota" } },
233
+ { _id: "62b5a0af6143c2335f85905f", title: "Navara", data: { make: "Nissan" } }
234
+ ],
235
+ total: 2,
236
+ page: { index: 1, total: 1 }
237
+ },
238
+ description: "Complex filtering with multiple conditions and field selection"
239
+ }
240
+ ],
241
+ commonErrors: [
242
+ "Invalid filter syntax",
243
+ "Unknown comparator in filter",
244
+ "Invalid content type",
245
+ "Page size exceeds maximum (100)"
246
+ ],
247
+ relatedEndpoints: [
248
+ "/content/:type/create",
249
+ "/content/:id",
250
+ "/glossary"
251
+ ]
252
+ }
253
+ },
254
+ contentTypes: {
255
+ "profile": {
256
+ description: "Represents a human person's details including contact information, demographics, and custom fields",
257
+ useCase: "Managing people in your organization - customers, employees, students, members, etc.",
258
+ fieldStructure: {
259
+ rootLevel: ["firstName", "lastName", "emails", "phoneNumbers", "gender", "dob*", "addresses", "meta"],
260
+ dataObject: ["customField1", "customField2", "additionalInfo"]
261
+ },
262
+ examples: {
263
+ creation: {
264
+ firstName: "John",
265
+ lastName: "Smith",
266
+ emails: ["john@example.com"],
267
+ phoneNumbers: [{ label: "Mobile", countryCode: "AU", number: "0412345678" }],
268
+ meta: { scopes: ["scope-id-here"] },
269
+ data: { department: "Engineering", startDate: "2024-01-15" }
270
+ },
271
+ update: {
272
+ emails: ["john.smith@newcompany.com"],
273
+ data: { department: "Product", role: "Senior Engineer" }
274
+ },
275
+ query: {
276
+ filter: {
277
+ operator: "and",
278
+ filters: [
279
+ { key: "firstName", comparator: "startswith", value: "John" },
280
+ { key: "data.department", comparator: "equal", value: "Engineering" }
281
+ ]
282
+ }
283
+ }
284
+ },
285
+ commonPatterns: [
286
+ "Use anniversarynext/anniversarypast for birthday queries",
287
+ "Search by name using 'contains' or 'startswith' comparators",
288
+ "Filter by custom fields using 'data.fieldName' notation",
289
+ "Use 'in' comparator for multiple email addresses"
290
+ ],
291
+ troubleshooting: [
292
+ "If profile creation fails, check that firstName and lastName are provided",
293
+ "Email validation errors - ensure valid email format",
294
+ "Phone number format - use separate countryCode and number fields",
295
+ "Custom fields must go in 'data' object, not at root level"
296
+ ]
297
+ },
298
+ "article": {
299
+ description: "Text-based content for blogs, knowledge bases, and other content-driven applications",
300
+ useCase: "Creating blog posts, documentation, news articles, knowledge base entries",
301
+ fieldStructure: {
302
+ rootLevel: ["title", "body", "meta"],
303
+ dataObject: ["category", "author", "tags", "customFields"]
304
+ },
305
+ examples: {
306
+ creation: {
307
+ title: "Getting Started with Qik",
308
+ body: "<p>Welcome to Qik platform...</p>",
309
+ meta: { scopes: ["public-scope"], security: "public" },
310
+ data: { category: "Tutorial", estimatedReadTime: 5 }
311
+ },
312
+ update: {
313
+ body: "<p>Updated content...</p>",
314
+ data: { category: "Advanced Tutorial", lastReviewed: "2024-01-15" }
315
+ },
316
+ query: {
317
+ search: "getting started",
318
+ filter: {
319
+ operator: "and",
320
+ filters: [
321
+ { key: "data.category", comparator: "equal", value: "Tutorial" },
322
+ { key: "meta.created", comparator: "datepast", value: 30, value2: "days" }
323
+ ]
324
+ }
325
+ }
326
+ },
327
+ commonPatterns: [
328
+ "Use 'body' field for main content (HTML supported)",
329
+ "Search across title and body content with search parameter",
330
+ "Filter by publication date using date comparators",
331
+ "Use security levels: public, secure, private"
332
+ ],
333
+ troubleshooting: [
334
+ "Body content should be at root level, not in data object",
335
+ "HTML content should be properly escaped",
336
+ "Large content may hit size limits - consider file attachments",
337
+ "Search indexing may take time for new articles"
338
+ ]
339
+ },
340
+ "event": {
341
+ description: "Represents events, meetings, or periods of time with start/end dates and attendee management",
342
+ useCase: "Managing calendar events, meetings, conferences, classes, appointments",
343
+ fieldStructure: {
344
+ rootLevel: ["title", "startDate", "endDate", "allDay", "timezone", "body", "meta"],
345
+ dataObject: ["location", "capacity", "registrationRequired", "customEventFields"]
346
+ },
347
+ examples: {
348
+ creation: {
349
+ title: "Team Meeting",
350
+ startDate: "2024-03-15T14:00:00Z",
351
+ endDate: "2024-03-15T15:00:00Z",
352
+ timezone: "Australia/Sydney",
353
+ body: "Weekly team sync meeting",
354
+ meta: { scopes: ["team-scope"] },
355
+ data: { location: "Conference Room A", capacity: 10 }
356
+ },
357
+ update: {
358
+ startDate: "2024-03-15T14:30:00Z",
359
+ data: { location: "Conference Room B", capacity: 15 }
360
+ },
361
+ query: {
362
+ filter: {
363
+ operator: "and",
364
+ filters: [
365
+ { key: "startDate", comparator: "datenext", value: 7, value2: "days" },
366
+ { key: "data.location", comparator: "contains", value: "Conference" }
367
+ ]
368
+ }
369
+ }
370
+ },
371
+ commonPatterns: [
372
+ "Use ISO 8601 format for dates",
373
+ "Filter upcoming events with 'datenext' comparator",
374
+ "Use 'datebetween' for date range queries",
375
+ "Set timezone for proper date handling"
376
+ ],
377
+ troubleshooting: [
378
+ "Date format must be ISO 8601 (YYYY-MM-DDTHH:mm:ssZ)",
379
+ "Timezone handling - ensure consistent timezone usage",
380
+ "All-day events should set allDay: true and omit times",
381
+ "End date must be after start date"
382
+ ]
383
+ }
384
+ },
385
+ filterSyntax: {
386
+ operators: {
387
+ "and": {
388
+ description: "All filters must match (logical AND)",
389
+ examples: [
390
+ {
391
+ operator: "and",
392
+ filters: [
393
+ { key: "firstName", comparator: "equal", value: "John" },
394
+ { key: "lastName", comparator: "equal", value: "Smith" }
395
+ ]
396
+ }
397
+ ],
398
+ commonUse: "Combining multiple conditions that all must be true"
399
+ },
400
+ "or": {
401
+ description: "Any filter can match (logical OR)",
402
+ examples: [
403
+ {
404
+ operator: "or",
405
+ filters: [
406
+ { key: "firstName", comparator: "equal", value: "John" },
407
+ { key: "firstName", comparator: "equal", value: "Jane" }
408
+ ]
409
+ }
410
+ ],
411
+ commonUse: "Finding items that match any of several conditions"
412
+ },
413
+ "nor": {
414
+ description: "None of the filters can match (logical NOR)",
415
+ examples: [
416
+ {
417
+ operator: "nor",
418
+ filters: [
419
+ { key: "status", comparator: "equal", value: "deleted" },
420
+ { key: "status", comparator: "equal", value: "archived" }
421
+ ]
422
+ }
423
+ ],
424
+ commonUse: "Excluding items that match certain conditions"
425
+ }
426
+ },
427
+ comparators: {
428
+ "equal": {
429
+ description: "Field value equals the specified value (case insensitive for strings)",
430
+ valueTypes: ["string", "number", "boolean"],
431
+ examples: [
432
+ { key: "firstName", comparator: "equal", value: "John" },
433
+ { key: "age", comparator: "equal", value: 25 },
434
+ { key: "active", comparator: "equal", value: true }
435
+ ],
436
+ relatedComparators: ["notequal", "in", "notin"]
437
+ },
438
+ "contains": {
439
+ description: "String field contains the specified substring (case insensitive)",
440
+ valueTypes: ["string"],
441
+ examples: [
442
+ { key: "title", comparator: "contains", value: "meeting" },
443
+ { key: "description", comparator: "contains", value: "urgent" }
444
+ ],
445
+ relatedComparators: ["excludes", "startswith", "endswith"]
446
+ },
447
+ "anniversarynext": {
448
+ description: "Find dates that have their anniversary in the next specified duration",
449
+ valueTypes: ["number", "string"],
450
+ examples: [
451
+ { key: "dob", comparator: "anniversarynext", value: 10, value2: "days" },
452
+ { key: "startDate", comparator: "anniversarynext", value: 1, value2: "months" }
453
+ ],
454
+ relatedComparators: ["anniversarypast", "anniversarybetween", "dateanniversary"]
455
+ },
456
+ "datepast": {
457
+ description: "Find dates that are in the last specified duration from now",
458
+ valueTypes: ["number", "string"],
459
+ examples: [
460
+ { key: "meta.created", comparator: "datepast", value: 30, value2: "days" },
461
+ { key: "lastLogin", comparator: "datepast", value: 1, value2: "weeks" }
462
+ ],
463
+ relatedComparators: ["datenext", "datebetween", "datebeforenow"]
464
+ },
465
+ "in": {
466
+ description: "Field value is in the specified array of values",
467
+ valueTypes: ["array"],
468
+ examples: [
469
+ { key: "status", comparator: "in", values: ["active", "pending", "approved"] },
470
+ { key: "department", comparator: "in", values: ["Engineering", "Product"] }
471
+ ],
472
+ relatedComparators: ["notin", "equal", "notequal"]
473
+ }
474
+ },
475
+ patterns: {
476
+ "birthday_queries": {
477
+ description: "Find people with birthdays in a specific timeframe",
478
+ example: {
479
+ operator: "and",
480
+ filters: [{
481
+ key: "dob",
482
+ comparator: "anniversarynext",
483
+ value: 7,
484
+ value2: "days"
485
+ }]
486
+ },
487
+ useCase: "Birthday reminders, celebration planning"
488
+ },
489
+ "recent_content": {
490
+ description: "Find content created or updated recently",
491
+ example: {
492
+ operator: "and",
493
+ filters: [{
494
+ key: "meta.updated",
495
+ comparator: "datepast",
496
+ value: 30,
497
+ value2: "days"
498
+ }]
499
+ },
500
+ useCase: "Activity feeds, recent changes reports"
501
+ },
502
+ "complex_profile_search": {
503
+ description: "Multi-criteria profile search with OR logic",
504
+ example: {
505
+ operator: "or",
506
+ filters: [
507
+ { key: "firstName", comparator: "startswith", value: "John" },
508
+ { key: "lastName", comparator: "contains", value: "Smith" },
509
+ { key: "emails", comparator: "contains", value: "john" }
510
+ ]
511
+ },
512
+ useCase: "Flexible people search across multiple fields"
513
+ }
514
+ }
515
+ },
516
+ widgetTypes: {
517
+ "dateobject": {
518
+ description: "A complex date/time widget that stores date and time components as separate fields in an object structure. Used for precise date/time input where individual components need to be accessible.",
519
+ expectedInput: {
520
+ hour: "number (0-23)",
521
+ minute: "number (0-59)",
522
+ day: "number (1-31)",
523
+ month: "number (1-12)",
524
+ year: "number (full year, e.g., 2025)"
525
+ },
526
+ examples: [
527
+ {
528
+ description: "Event start time - January 15, 2025 at 1:30 PM",
529
+ value: { hour: 13, minute: 30, day: 15, month: 1, year: 2025 }
530
+ },
531
+ {
532
+ description: "Meeting end time - March 22, 2024 at 9:45 AM",
533
+ value: { hour: 9, minute: 45, day: 22, month: 3, year: 2024 }
534
+ },
535
+ {
536
+ description: "All-day event (midnight start)",
537
+ value: { hour: 0, minute: 0, day: 10, month: 6, year: 2024 }
538
+ },
539
+ {
540
+ description: "Late evening event - 11:59 PM",
541
+ value: { hour: 23, minute: 59, day: 31, month: 12, year: 2024 }
542
+ }
543
+ ],
544
+ validation: [
545
+ "hour must be integer between 0-23 (24-hour format)",
546
+ "minute must be integer between 0-59",
547
+ "day must be integer between 1-31 (validated against month/year)",
548
+ "month must be integer between 1-12 (January=1, December=12)",
549
+ "year must be a 4-digit integer (e.g., 2024, 2025)",
550
+ "Date combination must be valid (e.g., no February 30th)",
551
+ "All fields are required - partial dates not supported"
552
+ ],
553
+ commonErrors: [
554
+ "Using 12-hour format instead of 24-hour (use 13 for 1 PM, not 1)",
555
+ "Using 0-based months instead of 1-based (January is 1, not 0)",
556
+ "Providing string values instead of numbers",
557
+ "Missing required fields (all 5 fields must be present)",
558
+ "Invalid date combinations (e.g., February 30, April 31)",
559
+ "Using minute values > 59 or hour values > 23",
560
+ "Providing ISO date strings instead of object structure"
561
+ ],
562
+ relatedWidgets: [
563
+ "date",
564
+ "time",
565
+ "datetime",
566
+ "timestamp"
567
+ ]
568
+ },
569
+ "date": {
570
+ description: "Simple date widget for date-only input without time components",
571
+ expectedInput: "ISO 8601 date string (YYYY-MM-DD)",
572
+ examples: [
573
+ { description: "Birthday", value: "1990-05-15" },
574
+ { description: "Event date", value: "2024-12-25" }
575
+ ],
576
+ validation: [
577
+ "Must be valid ISO 8601 date format (YYYY-MM-DD)",
578
+ "Date must be valid calendar date"
579
+ ],
580
+ commonErrors: [
581
+ "Using MM/DD/YYYY or DD/MM/YYYY format instead of ISO",
582
+ "Including time components in date-only field"
583
+ ],
584
+ relatedWidgets: ["dateobject", "datetime", "timestamp"]
585
+ },
586
+ "time": {
587
+ description: "Time-only widget for time input without date components",
588
+ expectedInput: "Time string in HH:MM format (24-hour)",
589
+ examples: [
590
+ { description: "Morning meeting", value: "09:30" },
591
+ { description: "Afternoon deadline", value: "15:45" }
592
+ ],
593
+ validation: [
594
+ "Must be in HH:MM format using 24-hour time",
595
+ "Hours must be 00-23, minutes must be 00-59"
596
+ ],
597
+ commonErrors: [
598
+ "Using 12-hour format with AM/PM",
599
+ "Single digit hours/minutes without leading zero"
600
+ ],
601
+ relatedWidgets: ["dateobject", "datetime"]
602
+ },
603
+ "datetime": {
604
+ description: "Combined date and time widget using ISO 8601 datetime format",
605
+ expectedInput: "ISO 8601 datetime string (YYYY-MM-DDTHH:MM:SSZ)",
606
+ examples: [
607
+ { description: "Event start", value: "2024-03-15T14:30:00Z" },
608
+ { description: "Deadline", value: "2024-12-31T23:59:59Z" }
609
+ ],
610
+ validation: [
611
+ "Must be valid ISO 8601 datetime format",
612
+ "Should include timezone (Z for UTC or offset like +10:00)"
613
+ ],
614
+ commonErrors: [
615
+ "Missing T separator between date and time",
616
+ "Missing timezone information",
617
+ "Using local time format instead of ISO 8601"
618
+ ],
619
+ relatedWidgets: ["dateobject", "date", "time", "timestamp"]
620
+ }
621
+ },
622
+ concepts: {
623
+ "field_placement": {
624
+ title: "Field Placement Rules",
625
+ description: "Understanding where fields go in the JSON payload - root level vs data object",
626
+ keyPoints: [
627
+ "Fields defined in glossary 'fields' array go at ROOT LEVEL",
628
+ "Fields defined in glossary 'definedFields' array go in DATA OBJECT",
629
+ "Standard fields (title, meta, reference, body) always go at root level",
630
+ "Custom content-specific fields typically go in data object"
631
+ ],
632
+ examples: [
633
+ {
634
+ description: "Correct field placement for a custom car content type",
635
+ correct: {
636
+ type: "car",
637
+ title: "My Car",
638
+ meta: { scopes: ["scope-id"] },
639
+ data: { make: "Toyota", model: "Camry" }
640
+ },
641
+ incorrect: {
642
+ type: "car",
643
+ data: {
644
+ title: "My Car",
645
+ make: "Toyota",
646
+ model: "Camry"
647
+ }
648
+ }
649
+ }
650
+ ],
651
+ relatedConcepts: ["content_types", "glossary_structure", "api_validation"],
652
+ commonMisunderstandings: [
653
+ "Putting title in data object instead of root level",
654
+ "Putting custom fields at root level instead of data object",
655
+ "Confusing 'fields' vs 'definedFields' in glossary"
656
+ ]
657
+ },
658
+ "widget_types": {
659
+ title: "Understanding Widget Types in Field Definitions",
660
+ description: "Widget types define how fields should be input and validated, with specific expected formats and structures",
661
+ keyPoints: [
662
+ "Widget type determines the expected input format for a field",
663
+ "dateobject widget requires object structure with hour, minute, day, month, year",
664
+ "Different widgets have different validation rules and formats",
665
+ "Widget type is specified in the glossary field definition"
666
+ ],
667
+ examples: [
668
+ {
669
+ description: "Event with dateobject start/end times",
670
+ correct: {
671
+ title: "Team Meeting",
672
+ meta: { scopes: ["team-scope"] },
673
+ data: {
674
+ start: { hour: 14, minute: 0, day: 15, month: 3, year: 2024 },
675
+ end: { hour: 15, minute: 30, day: 15, month: 3, year: 2024 }
676
+ }
677
+ },
678
+ incorrect: {
679
+ title: "Team Meeting",
680
+ meta: { scopes: ["team-scope"] },
681
+ data: {
682
+ start: "2024-03-15T14:00:00Z",
683
+ end: "2024-03-15T15:30:00Z"
684
+ }
685
+ }
686
+ }
687
+ ],
688
+ relatedConcepts: ["field_placement", "content_types", "validation"],
689
+ commonMisunderstandings: [
690
+ "Using ISO date strings for dateobject widgets",
691
+ "Not understanding widget-specific input requirements",
692
+ "Assuming all date fields use the same format"
693
+ ]
694
+ },
695
+ "scopes_and_permissions": {
696
+ title: "Scopes and Permissions System",
697
+ description: "Hierarchical permission structure that controls access to content and operations",
698
+ keyPoints: [
699
+ "Every content item must belong to at least one scope",
700
+ "Scopes are hierarchical like folders - permissions can inherit",
701
+ "Users need appropriate permissions within scopes to perform actions",
702
+ "Different token types have different permission models"
703
+ ],
704
+ examples: [
705
+ {
706
+ description: "Scope hierarchy example",
707
+ structure: {
708
+ "Organization": {
709
+ "HR Department": ["Employee Records", "Policies"],
710
+ "Engineering": ["Projects", "Documentation"],
711
+ "Public": ["Blog Posts", "Marketing"]
712
+ }
713
+ }
714
+ }
715
+ ],
716
+ relatedConcepts: ["authentication", "content_security", "user_roles"],
717
+ commonMisunderstandings: [
718
+ "Forgetting to include scopes in meta object",
719
+ "Using scope names instead of scope IDs",
720
+ "Not understanding permission inheritance"
721
+ ]
722
+ },
723
+ "workflow_system": {
724
+ title: "Workflow Definitions vs Workflow Cards",
725
+ description: "Understanding the difference between workflow templates and workflow instances",
726
+ keyPoints: [
727
+ "Workflow Definition = Template with columns, steps, automation rules",
728
+ "Workflow Card = Individual item that moves through the workflow",
729
+ "Definitions define the structure, Cards are the instances",
730
+ "One definition can have many cards moving through it"
731
+ ],
732
+ examples: [
733
+ {
734
+ description: "Student onboarding workflow",
735
+ definition: {
736
+ title: "Student Onboarding",
737
+ columns: ["Application", "Review", "Approved", "Enrolled"],
738
+ automation: "Entry/exit functions for each step"
739
+ },
740
+ cards: [
741
+ { title: "John Smith - Application", currentStep: "Review" },
742
+ { title: "Jane Doe - Application", currentStep: "Approved" }
743
+ ]
744
+ }
745
+ ],
746
+ relatedConcepts: ["content_types", "definitions_vs_instances", "automation"],
747
+ commonMisunderstandings: [
748
+ "Confusing when to create definition vs card",
749
+ "Not understanding the template/instance relationship",
750
+ "Trying to add people directly to definitions instead of creating cards"
751
+ ]
752
+ }
753
+ },
754
+ examples: {
755
+ "authentication": {
756
+ "bearer_token": {
757
+ title: "Using Bearer Token Authentication",
758
+ description: "How to properly authenticate API requests using Bearer tokens",
759
+ code: {
760
+ headers: {
761
+ "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsIn...",
762
+ "Content-Type": "application/json"
763
+ }
764
+ },
765
+ explanation: "Include the access token in the Authorization header with 'Bearer ' prefix",
766
+ variations: [
767
+ {
768
+ description: "Query string authentication",
769
+ code: "https://api.qik.dev/user?access_token=eyJhbGciOiJIUzI1NiIsIn..."
770
+ }
771
+ ]
772
+ }
773
+ },
774
+ "content_creation": {
775
+ "basic_article": {
776
+ title: "Creating a Basic Article",
777
+ description: "Simple article creation with title, body, and scopes",
778
+ code: {
779
+ type: "article",
780
+ title: "Getting Started Guide",
781
+ body: "<p>Welcome to our platform...</p>",
782
+ meta: {
783
+ scopes: ["public-content"],
784
+ security: "public"
785
+ }
786
+ },
787
+ explanation: "Articles require title and body at root level, with scopes in meta object",
788
+ variations: [
789
+ {
790
+ description: "Article with custom fields",
791
+ code: {
792
+ type: "article",
793
+ title: "Advanced Guide",
794
+ body: "<p>Advanced content...</p>",
795
+ meta: { scopes: ["public-content"] },
796
+ data: { category: "Tutorial", difficulty: "Advanced" }
797
+ }
798
+ }
799
+ ]
800
+ },
801
+ "profile_with_contacts": {
802
+ title: "Creating Profile with Contact Information",
803
+ description: "Complete profile creation including phone numbers and addresses",
804
+ code: {
805
+ firstName: "John",
806
+ lastName: "Smith",
807
+ emails: ["john@example.com", "j.smith@work.com"],
808
+ phoneNumbers: [
809
+ { label: "Mobile", countryCode: "AU", number: "0412345678" },
810
+ { label: "Work", countryCode: "AU", number: "0287654321" }
811
+ ],
812
+ addresses: [{
813
+ title: "Home",
814
+ addressLine1: "123 Main St",
815
+ suburb: "Sydney",
816
+ state: "NSW",
817
+ postalCode: "2000",
818
+ country: "Australia"
819
+ }],
820
+ meta: { scopes: ["employee-records"] }
821
+ },
822
+ explanation: "Profiles support multiple emails, phone numbers, and addresses with structured data",
823
+ variations: [
824
+ {
825
+ description: "Profile with custom fields",
826
+ code: {
827
+ firstName: "Jane",
828
+ lastName: "Doe",
829
+ emails: ["jane@example.com"],
830
+ meta: { scopes: ["employee-records"] },
831
+ data: { department: "Engineering", startDate: "2024-01-15", employeeId: "EMP001" }
832
+ }
833
+ }
834
+ ]
835
+ }
836
+ },
837
+ "filtering": {
838
+ "birthday_search": {
839
+ title: "Finding Upcoming Birthdays",
840
+ description: "Search for people with birthdays in the next 10 days",
841
+ code: {
842
+ type: "profile",
843
+ filter: {
844
+ operator: "and",
845
+ filters: [{
846
+ key: "dob",
847
+ comparator: "anniversarynext",
848
+ value: 10,
849
+ value2: "days"
850
+ }]
851
+ },
852
+ sort: { key: "dob", direction: "asc", type: "date" }
853
+ },
854
+ explanation: "Use 'anniversarynext' comparator to find anniversary dates in the future",
855
+ variations: [
856
+ {
857
+ description: "Birthdays this month",
858
+ code: {
859
+ filter: {
860
+ operator: "and",
861
+ filters: [{ key: "dobMonth", comparator: "equal", value: 3 }]
862
+ }
863
+ }
864
+ }
865
+ ]
866
+ },
867
+ "complex_content_search": {
868
+ title: "Multi-Criteria Content Search",
869
+ description: "Search articles by category, date range, and author",
870
+ code: {
871
+ type: "article",
872
+ search: "tutorial",
873
+ filter: {
874
+ operator: "and",
875
+ filters: [
876
+ { key: "data.category", comparator: "in", values: ["Tutorial", "Guide"] },
877
+ { key: "meta.created", comparator: "datepast", value: 90, value2: "days" },
878
+ { key: "data.author", comparator: "startswith", value: "John" }
879
+ ]
880
+ },
881
+ sort: { key: "meta.created", direction: "desc", type: "date" }
882
+ },
883
+ explanation: "Combine search terms with complex filters for precise content discovery",
884
+ variations: [
885
+ {
886
+ description: "OR logic for flexible matching",
887
+ code: {
888
+ filter: {
889
+ operator: "or",
890
+ filters: [
891
+ { key: "data.category", comparator: "equal", value: "Tutorial" },
892
+ { key: "title", comparator: "contains", value: "guide" }
893
+ ]
894
+ }
895
+ }
896
+ }
897
+ ]
898
+ }
899
+ }
900
+ },
901
+ troubleshooting: {
902
+ "field_placement_errors": {
903
+ symptoms: [
904
+ "Error: Field 'X' is defined in glossary 'fields' array and must be at ROOT LEVEL",
905
+ "Error: Field 'Y' is defined in glossary 'definedFields' array and must be in DATA OBJECT",
906
+ "Validation failed: incorrect field placement",
907
+ "Content creation rejected due to field structure"
908
+ ],
909
+ causes: [
910
+ "Putting glossary 'fields' in data object instead of root level",
911
+ "Putting glossary 'definedFields' at root level instead of data object",
912
+ "Misunderstanding the difference between fields and definedFields",
913
+ "Not checking content type definition before creating content"
914
+ ],
915
+ solutions: [
916
+ "Check content type definition using qik_get_content_definition",
917
+ "Move 'fields' array items to root level of payload",
918
+ "Move 'definedFields' array items to data object",
919
+ "Use qik_create_content_intelligent for automatic field placement"
920
+ ],
921
+ prevention: [
922
+ "Always review content type definition before creating content",
923
+ "Use the intelligent creation tool when unsure about field placement",
924
+ "Create documentation for custom content types",
925
+ "Test with simple examples before complex implementations"
926
+ ],
927
+ relatedIssues: ["validation_errors", "content_creation_failures", "api_rejection"]
928
+ },
929
+ "authentication_failures": {
930
+ symptoms: [
931
+ "401 Unauthorized responses",
932
+ "403 Access Denied errors",
933
+ "Token validation failed messages",
934
+ "Unable to access content or perform operations"
935
+ ],
936
+ causes: [
937
+ "Missing or expired access token",
938
+ "Incorrect token format in Authorization header",
939
+ "Using wrong token type for the operation",
940
+ "Insufficient permissions for the requested scope"
941
+ ],
942
+ solutions: [
943
+ "Verify QIK_ACCESS_TOKEN environment variable is set",
944
+ "Check token expiration and refresh if needed",
945
+ "Ensure Bearer prefix in Authorization header",
946
+ "Use appropriate token type (user/persona/application)",
947
+ "Contact administrator for permission grants"
948
+ ],
949
+ prevention: [
950
+ "Implement token refresh logic for user/persona tokens",
951
+ "Monitor token expiration times",
952
+ "Use application tokens for static/public content",
953
+ "Regularly audit user permissions"
954
+ ],
955
+ relatedIssues: ["permission_errors", "scope_access_denied", "token_expiration"]
956
+ },
957
+ "filter_syntax_errors": {
958
+ symptoms: [
959
+ "Invalid filter syntax error messages",
960
+ "Unknown comparator errors",
961
+ "Filter validation failed",
962
+ "Unexpected query results or empty results"
963
+ ],
964
+ causes: [
965
+ "Using unsupported comparator names",
966
+ "Incorrect value types for comparators",
967
+ "Missing required value2 parameter for range comparators",
968
+ "Malformed nested filter structure"
969
+ ],
970
+ solutions: [
971
+ "Check comparator spelling and supported list",
972
+ "Verify value types match comparator requirements",
973
+ "Add value2 for range comparators (between, anniversarynext, etc.)",
974
+ "Validate nested filter structure with proper operators",
975
+ "Test filters with simple examples first"
976
+ ],
977
+ prevention: [
978
+ "Use filter builder tools or templates",
979
+ "Reference documentation for comparator requirements",
980
+ "Start with simple filters and build complexity gradually",
981
+ "Test filters in isolation before combining"
982
+ ],
983
+ relatedIssues: ["query_performance", "unexpected_results", "data_type_mismatches"]
984
+ },
985
+ "scope_permission_issues": {
986
+ symptoms: [
987
+ "403 Access Denied when creating content",
988
+ "Empty results when listing content",
989
+ "Unable to access specific content items",
990
+ "Permission denied for scope operations"
991
+ ],
992
+ causes: [
993
+ "User lacks permissions for specified scopes",
994
+ "Using scope names instead of scope IDs",
995
+ "Scopes not properly assigned to content",
996
+ "Token type doesn't have required scope access"
997
+ ],
998
+ solutions: [
999
+ "Use qik_get_scopes to find available scopes and permissions",
1000
+ "Verify scope IDs are correct (not names)",
1001
+ "Check user permissions within the scope hierarchy",
1002
+ "Use appropriate token type for scope access level"
1003
+ ],
1004
+ prevention: [
1005
+ "Implement scope validation before content operations",
1006
+ "Maintain clear scope hierarchy documentation",
1007
+ "Regular permission audits and cleanup",
1008
+ "Use descriptive scope names for easier management"
1009
+ ],
1010
+ relatedIssues: ["authentication_failures", "content_access_denied", "hierarchy_confusion"]
1011
+ },
1012
+ "workflow_confusion": {
1013
+ symptoms: [
1014
+ "Confusion about when to create workflow definitions vs cards",
1015
+ "Unable to add people to workflows",
1016
+ "Workflow structure not working as expected",
1017
+ "Cards not moving through workflow properly"
1018
+ ],
1019
+ causes: [
1020
+ "Not understanding definition vs card concept",
1021
+ "Trying to add people directly to definitions",
1022
+ "Incorrect workflow structure setup",
1023
+ "Missing automation or step configuration"
1024
+ ],
1025
+ solutions: [
1026
+ "Create workflow DEFINITION first (template)",
1027
+ "Create workflow CARDS for individual instances",
1028
+ "Reference profiles in workflow cards, not definitions",
1029
+ "Set up proper column and step structure in definitions"
1030
+ ],
1031
+ prevention: [
1032
+ "Study workflow examples and patterns",
1033
+ "Start with simple workflows before complex automation",
1034
+ "Document workflow processes clearly",
1035
+ "Test workflow flow with sample data"
1036
+ ],
1037
+ relatedIssues: ["content_type_confusion", "automation_failures", "process_design"]
1038
+ },
1039
+ "date_handling_issues": {
1040
+ symptoms: [
1041
+ "Date filter queries returning unexpected results",
1042
+ "Timezone-related date mismatches",
1043
+ "Anniversary queries not working correctly",
1044
+ "Date format validation errors"
1045
+ ],
1046
+ causes: [
1047
+ "Incorrect date format (not ISO 8601)",
1048
+ "Timezone confusion or missing timezone info",
1049
+ "Using wrong date comparators",
1050
+ "Date field not properly indexed or formatted"
1051
+ ],
1052
+ solutions: [
1053
+ "Use ISO 8601 format (YYYY-MM-DDTHH:mm:ssZ)",
1054
+ "Specify timezone consistently",
1055
+ "Use appropriate date comparators (datepast, datenext, anniversarynext)",
1056
+ "Validate date formats before API calls"
1057
+ ],
1058
+ prevention: [
1059
+ "Standardize on UTC for storage, convert for display",
1060
+ "Use date validation libraries",
1061
+ "Document date format requirements clearly",
1062
+ "Test date queries across timezone boundaries"
1063
+ ],
1064
+ relatedIssues: ["filter_syntax_errors", "data_validation", "timezone_confusion"]
1065
+ },
1066
+ "performance_issues": {
1067
+ symptoms: [
1068
+ "Slow query responses",
1069
+ "Timeout errors on large datasets",
1070
+ "Rate limiting (429 errors)",
1071
+ "Memory issues with large result sets"
1072
+ ],
1073
+ causes: [
1074
+ "Inefficient filter queries",
1075
+ "Large page sizes without proper pagination",
1076
+ "Too many concurrent requests",
1077
+ "Complex nested filters without optimization"
1078
+ ],
1079
+ solutions: [
1080
+ "Optimize filter queries with indexed fields",
1081
+ "Use appropriate page sizes (20-50 items)",
1082
+ "Implement request throttling and retry logic",
1083
+ "Use select parameter to limit returned fields",
1084
+ "Cache frequently accessed data"
1085
+ ],
1086
+ prevention: [
1087
+ "Design queries with performance in mind",
1088
+ "Monitor query performance and optimize regularly",
1089
+ "Implement proper pagination strategies",
1090
+ "Use background processing for bulk operations"
1091
+ ],
1092
+ relatedIssues: ["rate_limiting", "memory_usage", "query_optimization"]
1093
+ }
1094
+ }
1095
+ };
1096
+ /**
1097
+ * Helper functions for documentation integration
1098
+ */
1099
+ export class QikDocumentationHelper {
1100
+ /**
1101
+ * Get documentation for a specific topic
1102
+ */
1103
+ static getTopicDocumentation(topic) {
1104
+ const parts = topic.split('.');
1105
+ let current = QIK_DOCUMENTATION;
1106
+ for (const part of parts) {
1107
+ if (current && typeof current === 'object' && part in current) {
1108
+ current = current[part];
1109
+ }
1110
+ else {
1111
+ return null;
1112
+ }
1113
+ }
1114
+ return current;
1115
+ }
1116
+ /**
1117
+ * Search documentation for relevant information
1118
+ */
1119
+ static searchDocumentation(query) {
1120
+ const results = [];
1121
+ const searchTerm = query.toLowerCase();
1122
+ // Search through all documentation sections
1123
+ this.searchInObject(QIK_DOCUMENTATION, searchTerm, '', results);
1124
+ return results.slice(0, 10); // Limit to top 10 results
1125
+ }
1126
+ static searchInObject(obj, searchTerm, path, results) {
1127
+ if (typeof obj === 'string' && obj.toLowerCase().includes(searchTerm)) {
1128
+ results.push({ path, content: obj, type: 'text' });
1129
+ }
1130
+ else if (Array.isArray(obj)) {
1131
+ obj.forEach((item, index) => {
1132
+ this.searchInObject(item, searchTerm, `${path}[${index}]`, results);
1133
+ });
1134
+ }
1135
+ else if (typeof obj === 'object' && obj !== null) {
1136
+ Object.keys(obj).forEach(key => {
1137
+ if (key.toLowerCase().includes(searchTerm)) {
1138
+ results.push({ path: `${path}.${key}`, content: obj[key], type: 'key' });
1139
+ }
1140
+ this.searchInObject(obj[key], searchTerm, `${path}.${key}`, results);
1141
+ });
1142
+ }
1143
+ }
1144
+ /**
1145
+ * Get troubleshooting information for a specific error
1146
+ */
1147
+ static getTroubleshootingInfo(errorMessage) {
1148
+ const troubleshooting = QIK_DOCUMENTATION.troubleshooting;
1149
+ // Try to match error message to known issues
1150
+ for (const [issueKey, issue] of Object.entries(troubleshooting)) {
1151
+ if (issue.symptoms.some((symptom) => errorMessage.toLowerCase().includes(symptom.toLowerCase()) ||
1152
+ symptom.toLowerCase().includes(errorMessage.toLowerCase()))) {
1153
+ return { issue: issueKey, ...issue };
1154
+ }
1155
+ }
1156
+ return null;
1157
+ }
1158
+ /**
1159
+ * Get examples for a specific use case
1160
+ */
1161
+ static getExamples(category, example) {
1162
+ const examples = QIK_DOCUMENTATION.examples[category];
1163
+ if (!examples)
1164
+ return null;
1165
+ if (example && examples[example]) {
1166
+ return examples[example];
1167
+ }
1168
+ return examples;
1169
+ }
1170
+ /**
1171
+ * Validate field placement based on content type
1172
+ */
1173
+ static validateFieldPlacement(contentType, payload) {
1174
+ const errors = [];
1175
+ // This would need to be enhanced with actual glossary data
1176
+ // For now, provide basic validation rules
1177
+ const rootLevelFields = ['title', 'meta', 'reference', 'referenceType', 'body', 'organisation'];
1178
+ const dataObjectFields = ['customField1', 'customField2']; // This would come from glossary
1179
+ // Check for common mistakes
1180
+ if (payload.data) {
1181
+ rootLevelFields.forEach(field => {
1182
+ if (payload.data[field]) {
1183
+ errors.push(`Field '${field}' should be at root level, not in data object`);
1184
+ }
1185
+ });
1186
+ }
1187
+ // Check for missing required fields
1188
+ if (!payload.title) {
1189
+ errors.push('Missing required field: title');
1190
+ }
1191
+ if (!payload.meta || !payload.meta.scopes) {
1192
+ errors.push('Missing required field: meta.scopes');
1193
+ }
1194
+ return {
1195
+ valid: errors.length === 0,
1196
+ errors
1197
+ };
1198
+ }
1199
+ }
1200
+ //# sourceMappingURL=documentation.js.map