@ram_28/kf-ai-sdk 1.0.16 → 1.0.18
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/docs/QUICK_REFERENCE.md +528 -0
- package/docs/useAuth.md +402 -0
- package/docs/useFilter.md +273 -0
- package/docs/useForm.md +629 -0
- package/docs/useKanban.md +421 -0
- package/docs/useTable.md +372 -0
- package/package.json +4 -2
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
# KF AI SDK - Quick Reference
|
|
2
|
+
|
|
3
|
+
## Installation & Setup
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @ram_28/kf-ai-sdk
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { setApiBaseUrl } from "@ram_28/kf-ai-sdk/api";
|
|
11
|
+
|
|
12
|
+
// Configure API base URL (without /api/app - SDK adds proper paths automatically)
|
|
13
|
+
setApiBaseUrl("https://api.your-domain.com");
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## useTable Hook
|
|
17
|
+
|
|
18
|
+
### Basic Usage
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { useTable } from "@ram_28/kf-ai-sdk/table";
|
|
22
|
+
import type { UseTableOptionsType, UseTableReturnType, ColumnDefinitionType } from "@ram_28/kf-ai-sdk/table/types";
|
|
23
|
+
|
|
24
|
+
const table = useTable<ProductType>({
|
|
25
|
+
source: "BDO_AmazonProductMaster",
|
|
26
|
+
columns: [
|
|
27
|
+
{ fieldId: "Title", enableSorting: true },
|
|
28
|
+
{ fieldId: "Price", enableSorting: true, enableFiltering: true },
|
|
29
|
+
],
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Key Properties
|
|
34
|
+
|
|
35
|
+
| Property | Type | Description |
|
|
36
|
+
| --------------------- | -------------------------- | ------------------ |
|
|
37
|
+
| `rows` | `T[]` | Current table data |
|
|
38
|
+
| `isLoading` | `boolean` | Loading state |
|
|
39
|
+
| `totalItems` | `number` | Total count |
|
|
40
|
+
| `search.query` | `string` | Current search |
|
|
41
|
+
| `search.setQuery` | `(query: string) => void` | Update search |
|
|
42
|
+
| `sort.toggle` | `(field: keyof T) => void` | Toggle sort |
|
|
43
|
+
| `pagination.goToNext` | `() => void` | Next page |
|
|
44
|
+
| `filter.addCondition` | `(condition) => string` | Add filter |
|
|
45
|
+
|
|
46
|
+
## useForm Hook
|
|
47
|
+
|
|
48
|
+
### Basic Usage
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { useForm } from "@ram_28/kf-ai-sdk/form";
|
|
52
|
+
import type { UseFormOptionsType, UseFormReturnType, FormFieldConfigType } from "@ram_28/kf-ai-sdk/form/types";
|
|
53
|
+
|
|
54
|
+
const form = useForm<ProductType>({
|
|
55
|
+
source: "BDO_AmazonProductMaster",
|
|
56
|
+
operation: "create", // or "update"
|
|
57
|
+
userRole: "Seller",
|
|
58
|
+
onComputationRule: async (context) => {
|
|
59
|
+
// Handle server-side computation rules
|
|
60
|
+
const result = await api(context.source).update(id, data);
|
|
61
|
+
return result.computedFields;
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Key Properties
|
|
67
|
+
|
|
68
|
+
| Property | Type | Description |
|
|
69
|
+
| -------------- | ------------------------------------ | -------------- |
|
|
70
|
+
| `register` | `(name, options?) => RegisterReturn` | Register field |
|
|
71
|
+
| `handleSubmit` | `() => (e?) => Promise<void>` | Submit handler |
|
|
72
|
+
| `errors` | `FieldErrors<T>` | Form errors |
|
|
73
|
+
| `isValid` | `boolean` | Form validity |
|
|
74
|
+
| `isSubmitting` | `boolean` | Submit state |
|
|
75
|
+
| `getField` | `(fieldName) => ProcessedField` | Field metadata |
|
|
76
|
+
|
|
77
|
+
### Field Permissions
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
const field = form.getField("Price");
|
|
81
|
+
if (field.permission.editable) {
|
|
82
|
+
// Field is editable for current role
|
|
83
|
+
}
|
|
84
|
+
if (field.permission.hidden) {
|
|
85
|
+
// Field should not be displayed
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Business Object Classes
|
|
90
|
+
|
|
91
|
+
### Role-Based Access
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// Admin - Full access
|
|
95
|
+
const adminProducts = new AmazonProductMaster("Admin");
|
|
96
|
+
|
|
97
|
+
// Seller - Limited access
|
|
98
|
+
const sellerProducts = new AmazonProductMaster("Seller");
|
|
99
|
+
|
|
100
|
+
// Buyer - Read-only
|
|
101
|
+
const buyerProducts = new AmazonProductMaster("Buyer");
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### CRUD Operations
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// Create
|
|
108
|
+
const result = await products.create({
|
|
109
|
+
ASIN: "B08N5WRWNW",
|
|
110
|
+
Title: "Product Name",
|
|
111
|
+
Price: 49.99,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Read
|
|
115
|
+
const product = await products.get("PROD-001");
|
|
116
|
+
|
|
117
|
+
// Update
|
|
118
|
+
await products.update("PROD-001", { Price: 44.99 });
|
|
119
|
+
|
|
120
|
+
// Delete (Admin only)
|
|
121
|
+
await products.delete("PROD-001");
|
|
122
|
+
|
|
123
|
+
// List with options
|
|
124
|
+
const list = await products.list({
|
|
125
|
+
Sort: [{ Price: "DESC" }],
|
|
126
|
+
PageSize: 20,
|
|
127
|
+
Filter: {
|
|
128
|
+
Operator: "AND",
|
|
129
|
+
Condition: [
|
|
130
|
+
{ LhsField: "Category", Operator: "EQ", RhsValue: "Electronics" },
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Performance Optimizations
|
|
137
|
+
|
|
138
|
+
### Expression Caching
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { clearExpressionCache } from "@ram_28/kf-ai-sdk/form";
|
|
142
|
+
|
|
143
|
+
// Clear cache when role changes
|
|
144
|
+
clearExpressionCache();
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Dependency Tracking
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// Automatically optimized - only watches relevant fields
|
|
151
|
+
const form = useForm({
|
|
152
|
+
source: "BDO_AmazonProductMaster",
|
|
153
|
+
// Price changes will only trigger discount recalculation
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Rule Types
|
|
158
|
+
|
|
159
|
+
| Rule Type | Execution | Purpose | Example |
|
|
160
|
+
| ------------------ | ----------- | ----------------- | ------------------- |
|
|
161
|
+
| **Validation** | Client-side | Field validation | ASIN format check |
|
|
162
|
+
| **Computation** | Server-side | Calculated fields | Discount percentage |
|
|
163
|
+
| **Business Logic** | Server-side | Complex logic | Inventory updates |
|
|
164
|
+
|
|
165
|
+
### Rule Implementation
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
// Client-side validation (automatic)
|
|
169
|
+
"LENGTH(ASIN) == 10 AND MATCHES(ASIN, '^[A-Z0-9]{10}$')";
|
|
170
|
+
|
|
171
|
+
// Server-side computation (triggers API call)
|
|
172
|
+
"IF(MRP > 0, ((MRP - Price) / MRP) * 100, 0)";
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Error Handling
|
|
176
|
+
|
|
177
|
+
### Form Errors
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
const form = useForm({
|
|
181
|
+
onError: (error) => toast.error(error.message),
|
|
182
|
+
onSubmitError: (error) => {
|
|
183
|
+
if (error.code === "VALIDATION_FAILED") {
|
|
184
|
+
// Handle validation errors
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### API Errors
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
try {
|
|
194
|
+
await products.create(data);
|
|
195
|
+
} catch (error) {
|
|
196
|
+
switch (error.code) {
|
|
197
|
+
case "PERMISSION_DENIED":
|
|
198
|
+
// Handle permission error
|
|
199
|
+
break;
|
|
200
|
+
case "VALIDATION_FAILED":
|
|
201
|
+
// Handle validation error
|
|
202
|
+
break;
|
|
203
|
+
default:
|
|
204
|
+
// Handle other errors
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Filter Conditions
|
|
210
|
+
|
|
211
|
+
### Basic Filters
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
table.filter.addCondition({
|
|
215
|
+
fieldName: "Price",
|
|
216
|
+
operator: "GT",
|
|
217
|
+
value: 50,
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Complex Filters
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
table.filter.addCondition({
|
|
225
|
+
fieldName: "Category",
|
|
226
|
+
operator: "IN",
|
|
227
|
+
value: ["Electronics", "Books"],
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
table.filter.addCondition({
|
|
231
|
+
fieldName: "Price",
|
|
232
|
+
operator: "BETWEEN",
|
|
233
|
+
value: { min: 10, max: 100 },
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
table.filter.setLogicalOperator("AND");
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Sorting & Pagination
|
|
240
|
+
|
|
241
|
+
### Sorting
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
// Toggle sort on click
|
|
245
|
+
<th onClick={() => table.sort.toggle("Title")}>
|
|
246
|
+
Title {table.sort.field === "Title" && table.sort.direction}
|
|
247
|
+
</th>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Pagination
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
<button
|
|
254
|
+
disabled={!table.pagination.canGoPrevious}
|
|
255
|
+
onClick={table.pagination.goToPrevious}
|
|
256
|
+
>
|
|
257
|
+
Previous
|
|
258
|
+
</button>
|
|
259
|
+
|
|
260
|
+
<span>
|
|
261
|
+
Page {table.pagination.currentPage} of {table.pagination.totalPages}
|
|
262
|
+
</span>
|
|
263
|
+
|
|
264
|
+
<button
|
|
265
|
+
disabled={!table.pagination.canGoNext}
|
|
266
|
+
onClick={table.pagination.goToNext}
|
|
267
|
+
>
|
|
268
|
+
Next
|
|
269
|
+
</button>
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Permission Checks
|
|
273
|
+
|
|
274
|
+
### Role-Based Field Access
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
// Check if field is editable
|
|
278
|
+
const canEdit = form.getField("Cost")?.permission.editable;
|
|
279
|
+
|
|
280
|
+
// Conditional rendering based on permissions
|
|
281
|
+
{form.getField("Cost")?.permission.readable && (
|
|
282
|
+
<input {...form.register("Cost")} disabled={!canEdit} />
|
|
283
|
+
)}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Method Permissions
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
// TypeScript enforces this at compile time
|
|
290
|
+
const buyerProducts = AmazonProducts.Buyer();
|
|
291
|
+
// buyerProducts.create() // ❌ Compile error
|
|
292
|
+
// buyerProducts.delete() // ❌ Compile error
|
|
293
|
+
const products = await buyerProducts.list(); // ✅ OK
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Common Patterns
|
|
297
|
+
|
|
298
|
+
### Search with Debouncing
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
const [search, setSearch] = useState("");
|
|
302
|
+
|
|
303
|
+
useEffect(() => {
|
|
304
|
+
const timer = setTimeout(() => {
|
|
305
|
+
table.search.setQuery(search);
|
|
306
|
+
}, 300);
|
|
307
|
+
|
|
308
|
+
return () => clearTimeout(timer);
|
|
309
|
+
}, [search, table.search]);
|
|
310
|
+
|
|
311
|
+
<input
|
|
312
|
+
value={search}
|
|
313
|
+
onChange={(e) => setSearch(e.target.value)}
|
|
314
|
+
placeholder="Search..."
|
|
315
|
+
/>
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Dynamic Field Rendering
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
const fields = form.getFields();
|
|
322
|
+
|
|
323
|
+
{Object.entries(fields).map(([fieldName, field]) => {
|
|
324
|
+
if (field.permission.hidden) return null;
|
|
325
|
+
|
|
326
|
+
return (
|
|
327
|
+
<div key={fieldName}>
|
|
328
|
+
<label>{field.label}</label>
|
|
329
|
+
<input
|
|
330
|
+
{...form.register(fieldName)}
|
|
331
|
+
disabled={!field.permission.editable}
|
|
332
|
+
type={field.type}
|
|
333
|
+
/>
|
|
334
|
+
</div>
|
|
335
|
+
);
|
|
336
|
+
})}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Conditional Business Logic
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
const form = useForm({
|
|
343
|
+
onComputationRule: async (context) => {
|
|
344
|
+
switch (context.ruleType) {
|
|
345
|
+
case "Computation":
|
|
346
|
+
// Handle computation rules
|
|
347
|
+
return await calculateFields(context);
|
|
348
|
+
case "BusinessLogic":
|
|
349
|
+
// Handle business logic rules
|
|
350
|
+
return await executeBusinessLogic(context);
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
});
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## Type Definitions
|
|
357
|
+
|
|
358
|
+
### Hook Types
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
// useTable types
|
|
362
|
+
import type {
|
|
363
|
+
UseTableOptionsType,
|
|
364
|
+
UseTableReturnType,
|
|
365
|
+
ColumnDefinitionType,
|
|
366
|
+
} from '@ram_28/kf-ai-sdk/table/types';
|
|
367
|
+
|
|
368
|
+
// useFilter types
|
|
369
|
+
import type {
|
|
370
|
+
UseFilterOptionsType,
|
|
371
|
+
UseFilterReturnType,
|
|
372
|
+
ConditionType,
|
|
373
|
+
ConditionGroupType,
|
|
374
|
+
FilterType,
|
|
375
|
+
} from '@ram_28/kf-ai-sdk/filter/types';
|
|
376
|
+
|
|
377
|
+
// useForm types
|
|
378
|
+
import type {
|
|
379
|
+
UseFormOptionsType,
|
|
380
|
+
UseFormReturnType,
|
|
381
|
+
FormFieldConfigType,
|
|
382
|
+
FormSchemaConfigType,
|
|
383
|
+
FormOperationType,
|
|
384
|
+
BDOSchemaType,
|
|
385
|
+
} from '@ram_28/kf-ai-sdk/form/types';
|
|
386
|
+
|
|
387
|
+
// useKanban types
|
|
388
|
+
import type {
|
|
389
|
+
UseKanbanOptionsType,
|
|
390
|
+
UseKanbanReturnType,
|
|
391
|
+
KanbanCardType,
|
|
392
|
+
KanbanColumnType,
|
|
393
|
+
ColumnConfigType,
|
|
394
|
+
} from '@ram_28/kf-ai-sdk/kanban/types';
|
|
395
|
+
|
|
396
|
+
// useAuth types
|
|
397
|
+
import type {
|
|
398
|
+
UseAuthReturnType,
|
|
399
|
+
UserDetailsType,
|
|
400
|
+
AuthStatusType,
|
|
401
|
+
AuthProviderPropsType,
|
|
402
|
+
LoginOptionsType,
|
|
403
|
+
LogoutOptionsType,
|
|
404
|
+
} from '@ram_28/kf-ai-sdk/auth/types';
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Common Types
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
import type {
|
|
411
|
+
// Filter operators
|
|
412
|
+
ConditionOperatorType, // "EQ" | "NE" | "GT" | "GTE" | "LT" | "LTE" | "Between" | "NotBetween" | "IN" | "NIN" | "Empty" | "NotEmpty" | "Contains" | "NotContains" | "MinLength" | "MaxLength"
|
|
413
|
+
ConditionGroupOperatorType, // "And" | "Or" | "Not"
|
|
414
|
+
FilterRHSTypeType, // "Constant" | "BOField" | "AppVariable"
|
|
415
|
+
|
|
416
|
+
// API types
|
|
417
|
+
ListOptionsType,
|
|
418
|
+
ListResponseType,
|
|
419
|
+
CreateUpdateResponseType,
|
|
420
|
+
} from '@ram_28/kf-ai-sdk/api/types';
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Base Field Types
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
import type {
|
|
427
|
+
IdFieldType,
|
|
428
|
+
StringFieldType,
|
|
429
|
+
TextAreaFieldType,
|
|
430
|
+
NumberFieldType,
|
|
431
|
+
BooleanFieldType,
|
|
432
|
+
DateFieldType,
|
|
433
|
+
DateTimeFieldType,
|
|
434
|
+
CurrencyFieldType,
|
|
435
|
+
SelectFieldType,
|
|
436
|
+
LookupFieldType,
|
|
437
|
+
ReferenceFieldType,
|
|
438
|
+
} from '@ram_28/kf-ai-sdk/types';
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### Quick Type Summary
|
|
442
|
+
|
|
443
|
+
| Type | Values/Purpose |
|
|
444
|
+
|------|----------------|
|
|
445
|
+
| `ConditionOperatorType` | `"EQ"`, `"NE"`, `"GT"`, `"GTE"`, `"LT"`, `"LTE"`, `"Between"`, `"NotBetween"`, `"IN"`, `"NIN"`, `"Empty"`, `"NotEmpty"`, `"Contains"`, `"NotContains"`, `"MinLength"`, `"MaxLength"` |
|
|
446
|
+
| `ConditionGroupOperatorType` | `"And"`, `"Or"`, `"Not"` (title case) |
|
|
447
|
+
| `FormOperationType` | `"create"`, `"update"` |
|
|
448
|
+
| `AuthStatusType` | `"loading"`, `"authenticated"`, `"unauthenticated"` |
|
|
449
|
+
| `FilterRHSTypeType` | `"Constant"`, `"BOField"`, `"AppVariable"` |
|
|
450
|
+
|
|
451
|
+
## Debugging Tips
|
|
452
|
+
|
|
453
|
+
### Debug Table Issues
|
|
454
|
+
|
|
455
|
+
```typescript
|
|
456
|
+
console.log("Table state:", {
|
|
457
|
+
isLoading: table.isLoading,
|
|
458
|
+
totalItems: table.totalItems,
|
|
459
|
+
currentPage: table.pagination.currentPage,
|
|
460
|
+
filters: table.filter.conditions,
|
|
461
|
+
sort: { field: table.sort.field, direction: table.sort.direction },
|
|
462
|
+
});
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### Debug Form Issues
|
|
466
|
+
|
|
467
|
+
```typescript
|
|
468
|
+
console.log("Form state:", {
|
|
469
|
+
isValid: form.isValid,
|
|
470
|
+
errors: form.errors,
|
|
471
|
+
values: form.watch(),
|
|
472
|
+
schema: form.processedSchema,
|
|
473
|
+
});
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### Debug API Issues
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
import { getApiBaseUrl, getDefaultHeaders } from "@ram_28/kf-ai-sdk/api";
|
|
480
|
+
|
|
481
|
+
console.log("API Config:", {
|
|
482
|
+
baseUrl: getApiBaseUrl(),
|
|
483
|
+
headers: getDefaultHeaders(),
|
|
484
|
+
});
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
## Configuration
|
|
488
|
+
|
|
489
|
+
### API Setup
|
|
490
|
+
|
|
491
|
+
```typescript
|
|
492
|
+
import { setApiBaseUrl, setDefaultHeaders } from "@ram_28/kf-ai-sdk/api";
|
|
493
|
+
|
|
494
|
+
// Set base URL - SDK automatically appends /api/app/{bo_id} paths
|
|
495
|
+
setApiBaseUrl("https://api.example.com");
|
|
496
|
+
setDefaultHeaders({
|
|
497
|
+
Authorization: `Bearer ${token}`,
|
|
498
|
+
"X-API-Version": "1.0",
|
|
499
|
+
});
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### React Query Setup
|
|
503
|
+
|
|
504
|
+
```typescript
|
|
505
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
506
|
+
|
|
507
|
+
const queryClient = new QueryClient({
|
|
508
|
+
defaultOptions: {
|
|
509
|
+
queries: {
|
|
510
|
+
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
511
|
+
gcTime: 10 * 60 * 1000 // 10 minutes
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
<QueryClientProvider client={queryClient}>
|
|
517
|
+
<App />
|
|
518
|
+
</QueryClientProvider>
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
---
|
|
522
|
+
|
|
523
|
+
## Quick Links
|
|
524
|
+
|
|
525
|
+
- [Full Implementation Guide](./IMPLEMENTATION_GUIDE.md)
|
|
526
|
+
- [Examples Directory](./examples/)
|
|
527
|
+
- [API Documentation](./api-docs/)
|
|
528
|
+
- [Business Object Schemas](./schemas/)
|