@ram_28/kf-ai-sdk 2.0.16 → 2.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.
Files changed (105) hide show
  1. package/README.md +16 -8
  2. package/dist/{FileField-BWrSHNRq.js → FileField-CZjS2uLh.js} +3 -3
  3. package/dist/{FileField-eDeuzln8.cjs → FileField-DU4UWo_t.cjs} +1 -1
  4. package/dist/api.cjs +1 -1
  5. package/dist/api.mjs +1 -1
  6. package/dist/auth/authConfig.d.ts +1 -1
  7. package/dist/auth/types.d.ts +1 -1
  8. package/dist/auth/types.d.ts.map +1 -1
  9. package/dist/auth.cjs +1 -1
  10. package/dist/auth.mjs +1 -1
  11. package/dist/bdo/core/Item.d.ts +0 -4
  12. package/dist/bdo/core/Item.d.ts.map +1 -1
  13. package/dist/bdo/fields/ReferenceField.d.ts +1 -1
  14. package/dist/bdo/fields/ReferenceField.d.ts.map +1 -1
  15. package/dist/bdo/fields/SelectField.d.ts +1 -1
  16. package/dist/bdo/fields/SelectField.d.ts.map +1 -1
  17. package/dist/bdo/fields/UserField.d.ts +1 -1
  18. package/dist/bdo/fields/UserField.d.ts.map +1 -1
  19. package/dist/bdo.cjs +1 -1
  20. package/dist/bdo.mjs +53 -62
  21. package/dist/components/hooks/useActivityForm/types.d.ts +4 -5
  22. package/dist/components/hooks/useActivityForm/types.d.ts.map +1 -1
  23. package/dist/components/hooks/useActivityForm/useActivityForm.d.ts.map +1 -1
  24. package/dist/components/hooks/useActivityTable/types.d.ts +5 -4
  25. package/dist/components/hooks/useActivityTable/types.d.ts.map +1 -1
  26. package/dist/components/hooks/useActivityTable/useActivityTable.d.ts.map +1 -1
  27. package/dist/components/hooks/useBDOForm/createItemProxy.d.ts +2 -3
  28. package/dist/components/hooks/useBDOForm/createItemProxy.d.ts.map +1 -1
  29. package/dist/components/hooks/useBDOTable/types.d.ts +20 -12
  30. package/dist/components/hooks/useBDOTable/types.d.ts.map +1 -1
  31. package/dist/components/hooks/useBDOTable/useBDOTable.d.ts +2 -2
  32. package/dist/components/hooks/useBDOTable/useBDOTable.d.ts.map +1 -1
  33. package/dist/{constants-ConHc1oS.js → constants-Cyi942Yr.js} +5 -5
  34. package/dist/constants-DEmYwKfC.cjs +1 -0
  35. package/dist/filter.cjs +1 -1
  36. package/dist/filter.mjs +1 -1
  37. package/dist/form.cjs +1 -1
  38. package/dist/form.mjs +226 -243
  39. package/dist/table.cjs +1 -1
  40. package/dist/table.mjs +15 -16
  41. package/dist/table.types.d.ts +1 -1
  42. package/dist/table.types.d.ts.map +1 -1
  43. package/dist/types/constants.d.ts +1 -1
  44. package/dist/workflow/Activity.d.ts +8 -5
  45. package/dist/workflow/Activity.d.ts.map +1 -1
  46. package/dist/workflow.cjs +1 -1
  47. package/dist/workflow.mjs +461 -476
  48. package/docs/README.md +57 -0
  49. package/docs/bdo/README.md +161 -0
  50. package/docs/bdo/api_reference.md +281 -0
  51. package/docs/examples/bdo/create-product.md +69 -0
  52. package/docs/examples/bdo/edit-product-dialog.md +95 -0
  53. package/docs/examples/bdo/filtered-product-table.md +100 -0
  54. package/docs/examples/bdo/product-listing.md +73 -0
  55. package/docs/examples/bdo/supplier-dropdown.md +60 -0
  56. package/docs/examples/fields/complex-fields.md +248 -0
  57. package/docs/examples/fields/primitive-fields.md +217 -0
  58. package/docs/examples/workflow/approve-leave-request.md +76 -0
  59. package/docs/examples/workflow/filtered-activity-table.md +101 -0
  60. package/docs/examples/workflow/my-pending-requests.md +90 -0
  61. package/docs/examples/workflow/start-new-workflow.md +47 -0
  62. package/docs/examples/workflow/submit-leave-request.md +72 -0
  63. package/docs/examples/workflow/workflow-progress.md +49 -0
  64. package/docs/fields/README.md +141 -0
  65. package/docs/fields/api_reference.md +134 -0
  66. package/docs/useActivityForm/README.md +244 -0
  67. package/docs/useActivityForm/api_reference.md +279 -0
  68. package/docs/useActivityTable/README.md +263 -0
  69. package/docs/useActivityTable/api_reference.md +294 -0
  70. package/docs/useBDOForm/README.md +175 -0
  71. package/docs/useBDOForm/api_reference.md +244 -0
  72. package/docs/useBDOTable/README.md +242 -0
  73. package/docs/useBDOTable/api_reference.md +253 -0
  74. package/docs/useFilter/README.md +323 -0
  75. package/docs/useFilter/api_reference.md +228 -0
  76. package/docs/workflow/README.md +158 -0
  77. package/docs/workflow/api_reference.md +161 -0
  78. package/package.json +1 -1
  79. package/sdk/auth/authConfig.ts +1 -1
  80. package/sdk/auth/types.ts +1 -1
  81. package/sdk/bdo/core/Item.ts +1 -10
  82. package/sdk/bdo/fields/ReferenceField.ts +1 -1
  83. package/sdk/bdo/fields/SelectField.ts +1 -1
  84. package/sdk/bdo/fields/UserField.ts +1 -1
  85. package/sdk/components/hooks/useActivityForm/types.ts +4 -6
  86. package/sdk/components/hooks/useActivityForm/useActivityForm.ts +10 -73
  87. package/sdk/components/hooks/useActivityTable/types.ts +4 -5
  88. package/sdk/components/hooks/useActivityTable/useActivityTable.ts +10 -8
  89. package/sdk/components/hooks/useBDOForm/createItemProxy.ts +17 -58
  90. package/sdk/components/hooks/useBDOTable/types.ts +20 -10
  91. package/sdk/components/hooks/useBDOTable/useBDOTable.ts +12 -8
  92. package/sdk/table.types.ts +2 -0
  93. package/sdk/types/constants.ts +1 -1
  94. package/sdk/workflow/Activity.ts +39 -7
  95. package/dist/constants-QX2RX-wu.cjs +0 -1
  96. package/docs/api.md +0 -95
  97. package/docs/bdo.md +0 -224
  98. package/docs/gaps.md +0 -360
  99. package/docs/useActivityForm.md +0 -393
  100. package/docs/useActivityTable.md +0 -418
  101. package/docs/useBDOForm.md +0 -376
  102. package/docs/useBDOTable.md +0 -284
  103. package/docs/useFilter.md +0 -188
  104. package/docs/workflow.md +0 -560
  105. /package/docs/{useAuth.md → useAuth/README.md} +0 -0
