@lssm/example.integration-hub 0.0.0-canary-20251217083314 → 0.0.0-canary-20251220002821

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 (209) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/dist/connection/connection.contracts.d.ts +29 -28
  4. package/dist/connection/connection.contracts.d.ts.map +1 -0
  5. package/dist/connection/connection.contracts.js +2 -1
  6. package/dist/connection/connection.contracts.js.map +1 -0
  7. package/dist/connection/connection.enum.d.ts +4 -3
  8. package/dist/connection/connection.enum.d.ts.map +1 -0
  9. package/dist/connection/connection.enum.js +4 -4
  10. package/dist/connection/connection.enum.js.map +1 -0
  11. package/dist/connection/connection.presentation.d.ts +2 -1
  12. package/dist/connection/connection.presentation.d.ts.map +1 -0
  13. package/dist/connection/connection.presentation.js +2 -1
  14. package/dist/connection/connection.presentation.js.map +1 -0
  15. package/dist/connection/connection.schema.d.ts +18 -17
  16. package/dist/connection/connection.schema.d.ts.map +1 -0
  17. package/dist/connection/connection.schema.js +17 -18
  18. package/dist/connection/connection.schema.js.map +1 -0
  19. package/dist/docs/integration-hub.docblock.js +2 -1
  20. package/dist/docs/integration-hub.docblock.js.map +1 -0
  21. package/dist/events.d.ts +45 -44
  22. package/dist/events.d.ts.map +1 -0
  23. package/dist/events.js +44 -45
  24. package/dist/events.js.map +1 -0
  25. package/dist/example.d.ts +2 -1
  26. package/dist/example.d.ts.map +1 -0
  27. package/dist/example.js +2 -1
  28. package/dist/example.js.map +1 -0
  29. package/dist/integration/integration.contracts.d.ts +27 -26
  30. package/dist/integration/integration.contracts.d.ts.map +1 -0
  31. package/dist/integration/integration.contracts.js +2 -1
  32. package/dist/integration/integration.contracts.js.map +1 -0
  33. package/dist/integration/integration.enum.d.ts +4 -3
  34. package/dist/integration/integration.enum.d.ts.map +1 -0
  35. package/dist/integration/integration.enum.js +4 -4
  36. package/dist/integration/integration.enum.js.map +1 -0
  37. package/dist/integration/integration.presentation.d.ts +2 -1
  38. package/dist/integration/integration.presentation.d.ts.map +1 -0
  39. package/dist/integration/integration.presentation.js +2 -1
  40. package/dist/integration/integration.presentation.js.map +1 -0
  41. package/dist/integration/integration.schema.d.ts +18 -17
  42. package/dist/integration/integration.schema.d.ts.map +1 -0
  43. package/dist/integration/integration.schema.js +17 -18
  44. package/dist/integration/integration.schema.js.map +1 -0
  45. package/dist/integration-hub.feature.d.ts +2 -1
  46. package/dist/integration-hub.feature.d.ts.map +1 -0
  47. package/dist/integration-hub.feature.js +2 -1
  48. package/dist/integration-hub.feature.js.map +1 -0
  49. package/dist/libs/contracts/dist/capabilities/openbanking.js +2 -1
  50. package/dist/libs/contracts/dist/capabilities/openbanking.js.map +1 -0
  51. package/dist/libs/contracts/dist/contract-registry/schemas.js +2 -1
  52. package/dist/libs/contracts/dist/contract-registry/schemas.js.map +1 -0
  53. package/dist/libs/contracts/dist/docs/accessibility_wcag_compliance_specs.docblock.js +2 -1
  54. package/dist/libs/contracts/dist/docs/accessibility_wcag_compliance_specs.docblock.js.map +1 -0
  55. package/dist/libs/contracts/dist/docs/index.js +2 -6
  56. package/dist/libs/contracts/dist/docs/meta.docs.js +30 -0
  57. package/dist/libs/contracts/dist/docs/meta.docs.js.map +1 -0
  58. package/dist/libs/contracts/dist/docs/presentations.js +2 -1
  59. package/dist/libs/contracts/dist/docs/presentations.js.map +1 -0
  60. package/dist/libs/contracts/dist/docs/registry.js +2 -1
  61. package/dist/libs/contracts/dist/docs/registry.js.map +1 -0
  62. package/dist/libs/contracts/dist/docs/tech/auth/better-auth-nextjs.docblock.js +2 -1
  63. package/dist/libs/contracts/dist/docs/tech/auth/better-auth-nextjs.docblock.js.map +1 -0
  64. package/dist/libs/contracts/dist/docs/tech/contracts/openapi-export.docblock.js +2 -1
  65. package/dist/libs/contracts/dist/docs/tech/contracts/openapi-export.docblock.js.map +1 -0
  66. package/dist/libs/contracts/dist/docs/tech/lifecycle-stage-system.docblock.js +2 -1
  67. package/dist/libs/contracts/dist/docs/tech/lifecycle-stage-system.docblock.js.map +1 -0
  68. package/dist/libs/contracts/dist/docs/tech/llm/llm-integration.docblock.js +2 -1
  69. package/dist/libs/contracts/dist/docs/tech/llm/llm-integration.docblock.js.map +1 -0
  70. package/dist/libs/contracts/dist/docs/tech/mcp-endpoints.docblock.js +2 -1
  71. package/dist/libs/contracts/dist/docs/tech/mcp-endpoints.docblock.js.map +1 -0
  72. package/dist/libs/contracts/dist/docs/tech/presentation-runtime.docblock.js +2 -1
  73. package/dist/libs/contracts/dist/docs/tech/presentation-runtime.docblock.js.map +1 -0
  74. package/dist/libs/contracts/dist/docs/tech/schema/README.docblock.js +2 -1
  75. package/dist/libs/contracts/dist/docs/tech/schema/README.docblock.js.map +1 -0
  76. package/dist/libs/contracts/dist/docs/tech/studio/learning-events.docblock.js +2 -1
  77. package/dist/libs/contracts/dist/docs/tech/studio/learning-events.docblock.js.map +1 -0
  78. package/dist/libs/contracts/dist/docs/tech/studio/learning-journeys.docblock.js +2 -1
  79. package/dist/libs/contracts/dist/docs/tech/studio/learning-journeys.docblock.js.map +1 -0
  80. package/dist/libs/contracts/dist/docs/tech/studio/platform-admin-panel.docblock.js +2 -1
  81. package/dist/libs/contracts/dist/docs/tech/studio/platform-admin-panel.docblock.js.map +1 -0
  82. package/dist/libs/contracts/dist/docs/tech/studio/project-access-teams.docblock.js +2 -1
  83. package/dist/libs/contracts/dist/docs/tech/studio/project-access-teams.docblock.js.map +1 -0
  84. package/dist/libs/contracts/dist/docs/tech/studio/project-routing.docblock.js +2 -1
  85. package/dist/libs/contracts/dist/docs/tech/studio/project-routing.docblock.js.map +1 -0
  86. package/dist/libs/contracts/dist/docs/tech/studio/sandbox-unlogged.docblock.js +2 -1
  87. package/dist/libs/contracts/dist/docs/tech/studio/sandbox-unlogged.docblock.js.map +1 -0
  88. package/dist/libs/contracts/dist/docs/tech/studio/team-invitations.docblock.js +2 -1
  89. package/dist/libs/contracts/dist/docs/tech/studio/team-invitations.docblock.js.map +1 -0
  90. package/dist/libs/contracts/dist/docs/tech/studio/workspace-ops.docblock.js +2 -1
  91. package/dist/libs/contracts/dist/docs/tech/studio/workspace-ops.docblock.js.map +1 -0
  92. package/dist/libs/contracts/dist/docs/tech/studio/workspaces.docblock.js +2 -1
  93. package/dist/libs/contracts/dist/docs/tech/studio/workspaces.docblock.js.map +1 -0
  94. package/dist/libs/contracts/dist/docs/tech/telemetry-ingest.docblock.js +2 -1
  95. package/dist/libs/contracts/dist/docs/tech/telemetry-ingest.docblock.js.map +1 -0
  96. package/dist/libs/contracts/dist/docs/tech/templates/runtime.docblock.js +2 -1
  97. package/dist/libs/contracts/dist/docs/tech/templates/runtime.docblock.js.map +1 -0
  98. package/dist/libs/contracts/dist/docs/tech/vscode-extension.docblock.js +2 -1
  99. package/dist/libs/contracts/dist/docs/tech/vscode-extension.docblock.js.map +1 -0
  100. package/dist/libs/contracts/dist/docs/tech/workflows/overview.docblock.js +2 -1
  101. package/dist/libs/contracts/dist/docs/tech/workflows/overview.docblock.js.map +1 -0
  102. package/dist/libs/contracts/dist/docs/tech-contracts.docs.js +97 -0
  103. package/dist/libs/contracts/dist/docs/tech-contracts.docs.js.map +1 -0
  104. package/dist/libs/contracts/dist/events.js +2 -1
  105. package/dist/libs/contracts/dist/events.js.map +1 -0
  106. package/dist/libs/contracts/dist/index.js +2 -1
  107. package/dist/libs/contracts/dist/integrations/contracts.js +65 -66
  108. package/dist/libs/contracts/dist/integrations/contracts.js.map +1 -0
  109. package/dist/libs/contracts/dist/integrations/openbanking/contracts/accounts.js +31 -32
  110. package/dist/libs/contracts/dist/integrations/openbanking/contracts/accounts.js.map +1 -0
  111. package/dist/libs/contracts/dist/integrations/openbanking/contracts/balances.js +18 -19
  112. package/dist/libs/contracts/dist/integrations/openbanking/contracts/balances.js.map +1 -0
  113. package/dist/libs/contracts/dist/integrations/openbanking/contracts/transactions.js +32 -33
  114. package/dist/libs/contracts/dist/integrations/openbanking/contracts/transactions.js.map +1 -0
  115. package/dist/libs/contracts/dist/integrations/openbanking/models.js +60 -61
  116. package/dist/libs/contracts/dist/integrations/openbanking/models.js.map +1 -0
  117. package/dist/libs/contracts/dist/integrations/openbanking/telemetry.js +2 -1
  118. package/dist/libs/contracts/dist/integrations/openbanking/telemetry.js.map +1 -0
  119. package/dist/libs/contracts/dist/integrations/providers/elevenlabs.js +2 -1
  120. package/dist/libs/contracts/dist/integrations/providers/elevenlabs.js.map +1 -0
  121. package/dist/libs/contracts/dist/integrations/providers/gcs-storage.js +2 -1
  122. package/dist/libs/contracts/dist/integrations/providers/gcs-storage.js.map +1 -0
  123. package/dist/libs/contracts/dist/integrations/providers/gmail.js +2 -1
  124. package/dist/libs/contracts/dist/integrations/providers/gmail.js.map +1 -0
  125. package/dist/libs/contracts/dist/integrations/providers/google-calendar.js +2 -1
  126. package/dist/libs/contracts/dist/integrations/providers/google-calendar.js.map +1 -0
  127. package/dist/libs/contracts/dist/integrations/providers/mistral.js +2 -1
  128. package/dist/libs/contracts/dist/integrations/providers/mistral.js.map +1 -0
  129. package/dist/libs/contracts/dist/integrations/providers/postmark.js +2 -1
  130. package/dist/libs/contracts/dist/integrations/providers/postmark.js.map +1 -0
  131. package/dist/libs/contracts/dist/integrations/providers/powens.js +2 -1
  132. package/dist/libs/contracts/dist/integrations/providers/powens.js.map +1 -0
  133. package/dist/libs/contracts/dist/integrations/providers/qdrant.js +2 -1
  134. package/dist/libs/contracts/dist/integrations/providers/qdrant.js.map +1 -0
  135. package/dist/libs/contracts/dist/integrations/providers/stripe.js +2 -1
  136. package/dist/libs/contracts/dist/integrations/providers/stripe.js.map +1 -0
  137. package/dist/libs/contracts/dist/integrations/providers/twilio-sms.js +2 -1
  138. package/dist/libs/contracts/dist/integrations/providers/twilio-sms.js.map +1 -0
  139. package/dist/libs/contracts/dist/knowledge/contracts.js +44 -45
  140. package/dist/libs/contracts/dist/knowledge/contracts.js.map +1 -0
  141. package/dist/libs/contracts/dist/knowledge/spaces/email-threads.js +2 -1
  142. package/dist/libs/contracts/dist/knowledge/spaces/email-threads.js.map +1 -0
  143. package/dist/libs/contracts/dist/knowledge/spaces/financial-docs.js +2 -1
  144. package/dist/libs/contracts/dist/knowledge/spaces/financial-docs.js.map +1 -0
  145. package/dist/libs/contracts/dist/knowledge/spaces/financial-overview.js +2 -1
  146. package/dist/libs/contracts/dist/knowledge/spaces/financial-overview.js.map +1 -0
  147. package/dist/libs/contracts/dist/knowledge/spaces/product-canon.js +2 -1
  148. package/dist/libs/contracts/dist/knowledge/spaces/product-canon.js.map +1 -0
  149. package/dist/libs/contracts/dist/knowledge/spaces/support-faq.js +2 -1
  150. package/dist/libs/contracts/dist/knowledge/spaces/support-faq.js.map +1 -0
  151. package/dist/libs/contracts/dist/knowledge/spaces/uploaded-docs.js +2 -1
  152. package/dist/libs/contracts/dist/knowledge/spaces/uploaded-docs.js.map +1 -0
  153. package/dist/libs/contracts/dist/llm/exporters.js +2 -1
  154. package/dist/libs/contracts/dist/llm/exporters.js.map +1 -0
  155. package/dist/libs/contracts/dist/onboarding-base.js +22 -23
  156. package/dist/libs/contracts/dist/onboarding-base.js.map +1 -0
  157. package/dist/libs/contracts/dist/ownership.js +4 -2
  158. package/dist/libs/contracts/dist/ownership.js.map +1 -0
  159. package/dist/libs/contracts/dist/presentations.v2.js +2 -1
  160. package/dist/libs/contracts/dist/presentations.v2.js.map +1 -0
  161. package/dist/libs/contracts/dist/regenerator/service.js +2 -1
  162. package/dist/libs/contracts/dist/regenerator/service.js.map +1 -0
  163. package/dist/libs/contracts/dist/schema/dist/index.js +3873 -6
  164. package/dist/libs/contracts/dist/schema/dist/index.js.map +1 -0
  165. package/dist/libs/contracts/dist/spec.js +2 -1
  166. package/dist/libs/contracts/dist/spec.js.map +1 -0
  167. package/dist/libs/schema/dist/index.js +4717 -6
  168. package/dist/libs/schema/dist/index.js.map +1 -0
  169. package/dist/sync/sync.contracts.d.ts +128 -127
  170. package/dist/sync/sync.contracts.d.ts.map +1 -0
  171. package/dist/sync/sync.contracts.js +2 -1
  172. package/dist/sync/sync.contracts.js.map +1 -0
  173. package/dist/sync/sync.enum.d.ts +6 -5
  174. package/dist/sync/sync.enum.d.ts.map +1 -0
  175. package/dist/sync/sync.enum.js +6 -6
  176. package/dist/sync/sync.enum.js.map +1 -0
  177. package/dist/sync/sync.presentation.d.ts +2 -1
  178. package/dist/sync/sync.presentation.d.ts.map +1 -0
  179. package/dist/sync/sync.presentation.js +2 -1
  180. package/dist/sync/sync.presentation.js.map +1 -0
  181. package/dist/sync/sync.schema.d.ts +87 -86
  182. package/dist/sync/sync.schema.d.ts.map +1 -0
  183. package/dist/sync/sync.schema.js +58 -59
  184. package/dist/sync/sync.schema.js.map +1 -0
  185. package/dist/sync-engine/index.d.ts +3 -2
  186. package/dist/sync-engine/index.d.ts.map +1 -0
  187. package/dist/sync-engine/index.js +5 -3
  188. package/dist/sync-engine/index.js.map +1 -0
  189. package/package.json +20 -13
  190. package/dist/libs/contracts/dist/docs/PUBLISHING.docblock.js +0 -16
  191. package/dist/libs/contracts/dist/docs/tech/PHASE_1_QUICKSTART.docblock.js +0 -16
  192. package/dist/libs/contracts/dist/docs/tech/PHASE_2_AI_NATIVE_OPERATIONS.docblock.js +0 -16
  193. package/dist/libs/contracts/dist/docs/tech/PHASE_3_AUTO_EVOLUTION.docblock.js +0 -16
  194. package/dist/libs/contracts/dist/docs/tech/PHASE_4_PERSONALIZATION_ENGINE.docblock.js +0 -16
  195. package/dist/libs/contracts/dist/docs/tech/PHASE_5_ZERO_TOUCH_OPERATIONS.docblock.js +0 -16
  196. package/dist/libs/contracts/dist/schema/dist/EnumType.js +0 -2
  197. package/dist/libs/contracts/dist/schema/dist/FieldType.js +0 -49
  198. package/dist/libs/contracts/dist/schema/dist/ScalarTypeEnum.js +0 -236
  199. package/dist/libs/contracts/dist/schema/dist/SchemaModel.js +0 -34
  200. package/dist/libs/contracts/dist/schema/dist/entity/defineEntity.js +0 -1
  201. package/dist/libs/contracts/dist/schema/dist/entity/index.js +0 -2
  202. package/dist/libs/contracts/dist/schema/dist/entity/types.js +0 -1
  203. package/dist/libs/schema/dist/EnumType.js +0 -56
  204. package/dist/libs/schema/dist/FieldType.js +0 -49
  205. package/dist/libs/schema/dist/ScalarTypeEnum.js +0 -236
  206. package/dist/libs/schema/dist/SchemaModel.js +0 -39
  207. package/dist/libs/schema/dist/entity/defineEntity.js +0 -1
  208. package/dist/libs/schema/dist/entity/index.js +0 -2
  209. package/dist/libs/schema/dist/entity/types.js +0 -1
