@ram_28/kf-ai-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +840 -0
  3. package/dist/api/client.d.ts +78 -0
  4. package/dist/api/client.d.ts.map +1 -0
  5. package/dist/api/datetime.d.ts +21 -0
  6. package/dist/api/datetime.d.ts.map +1 -0
  7. package/dist/api/index.d.ts +7 -0
  8. package/dist/api/index.d.ts.map +1 -0
  9. package/dist/api/metadata.d.ts +75 -0
  10. package/dist/api/metadata.d.ts.map +1 -0
  11. package/dist/components/hooks/index.d.ts +8 -0
  12. package/dist/components/hooks/index.d.ts.map +1 -0
  13. package/dist/components/hooks/useFilter/index.d.ts +5 -0
  14. package/dist/components/hooks/useFilter/index.d.ts.map +1 -0
  15. package/dist/components/hooks/useFilter/payloadBuilder.utils.d.ts +33 -0
  16. package/dist/components/hooks/useFilter/payloadBuilder.utils.d.ts.map +1 -0
  17. package/dist/components/hooks/useFilter/types.d.ts +137 -0
  18. package/dist/components/hooks/useFilter/types.d.ts.map +1 -0
  19. package/dist/components/hooks/useFilter/useFilter.d.ts +3 -0
  20. package/dist/components/hooks/useFilter/useFilter.d.ts.map +1 -0
  21. package/dist/components/hooks/useFilter/validation.utils.d.ts +38 -0
  22. package/dist/components/hooks/useFilter/validation.utils.d.ts.map +1 -0
  23. package/dist/components/hooks/useForm/apiClient.d.ts +71 -0
  24. package/dist/components/hooks/useForm/apiClient.d.ts.map +1 -0
  25. package/dist/components/hooks/useForm/expressionValidator.utils.d.ts +28 -0
  26. package/dist/components/hooks/useForm/expressionValidator.utils.d.ts.map +1 -0
  27. package/dist/components/hooks/useForm/index.d.ts +6 -0
  28. package/dist/components/hooks/useForm/index.d.ts.map +1 -0
  29. package/dist/components/hooks/useForm/optimizedExpressionValidator.utils.d.ts +88 -0
  30. package/dist/components/hooks/useForm/optimizedExpressionValidator.utils.d.ts.map +1 -0
  31. package/dist/components/hooks/useForm/ruleClassifier.utils.d.ts +28 -0
  32. package/dist/components/hooks/useForm/ruleClassifier.utils.d.ts.map +1 -0
  33. package/dist/components/hooks/useForm/schemaParser.utils.d.ts +29 -0
  34. package/dist/components/hooks/useForm/schemaParser.utils.d.ts.map +1 -0
  35. package/dist/components/hooks/useForm/types.d.ts +412 -0
  36. package/dist/components/hooks/useForm/types.d.ts.map +1 -0
  37. package/dist/components/hooks/useForm/useForm.d.ts +3 -0
  38. package/dist/components/hooks/useForm/useForm.d.ts.map +1 -0
  39. package/dist/components/hooks/useKanban/apiClient.d.ts +99 -0
  40. package/dist/components/hooks/useKanban/apiClient.d.ts.map +1 -0
  41. package/dist/components/hooks/useKanban/context.d.ts +4 -0
  42. package/dist/components/hooks/useKanban/context.d.ts.map +1 -0
  43. package/dist/components/hooks/useKanban/dragDropManager.d.ts +27 -0
  44. package/dist/components/hooks/useKanban/dragDropManager.d.ts.map +1 -0
  45. package/dist/components/hooks/useKanban/index.d.ts +6 -0
  46. package/dist/components/hooks/useKanban/index.d.ts.map +1 -0
  47. package/dist/components/hooks/useKanban/types.d.ts +438 -0
  48. package/dist/components/hooks/useKanban/types.d.ts.map +1 -0
  49. package/dist/components/hooks/useKanban/useKanban.d.ts +3 -0
  50. package/dist/components/hooks/useKanban/useKanban.d.ts.map +1 -0
  51. package/dist/components/hooks/useKanban/useKanbanSimple.d.ts +62 -0
  52. package/dist/components/hooks/useKanban/useKanbanSimple.d.ts.map +1 -0
  53. package/dist/components/hooks/useTable/index.d.ts +3 -0
  54. package/dist/components/hooks/useTable/index.d.ts.map +1 -0
  55. package/dist/components/hooks/useTable/types.d.ts +107 -0
  56. package/dist/components/hooks/useTable/types.d.ts.map +1 -0
  57. package/dist/components/hooks/useTable/useTable.d.ts +8 -0
  58. package/dist/components/hooks/useTable/useTable.d.ts.map +1 -0
  59. package/dist/components/index.d.ts +3 -0
  60. package/dist/components/index.d.ts.map +1 -0
  61. package/dist/components/ui/index.d.ts +2 -0
  62. package/dist/components/ui/index.d.ts.map +1 -0
  63. package/dist/components/ui/kanban/Kanban.d.ts +12 -0
  64. package/dist/components/ui/kanban/Kanban.d.ts.map +1 -0
  65. package/dist/components/ui/kanban/index.d.ts +2 -0
  66. package/dist/components/ui/kanban/index.d.ts.map +1 -0
  67. package/dist/index.cjs +45 -0
  68. package/dist/index.d.ts +5 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.mjs +6522 -0
  71. package/dist/types/base-fields.d.ts +182 -0
  72. package/dist/types/base-fields.d.ts.map +1 -0
  73. package/dist/types/common.d.ts +238 -0
  74. package/dist/types/common.d.ts.map +1 -0
  75. package/dist/types/index.d.ts +3 -0
  76. package/dist/types/index.d.ts.map +1 -0
  77. package/dist/utils/cn.d.ts +7 -0
  78. package/dist/utils/cn.d.ts.map +1 -0
  79. package/dist/utils/formatting.d.ts +52 -0
  80. package/dist/utils/formatting.d.ts.map +1 -0
  81. package/dist/utils/index.d.ts +3 -0
  82. package/dist/utils/index.d.ts.map +1 -0
  83. package/package.json +98 -0
  84. package/sdk/api/client.ts +447 -0
  85. package/sdk/api/datetime.ts +33 -0
  86. package/sdk/api/index.ts +61 -0
  87. package/sdk/api/metadata.ts +148 -0
  88. package/sdk/components/hooks/index.ts +34 -0
  89. package/sdk/components/hooks/useFilter/index.ts +37 -0
  90. package/sdk/components/hooks/useFilter/payloadBuilder.utils.ts +298 -0
  91. package/sdk/components/hooks/useFilter/types.ts +158 -0
  92. package/sdk/components/hooks/useFilter/useFilter.llm.txt +497 -0
  93. package/sdk/components/hooks/useFilter/useFilter.ts +494 -0
  94. package/sdk/components/hooks/useFilter/validation.utils.ts +401 -0
  95. package/sdk/components/hooks/useForm/apiClient.ts +441 -0
  96. package/sdk/components/hooks/useForm/expressionValidator.utils.ts +444 -0
  97. package/sdk/components/hooks/useForm/index.ts +64 -0
  98. package/sdk/components/hooks/useForm/optimizedExpressionValidator.utils.ts +482 -0
  99. package/sdk/components/hooks/useForm/ruleClassifier.utils.ts +424 -0
  100. package/sdk/components/hooks/useForm/schemaParser.utils.ts +519 -0
  101. package/sdk/components/hooks/useForm/types.ts +630 -0
  102. package/sdk/components/hooks/useForm/useForm.llm.txt +340 -0
  103. package/sdk/components/hooks/useForm/useForm.ts +821 -0
  104. package/sdk/components/hooks/useKanban/apiClient.ts +494 -0
  105. package/sdk/components/hooks/useKanban/context.ts +14 -0
  106. package/sdk/components/hooks/useKanban/dragDropManager.ts +529 -0
  107. package/sdk/components/hooks/useKanban/index.ts +63 -0
  108. package/sdk/components/hooks/useKanban/types.ts +606 -0
  109. package/sdk/components/hooks/useKanban/useKanban.llm.txt +482 -0
  110. package/sdk/components/hooks/useKanban/useKanban.ts +725 -0
  111. package/sdk/components/hooks/useKanban/useKanbanSimple.ts +389 -0
  112. package/sdk/components/hooks/useTable/index.ts +5 -0
  113. package/sdk/components/hooks/useTable/types.ts +154 -0
  114. package/sdk/components/hooks/useTable/useTable.llm.txt +344 -0
  115. package/sdk/components/hooks/useTable/useTable.ts +413 -0
  116. package/sdk/components/index.ts +15 -0
  117. package/sdk/components/ui/index.ts +2 -0
  118. package/sdk/components/ui/kanban/Kanban.tsx +134 -0
  119. package/sdk/components/ui/kanban/index.ts +11 -0
  120. package/sdk/index.ts +13 -0
  121. package/sdk/types/base-fields.ts +221 -0
  122. package/sdk/types/common.ts +306 -0
  123. package/sdk/types/index.ts +5 -0
  124. package/sdk/utils/cn.ts +10 -0
  125. package/sdk/utils/formatting.ts +212 -0
  126. package/sdk/utils/index.ts +5 -0