@@ -0,0 +1,228 @@
1
+ # useFilter API Reference
2
+
3
+ ```tsx
4
+ import { useFilter, ConditionOperator, GroupOperator, FilterValueSource } from "@ram_28/kf-ai-sdk/filter";
5
+ import { isCondition, isConditionGroup } from "@ram_28/kf-ai-sdk/filter";
6
+ import type {
7
+ UseFilterOptionsType,
8
+ UseFilterReturnType,
9
+ ConditionType,
10
+ ConditionGroupType,
11
+ ConditionGroupOperatorType,
12
+ FilterType,
13
+ FilterRHSType,
14
+ } from "@ram_28/kf-ai-sdk/filter/types";
15
+ import type { ConditionOperatorType } from "@ram_28/kf-ai-sdk/api/types";
16
+ ```
17
+
18
+ ## Signature
19
+
20
+ ```tsx
21
+ const filter: UseFilterReturnType<T> = useFilter<T>(options: UseFilterOptionsType<T>);
22
+ ```
23
+
24
+ ## Options
25
+
26
+ `UseFilterOptionsType<T>`
27
+
28
+ - `conditions?: Array<ConditionType<T> | ConditionGroupType<T>>`
29
+ - **Optional**, defaults to `[]`
30
+ - Initial filter conditions. Each item is cloned and assigned an auto-generated `id`.
31
+ - `operator?: ConditionGroupOperatorType`
32
+ - **Optional**, defaults to `"And"`
33
+ - Root operator for combining top-level conditions.
34
+
35
+ ## Return Value
36
+
37
+ `UseFilterReturnType<T>`
38
+
39
+ ### State
40
+
41
+ - `operator: ConditionGroupOperatorType`
42
+ - Current root operator (`"And"` | `"Or"` | `"Not"`).
43
+ - `items: Array<ConditionType<T> | ConditionGroupType<T>>`
44
+ - Current filter items with `id` populated. This is the stateful tree used for rendering and lookups.
45
+ - `payload: FilterType<T> | undefined`
46
+ - API-ready filter payload with all `id` fields stripped. Returns `undefined` when there are no conditions.
47
+ - `hasConditions: boolean`
48
+ - `true` when at least one condition exists. Equivalent to `items.length > 0`.
49
+
50
+ ### Add Operations
51
+
52
+ Both methods return the `id` (string) of the newly created item.
53
+
54
+ - `addCondition(condition: Omit<ConditionType<T>, "id">, parentId?: string): string`
55
+ - Add a leaf condition. When `parentId` is omitted, appended at root level. When provided, added inside the matching group's `Condition` array. Returns the auto-generated `id`.
56
+ - `addConditionGroup(operator: ConditionGroupOperatorType, parentId?: string): string`
57
+ - Create an empty condition group with the given operator. Same `parentId` behavior as `addCondition`. Returns the group's `id`.
58
+
59
+ ### Update Operations
60
+
61
+ - `updateCondition(id: string, updates: Partial<Omit<ConditionType<T>, "id">>): void`
62
+ - Partially update a leaf condition by `id`. Only provided fields are merged. No effect if `id` matches a group.
63
+ - `updateGroupOperator(id: string, operator: ConditionGroupOperatorType): void`
64
+ - Change the `Operator` of a condition group by `id`. No effect if `id` matches a leaf condition.
65
+
66
+ ### Remove & Access
67
+
68
+ - `removeCondition(id: string): void`
69
+ - Remove a condition or group by `id`. Searches recursively. Removing a group removes all its children.
70
+ - `getCondition(id: string): ConditionType<T> | ConditionGroupType<T> | undefined`
71
+ - Look up a condition or group by `id`. Returns `undefined` if not found. Searches recursively.
72
+
73
+ ### Utility
74
+
75
+ - `clearAllConditions(): void`
76
+ - Remove all conditions and groups, resetting `items` to `[]`. After this, `payload` is `undefined` and `hasConditions` is `false`.
77
+ - `setRootOperator(op: ConditionGroupOperatorType): void`
78
+ - Change the root-level operator that combines all top-level conditions.
79
+
80
+ ## Exported Constants
81
+
82
+ ### ConditionOperator
83
+
84
+ Import from `@ram_28/kf-ai-sdk/filter`. Used as the `Operator` value on leaf conditions (`ConditionType`).
85
+
86
+ **Comparison:**
87
+
88
+ - `EQ` (`"EQ"`) -- Equal. RHSValue: single value.
89
+ - `NE` (`"NE"`) -- Not equal. RHSValue: single value.
90
+ - `GT` (`"GT"`) -- Greater than. RHSValue: single value.
91
+ - `GTE` (`"GTE"`) -- Greater than or equal. RHSValue: single value.
92
+ - `LT` (`"LT"`) -- Less than. RHSValue: single value.
93
+ - `LTE` (`"LTE"`) -- Less than or equal. RHSValue: single value.
94
+
95
+ **Range:**
96
+
97
+ - `Between` (`"Between"`) -- Value within range. RHSValue: `[min, max]`.
98
+ - `NotBetween` (`"NotBetween"`) -- Value outside range. RHSValue: `[min, max]`.
99
+
100
+ **List:**
101
+
102
+ - `IN` (`"IN"`) -- Value in list. RHSValue: `[value1, value2, ...]`.
103
+ - `NIN` (`"NIN"`) -- Value not in list. RHSValue: `[value1, value2, ...]`.
104
+
105
+ **Presence:**
106
+
107
+ - `Empty` (`"Empty"`) -- Field is empty/null. RHSValue: not required.
108
+ - `NotEmpty` (`"NotEmpty"`) -- Field is not empty. RHSValue: not required.
109
+
110
+ **String:**
111
+
112
+ - `Contains` (`"Contains"`) -- String contains substring. RHSValue: string.
113
+ - `NotContains` (`"NotContains"`) -- Does not contain. RHSValue: string.
114
+
115
+ **Length:**
116
+
117
+ - `MinLength` (`"MinLength"`) -- Minimum length. RHSValue: number.
118
+ - `MaxLength` (`"MaxLength"`) -- Maximum length. RHSValue: number.
119
+ - `Length` (`"Length"`) -- Exact length. RHSValue: number.
120
+
121
+ ### GroupOperator
122
+
123
+ Import from `@ram_28/kf-ai-sdk/filter`. Used as the `Operator` value on condition groups (`ConditionGroupType`).
124
+
125
+ - `And` (`"And"`) -- All conditions must match.
126
+ - `Or` (`"Or"`) -- Any condition can match.
127
+ - `Not` (`"Not"`) -- Negate the conditions.
128
+
129
+ ### FilterValueSource
130
+
131
+ Import from `@ram_28/kf-ai-sdk/filter`. Used as the `RHSType` value on leaf conditions. The import name is `FilterValueSource`; the property name on the condition object is `RHSType`.
132
+
133
+ - `Constant` (`"Constant"`) -- RHSValue is a literal value (string, number, boolean, array, etc.).
134
+ - `BDOField` (`"BDOField"`) -- RHSValue is another field name (field-to-field comparison).
135
+ - `AppVariable` (`"AppVariable"`) -- RHSValue is an application-level variable.
136
+
137
+ ## Type Guards
138
+
139
+ Import from `@ram_28/kf-ai-sdk/filter`.
140
+
141
+ - `isCondition(item): item is ConditionType` -- Returns `true` when the item has an `LHSField` property (leaf condition).
142
+ - `isConditionGroup(item): item is ConditionGroupType` -- Returns `true` when the item has a `Condition` property (group node).
143
+
144
+ ```tsx
145
+ filter.items.forEach((item) => {
146
+ if (isCondition(item)) {
147
+ console.log(item.LHSField, item.Operator, item.RHSValue);
148
+ }
149
+ if (isConditionGroup(item)) {
150
+ console.log(item.Operator, "group with", item.Condition.length, "children");
151
+ }
152
+ });
153
+ ```
154
+
155
+ ## Types
156
+
157
+ ```typescript
158
+ // ============================================================
159
+ // Condition types
160
+ // ============================================================
161
+
162
+ interface ConditionType<T = any> {
163
+ /** Auto-generated by useFilter for state management. Stripped from payload. */
164
+ id?: string;
165
+ /** Comparison operator (use ConditionOperator constants). */
166
+ Operator: ConditionOperatorType;
167
+ /** Field name to compare. When T is provided, autocompletes to keyof T. */
168
+ LHSField: T extends any ? keyof T | string : string;
169
+ /** Value to compare against. Format depends on the Operator. */
170
+ RHSValue: any;
171
+ /** How RHSValue is interpreted. Use FilterValueSource constants. */
172
+ RHSType?: FilterRHSType;
173
+ }
174
+
175
+ interface ConditionGroupType<T = any> {
176
+ /** Auto-generated by useFilter for state management. Stripped from payload. */
177
+ id?: string;
178
+ /** Logical operator: "And", "Or", or "Not" (use GroupOperator constants). */
179
+ Operator: ConditionGroupOperatorType;
180
+ /** Nested conditions and/or groups. */
181
+ Condition: Array<ConditionType<T> | ConditionGroupType<T>>;
182
+ }
183
+
184
+ /** Root filter structure sent to the API. Alias for ConditionGroupType. */
185
+ type FilterType<T = any> = ConditionGroupType<T>;
186
+
187
+ type ConditionOperatorType = (typeof ConditionOperator)[keyof typeof ConditionOperator];
188
+ // "EQ" | "NE" | "GT" | "GTE" | "LT" | "LTE" | "Between" | "NotBetween"
189
+ // | "IN" | "NIN" | "Empty" | "NotEmpty" | "Contains" | "NotContains"
190
+ // | "MinLength" | "MaxLength" | "Length"
191
+
192
+ type ConditionGroupOperatorType = (typeof GroupOperator)[keyof typeof GroupOperator];
193
+ // "And" | "Or" | "Not"
194
+
195
+ type FilterRHSType = (typeof FilterValueSource)[keyof typeof FilterValueSource];
196
+ // "Constant" | "BDOField" | "AppVariable"
197
+
198
+ interface UseFilterOptionsType<T = any> {
199
+ /** Initial filter conditions. Each item is cloned and assigned an auto-generated id. */
200
+ conditions?: Array<ConditionType<T> | ConditionGroupType<T>>;
201
+ /** Root operator for combining conditions. Defaults to "And". */
202
+ operator?: ConditionGroupOperatorType;
203
+ }
204
+
205
+ interface UseFilterReturnType<T = any> {
206
+ // State
207
+ operator: ConditionGroupOperatorType;
208
+ items: Array<ConditionType<T> | ConditionGroupType<T>>;
209
+ payload: FilterType<T> | undefined;
210
+ hasConditions: boolean;
211
+
212
+ // Add (return id of created item)
213
+ addCondition: (condition: Omit<ConditionType<T>, "id">, parentId?: string) => string;
214
+ addConditionGroup: (operator: ConditionGroupOperatorType, parentId?: string) => string;
215
+
216
+ // Update
217
+ updateCondition: (id: string, updates: Partial<Omit<ConditionType<T>, "id">>) => void;
218
+ updateGroupOperator: (id: string, operator: ConditionGroupOperatorType) => void;
219
+
220
+ // Remove and access
221
+ removeCondition: (id: string) => void;
222
+ getCondition: (id: string) => ConditionType<T> | ConditionGroupType<T> | undefined;
223
+
224
+ // Utility
225
+ clearAllConditions: () => void;
226
+ setRootOperator: (op: ConditionGroupOperatorType) => void;
227
+ }
228
+ ```
@@ -0,0 +1,158 @@
1
+ # Workflow
2
+
3
+ Business process orchestration with typed Activity classes and a Workflow wrapper. Activity classes use the same three-generics pattern as BDO (`Activity<TEntity, TEditable, TReadonly>`), and a Workflow class ties multiple activities into a process.
4
+
5
+ ## Imports
6
+
7
+ ```typescript
8
+ // Page component — import the generated workflow and activity classes, plus hooks
9
+ import { LeaveProcess } from "../workflow/LeaveProcess";
10
+ import { EmployeeInputActivity } from "../workflow/EmployeeInputActivity";
11
+ import { useActivityForm } from "@ram_28/kf-ai-sdk/workflow";
12
+ import { useActivityTable, ActivityTableStatus } from "@ram_28/kf-ai-sdk/workflow";
13
+ ```
14
+
15
+ ```typescript
16
+ // Workflow class definition — used by the js_sdk generator
17
+ import { Activity, Workflow } from "@ram_28/kf-ai-sdk/workflow";
18
+ import type { WorkflowStartResponseType, ActivityProgressType } from "@ram_28/kf-ai-sdk/workflow";
19
+ ```
20
+
21
+ Field classes and field value types are imported from `@ram_28/kf-ai-sdk/bdo` and `@ram_28/kf-ai-sdk/types`, same as BDO.
22
+
23
+ ## Common Mistakes (READ FIRST)
24
+
25
+ 1. **`BPInstanceId` vs `_id`** — `start()` returns both. `BPInstanceId` is for `progress()`. `_id` is the first activity instance ID for `getInstance()`.
26
+ 2. **`complete()` does not save** — `complete()` only marks the activity done and advances the workflow. Call `update()` first to persist field changes, then `complete()`.
27
+ 3. **No single `list()` method** — Use `getInProgressList()` or `getCompletedList()`. The backend filters by status automatically.
28
+ 4. **Memoize Activity instances in React** — Wrap in `useMemo` to prevent re-creation on every render:
29
+ ```typescript
30
+ const activity = useMemo(() => new EmployeeInputActivity(), []);
31
+ ```
32
+
33
+ ## Quick Start
34
+
35
+ ```typescript
36
+ const leaveProcess = new LeaveProcess();
37
+ const employeeInput = new EmployeeInputActivity();
38
+
39
+ // Start workflow — returns { BPInstanceId, ActivityId, _id }
40
+ const { BPInstanceId, _id } = await leaveProcess.start();
41
+
42
+ // Get the first activity instance
43
+ const instance = await employeeInput.getInstance(_id);
44
+ instance.StartDate.get(); // read field value
45
+
46
+ // Update fields, then complete
47
+ await instance.update({ StartDate: "2026-04-01", EndDate: "2026-04-05", LeaveType: "PTO" });
48
+ await instance.complete();
49
+
50
+ // Check workflow progress
51
+ const stages = await leaveProcess.progress(BPInstanceId);
52
+ // [{ ActivityId: "EMPLOYEE_INPUT", Status: "COMPLETED" }, { ActivityId: "MANAGER_APPROVAL", Status: "IN_PROGRESS" }]
53
+ ```
54
+
55
+ ## Usage Guide
56
+
57
+ ### Workflow Methods
58
+
59
+ The Workflow class is a thin wrapper — `start()` and `progress()` only.
60
+
61
+ ```typescript
62
+ const leaveProcess = new LeaveProcess();
63
+
64
+ // Start a new instance
65
+ const { BPInstanceId, ActivityId, _id } = await leaveProcess.start();
66
+
67
+ // Get progress for all stages (pass BPInstanceId, not _id)
68
+ const stages = await leaveProcess.progress(BPInstanceId);
69
+ stages.forEach((s) => console.log(s.ActivityId, s.Status));
70
+ ```
71
+
72
+ ### Activity Methods
73
+
74
+ ```typescript
75
+ const activity = new EmployeeInputActivity();
76
+
77
+ // List instances by status
78
+ const inProgress = await activity.getInProgressList({ Page: 1, PageSize: 10 });
79
+ const completed = await activity.getCompletedList({ Page: 1, PageSize: 10 });
80
+
81
+ // Count
82
+ const pendingCount = await activity.inProgressCount();
83
+ const doneCount = await activity.completedCount();
84
+
85
+ // Metrics
86
+ const result = await activity.inProgressMetric({
87
+ GroupBy: ["LeaveType"],
88
+ Metric: [{ Field: "LeaveDays", Type: "Sum" }],
89
+ });
90
+
91
+ // Get single instance
92
+ const instance = await activity.getInstance("instance_id");
93
+ ```
94
+
95
+ ### ActivityInstance Field Accessors
96
+
97
+ Same accessor pattern as BDO `ItemType`.
98
+
99
+ ```typescript
100
+ const instance = await activity.getInstance(_id);
101
+
102
+ // Read values
103
+ instance._id; // string (direct)
104
+ instance.StartDate.get(); // DateFieldType | undefined
105
+ instance.LeaveDays.getOrDefault(0); // number (never undefined)
106
+
107
+ // Write values (editable fields only)
108
+ instance.StartDate.set("2026-04-01");
109
+
110
+ // Field metadata
111
+ instance.StartDate.label; // "Start Date"
112
+ instance.StartDate.required; // true
113
+ instance.StartDate.readOnly; // false
114
+
115
+ // Validation
116
+ instance.StartDate.validate(); // { valid, errors }
117
+ instance.validate(); // validates all fields
118
+
119
+ // Serialize
120
+ instance.toJSON(); // { StartDate: "2026-04-01", ... }
121
+ ```
122
+
123
+ ### Persistence: update, save, complete
124
+
125
+ ```typescript
126
+ const instance = await activity.getInstance(_id);
127
+
128
+ // update() — persists field changes
129
+ await instance.update({ StartDate: "2026-04-01", EndDate: "2026-04-05" });
130
+
131
+ // save() — commits a draft (used by useActivityForm internally)
132
+ await instance.save({ StartDate: "2026-04-01" });
133
+
134
+ // complete() — marks activity done, advances workflow (does NOT auto-save)
135
+ await instance.complete();
136
+
137
+ // progress() — get workflow progress from this instance
138
+ const stages = await instance.progress();
139
+ ```
140
+
141
+ ### Progress Tracking
142
+
143
+ ```typescript
144
+ const stages = await leaveProcess.progress(BPInstanceId);
145
+
146
+ for (const stage of stages) {
147
+ console.log(stage.ActivityId); // "EMPLOYEE_INPUT"
148
+ console.log(stage.Status); // "COMPLETED" | "IN_PROGRESS"
149
+ console.log(stage.CompletedAt); // string | null
150
+ console.log(stage.CompletedBy); // { _id, _name } | null
151
+ }
152
+ ```
153
+
154
+ ## Further Reading
155
+
156
+ - [API Reference](./api_reference.md) — full method signatures, parameter types, and return types
157
+ - [Start New Workflow](../examples/workflow/start-new-workflow.md) — `workflow.start()` flow
158
+ - [Workflow Progress](../examples/workflow/workflow-progress.md) — progress badges for activity stages
@@ -0,0 +1,161 @@
1
+ ```typescript
2
+ import { Activity, Workflow } from "@ram_28/kf-ai-sdk/workflow";
3
+ import { useActivityForm } from "@ram_28/kf-ai-sdk/workflow";
4
+ import { useActivityTable, ActivityTableStatus } from "@ram_28/kf-ai-sdk/workflow";
5
+ import type {
6
+ WorkflowStartResponseType,
7
+ ActivityProgressType,
8
+ ActivityInstanceFieldsType,
9
+ ActivityTableStatusType,
10
+ } from "@ram_28/kf-ai-sdk/workflow";
11
+ import type {
12
+ ListOptionsType,
13
+ CreateUpdateResponseType,
14
+ MetricOptionsType,
15
+ MetricResponseType,
16
+ } from "@ram_28/kf-ai-sdk/api/types";
17
+ import type { ValidationResultType } from "@ram_28/kf-ai-sdk/bdo/types";
18
+ ```
19
+
20
+ ## Workflow Methods
21
+
22
+ | Method | Params | Returns |
23
+ |--------|--------|---------|
24
+ | `start()` | — | `Promise<WorkflowStartResponseType>` |
25
+ | `progress(instanceId)` | `instance_id: string` (pass `BPInstanceId`) | `Promise<ActivityProgressType[]>` |
26
+
27
+ ## Activity Methods
28
+
29
+ | Method | Params | Returns |
30
+ |--------|--------|---------|
31
+ | `getInstance(id)` | `instanceId: string` | `Promise<ActivityInstanceType<TEntity, TEditable, TReadonly>>` |
32
+ | `getInProgressList(options?)` | `options?: ListOptionsType` | `Promise<ActivityInstanceType<...>[]>` |
33
+ | `getCompletedList(options?)` | `options?: ListOptionsType` | `Promise<ActivityInstanceType<...>[]>` |
34
+ | `inProgressCount(options?)` | `options?: ListOptionsType` | `Promise<number>` |
35
+ | `completedCount(options?)` | `options?: ListOptionsType` | `Promise<number>` |
36
+ | `inProgressMetric(options)` | `options: Omit<MetricOptionsType, "Type">` | `Promise<MetricResponseType>` |
37
+ | `completedMetric(options)` | `options: Omit<MetricOptionsType, "Type">` | `Promise<MetricResponseType>` |
38
+
39
+ ## ActivityInstance Methods
40
+
41
+ | Method | Params | Returns |
42
+ |--------|--------|---------|
43
+ | `update(data)` | `data: Partial<TEditable>` | `Promise<CreateUpdateResponseType>` |
44
+ | `complete()` | — | `Promise<CreateUpdateResponseType>` |
45
+ | `save(data)` | `data: Partial<TEditable>` | `Promise<CreateUpdateResponseType>` |
46
+ | `progress()` | — | `Promise<ActivityProgressType[]>` |
47
+ | `toJSON()` | — | `Partial<TEntity>` |
48
+ | `validate()` | — | `ValidationResultType` |
49
+
50
+ ActivityInstance field accessors follow the same pattern as BDO `ItemType` — see [BDO API Reference](../bdo/api_reference.md#editablefieldaccessortypet) for `EditableFieldAccessorType` and `ReadonlyFieldAccessorType`.
51
+
52
+ ## Types
53
+
54
+ ### WorkflowStartResponseType
55
+
56
+ ```typescript
57
+ interface WorkflowStartResponseType {
58
+ BPInstanceId: string; // business process instance ID — pass to progress()
59
+ ActivityId: string; // first activity's ID
60
+ _id: string; // first activity instance ID — pass to getInstance()
61
+ }
62
+ ```
63
+
64
+ ### ActivityProgressType
65
+
66
+ ```typescript
67
+ interface ActivityProgressType {
68
+ ActivityId: string;
69
+ ActivityInstanceId: string;
70
+ ActivityType: string;
71
+ AssignedTo: { Type: string; _id: string }[];
72
+ CompletedAt: string | null;
73
+ CompletedBy: { _id: string; _name: string } | null;
74
+ Status: "COMPLETED" | "IN_PROGRESS";
75
+ _name: string;
76
+ }
77
+ ```
78
+
79
+ ### ActivityInstanceType\<TEntity, TEditable, TReadonly\>
80
+
81
+ Proxy-wrapped activity instance. Same accessor pattern as BDO `ItemType`.
82
+
83
+ ```typescript
84
+ type ActivityInstanceType<TEntity, TEditable, TReadonly> = {
85
+ readonly _id: string;
86
+
87
+ // Editable fields → EditableFieldAccessorType<T> (get/set/validate)
88
+ // Readonly fields → ReadonlyFieldAccessorType<T> (get/validate, no set)
89
+
90
+ update(data: Partial<TEditable>): Promise<CreateUpdateResponseType>;
91
+ complete(): Promise<CreateUpdateResponseType>;
92
+ save(data: Partial<TEditable>): Promise<CreateUpdateResponseType>;
93
+ progress(): Promise<ActivityProgressType[]>;
94
+ toJSON(): Partial<TEntity>;
95
+ validate(): ValidationResultType;
96
+ };
97
+ ```
98
+
99
+ ### ActivityInstanceFieldsType
100
+
101
+ System fields present on every activity instance record.
102
+
103
+ ```typescript
104
+ type ActivityInstanceFieldsType = {
105
+ _id: StringFieldType;
106
+ BPInstanceId: StringFieldType;
107
+ Status: SelectFieldType<"InProgress" | "Completed">;
108
+ AssignedTo: UserFieldType[];
109
+ CompletedAt: DateTimeFieldType;
110
+ };
111
+ ```
112
+
113
+ ### ActivityTableStatus
114
+
115
+ Constants for the `useActivityTable` status parameter.
116
+
117
+ ```typescript
118
+ const ActivityTableStatus = {
119
+ InProgress: "inprogress",
120
+ Completed: "completed",
121
+ } as const;
122
+
123
+ type ActivityTableStatusType =
124
+ (typeof ActivityTableStatus)[keyof typeof ActivityTableStatus];
125
+ ```
126
+
127
+ ### ListOptionsType
128
+
129
+ Same type as BDO — see [BDO API Reference](../bdo/api_reference.md#listoptionstype).
130
+
131
+ ```typescript
132
+ interface ListOptionsType {
133
+ Filter?: FilterType;
134
+ Sort?: SortType;
135
+ Page?: number; // 1-indexed
136
+ PageSize?: number;
137
+ Search?: string;
138
+ Field?: string[];
139
+ }
140
+ ```
141
+
142
+ ### Generated Type Patterns
143
+
144
+ The js_sdk generator creates these types per activity:
145
+
146
+ ```typescript
147
+ // workflow/EmployeeInputActivity.ts
148
+ type LeaveEntityType = {
149
+ StartDate: DateFieldType;
150
+ EndDate: DateFieldType;
151
+ LeaveType: StringFieldType;
152
+ LeaveDays: NumberFieldType;
153
+ };
154
+ type LeaveEditableFieldType = Pick<LeaveEntityType, "StartDate" | "EndDate" | "LeaveType">;
155
+ type LeaveReadonlyFieldType = Pick<LeaveEntityType, "LeaveDays">;
156
+
157
+ class EmployeeInputActivity extends Activity<LeaveEntityType, LeaveEditableFieldType, LeaveReadonlyFieldType> {
158
+ readonly meta = { businessProcessId: "SimpleLeaveProcess", activityId: "EMPLOYEE_INPUT" } as const;
159
+ // ... field declarations
160
+ }
161
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ram_28/kf-ai-sdk",
3
- "version": "2.0.16",
3
+ "version": "2.0.18",
4
4
  "description": "Type-safe, AI-driven SDK for building modern web applications with role-based access control",
5
5
  "author": "Ramprasad",
6
6
  "license": "MIT",
@@ -43,7 +43,7 @@ let authConfig: AuthConfigType = { ...defaultAuthConfig };
43
43
  * autoRedirect: true,
44
44
  * providers: {
45
45
  * google: { loginPath: "/api/auth/google/login" },
46
- * microsoft: { loginPath: "/api/auth/microsoft/login" },
46
+ * azure: { loginPath: "/api/auth/azure/login" },
47
47
  * },
48
48
  * });
49
49
  * ```
package/sdk/auth/types.ts CHANGED
@@ -29,7 +29,7 @@ export type AuthStatusType = "loading" | "authenticated" | "unauthenticated";
29
29
  /**
30
30
  * Authentication provider type (extensible for multiple OAuth providers)
31
31
  */
32
- export type AuthProviderNameType = "google" | "microsoft" | "github" | "custom";
32
+ export type AuthProviderNameType = "google" | "azure" | "github" | "custom";
33
33
 
34
34
  /**
35
35
  * Auth endpoint configuration for a specific provider
@@ -196,18 +196,9 @@ export class Item<T extends Record<string, unknown>> {
196
196
  }) as Item<T>;
197
197
  }
198
198
 
199
- /**
200
- * Require instanceId or throw.
201
- * TODO: Support create flow via draftInteraction to get temp _id
202
- */
203
199
  private _requireInstanceId(): string {
204
200
  const id = this._data._id as string | undefined;
205
- if (!id) {
206
- throw new Error(
207
- "Cannot perform attachment operation: item has no _id. Save the item first.",
208
- );
209
- }
210
- return id;
201
+ return id || "draft";
211
202
  }
212
203
 
213
204
  /**
@@ -71,7 +71,7 @@ export class ReferenceField<TRef = unknown> extends BaseField<
71
71
  * Fetch referenced records from the backend via the fetchField API.
72
72
  * Requires the field to be bound to a parent BDO.
73
73
  */
74
- async fetchOptions(instanceId: string): Promise<TRef[]> {
74
+ async fetchOptions(instanceId: string = "draft"): Promise<TRef[]> {
75
75
  if (!this._parentBoId) {
76
76
  throw new Error(
77
77
  `Field ${this.id} not bound to a BDO. Cannot fetch options.`
@@ -57,7 +57,7 @@ export class SelectField<T extends string | number = string> extends BaseField<T
57
57
  /**
58
58
  * Fetch dynamic options from the backend, returned as typed SelectOption[]
59
59
  */
60
- async fetchOptions(instanceId: string): Promise<SelectOptionType<T>[]> {
60
+ async fetchOptions(instanceId: string = "draft"): Promise<SelectOptionType<T>[]> {
61
61
  if (!this._parentBoId) {
62
62
  throw new Error(
63
63
  `Field ${this.id} not bound to a BDO. Cannot fetch options.`
@@ -32,7 +32,7 @@ export class UserField extends BaseField<UserFieldType> {
32
32
  * Fetch user records from the backend via the fetchField API.
33
33
  * Requires the field to be bound to a parent BDO.
34
34
  */
35
- async fetchOptions(instanceId: string): Promise<UserFieldType[]> {
35
+ async fetchOptions(instanceId: string = "draft"): Promise<UserFieldType[]> {
36
36
  if (!this._parentBoId) {
37
37
  throw new Error(
38
38
  `Field ${this.id} not bound to a BDO. Cannot fetch options.`,
@@ -15,6 +15,7 @@ import type {
15
15
  } from 'react-hook-form';
16
16
 
17
17
  import type { Activity } from '../../../workflow/Activity';
18
+ import type { CreateUpdateResponseType } from '../../../types/common';
18
19
 
19
20
  // Reuse shared types from useBDOForm — identical interfaces, no duplication
20
21
  import type {
@@ -104,11 +105,8 @@ export interface UseActivityFormReturn<A extends Activity<any, any, any>> {
104
105
  ExtractActivityReadonly<A>
105
106
  >;
106
107
 
107
- /** Handle form submission — calls activity.update() */
108
- handleSubmit: HandleSubmitType<AllActivityFields<A>>;
109
-
110
- /** Handle form completion — calls activity.update() + activity.complete() */
111
- handleComplete: HandleSubmitType<AllActivityFields<A>>;
108
+ /** Handle form submission — validates, updates dirty fields, then completes the activity */
109
+ handleSubmit: HandleSubmitType<CreateUpdateResponseType>;
112
110
 
113
111
  /** Watch field values */
114
112
  watch: UseFormWatch<AllActivityFields<A>>;
@@ -141,7 +139,7 @@ export interface UseActivityFormReturn<A extends Activity<any, any, any>> {
141
139
  /** Form has been modified */
142
140
  isDirty: boolean;
143
141
 
144
- /** Form is currently submitting (save or complete) */
142
+ /** Form is currently submitting */
145
143
  isSubmitting: boolean;
146
144
 
147
145
  /** Form submission was successful */