@@ -1,25 +1,23 @@
1
- import { ScalarTypeEnum } from "../libs/schema/dist/ScalarTypeEnum.js";
2
- import { defineSchemaModel } from "../libs/schema/dist/SchemaModel.js";
3
- import "../libs/schema/dist/index.js";
1
+ import { E5, K5 } from "../libs/schema/dist/index.js";
4
2
  import { MappingTypeEnum, SyncDirectionEnum, SyncStatusEnum } from "./sync.enum.js";
5
3
 
6
4
  //#region src/sync/sync.schema.ts
7
5
  /**
8
6
  * A field mapping configuration.
9
7
  */
10
- const FieldMappingModel = defineSchemaModel({
8
+ const FieldMappingModel = K5({
11
9
  name: "FieldMappingModel",
12
10
  fields: {
13
11
  id: {
14
- type: ScalarTypeEnum.String_unsecure(),
12
+ type: E5.String_unsecure(),
15
13
  isOptional: false
16
14
  },
17
15
  sourceField: {
18
- type: ScalarTypeEnum.String_unsecure(),
16
+ type: E5.String_unsecure(),
19
17
  isOptional: false
20
18
  },
21
19
  targetField: {
22
- type: ScalarTypeEnum.String_unsecure(),
20
+ type: E5.String_unsecure(),
23
21
  isOptional: false
24
22
  },
25
23
  mappingType: {
@@ -27,11 +25,11 @@ const FieldMappingModel = defineSchemaModel({
27
25
  isOptional: false
28
26
  },
29
27
  transformExpression: {
30
- type: ScalarTypeEnum.String_unsecure(),
28
+ type: E5.String_unsecure(),
31
29
  isOptional: true
32
30
  },
33
31
  isRequired: {
34
- type: ScalarTypeEnum.Boolean(),
32
+ type: E5.Boolean(),
35
33
  isOptional: false
36
34
  }
37
35
  }
@@ -39,23 +37,23 @@ const FieldMappingModel = defineSchemaModel({
39
37
  /**
40
38
  * A sync configuration.
41
39
  */
42
- const SyncConfigModel = defineSchemaModel({
40
+ const SyncConfigModel = K5({
43
41
  name: "SyncConfigModel",
44
42
  fields: {
45
43
  id: {
46
- type: ScalarTypeEnum.String_unsecure(),
44
+ type: E5.String_unsecure(),
47
45
  isOptional: false
48
46
  },
49
47
  integrationId: {
50
- type: ScalarTypeEnum.String_unsecure(),
48
+ type: E5.String_unsecure(),
51
49
  isOptional: false
52
50
  },
53
51
  connectionId: {
54
- type: ScalarTypeEnum.String_unsecure(),
52
+ type: E5.String_unsecure(),
55
53
  isOptional: false
56
54
  },
57
55
  name: {
58
- type: ScalarTypeEnum.String_unsecure(),
56
+ type: E5.String_unsecure(),
59
57
  isOptional: false
60
58
  },
61
59
  direction: {
@@ -63,27 +61,27 @@ const SyncConfigModel = defineSchemaModel({
63
61
  isOptional: false
64
62
  },
65
63
  sourceObject: {
66
- type: ScalarTypeEnum.String_unsecure(),
64
+ type: E5.String_unsecure(),
67
65
  isOptional: false
68
66
  },
69
67
  targetObject: {
70
- type: ScalarTypeEnum.String_unsecure(),
68
+ type: E5.String_unsecure(),
71
69
  isOptional: false
72
70
  },
73
71
  scheduleEnabled: {
74
- type: ScalarTypeEnum.Boolean(),
72
+ type: E5.Boolean(),
75
73
  isOptional: false
76
74
  },
77
75
  scheduleCron: {
78
- type: ScalarTypeEnum.String_unsecure(),
76
+ type: E5.String_unsecure(),
79
77
  isOptional: true
80
78
  },
81
79
  isActive: {
82
- type: ScalarTypeEnum.Boolean(),
80
+ type: E5.Boolean(),
83
81
  isOptional: false
84
82
  },
85
83
  lastSyncAt: {
86
- type: ScalarTypeEnum.DateTime(),
84
+ type: E5.DateTime(),
87
85
  isOptional: true
88
86
  },
89
87
  fieldMappings: {
@@ -96,15 +94,15 @@ const SyncConfigModel = defineSchemaModel({
96
94
  /**
97
95
  * A sync run.
98
96
  */
99
- const SyncRunModel = defineSchemaModel({
97
+ const SyncRunModel = K5({
100
98
  name: "SyncRunModel",
101
99
  fields: {
102
100
  id: {
103
- type: ScalarTypeEnum.String_unsecure(),
101
+ type: E5.String_unsecure(),
104
102
  isOptional: false
105
103
  },
106
104
  syncConfigId: {
107
- type: ScalarTypeEnum.String_unsecure(),
105
+ type: E5.String_unsecure(),
108
106
  isOptional: false
109
107
  },
110
108
  status: {
@@ -116,39 +114,39 @@ const SyncRunModel = defineSchemaModel({
116
114
  isOptional: false
117
115
  },
118
116
  trigger: {
119
- type: ScalarTypeEnum.String_unsecure(),
117
+ type: E5.String_unsecure(),
120
118
  isOptional: false
121
119
  },
122
120
  recordsProcessed: {
123
- type: ScalarTypeEnum.Int_unsecure(),
121
+ type: E5.Int_unsecure(),
124
122
  isOptional: false
125
123
  },
126
124
  recordsCreated: {
127
- type: ScalarTypeEnum.Int_unsecure(),
125
+ type: E5.Int_unsecure(),
128
126
  isOptional: false
129
127
  },
130
128
  recordsUpdated: {
131
- type: ScalarTypeEnum.Int_unsecure(),
129
+ type: E5.Int_unsecure(),
132
130
  isOptional: false
133
131
  },
134
132
  recordsFailed: {
135
- type: ScalarTypeEnum.Int_unsecure(),
133
+ type: E5.Int_unsecure(),
136
134
  isOptional: false
137
135
  },
138
136
  errorMessage: {
139
- type: ScalarTypeEnum.String_unsecure(),
137
+ type: E5.String_unsecure(),
140
138
  isOptional: true
141
139
  },
142
140
  startedAt: {
143
- type: ScalarTypeEnum.DateTime(),
141
+ type: E5.DateTime(),
144
142
  isOptional: true
145
143
  },
146
144
  completedAt: {
147
- type: ScalarTypeEnum.DateTime(),
145
+ type: E5.DateTime(),
148
146
  isOptional: true
149
147
  },
150
148
  createdAt: {
151
- type: ScalarTypeEnum.DateTime(),
149
+ type: E5.DateTime(),
152
150
  isOptional: false
153
151
  }
154
152
  }
@@ -156,19 +154,19 @@ const SyncRunModel = defineSchemaModel({
156
154
  /**
157
155
  * Input for creating a sync config.
158
156
  */
159
- const CreateSyncConfigInputModel = defineSchemaModel({
157
+ const CreateSyncConfigInputModel = K5({
160
158
  name: "CreateSyncConfigInput",
161
159
  fields: {
162
160
  integrationId: {
163
- type: ScalarTypeEnum.String_unsecure(),
161
+ type: E5.String_unsecure(),
164
162
  isOptional: false
165
163
  },
166
164
  connectionId: {
167
- type: ScalarTypeEnum.String_unsecure(),
165
+ type: E5.String_unsecure(),
168
166
  isOptional: false
169
167
  },
170
168
  name: {
171
- type: ScalarTypeEnum.NonEmptyString(),
169
+ type: E5.NonEmptyString(),
172
170
  isOptional: false
173
171
  },
174
172
  direction: {
@@ -176,19 +174,19 @@ const CreateSyncConfigInputModel = defineSchemaModel({
176
174
  isOptional: false
177
175
  },
178
176
  sourceObject: {
179
- type: ScalarTypeEnum.NonEmptyString(),
177
+ type: E5.NonEmptyString(),
180
178
  isOptional: false
181
179
  },
182
180
  targetObject: {
183
- type: ScalarTypeEnum.NonEmptyString(),
181
+ type: E5.NonEmptyString(),
184
182
  isOptional: false
185
183
  },
186
184
  scheduleEnabled: {
187
- type: ScalarTypeEnum.Boolean(),
185
+ type: E5.Boolean(),
188
186
  isOptional: true
189
187
  },
190
188
  scheduleCron: {
191
- type: ScalarTypeEnum.String_unsecure(),
189
+ type: E5.String_unsecure(),
192
190
  isOptional: true
193
191
  }
194
192
  }
@@ -196,19 +194,19 @@ const CreateSyncConfigInputModel = defineSchemaModel({
196
194
  /**
197
195
  * Input for adding a field mapping.
198
196
  */
199
- const AddFieldMappingInputModel = defineSchemaModel({
197
+ const AddFieldMappingInputModel = K5({
200
198
  name: "AddFieldMappingInput",
201
199
  fields: {
202
200
  syncConfigId: {
203
- type: ScalarTypeEnum.String_unsecure(),
201
+ type: E5.String_unsecure(),
204
202
  isOptional: false
205
203
  },
206
204
  sourceField: {
207
- type: ScalarTypeEnum.NonEmptyString(),
205
+ type: E5.NonEmptyString(),
208
206
  isOptional: false
209
207
  },
210
208
  targetField: {
211
- type: ScalarTypeEnum.NonEmptyString(),
209
+ type: E5.NonEmptyString(),
212
210
  isOptional: false
213
211
  },
214
212
  mappingType: {
@@ -216,23 +214,23 @@ const AddFieldMappingInputModel = defineSchemaModel({
216
214
  isOptional: false
217
215
  },
218
216
  transformExpression: {
219
- type: ScalarTypeEnum.String_unsecure(),
217
+ type: E5.String_unsecure(),
220
218
  isOptional: true
221
219
  },
222
220
  lookupConfig: {
223
- type: ScalarTypeEnum.JSON(),
221
+ type: E5.JSON(),
224
222
  isOptional: true
225
223
  },
226
224
  constantValue: {
227
- type: ScalarTypeEnum.JSON(),
225
+ type: E5.JSON(),
228
226
  isOptional: true
229
227
  },
230
228
  isRequired: {
231
- type: ScalarTypeEnum.Boolean(),
229
+ type: E5.Boolean(),
232
230
  isOptional: true
233
231
  },
234
232
  defaultValue: {
235
- type: ScalarTypeEnum.JSON(),
233
+ type: E5.JSON(),
236
234
  isOptional: true
237
235
  }
238
236
  }
@@ -240,11 +238,11 @@ const AddFieldMappingInputModel = defineSchemaModel({
240
238
  /**
241
239
  * Input for triggering a sync.
242
240
  */
243
- const TriggerSyncInputModel = defineSchemaModel({
241
+ const TriggerSyncInputModel = K5({
244
242
  name: "TriggerSyncInput",
245
243
  fields: {
246
244
  syncConfigId: {
247
- type: ScalarTypeEnum.String_unsecure(),
245
+ type: E5.String_unsecure(),
248
246
  isOptional: false
249
247
  },
250
248
  direction: {
@@ -252,7 +250,7 @@ const TriggerSyncInputModel = defineSchemaModel({
252
250
  isOptional: true
253
251
  },
254
252
  fullSync: {
255
- type: ScalarTypeEnum.Boolean(),
253
+ type: E5.Boolean(),
256
254
  isOptional: true
257
255
  }
258
256
  }
@@ -260,11 +258,11 @@ const TriggerSyncInputModel = defineSchemaModel({
260
258
  /**
261
259
  * Input for listing sync runs.
262
260
  */
263
- const ListSyncRunsInputModel = defineSchemaModel({
261
+ const ListSyncRunsInputModel = K5({
264
262
  name: "ListSyncRunsInput",
265
263
  fields: {
266
264
  syncConfigId: {
267
- type: ScalarTypeEnum.String_unsecure(),
265
+ type: E5.String_unsecure(),
268
266
  isOptional: false
269
267
  },
270
268
  status: {
@@ -272,12 +270,12 @@ const ListSyncRunsInputModel = defineSchemaModel({
272
270
  isOptional: true
273
271
  },
274
272
  limit: {
275
- type: ScalarTypeEnum.Int_unsecure(),
273
+ type: E5.Int_unsecure(),
276
274
  isOptional: true,
277
275
  defaultValue: 20
278
276
  },
279
277
  offset: {
280
- type: ScalarTypeEnum.Int_unsecure(),
278
+ type: E5.Int_unsecure(),
281
279
  isOptional: true,
282
280
  defaultValue: 0
283
281
  }
@@ -286,7 +284,7 @@ const ListSyncRunsInputModel = defineSchemaModel({
286
284
  /**
287
285
  * Output for listing sync runs.
288
286
  */
289
- const ListSyncRunsOutputModel = defineSchemaModel({
287
+ const ListSyncRunsOutputModel = K5({
290
288
  name: "ListSyncRunsOutput",
291
289
  fields: {
292
290
  runs: {
@@ -295,11 +293,12 @@ const ListSyncRunsOutputModel = defineSchemaModel({
295
293
  isOptional: false
296
294
  },
297
295
  total: {
298
- type: ScalarTypeEnum.Int_unsecure(),
296
+ type: E5.Int_unsecure(),
299
297
  isOptional: false
300
298
  }
301
299
  }
302
300
  });
303
301
 
304
302
  //#endregion
305
- export { AddFieldMappingInputModel, CreateSyncConfigInputModel, FieldMappingModel, ListSyncRunsInputModel, ListSyncRunsOutputModel, SyncConfigModel, SyncRunModel, TriggerSyncInputModel };
303
+ export { AddFieldMappingInputModel, CreateSyncConfigInputModel, FieldMappingModel, ListSyncRunsInputModel, ListSyncRunsOutputModel, SyncConfigModel, SyncRunModel, TriggerSyncInputModel };
304
+ //# sourceMappingURL=sync.schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.schema.js","names":["defineSchemaModel","ScalarTypeEnum"],"sources":["../../src/sync/sync.schema.ts"],"sourcesContent":["import { defineSchemaModel, ScalarTypeEnum } from '@lssm/lib.schema';\nimport {\n SyncDirectionEnum,\n SyncStatusEnum,\n MappingTypeEnum,\n} from './sync.enum';\n\n/**\n * A field mapping configuration.\n */\nexport const FieldMappingModel = defineSchemaModel({\n name: 'FieldMappingModel',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n sourceField: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n targetField: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n mappingType: { type: MappingTypeEnum, isOptional: false },\n transformExpression: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n isRequired: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n },\n});\n\n/**\n * A sync configuration.\n */\nexport const SyncConfigModel = defineSchemaModel({\n name: 'SyncConfigModel',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n integrationId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n connectionId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n direction: { type: SyncDirectionEnum, isOptional: false },\n sourceObject: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n targetObject: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n scheduleEnabled: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n scheduleCron: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n isActive: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n lastSyncAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n fieldMappings: { type: FieldMappingModel, isArray: true, isOptional: true },\n },\n});\n\n/**\n * A sync run.\n */\nexport const SyncRunModel = defineSchemaModel({\n name: 'SyncRunModel',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n syncConfigId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n status: { type: SyncStatusEnum, isOptional: false },\n direction: { type: SyncDirectionEnum, isOptional: false },\n trigger: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n recordsProcessed: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: false,\n },\n recordsCreated: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n recordsUpdated: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n recordsFailed: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n errorMessage: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n startedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n completedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\n/**\n * Input for creating a sync config.\n */\nexport const CreateSyncConfigInputModel = defineSchemaModel({\n name: 'CreateSyncConfigInput',\n fields: {\n integrationId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n connectionId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },\n direction: { type: SyncDirectionEnum, isOptional: false },\n sourceObject: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },\n targetObject: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },\n scheduleEnabled: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n scheduleCron: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n});\n\n/**\n * Input for adding a field mapping.\n */\nexport const AddFieldMappingInputModel = defineSchemaModel({\n name: 'AddFieldMappingInput',\n fields: {\n syncConfigId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n sourceField: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },\n targetField: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },\n mappingType: { type: MappingTypeEnum, isOptional: false },\n transformExpression: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n lookupConfig: { type: ScalarTypeEnum.JSON(), isOptional: true },\n constantValue: { type: ScalarTypeEnum.JSON(), isOptional: true },\n isRequired: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n defaultValue: { type: ScalarTypeEnum.JSON(), isOptional: true },\n },\n});\n\n/**\n * Input for triggering a sync.\n */\nexport const TriggerSyncInputModel = defineSchemaModel({\n name: 'TriggerSyncInput',\n fields: {\n syncConfigId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n direction: { type: SyncDirectionEnum, isOptional: true },\n fullSync: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n },\n});\n\n/**\n * Input for listing sync runs.\n */\nexport const ListSyncRunsInputModel = defineSchemaModel({\n name: 'ListSyncRunsInput',\n fields: {\n syncConfigId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n status: { type: SyncStatusEnum, isOptional: true },\n limit: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n defaultValue: 20,\n },\n offset: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n defaultValue: 0,\n },\n },\n});\n\n/**\n * Output for listing sync runs.\n */\nexport const ListSyncRunsOutputModel = defineSchemaModel({\n name: 'ListSyncRunsOutput',\n fields: {\n runs: { type: SyncRunModel, isArray: true, isOptional: false },\n total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n },\n});\n"],"mappings":"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"}
@@ -91,7 +91,7 @@ declare class BasicFieldTransformer implements IFieldTransformer {
91
91
  declare class BasicSyncEngine implements ISyncEngine {
92
92
  private transformer;
93
93
  constructor(transformer?: IFieldTransformer);
94
- sync(context: SyncContext): Promise<SyncResult>;
94
+ sync(_context: SyncContext): Promise<SyncResult>;
95
95
  transformRecord(sourceRecord: SourceRecord, mappings: FieldMapping[], _context: SyncContext): TargetRecord;
96
96
  validateRecord(record: TargetRecord, mappings: FieldMapping[]): {
97
97
  valid: boolean;
@@ -105,4 +105,5 @@ declare function createSyncEngine(transformer?: IFieldTransformer): ISyncEngine;
105
105
  declare function computeChecksum(data: Record<string, unknown>): string;
106
106
  declare function hasChanges(sourceChecksum: string | undefined, targetChecksum: string | undefined): boolean;
107
107
  //#endregion
108
- export { BasicFieldTransformer, BasicSyncEngine, FieldMapping, IFieldTransformer, ISyncEngine, LookupConfig, SourceRecord, SyncConfig, SyncContext, SyncError, SyncResult, TargetRecord, computeChecksum, createSyncEngine, hasChanges };
108
+ export { BasicFieldTransformer, BasicSyncEngine, FieldMapping, IFieldTransformer, ISyncEngine, LookupConfig, SourceRecord, SyncConfig, SyncContext, SyncError, SyncResult, TargetRecord, computeChecksum, createSyncEngine, hasChanges };
109
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/sync-engine/index.ts"],"sourcesContent":[],"mappings":";;AAQA;AAWA;AAMA;AAYA;AAUiB,UAvCA,YAAA,CA+CP;EAGO,WAAA,EAAS,MAAA;EAOT,WAAA,EAAA,MAAY;EAMZ,WAAA,EAAA,QAAY,GAAA,WAEf,GAAA,QAAA,GAAA,UAAA,GAAA,UAAA;EAMG,mBAAW,CAAA,EAAA,MAAA;EAIZ,YAAA,CAAA,EAtEC,YAsED;EAAsB,aAAA,CAAA,EAAA,OAAA;EAAR,UAAA,EAAA,OAAA;EAMZ,YAAA,CAAA,EAAA,OAAA;;AAEL,UAxEI,YAAA,CAwEJ;EACR,YAAA,EAAA,MAAA;EAMO,WAAA,EAAA,MAAA;EACE,WAAA,EAAA,MAAA;;AAC0B,UA3EvB,UAAA,CA2EuB;EAKvB,EAAA,EAAA,MAAA;EAIJ,SAAA,EAAA,SAAA,GAAA,UAAsB,GAAW,eAAA;EAoDjC,YAAA,EAAA,MAAgB;EAGD,YAAA,EAAA,MAAA;EAIL,aAAA,EA1IN,YA0IM,EAAA;EAAsB,SAAA,EAAA,OAAA;EAAR,cAAA,EAAA,OAAA;EAuBnB,aAAA,EAAA,OAAA;EACJ,YAAA,CAAA,EA9JG,MA8JH,CAAA,MAAA,EAAA,OAAA,CAAA;;AAET,UA7JY,WAAA,CA6JZ;EAgEO,KAAA,EAAA,MAAA;EACE,MAAA,EA5NJ,UA4NI;EACiB,UAAA,EAAA;IAnGS,EAAA,EAAA,MAAA;IAAW,QAAA,EAAA,MAAA;IAoLnC,WAAA,CAAA,EA1SE,MA0Sc,CAAA,MAAe,EAAA,OAAA,CAAA;EAM/B,CAAA;AAahB;UAzTiB,UAAA;;;;;;;;UAQP;;UAGO,SAAA;;;;;;UAOA,YAAA;;QAET;;;UAIS,YAAA;;QAET;;;UAMS,WAAA;;;;gBAID,cAAc,QAAQ;;;;gCAMpB,wBACJ,yBACD,cACR;;;;yBAMO,wBACE;;YACiB;;;UAKd,iBAAA;;;cAIJ,qBAAA,YAAiC;;;cAoDjC,eAAA,YAA2B;;4BAGZ;iBAIL,cAAc,QAAQ;gCAuB3B,wBACJ,0BACA,cACT;yBAgEO,wBACE;;YACiB;;;;;;iBAiFf,gBAAA,eAA+B,oBAAoB;iBAMnD,eAAA,OAAsB;iBAatB,UAAA"}
@@ -33,7 +33,7 @@ var BasicSyncEngine = class {
33
33
  constructor(transformer) {
34
34
  this.transformer = transformer ?? new BasicFieldTransformer();
35
35
  }
36
- async sync(context) {
36
+ async sync(_context) {
37
37
  return {
38
38
  success: true,
39
39
  recordsProcessed: 0,
@@ -49,12 +49,13 @@ var BasicSyncEngine = class {
49
49
  const targetData = {};
50
50
  for (const mapping of mappings) {
51
51
  let value;
52
+ let sourceValue;
52
53
  switch (mapping.mappingType) {
53
54
  case "DIRECT":
54
55
  value = this.getNestedValue(sourceRecord.data, mapping.sourceField);
55
56
  break;
56
57
  case "TRANSFORM":
57
- const sourceValue = this.getNestedValue(sourceRecord.data, mapping.sourceField);
58
+ sourceValue = this.getNestedValue(sourceRecord.data, mapping.sourceField);
58
59
  value = mapping.transformExpression ? this.transformer.transform(sourceValue, mapping.transformExpression) : sourceValue;
59
60
  break;
60
61
  case "CONSTANT":
@@ -143,4 +144,5 @@ function hasChanges(sourceChecksum, targetChecksum) {
143
144
  }
144
145
 
145
146
  //#endregion
146
- export { BasicFieldTransformer, BasicSyncEngine, computeChecksum, createSyncEngine, hasChanges };
147
+ export { BasicFieldTransformer, BasicSyncEngine, computeChecksum, createSyncEngine, hasChanges };
148
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["targetData: Record<string, unknown>","value: unknown","sourceValue: unknown","errors: SyncError[]","current: unknown"],"sources":["../../src/sync-engine/index.ts"],"sourcesContent":["/**\n * Sync Engine\n *\n * Core sync logic for the Integration Hub.\n */\n\n// ============ Types ============\n\nexport interface FieldMapping {\n sourceField: string;\n targetField: string;\n mappingType: 'DIRECT' | 'TRANSFORM' | 'LOOKUP' | 'CONSTANT' | 'COMPUTED';\n transformExpression?: string;\n lookupConfig?: LookupConfig;\n constantValue?: unknown;\n isRequired: boolean;\n defaultValue?: unknown;\n}\n\nexport interface LookupConfig {\n sourceObject: string;\n lookupField: string;\n returnField: string;\n}\n\nexport interface SyncConfig {\n id: string;\n direction: 'INBOUND' | 'OUTBOUND' | 'BIDIRECTIONAL';\n sourceObject: string;\n targetObject: string;\n fieldMappings: FieldMapping[];\n createNew: boolean;\n updateExisting: boolean;\n deleteRemoved: boolean;\n sourceFilter?: Record<string, unknown>;\n}\n\nexport interface SyncContext {\n runId: string;\n config: SyncConfig;\n connection: {\n id: string;\n authType: string;\n credentials?: Record<string, unknown>;\n };\n}\n\nexport interface SyncResult {\n success: boolean;\n recordsProcessed: number;\n recordsCreated: number;\n recordsUpdated: number;\n recordsDeleted: number;\n recordsFailed: number;\n recordsSkipped: number;\n errors: SyncError[];\n}\n\nexport interface SyncError {\n recordId?: string;\n field?: string;\n message: string;\n code: string;\n}\n\nexport interface SourceRecord {\n id: string;\n data: Record<string, unknown>;\n checksum?: string;\n}\n\nexport interface TargetRecord {\n id: string;\n data: Record<string, unknown>;\n checksum?: string;\n}\n\n// ============ Sync Engine Interface ============\n\nexport interface ISyncEngine {\n /**\n * Execute a sync operation.\n */\n sync(context: SyncContext): Promise<SyncResult>;\n\n /**\n * Transform a source record to target format.\n */\n transformRecord(\n sourceRecord: SourceRecord,\n mappings: FieldMapping[],\n context: SyncContext\n ): TargetRecord;\n\n /**\n * Validate a transformed record.\n */\n validateRecord(\n record: TargetRecord,\n mappings: FieldMapping[]\n ): { valid: boolean; errors: SyncError[] };\n}\n\n// ============ Field Transformer ============\n\nexport interface IFieldTransformer {\n transform(value: unknown, expression: string): unknown;\n}\n\nexport class BasicFieldTransformer implements IFieldTransformer {\n transform(value: unknown, expression: string): unknown {\n // Simple expression evaluation\n // In production, use a proper expression language\n try {\n if (expression.startsWith('uppercase')) {\n return typeof value === 'string' ? value.toUpperCase() : value;\n }\n if (expression.startsWith('lowercase')) {\n return typeof value === 'string' ? value.toLowerCase() : value;\n }\n if (expression.startsWith('trim')) {\n return typeof value === 'string' ? value.trim() : value;\n }\n if (expression.startsWith('default:')) {\n const defaultVal = expression.replace('default:', '');\n return value ?? JSON.parse(defaultVal);\n }\n if (expression.startsWith('concat:')) {\n const separator = expression.replace('concat:', '') || ' ';\n if (Array.isArray(value)) {\n return value.join(separator);\n }\n return value;\n }\n if (expression.startsWith('split:')) {\n const separator = expression.replace('split:', '') || ',';\n if (typeof value === 'string') {\n return value.split(separator);\n }\n return value;\n }\n if (expression.startsWith('number')) {\n return Number(value);\n }\n if (expression.startsWith('boolean')) {\n return Boolean(value);\n }\n if (expression.startsWith('string')) {\n return String(value);\n }\n\n // Return as-is if no transformation matches\n return value;\n } catch {\n return value;\n }\n }\n}\n\n// ============ Basic Sync Engine ============\n\nexport class BasicSyncEngine implements ISyncEngine {\n private transformer: IFieldTransformer;\n\n constructor(transformer?: IFieldTransformer) {\n this.transformer = transformer ?? new BasicFieldTransformer();\n }\n\n async sync(_context: SyncContext): Promise<SyncResult> {\n const result: SyncResult = {\n success: true,\n recordsProcessed: 0,\n recordsCreated: 0,\n recordsUpdated: 0,\n recordsDeleted: 0,\n recordsFailed: 0,\n recordsSkipped: 0,\n errors: [],\n };\n\n // In a real implementation, this would:\n // 1. Fetch records from source\n // 2. Transform each record\n // 3. Validate each record\n // 4. Upsert to target\n // 5. Track sync records for deduplication\n\n return result;\n }\n\n transformRecord(\n sourceRecord: SourceRecord,\n mappings: FieldMapping[],\n _context: SyncContext\n ): TargetRecord {\n const targetData: Record<string, unknown> = {};\n\n for (const mapping of mappings) {\n let value: unknown;\n let sourceValue: unknown;\n\n switch (mapping.mappingType) {\n case 'DIRECT':\n value = this.getNestedValue(sourceRecord.data, mapping.sourceField);\n break;\n\n case 'TRANSFORM':\n sourceValue = this.getNestedValue(\n sourceRecord.data,\n mapping.sourceField\n );\n value = mapping.transformExpression\n ? this.transformer.transform(\n sourceValue,\n mapping.transformExpression\n )\n : sourceValue;\n break;\n\n case 'CONSTANT':\n value = mapping.constantValue;\n break;\n\n case 'LOOKUP':\n // In production, this would fetch from a lookup table\n value = this.getNestedValue(sourceRecord.data, mapping.sourceField);\n break;\n\n case 'COMPUTED':\n // In production, this would evaluate a computed expression\n value = mapping.transformExpression\n ? this.evaluateComputed(\n sourceRecord.data,\n mapping.transformExpression\n )\n : null;\n break;\n\n default:\n value = this.getNestedValue(sourceRecord.data, mapping.sourceField);\n }\n\n // Apply default value if needed\n if (value === undefined || value === null) {\n value = mapping.defaultValue;\n }\n\n // Set the target field\n this.setNestedValue(targetData, mapping.targetField, value);\n }\n\n return {\n id: sourceRecord.id,\n data: targetData,\n };\n }\n\n validateRecord(\n record: TargetRecord,\n mappings: FieldMapping[]\n ): { valid: boolean; errors: SyncError[] } {\n const errors: SyncError[] = [];\n\n for (const mapping of mappings) {\n if (mapping.isRequired) {\n const value = this.getNestedValue(record.data, mapping.targetField);\n if (value === undefined || value === null) {\n errors.push({\n recordId: record.id,\n field: mapping.targetField,\n message: `Required field ${mapping.targetField} is missing`,\n code: 'REQUIRED_FIELD_MISSING',\n });\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n private getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = obj;\n\n for (const part of parts) {\n if (current === null || current === undefined) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n\n return current;\n }\n\n private setNestedValue(\n obj: Record<string, unknown>,\n path: string,\n value: unknown\n ): void {\n const parts = path.split('.');\n let current = obj;\n\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n if (part === undefined) continue;\n if (!(part in current)) {\n current[part] = {};\n }\n current = current[part] as Record<string, unknown>;\n }\n\n const lastPart = parts[parts.length - 1];\n if (lastPart !== undefined) {\n current[lastPart] = value;\n }\n }\n\n private evaluateComputed(\n data: Record<string, unknown>,\n expression: string\n ): unknown {\n // Simple computed field evaluation\n // In production, use a proper expression evaluator\n try {\n // Support simple field references like ${field.path}\n const result = expression.replace(/\\$\\{([^}]+)\\}/g, (_, path) => {\n const value = this.getNestedValue(data, path);\n return String(value ?? '');\n });\n return result;\n } catch {\n return null;\n }\n }\n}\n\n// ============ Factory ============\n\nexport function createSyncEngine(transformer?: IFieldTransformer): ISyncEngine {\n return new BasicSyncEngine(transformer);\n}\n\n// ============ Checksum Utilities ============\n\nexport function computeChecksum(data: Record<string, unknown>): string {\n // Simple checksum based on JSON serialization\n // In production, use a proper hash function\n const str = JSON.stringify(data, Object.keys(data).sort());\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return hash.toString(16);\n}\n\nexport function hasChanges(\n sourceChecksum: string | undefined,\n targetChecksum: string | undefined\n): boolean {\n if (!sourceChecksum || !targetChecksum) {\n return true;\n }\n return sourceChecksum !== targetChecksum;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lssm/example.integration-hub",
3
- "version": "0.0.0-canary-20251217083314",
3
+ "version": "0.0.0-canary-20251220002821",
4
4
  "description": "Integration Hub example with sync engine and field mappings for ContractSpec",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -18,20 +18,20 @@
18
18
  "lint:check": "eslint src"
19
19
  },
20
20
  "dependencies": {
21
- "@lssm/lib.schema": "0.0.0-canary-20251217083314",
22
- "@lssm/lib.contracts": "0.0.0-canary-20251217083314",
23
- "@lssm/lib.bus": "0.0.0-canary-20251217083314",
24
- "@lssm/lib.identity-rbac": "0.0.0-canary-20251217083314",
25
- "@lssm/lib.files": "0.0.0-canary-20251217083314",
26
- "@lssm/lib.feature-flags": "0.0.0-canary-20251217083314",
27
- "@lssm/lib.jobs": "0.0.0-canary-20251217083314",
28
- "@lssm/module.audit-trail": "0.0.0-canary-20251217083314",
29
- "@lssm/module.notifications": "0.0.0-canary-20251217083314",
21
+ "@lssm/lib.schema": "0.0.0-canary-20251220002821",
22
+ "@lssm/lib.contracts": "0.0.0-canary-20251220002821",
23
+ "@lssm/lib.bus": "0.0.0-canary-20251220002821",
24
+ "@lssm/lib.identity-rbac": "0.0.0-canary-20251220002821",
25
+ "@lssm/lib.files": "0.0.0-canary-20251220002821",
26
+ "@lssm/lib.feature-flags": "0.0.0-canary-20251220002821",
27
+ "@lssm/lib.jobs": "0.0.0-canary-20251220002821",
28
+ "@lssm/module.audit-trail": "0.0.0-canary-20251220002821",
29
+ "@lssm/module.notifications": "0.0.0-canary-20251220002821",
30
30
  "zod": "^4.1.13"
31
31
  },
32
32
  "devDependencies": {
33
- "@lssm/tool.typescript": "0.0.0-canary-20251217083314",
34
- "@lssm/tool.tsdown": "0.0.0-canary-20251217083314",
33
+ "@lssm/tool.typescript": "0.0.0-canary-20251220002821",
34
+ "@lssm/tool.tsdown": "0.0.0-canary-20251220002821",
35
35
  "typescript": "^5.9.3"
36
36
  },
37
37
  "exports": {
@@ -90,6 +90,13 @@
90
90
  "./sync/sync.presentation": "./dist/sync/sync.presentation.js",
91
91
  "./sync/sync.schema": "./dist/sync/sync.schema.js",
92
92
  "./*": "./*"
93
- }
93
+ },
94
+ "registry": "https://registry.npmjs.org/"
95
+ },
96
+ "license": "MIT",
97
+ "repository": {
98
+ "type": "git",
99
+ "url": "https://github.com/lssm-tech/contractspec.git",
100
+ "directory": "packages/examples/integration-hub"
94
101
  }
95
102
  }
@@ -1,16 +0,0 @@
1
- import { registerDocBlocks } from "./registry.js";
2
-
3
- //#region ../../libs/contracts/dist/docs/PUBLISHING.docblock.js
4
- const PUBLISHING_DocBlocks = [{
5
- id: "docs.PUBLISHING",
6
- title: "Publishing ContractSpec Libraries",
7
- summary: "This guide describes how we release the ContractSpec libraries to npm. We use a dual-track release system: **Stable** (manual) and **Canary** (automatic).",
8
- kind: "reference",
9
- visibility: "public",
10
- route: "/docs/PUBLISHING",
11
- tags: ["PUBLISHING"],
12
- body: "# Publishing ContractSpec Libraries\n\nThis guide describes how we release the ContractSpec libraries to npm. We use a dual-track release system: **Stable** (manual) and **Canary** (automatic).\n\n## Release Tracks\n\n| Track | Branch | npm Tag | Frequency | Versioning | Use Case |\n|-------|--------|---------|-----------|------------|----------|\n| **Stable** | `release` | `latest` | Manual | SemVer (e.g., `1.7.4`) | Production, external users |\n| **Canary** | `main` | `canary` | Every Push | Snapshot (e.g., `1.7.4-canary...`) | Dev, internal testing |\n\n## Prerequisites\n\n- ✅ `NPM_TOKEN` secret is configured in GitHub (owner or automation token with _publish_ scope).\n- ✅ `GITHUB_TOKEN` (built-in) has permissions to create PRs (enabled by default in new repos).\n- ✅ For stable releases: `release` branch exists and is protected.\n\n## Canary Workflow (Automatic)\n\nEvery commit pushed to `main` triggers the `.github/workflows/publish-canary.yml` workflow.\n\n1. **Trigger**: Push to `main`.\n2. **Versioning**: Runs `changeset version --snapshot canary` to generate a temporary snapshot version.\n3. **Publish**: Packages are published to npm with the `canary` tag using `changeset publish --tag canary`.\n\n### Consuming Canary Builds\n\nTo install the latest bleeding-edge version:\n\n```bash\nnpm install @lssm/lib.contracts@canary\n# or\nbun add @lssm/lib.contracts@canary\n```\n\n## Stable Release Workflow (Manual)\n\nStable releases are managed via the `release` branch using the standard [Changesets Action](https://github.com/changesets/action).\n\n1. **Develop on `main`**: Create features and fixes.\n2. **Add Changesets**: Run `bun changeset` to document changes and impact (major/minor/patch).\n3. **Merge to `release`**: When ready to ship, open a PR from `main` to `release` or merge manually.\n4. **\"Version Packages\" PR**:\n - The GitHub Action detects new changesets and automatically creates a Pull Request titled **\"Version Packages\"**.\n - This PR contains the version bumps and updated `CHANGELOG.md` files.\n5. **Merge & Publish**:\n - Review and merge the \"Version Packages\" PR.\n - The Action runs again, detects the versions have been bumped, builds the libraries, and publishes them to npm with the `latest` tag.\n\n### Publishing Steps\n\n1. Ensure all changesets are present on `main`.\n2. Merge `main` into `release`:\n ```bash\n git checkout release\n git pull origin release\n git merge main\n git push origin release\n ```\n3. Go to GitHub Pull Requests. You will see a **\"Version Packages\"** PR created by the bot.\n4. Merge that PR.\n5. The release is now live on npm!\n\n## Manual Verification (Optional)\n\nBefore publishing a new version you can run:\n\n```bash\nbun run build:not-apps\nnpx npm-packlist --json packages/libs/contracts\n```\n\n## Rollback\n\nIf a publish fails mid-way, re-run the workflow once the issue is fixed. Already published packages are skipped automatically. Use `npm deprecate <package>@<version>` if we need to warn consumers about a broken release.\n"
13
- }];
14
- registerDocBlocks(PUBLISHING_DocBlocks);
15
-
16
- //#endregion
@@ -1,16 +0,0 @@
1
- import { registerDocBlocks } from "../registry.js";
2
-
3
- //#region ../../libs/contracts/dist/docs/tech/PHASE_1_QUICKSTART.docblock.js
4
- const tech_PHASE_1_QUICKSTART_DocBlocks = [{
5
- id: "docs.tech.PHASE_1_QUICKSTART",
6
- title: "Phase 1: API Reference Index",
7
- summary: "Quick reference for all new Phase 1 APIs.",
8
- kind: "reference",
9
- visibility: "public",
10
- route: "/docs/tech/PHASE_1_QUICKSTART",
11
- tags: ["tech", "PHASE_1_QUICKSTART"],
12
- body: "# Phase 1: API Reference Index\n\nQuick reference for all new Phase 1 APIs.\n\n---\n\n## @lssm/lib.multi-tenancy\n\n### RLS\n```typescript\nimport { createRlsMiddleware, type TenantIdProvider } from '@lssm/lib.multi-tenancy/rls';\n```\n\n### Provisioning\n```typescript\nimport { \n TenantProvisioningService,\n type CreateTenantInput,\n type TenantProvisioningConfig \n} from '@lssm/lib.multi-tenancy/provisioning';\n```\n\n### Isolation\n```typescript\nimport { IsolationValidator } from '@lssm/lib.multi-tenancy/isolation';\n```\n\n---\n\n## @lssm/lib.observability\n\n### Tracing\n```typescript\nimport { \n getTracer,\n traceAsync,\n traceSync,\n createTracingMiddleware \n} from '@lssm/lib.observability/tracing';\n```\n\n### Metrics\n```typescript\nimport {\n getMeter,\n createCounter,\n createUpDownCounter,\n createHistogram,\n standardMetrics\n} from '@lssm/lib.observability/metrics';\n```\n\n### Logging\n```typescript\nimport {\n Logger,\n logger,\n type LogLevel,\n type LogEntry\n} from '@lssm/lib.observability/logging';\n```\n\n---\n\n## @lssm/lib.resilience\n\n### Circuit Breaker\n```typescript\nimport {\n CircuitBreaker,\n type CircuitState,\n type CircuitBreakerConfig\n} from '@lssm/lib.resilience/circuit-breaker';\n```\n\n### Retry\n```typescript\nimport { retry } from '@lssm/lib.resilience/retry';\n```\n\n### Timeout\n```typescript\nimport { timeout } from '@lssm/lib.resilience/timeout';\n```\n\n### Fallback\n```typescript\nimport { fallback } from '@lssm/lib.resilience/fallback';\n```\n\n---\n\n## Enhanced: @lssm/lib.contracts\n\n### DataViews\n```typescript\nimport { DataViewQueryGenerator } from '@lssm/lib.contracts/data-views/query-generator';\nimport { DataViewRuntime } from '@lssm/lib.contracts/data-views/runtime';\n```\n\n### Workflows\n```typescript\nimport { SLAMonitor, type SLABreachEvent } from '@lssm/lib.contracts/workflow/sla-monitor';\nimport { PrismaStateStore } from '@lssm/lib.contracts/workflow/adapters/db-adapter';\n```\n\n---\n\n## Enhanced: @lssm/lib.design-system\n\n### DataView Components\n```typescript\nimport { DataViewRenderer } from '@lssm/lib.design-system/components/data-view/DataViewRenderer';\n// Also available: DataViewList, DataViewTable, DataViewDetail\n```\n\n---\n\n## Usage Examples\n\n### Complete Workflow with All Features\n\n```typescript\nimport { WorkflowRunner } from '@lssm/lib.contracts/workflow/runner';\nimport { PrismaStateStore } from '@lssm/lib.contracts/workflow/adapters/db-adapter';\nimport { SLAMonitor } from '@lssm/lib.contracts/workflow/sla-monitor';\nimport { CircuitBreaker } from '@lssm/lib.resilience/circuit-breaker';\nimport { traceAsync } from '@lssm/lib.observability/tracing';\n\nconst runner = new WorkflowRunner({\n registry,\n stateStore: new PrismaStateStore(db),\n opExecutor: async (op, input, ctx) => {\n return traceAsync(`op.${op.name}`, async (span) => {\n span.setAttribute('operation', op.name);\n const breaker = getCircuitBreaker(op.name);\n return breaker.execute(() => executeOperation(op, input, ctx));\n });\n },\n eventEmitter: (event, payload) => {\n if (event.startsWith('workflow.')) {\n logger.info(event, payload);\n }\n },\n});\n\nconst monitor = new SLAMonitor((event, payload) => {\n logger.warn('SLA_BREACH', payload);\n alertOps(payload);\n});\n\n// Start workflow\nconst workflowId = await runner.start('payment.flow', 1);\n\n// Monitor SLA\nconst state = await runner.getState(workflowId);\nconst spec = registry.get('payment.flow', 1);\nmonitor.check(state, spec!);\n```\n\n### Complete DataView with Observability\n\n```typescript\nimport { DataViewRenderer } from '@lssm/lib.design-system';\nimport { DataViewQueryGenerator } from '@lssm/lib.contracts/data-views/query-generator';\nimport { traceAsync } from '@lssm/lib.observability/tracing';\nimport { MyDataView } from './specs/users.data-view';\n\nexport function UserListPage() {\n const [page, setPage] = useState(1);\n const [users, setUsers] = useState([]);\n\n const loadUsers = async () => {\n return traceAsync('load_users', async (span) => {\n const generator = new DataViewQueryGenerator(MyDataView);\n const query = generator.generate({ pagination: { page, pageSize: 20 } });\n \n span.setAttribute('page', page);\n const result = await api.execute(query);\n setUsers(result.data);\n });\n };\n\n return (\n <DataViewRenderer\n spec={MyDataView}\n items={users}\n pagination={{ page, pageSize: 20, total: users.length }}\n onPageChange={setPage}\n />\n );\n}\n```\n\n### Complete Multi-Tenant Setup\n\n```typescript\n// 1. RLS Middleware\nimport { createRlsMiddleware } from '@lssm/lib.multi-tenancy/rls';\ndb.$use(createRlsMiddleware(() => req.tenantId));\n\n// 2. Tenant Provisioning\nimport { TenantProvisioningService } from '@lssm/lib.multi-tenancy/provisioning';\nconst service = new TenantProvisioningService({ db });\n\n// 3. Create new tenant\nawait service.provision({\n id: 'acme',\n name: 'Acme Corp',\n slug: 'acme',\n ownerEmail: 'admin@acme.com',\n});\n\n// 4. Validate isolation in tests\nimport { IsolationValidator } from '@lssm/lib.multi-tenancy/isolation';\n\ntest('queries are isolated', () => {\n const isValid = IsolationValidator.validateQuery(\n 'User',\n 'findMany',\n { where: { tenantId: 'acme' } },\n 'acme'\n );\n expect(isValid).toBe(true);\n});\n```\n\n---\n\n## Testing\n\n### Test Circuit Breakers\n\n```typescript\nimport { CircuitBreaker } from '@lssm/lib.resilience/circuit-breaker';\n\ntest('circuit opens after threshold', async () => {\n const breaker = new CircuitBreaker({\n failureThreshold: 3,\n resetTimeoutMs: 5000,\n });\n\n // Trigger failures\n for (let i = 0; i < 3; i++) {\n await expect(\n breaker.execute(() => Promise.reject('error'))\n ).rejects.toThrow();\n }\n\n // Circuit should be open\n await expect(\n breaker.execute(() => Promise.resolve('ok'))\n ).rejects.toThrow('CircuitBreaker is OPEN');\n});\n```\n\n### Test Workflow Retry\n\n```typescript\ntest('workflow retries on failure', async () => {\n let attempts = 0;\n const opExecutor = async () => {\n attempts++;\n if (attempts < 3) throw new Error('fail');\n return 'success';\n };\n\n const runner = new WorkflowRunner({ /* ... */ opExecutor });\n await runner.executeStep(workflowId);\n \n expect(attempts).toBe(3);\n});\n```\n\n---\n\n## Common Patterns\n\n### Pattern: Resilient External Call\n\n```typescript\nimport { CircuitBreaker } from '@lssm/lib.resilience/circuit-breaker';\nimport { retry } from '@lssm/lib.resilience/retry';\nimport { timeout } from '@lssm/lib.resilience/timeout';\nimport { traceAsync } from '@lssm/lib.observability/tracing';\n\nconst breaker = new CircuitBreaker({ failureThreshold: 5, resetTimeoutMs: 30000 });\n\nexport async function callExternalAPI(input: any) {\n return traceAsync('external_api_call', async (span) => {\n span.setAttribute('service', 'stripe');\n \n return breaker.execute(() =>\n retry(\n () => timeout(() => stripe.api.call(input), 5000),\n 3,\n 1000,\n true\n )\n );\n });\n}\n```\n\n**Benefits**: Circuit breaker + retry + timeout + tracing in one place.\n\n---\n\n### Pattern: Tenant-Aware Operation\n\n```typescript\nimport { traceAsync } from '@lssm/lib.observability/tracing';\n\nexport async function listUsers(tenantId: string) {\n return traceAsync('list_users', async (span) => {\n span.setAttribute('tenant_id', tenantId);\n \n // RLS middleware will inject WHERE tenantId = ?\n return db.user.findMany();\n });\n}\n```\n\n---\n\n### Pattern: Monitored Workflow\n\n```typescript\nimport { WorkflowRunner } from '@lssm/lib.contracts/workflow/runner';\nimport { SLAMonitor } from '@lssm/lib.contracts/workflow/sla-monitor';\nimport { logger } from '@lssm/lib.observability/logging';\n\nconst monitor = new SLAMonitor((event, payload) => {\n logger.warn('workflow.sla_breach', payload);\n});\n\n// In workflow poller\nconst state = await runner.getState(workflowId);\nconst spec = registry.get(state.workflowName, state.workflowVersion);\nif (spec) {\n monitor.check(state, spec);\n}\n```\n\n---\n\n## Next Steps\n\n1. **Implement one quick win** (30 minutes)\n2. **Add tests for new functionality** (1 hour)\n3. **Deploy to staging and verify observability** (1 hour)\n4. **Roll out to production** (monitor closely)\n5. **Read full documentation** at https://contractspec.lssm.tech/docs\n\n---\n\n**Questions?** See `/docs/guides/phase-1-migration` or reach out via https://contractspec.lssm.tech/contact\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
13
- }];
14
- registerDocBlocks(tech_PHASE_1_QUICKSTART_DocBlocks);
15
-
16
- //#endregion
@@ -1,16 +0,0 @@
1
- import { registerDocBlocks } from "../registry.js";
2
-
3
- //#region ../../libs/contracts/dist/docs/tech/PHASE_2_AI_NATIVE_OPERATIONS.docblock.js
4
- const tech_PHASE_2_AI_NATIVE_OPERATIONS_DocBlocks = [{
5
- id: "docs.tech.PHASE_2_AI_NATIVE_OPERATIONS",
6
- title: "Phase 2: AI-Native Operations",
7
- summary: "_Last updated: 2025-11-20_",
8
- kind: "reference",
9
- visibility: "public",
10
- route: "/docs/tech/PHASE_2_AI_NATIVE_OPERATIONS",
11
- tags: ["tech", "PHASE_2_AI_NATIVE_OPERATIONS"],
12
- body: "# Phase 2: AI-Native Operations\n\n_Last updated: 2025-11-20_\n\nPhase 2 turns ContractSpec into an AI-first operations stack. The new libraries below are the building blocks used by support bots, growth agents, and human-in-the-loop flows.\n\n## Libraries\n\n### @lssm/lib.ai-agent\n\n- **Spec + Registry**: `defineAgent`, `AgentRegistry` keep agent definitions type-safe.\n- **Runner**: `AgentRunner` drives LLM conversations, tool calls, retries, escalation, and telemetry hooks.\n- **Tools**: `ToolExecutor` standardizes schema validation + timeouts.\n- **Memory**: `InMemoryAgentMemory` + interfaces for plugging persistent stores.\n- **Approvals**: new `ApprovalWorkflow` + `InMemoryApprovalStore` capture low-confidence decisions and surface them to reviewers.\n\n### @lssm/lib.support-bot\n\nComposable support automation primitives:\n\n- `TicketClassifier` → heuristics + optional LLM validation for category, priority, sentiment.\n- `TicketResolver` → RAG pipeline backed by knowledge spaces.\n- `AutoResponder` → tone-aware drafts with citations.\n- `SupportFeedbackLoop` → tracks resolution rates.\n- `createSupportTools` → ready-made tool definitions for AgentRunner.\n\n### @lssm/lib.content-gen\n\nContent generators that consume a `ContentBrief` and output production-ready assets:\n\n- `BlogGenerator`, `LandingPageGenerator`, `EmailCampaignGenerator`, `SocialPostGenerator`.\n- `SeoOptimizer` builds metadata + schema markup.\n\n### @lssm/lib.analytics\n\nQueryless analytics helpers:\n\n- `FunnelAnalyzer` – conversion/drop-off per step.\n- `CohortTracker` – retention + LTV per cohort.\n- `ChurnPredictor` – recency/frequency/error scoring.\n- `GrowthHypothesisGenerator` – surfaces experiment ideas from metric trends.\n\n### @lssm/lib.growth\n\nA/B testing toolkit:\n\n- `ExperimentRegistry` + `ExperimentRunner` – deterministic bucketing.\n- `ExperimentTracker` – persist exposures + metrics.\n- `StatsEngine` – Welch’s t-test + improvement calculations.\n\n### Human-in-the-loop UI\n\n`@lssm/lib.design-system` now exposes:\n\n- `ApprovalQueue` – list + act on pending approvals.\n- `AgentMonitor` – live view of agent sessions with confidence + status.\n\n## Examples\n\n- `examples/ai-support-bot/setup.ts` shows ticket classification → resolution → response draft.\n- `examples/content-generation/generate.ts` produces blog, landing, email, social, SEO output from one brief.\n\n## Next Steps\n\n1. Wire these libraries into vertical apps (H-Circle, ArtisanOS, etc.).\n2. Add background workers that consume the new analytics/growth trackers.\n3. Expand web-landing to highlight these Phase 2 capabilities (see separate TODO).\n"
13
- }];
14
- registerDocBlocks(tech_PHASE_2_AI_NATIVE_OPERATIONS_DocBlocks);
15
-
16
- //#endregion
@@ -1,16 +0,0 @@
1
- import { registerDocBlocks } from "../registry.js";
2
-
3
- //#region ../../libs/contracts/dist/docs/tech/PHASE_3_AUTO_EVOLUTION.docblock.js
4
- const tech_PHASE_3_AUTO_EVOLUTION_DocBlocks = [{
5
- id: "docs.tech.PHASE_3_AUTO_EVOLUTION",
6
- title: "Phase 3: Auto-Evolution Technical Notes",
7
- summary: "**Status**: In progress",
8
- kind: "reference",
9
- visibility: "public",
10
- route: "/docs/tech/PHASE_3_AUTO_EVOLUTION",
11
- tags: ["tech", "PHASE_3_AUTO_EVOLUTION"],
12
- body: "# Phase 3: Auto-Evolution Technical Notes\n\n**Status**: In progress \n**Last updated**: 2025-11-21 \n\nPhase 3 introduces self-learning capabilities that analyze production telemetry, suggest new specs, safely roll out variants, and generate golden tests from real traffic. This document captures the main building blocks delivered in this iteration.\n\n---\n\n## 1. Libraries\n\n### @lssm/lib.evolution\n\n- `SpecAnalyzer` converts raw telemetry samples into usage stats + anomalies.\n- `SpecGenerator` produces `SpecSuggestion` objects and validates confidence thresholds.\n- `SpecSuggestionOrchestrator` routes proposals through the AI approval workflow and writes approved specs to `packages/libs/contracts/src/generated`.\n- Storage adapters:\n - `InMemorySpecSuggestionRepository` for tests.\n - `PrismaSpecSuggestionRepository` persists to the new Prisma model (see §4).\n - `FileSystemSuggestionWriter` emits JSON envelopes for git review.\n\n### @lssm/lib.observability\n\n- Added intent detection modules:\n - `IntentAggregator` batches telemetry into rolling windows.\n - `IntentDetector` surfaces latency/error/throughput regressions and sequential intents.\n- `EvolutionPipeline` orchestrates aggregation → detection → intent events and exposes hooks for downstream orchestrators.\n- `createTracingMiddleware` now accepts `resolveOperation`/`onSample` hooks to feed telemetry samples into the pipeline.\n\n### @lssm/lib.growth\n\n- New `spec-experiments` module:\n - `SpecExperimentRegistry`, `SpecExperimentRunner`, `SpecExperimentAdapter`.\n - `SpecExperimentAnalyzer` + `SpecExperimentController` handle guardrails and staged rollouts.\n - Helper `createSpecVariantResolver` plugs directly into `HandlerCtx.specVariantResolver`.\n- `SpecVariantResolver` is now a first-class concept in `@lssm/lib.contracts`. The runtime will attempt to execute variant specs before falling back to the registered handler.\n\n### @lssm/lib.testing\n\n- `TrafficRecorder` + `TrafficStore` capture production requests with sampling and sanitization hooks.\n- `GoldenTestGenerator` converts `TrafficSnapshot`s into Vitest/Jest suites.\n- `generateVitestSuite` / `generateJestSuite` output self-contained test files, and `runGoldenTests` offers a programmatic harness for CI pipelines.\n\n---\n\n## 2. Telemetry → Intent → Spec Pipeline\n\n1. `createTracingMiddleware({ onSample })` emits `TelemetrySample`s for every HTTP request.\n2. `IntentAggregator` groups samples into statistical windows (default 15 minutes).\n3. `IntentDetector` raises signals for:\n - Error spikes\n - Latency regressions\n - Throughput drops\n - Sequential workflows that hint at missing specs\n4. `EvolutionPipeline` emits `intent.detected` events and hands them to `SpecGenerator`.\n5. `SpecSuggestionOrchestrator` persists suggestions, triggers approval workflows, and—upon approval—writes JSON envelopes to `packages/.../contracts/src/generated`.\n\n---\n\n## 3. Spec Experiments & Rollouts\n\n1. Register spec experiments in `SpecExperimentRegistry` with control + variant bindings.\n2. Expose bucketed specs by attaching `createSpecVariantResolver` to `HandlerCtx.specVariantResolver` inside adapters.\n3. Record outcomes via `SpecExperimentAdapter.trackOutcome()` (latency + error metrics).\n4. `SpecExperimentController` uses guardrails from config and `SpecExperimentAnalyzer` to:\n - Auto-rollback on error/latency breaches.\n - Advance rollout stages (1% → 10% → 50% → 100%) when metrics stay green.\n\n---\n\n## 4. Data Models (Prisma)\n\nFile: `packages/libs/database/prisma/schema.prisma`\n\n- `SpecSuggestion` – stores serialized suggestion payloads + statuses.\n- `IntentSnapshot` – captured detector output for auditing/training.\n- `TrafficSnapshot` – persisted production traffic (input/output/error blobs).\n- `SpecExperiment` / `SpecExperimentMetric` – rollout state + metrics for each variant.\n\n> Run `bun database generate` after pulling to refresh the Prisma client.\n\n---\n\n## 5. Golden Test Workflow\n\n1. Capture traffic via middleware or direct `TrafficRecorder.record`.\n2. Use the new CLI command to materialize suites:\n\n```bash\ncontractspec test generate \\\n --operation billing.createInvoice \\\n --output tests/billing.createInvoice.golden.test.ts \\\n --runner-import ./tests/run-operation \\\n --runner-fn runBillingCommand \\\n --from-production \\\n --days 7 \\\n --sample-rate 0.05\n```\n\n3. Generated files import your runner and assert against recorded outputs (or expected errors for negative paths).\n\n---\n\n## 6. Operational Notes\n\n- **Approvals**: By default, every suggestion still requires human approval. `EvolutionConfig.autoApproveThreshold` can be tuned per environment but should remain conservative (<0.3) until OverlaySpec tooling lands.\n- **Sampling**: Keep `TrafficRecorder.sampleRate` ≤ 0.05 in production to avoid sensitive payload storage; scrub PII through the `sanitize` callback before persistence.\n- **Rollouts**: Guardrails default to 5% error-rate and 750ms P99 latency. Override per experiment to match SLOs.\n\n---\n\n## 7. Next Steps\n\n1. Wire `SpecExperimentAdapter.trackOutcome` into adapters (REST, GraphQL, Workers) so every execution logs metrics automatically.\n2. Add a UI for reviewing `SpecSuggestion` objects alongside approval status.\n3. Expand `TrafficRecorder` to ship directly to the Prisma-backed store (currently in-memory by default).\n4. Integrate `EvolutionPipeline` events with the Regenerator to close the loop (auto-open proposals + attach evidence).\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
13
- }];
14
- registerDocBlocks(tech_PHASE_3_AUTO_EVOLUTION_DocBlocks);
15
-
16
- //#endregion
@@ -1,16 +0,0 @@
1
- import { registerDocBlocks } from "../registry.js";
2
-
3
- //#region ../../libs/contracts/dist/docs/tech/PHASE_4_PERSONALIZATION_ENGINE.docblock.js
4
- const tech_PHASE_4_PERSONALIZATION_ENGINE_DocBlocks = [{
5
- id: "docs.tech.PHASE_4_PERSONALIZATION_ENGINE",
6
- title: "Phase 4: Personalization Engine",
7
- summary: "**Status**: Complete",
8
- kind: "reference",
9
- visibility: "public",
10
- route: "/docs/tech/PHASE_4_PERSONALIZATION_ENGINE",
11
- tags: ["tech", "PHASE_4_PERSONALIZATION_ENGINE"],
12
- body: "# Phase 4: Personalization Engine\n\n**Status**: Complete \n**Last updated**: 2025-11-21\n\nPhase 4 unlocks tenant-scoped personalization with zero bespoke code. We shipped three new libraries, a signing-aware Overlay editor, and the persistence layer required to observe usage and apply overlays safely.\n\n---\n\n## 1. Libraries\n\n### @lssm/lib.overlay-engine\n\n- OverlaySpec types + validator mirror the public spec.\n- Cryptographic signer (`ed25519`, `rsa-pss-sha256`) with canonical JSON serialization.\n- Registry that merges tenant/role/user/device overlays with predictable specificity.\n- React hooks (`useOverlay`, `useOverlayFields`) for client-side rendering.\n- Runtime engine audits every applied overlay for traceability.\n\n### @lssm/lib.personalization\n\n- Behavior tracker buffers field/feature/workflow events and exports OTel metrics.\n- Analyzer summarizes field usage and workflow drop-offs into actionable insights.\n- Adapter translates insights into overlay suggestions or workflow tweaks.\n- In-memory store implementation + interface for plugging Prisma/ClickHouse later.\n\n### @lssm/lib.workflow-composer\n\n- `WorkflowComposer` merges base workflows with tenant/role/device extensions.\n- Step injection utilities keep transitions intact and validate anchor steps.\n- Template helpers for common tenant review/approval, plus merge helpers for multi-scope extensions.\n\n---\n\n## 2. Overlay Editor App\n\nPath: `packages/apps/overlay-editor`\n\n- Next.js App Router UI for toggling field visibility, renaming labels, and reordering lists.\n- Live JSON preview powered by `defineOverlay`.\n- Server action that signs overlays via PEM private keys (Ed25519 by default) using the overlay engine signer.\n\n---\n\n## 3. Persistence\n\nAdded Prisma models (see `packages/libs/database/prisma/schema.prisma`):\n\n- `UserBehaviorEvent` – field/feature/workflow telemetry.\n- `OverlaySigningKey` – tenant managed signing keys with revocation timestamps.\n- `Overlay` – stored overlays (tenant/user/role/device scope) plus signature metadata.\n\n---\n\n## 4. Integration Steps\n\n1. Track usage inside apps via `createBehaviorTracker`.\n2. Periodically run `BehaviorAnalyzer.analyze` to generate insights.\n3. Convert insights into OverlaySpecs or Workflow extensions.\n4. Register tenant overlays in `OverlayRegistry` and serve via presentation runtimes.\n5. Compose workflows per tenant using `WorkflowComposer`.\n\nSee the `docs/tech/personalization/*` guides for concrete examples.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
13
- }];
14
- registerDocBlocks(tech_PHASE_4_PERSONALIZATION_ENGINE_DocBlocks);
15
-
16
- //#endregion