@@ -0,0 +1,482 @@
1
+ # useKanban Hook - LLM Documentation
2
+
3
+ ## Overview
4
+
5
+ The `useKanban` hook is a React hook for building Kanban board interfaces with:
6
+ - Column-based card organization
7
+ - Drag and drop support (mouse, touch, keyboard)
8
+ - CRUD operations for cards
9
+ - Search functionality
10
+ - Filter support
11
+ - Real-time state management
12
+ - API integration with TanStack Query
13
+
14
+ ## Import
15
+
16
+ ```typescript
17
+ import { useKanban } from "kf-ai-sdk";
18
+ ```
19
+
20
+ ## Basic Usage
21
+
22
+ ```typescript
23
+ const COLUMNS = [
24
+ { id: "todo", title: "To Do", position: 0, color: "gray" },
25
+ { id: "inProgress", title: "In Progress", position: 1, color: "blue" },
26
+ { id: "done", title: "Done", position: 2, color: "green" },
27
+ ];
28
+
29
+ const kanban = useKanban<TaskType>({
30
+ source: "BDO_Tasks",
31
+ columns: COLUMNS,
32
+ enableDragDrop: true,
33
+ onCardMove: (card, fromColumnId, toColumnId) => {
34
+ console.log(`Moved ${card.title} from ${fromColumnId} to ${toColumnId}`);
35
+ },
36
+ onError: (error) => {
37
+ console.error(error);
38
+ },
39
+ });
40
+ ```
41
+
42
+ ## Configuration Options
43
+
44
+ ### UseKanbanOptions<T>
45
+
46
+ | Property | Type | Required | Default | Description |
47
+ |----------|------|----------|---------|-------------|
48
+ | `source` | `string` | Yes | - | Data source identifier (BDO name) |
49
+ | `columns` | `ColumnDefinition[]` | Yes | - | Static column configurations |
50
+ | `enableDragDrop` | `boolean` | No | `false` | Enable drag and drop |
51
+ | `enableFiltering` | `boolean` | No | `false` | Enable filtering |
52
+ | `enableSearch` | `boolean` | No | `false` | Enable search |
53
+ | `initialSearch` | `string` | No | `""` | Initial search query |
54
+ | `onCardMove` | `(card, fromColumnId, toColumnId) => void` | No | - | Card move callback |
55
+ | `onCardCreate` | `(card) => void` | No | - | Card create callback |
56
+ | `onCardUpdate` | `(card) => void` | No | - | Card update callback |
57
+ | `onCardDelete` | `(cardId) => void` | No | - | Card delete callback |
58
+ | `onSuccess` | `(data) => void` | No | - | Success callback |
59
+ | `onError` | `(error) => void` | No | - | Error callback |
60
+ | `onFilterError` | `(errors) => void` | No | - | Filter error callback |
61
+
62
+ ### ColumnDefinition
63
+
64
+ ```typescript
65
+ interface ColumnDefinition {
66
+ id: string; // Unique column identifier
67
+ title: string; // Display title
68
+ position: number; // Display order (0-indexed)
69
+ color?: string; // Optional color for header
70
+ limit?: number; // Optional WIP limit
71
+ }
72
+ ```
73
+
74
+ ## Return Value
75
+
76
+ ### UseKanbanReturn<T>
77
+
78
+ #### Data
79
+ | Property | Type | Description |
80
+ |----------|------|-------------|
81
+ | `columns` | `KanbanColumn<T>[]` | All columns with their cards |
82
+ | `totalCards` | `number` | Total card count |
83
+
84
+ #### Loading States
85
+ | Property | Type | Description |
86
+ |----------|------|-------------|
87
+ | `isLoading` | `boolean` | Initial data loading |
88
+ | `isFetching` | `boolean` | Background refetching |
89
+ | `isUpdating` | `boolean` | Any mutation in progress |
90
+
91
+ #### Error Handling
92
+ | Property | Type | Description |
93
+ |----------|------|-------------|
94
+ | `error` | `Error \| null` | Current error state |
95
+
96
+ #### Search
97
+ | Property | Type | Description |
98
+ |----------|------|-------------|
99
+ | `searchQuery` | `string` | Current search query |
100
+ | `setSearchQuery` | `(query: string) => void` | Set search query |
101
+ | `clearSearch` | `() => void` | Clear search |
102
+
103
+ #### Card Operations
104
+ | Property | Type | Description |
105
+ |----------|------|-------------|
106
+ | `createCard` | `(card) => Promise<void>` | Create a new card |
107
+ | `updateCard` | `(id, updates) => Promise<void>` | Update a card |
108
+ | `deleteCard` | `(id) => Promise<void>` | Delete a card |
109
+ | `moveCard` | `(cardId, toColumnId, position?) => Promise<void>` | Move card to column |
110
+
111
+ #### Drag Drop State
112
+ | Property | Type | Description |
113
+ |----------|------|-------------|
114
+ | `isDragging` | `boolean` | Drag operation in progress |
115
+ | `draggedCard` | `KanbanCard<T> \| null` | Currently dragged card |
116
+ | `handleDragStart` | `(card) => void` | Handle drag start |
117
+ | `handleDragEnd` | `() => void` | Handle drag end |
118
+ | `handleKeyboardMove` | `(cardId, direction) => Promise<void>` | Keyboard navigation |
119
+
120
+ #### Utilities
121
+ | Property | Type | Description |
122
+ |----------|------|-------------|
123
+ | `refresh` | `() => Promise<void>` | Refresh data |
124
+ | `refetch` | `() => Promise<void>` | Refetch data |
125
+ | `loadMore` | `(columnId: string) => void` | Load more cards |
126
+
127
+ ## Data Types
128
+
129
+ ### KanbanCard<T>
130
+
131
+ ```typescript
132
+ interface KanbanCard<T = Record<string, any>> {
133
+ _id: string; // Unique identifier
134
+ title: string; // Card title
135
+ columnId: string; // Column this card belongs to
136
+ position: number; // Position within column (0-indexed)
137
+ _created_at?: Date; // Creation timestamp
138
+ _modified_at?: Date; // Modification timestamp
139
+ } & T; // Custom fields from T
140
+ ```
141
+
142
+ ### KanbanColumn<T>
143
+
144
+ ```typescript
145
+ interface KanbanColumn<T = Record<string, any>> {
146
+ _id: string; // Unique identifier (from ColumnDefinition.id)
147
+ title: string; // Column title
148
+ position: number; // Position among columns
149
+ color?: string; // Optional color
150
+ limit?: number; // Optional WIP limit
151
+ cards: KanbanCard<T>[]; // Cards in this column
152
+ }
153
+ ```
154
+
155
+ ## E-Commerce App Usage Example
156
+
157
+ ### Inventory Restocking Page (InventoryRestockingPage.tsx)
158
+
159
+ ```typescript
160
+ const RESTOCKING_COLUMNS = [
161
+ { id: "LowStockAlert", title: "Low Stock Alert", position: 0, color: "red" },
162
+ { id: "OrderPlaced", title: "Order Placed", position: 1, color: "yellow" },
163
+ { id: "InTransit", title: "In Transit", position: 2, color: "blue" },
164
+ { id: "Received", title: "Received & Restocked", position: 3, color: "green" },
165
+ ];
166
+
167
+ const kanban = useKanban<InventoryManagerRestocking>({
168
+ source: "BDO_ProductRestocking",
169
+ columns: RESTOCKING_COLUMNS,
170
+ enableDragDrop: true,
171
+ enableFiltering: true,
172
+ enableSearch: true,
173
+ onCardMove: (card, fromColumnId, toColumnId) => {
174
+ // When moving to "Received" column, show stock update modal
175
+ if (toColumnId === "Received") {
176
+ setSelectedCard(card);
177
+ setShowStockUpdateModal(true);
178
+ }
179
+ },
180
+ onError: (error) => {
181
+ toast.error(`Failed to move card: ${error.message}`);
182
+ },
183
+ });
184
+
185
+ // Search
186
+ <Input
187
+ placeholder="Search by product title or SKU..."
188
+ value={kanban.searchQuery || ""}
189
+ onChange={(e) => kanban.setSearchQuery(e.target.value)}
190
+ />
191
+
192
+ // Error handling
193
+ {kanban.error ? (
194
+ <div className="text-center py-12 bg-red-50">
195
+ <p className="text-red-600">{kanban.error.message}</p>
196
+ <Button onClick={() => kanban.refetch()}>Try Again</Button>
197
+ </div>
198
+ ) : kanban.isLoading ? (
199
+ <div className="animate-spin">...</div>
200
+ ) : (
201
+ // Kanban board
202
+ <KanbanBoard instance={kanban}>
203
+ {kanban.columns.map((column) => (
204
+ <KanbanColumn key={column._id} columnId={column._id}>
205
+ <KanbanColumnHeader>
206
+ <KanbanColumnTitle>{column.title}</KanbanColumnTitle>
207
+ <Badge>{column.cards.length}</Badge>
208
+ </KanbanColumnHeader>
209
+
210
+ <KanbanColumnContent>
211
+ {column.cards.map((card) => (
212
+ <KanbanCard key={card._id} card={card}>
213
+ <KanbanCardTitle>{card.productTitle}</KanbanCardTitle>
214
+ <KanbanCardDescription>
215
+ <div>SKU: {card.productSKU}</div>
216
+ <div>Stock: {card.currentStock}</div>
217
+ <div>Ordered: {card.quantityOrdered}</div>
218
+ </KanbanCardDescription>
219
+ <Badge variant={getPriorityVariant(card.priority)}>
220
+ {card.priority}
221
+ </Badge>
222
+ </KanbanCard>
223
+ ))}
224
+ </KanbanColumnContent>
225
+
226
+ {column.cards.length >= 10 && (
227
+ <KanbanColumnFooter>
228
+ <Button onClick={() => kanban.loadMore(column._id)}>
229
+ Load More
230
+ </Button>
231
+ </KanbanColumnFooter>
232
+ )}
233
+ </KanbanColumn>
234
+ ))}
235
+ </KanbanBoard>
236
+ )}
237
+ ```
238
+
239
+ ## Card Operations
240
+
241
+ ### Create Card
242
+
243
+ ```typescript
244
+ await kanban.createCard({
245
+ title: "New Task",
246
+ columnId: "todo",
247
+ // Custom fields
248
+ description: "Task description",
249
+ priority: "High",
250
+ });
251
+ // Position is auto-calculated
252
+ ```
253
+
254
+ ### Update Card
255
+
256
+ ```typescript
257
+ await kanban.updateCard(cardId, {
258
+ title: "Updated Title",
259
+ description: "New description",
260
+ });
261
+ ```
262
+
263
+ ### Delete Card
264
+
265
+ ```typescript
266
+ await kanban.deleteCard(cardId);
267
+ ```
268
+
269
+ ### Move Card
270
+
271
+ ```typescript
272
+ // Move to another column
273
+ await kanban.moveCard(cardId, "inProgress");
274
+
275
+ // Move to specific position
276
+ await kanban.moveCard(cardId, "inProgress", 2);
277
+ ```
278
+
279
+ ## Drag and Drop
280
+
281
+ ### Mouse Drag
282
+
283
+ ```typescript
284
+ // Handled automatically when enableDragDrop: true
285
+ // Use the provided getCardProps and getColumnProps for event binding
286
+
287
+ const cardProps = kanban.getCardProps(card);
288
+ const columnProps = kanban.getColumnProps(columnId);
289
+
290
+ <div {...columnProps}>
291
+ {cards.map(card => (
292
+ <div {...cardProps}>{card.title}</div>
293
+ ))}
294
+ </div>
295
+ ```
296
+
297
+ ### Keyboard Navigation
298
+
299
+ ```typescript
300
+ // Move card left/right with keyboard
301
+ await kanban.handleKeyboardMove(cardId, "left"); // Previous column
302
+ await kanban.handleKeyboardMove(cardId, "right"); // Next column
303
+ ```
304
+
305
+ ### Touch Support
306
+
307
+ The hook includes touch handlers for mobile devices:
308
+ - `handleTouchStart`
309
+ - `handleTouchMove`
310
+ - `handleTouchEnd`
311
+
312
+ ## Drag Drop Manager
313
+
314
+ For advanced drag and drop control, use the exported `useDragDropManager`:
315
+
316
+ ```typescript
317
+ import { useDragDropManager } from "kf-ai-sdk";
318
+
319
+ const dragDrop = useDragDropManager<TaskType>({
320
+ onCardMove: handleMove,
321
+ onError: handleError,
322
+ columns: kanban.columns,
323
+ announceMove: (card, from, to) => {
324
+ // Accessibility announcement
325
+ console.log(`Moved ${card.title} from ${from} to ${to}`);
326
+ },
327
+ });
328
+ ```
329
+
330
+ ### DragDropManager Features
331
+
332
+ | Property | Type | Description |
333
+ |----------|------|-------------|
334
+ | `isDragging` | `boolean` | Drag in progress |
335
+ | `draggedCard` | `KanbanCard<T>` | Currently dragged card |
336
+ | `dragOverColumn` | `string \| null` | Column being hovered |
337
+ | `dragOverPosition` | `number \| null` | Position being hovered |
338
+ | `dragSourceColumn` | `string \| null` | Source column |
339
+ | `handleDragStart` | `(event, card) => void` | Start drag |
340
+ | `handleDragOver` | `(event, columnId) => void` | Handle drag over |
341
+ | `handleDrop` | `(event, columnId) => void` | Handle drop |
342
+ | `handleDragEnd` | `() => void` | End drag |
343
+ | `handleKeyDown` | `(event, card) => void` | Keyboard handler |
344
+ | `handleTouchStart` | `(event, card) => void` | Touch start |
345
+ | `handleTouchMove` | `(event) => void` | Touch move |
346
+ | `handleTouchEnd` | `(event) => void` | Touch end |
347
+ | `reset` | `() => void` | Reset state |
348
+
349
+ ## Context Provider
350
+
351
+ For component tree access, use the KanbanContext:
352
+
353
+ ```typescript
354
+ import { KanbanContext, useKanbanContext } from "kf-ai-sdk";
355
+
356
+ // Provider
357
+ <KanbanContext.Provider value={kanban}>
358
+ <KanbanBoard />
359
+ </KanbanContext.Provider>
360
+
361
+ // Consumer
362
+ function KanbanCard() {
363
+ const kanban = useKanbanContext<TaskType>();
364
+ // Access kanban state and methods
365
+ }
366
+ ```
367
+
368
+ ## API Client Functions
369
+
370
+ The hook exports utility functions for direct API access:
371
+
372
+ ```typescript
373
+ import {
374
+ mergeCardsIntoColumns,
375
+ calculateCardPosition,
376
+ calculateColumnPosition,
377
+ normalizePositions,
378
+ handleKanbanApiError,
379
+ validateApiResponse,
380
+ } from "kf-ai-sdk";
381
+
382
+ // Merge fetched cards into column structure
383
+ const columnsWithCards = mergeCardsIntoColumns(columns, cards);
384
+
385
+ // Calculate optimal position for new card
386
+ const position = calculateCardPosition(column, insertIndex);
387
+
388
+ // Normalize positions after reorder
389
+ const normalized = normalizePositions(items);
390
+ ```
391
+
392
+ ## Filter Integration
393
+
394
+ When `enableFiltering: true`, the hook includes filter functionality similar to useTable:
395
+
396
+ ```typescript
397
+ kanban.filter.addCondition({
398
+ lhsField: "priority",
399
+ operator: "EQ",
400
+ rhsValue: "High",
401
+ rhsType: "Constant",
402
+ });
403
+
404
+ kanban.filter.clearConditions();
405
+ ```
406
+
407
+ ## Key Behaviors
408
+
409
+ 1. **Static columns**: Columns are defined at configuration time, not fetched from API
410
+ 2. **Auto-sorting**: Cards sorted by position within each column
411
+ 3. **Position auto-calculation**: New cards get position based on column length
412
+ 4. **WIP limit checking**: Drop is prevented if column limit is reached
413
+ 5. **Optimistic updates**: UI updates immediately, then syncs with server
414
+ 6. **Auto-scroll**: Scrolls horizontally during drag near edges
415
+ 7. **Accessibility**: ARIA attributes and screen reader announcements
416
+ 8. **30s stale time**: Data considered fresh for 30 seconds
417
+
418
+ ## API Format
419
+
420
+ ### Sort Format
421
+
422
+ ```typescript
423
+ Sort: [
424
+ { columnId: "ASC" },
425
+ { position: "ASC" }
426
+ ]
427
+ ```
428
+
429
+ ### Move Card Request
430
+
431
+ ```typescript
432
+ {
433
+ columnId: "newColumnId",
434
+ position: 2 // Optional
435
+ }
436
+ ```
437
+
438
+ ## Architecture Notes
439
+
440
+ - Built on TanStack Query for data fetching
441
+ - Separate queries for cards and count
442
+ - Uses `useMemo` for column processing
443
+ - Mutations with automatic refetch on success
444
+ - Supports generic card types with TypeScript
445
+ - Includes comprehensive drag and drop manager
446
+ - Context provider for component tree access
447
+ - Full keyboard accessibility support
448
+
449
+ ## Error Handling
450
+
451
+ ```typescript
452
+ const kanban = useKanban({
453
+ source: "BDO_Tasks",
454
+ columns: COLUMNS,
455
+ onError: (error) => {
456
+ // Handle general errors
457
+ toast.error(error.message);
458
+ },
459
+ onFilterError: (errors) => {
460
+ // Handle filter validation errors
461
+ errors.forEach(err => console.log(err.message));
462
+ },
463
+ });
464
+
465
+ // Check error state
466
+ if (kanban.error) {
467
+ return <ErrorDisplay error={kanban.error} onRetry={kanban.refresh} />;
468
+ }
469
+ ```
470
+
471
+ ## WIP Limits
472
+
473
+ Columns can have work-in-progress limits:
474
+
475
+ ```typescript
476
+ const COLUMNS = [
477
+ { id: "inProgress", title: "In Progress", position: 1, limit: 5 },
478
+ ];
479
+
480
+ // Drop will be prevented if limit is reached
481
+ // Error callback will be triggered with limit message
482
+ ```