@frankieone/one-sdk 1.9.22-rc.1 → 1.9.22-rc.3

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 (38) hide show
  1. package/README.md +371 -279
  2. package/dist/cli/darwin-amd64/onesdk-cli +0 -0
  3. package/dist/cli/darwin-arm64/onesdk-cli +0 -0
  4. package/dist/cli/linux-amd64/onesdk-cli +0 -0
  5. package/dist/cli/linux-arm64/onesdk-cli +0 -0
  6. package/dist/cli/windows-amd64/onesdk-cli.exe +0 -0
  7. package/dist/commit.txt +1 -1
  8. package/dist/esm/modules/form/vendors/react/hooks/usePersonalDetailsUpdateFactory.hook.d.ts.map +1 -1
  9. package/dist/esm/modules/form/vendors/react/hooks/usePersonalDetailsUpdateFactory.hook.js +6 -2
  10. package/dist/esm/modules/form/vendors/react/hooks/usePersonalDetailsUpdateFactory.hook.js.map +1 -1
  11. package/dist/esm/modules/form/vendors/react/hooks/useReviewUpdateFactory.hook.d.ts +1 -1
  12. package/dist/esm/modules/form/vendors/react/hooks/useReviewUpdateFactory.hook.d.ts.map +1 -1
  13. package/dist/esm/modules/form/vendors/react/hooks/useReviewUpdateFactory.hook.js +46 -15
  14. package/dist/esm/modules/form/vendors/react/hooks/useReviewUpdateFactory.hook.js.map +1 -1
  15. package/dist/esm/modules/form/vendors/react/model/review.model.d.ts +0 -1
  16. package/dist/esm/modules/form/vendors/react/model/review.model.d.ts.map +1 -1
  17. package/dist/esm/modules/form/vendors/react/model/review.model.js +3 -7
  18. package/dist/esm/modules/form/vendors/react/model/review.model.js.map +1 -1
  19. package/dist/esm/modules/form/vendors/react/utils/object.util.d.ts +18 -0
  20. package/dist/esm/modules/form/vendors/react/utils/object.util.d.ts.map +1 -1
  21. package/dist/esm/modules/form/vendors/react/utils/object.util.js +53 -1
  22. package/dist/esm/modules/form/vendors/react/utils/object.util.js.map +1 -1
  23. package/dist/esm/modules/idv/vendors/common/iframeUtils/defineIframeIDVWrapper.js +6 -6
  24. package/dist/esm/modules/idv/vendors/common/iframeUtils/defineIframeIDVWrapper.js.map +1 -1
  25. package/dist/esm/modules/meta.json +1 -1
  26. package/dist/esm/modules/sdk/index.d.ts.map +1 -1
  27. package/dist/esm/modules/sdk/index.js +7 -2
  28. package/dist/esm/modules/sdk/index.js.map +1 -1
  29. package/dist/esm/modules/sdk/initialisation/componentLoader.d.ts.map +1 -1
  30. package/dist/esm/modules/sdk/initialisation/componentLoader.js +3 -2
  31. package/dist/esm/modules/sdk/initialisation/componentLoader.js.map +1 -1
  32. package/dist/esm/modules/sdk/initialisation/sanitizeTelemetry.d.ts +15 -0
  33. package/dist/esm/modules/sdk/initialisation/sanitizeTelemetry.d.ts.map +1 -0
  34. package/dist/esm/modules/sdk/initialisation/sanitizeTelemetry.js +58 -0
  35. package/dist/esm/modules/sdk/initialisation/sanitizeTelemetry.js.map +1 -0
  36. package/dist/release.txt +1 -1
  37. package/dist/version.txt +1 -1
  38. package/package.json +2 -2
package/README.md CHANGED
@@ -10,19 +10,19 @@ FrankieOne OneSDK - A comprehensive frontend SDK library for identity verificati
10
10
 
11
11
  ## Table of Contents
12
12
 
13
- - [Overview](#overview)
14
- - [Architecture](#architecture)
15
- - [Module Overview](#module-overview)
16
- - [Vendor Integrations](#vendor-integrations)
17
- - [IDV (Identity Verification)](#idv-identity-verification)
18
- - [OCR (Document Recognition)](#ocr-document-recognition)
19
- - [Biometrics](#biometrics)
20
- - [Device Fingerprinting](#device-fingerprinting)
21
- - [Federation](#federation)
22
- - [Form](#form)
23
- - [Integration Method Reference](#integration-method-reference)
24
- - [Build & Development](#build--development)
25
- - [Deployment](#deployment)
13
+ - [Overview](#overview)
14
+ - [Architecture](#architecture)
15
+ - [Module Overview](#module-overview)
16
+ - [Vendor Integrations](#vendor-integrations)
17
+ - [IDV (Identity Verification)](#idv-identity-verification)
18
+ - [OCR (Document Recognition)](#ocr-document-recognition)
19
+ - [Biometrics](#biometrics)
20
+ - [Device Fingerprinting](#device-fingerprinting)
21
+ - [Federation](#federation)
22
+ - [Form](#form)
23
+ - [Integration Method Reference](#integration-method-reference)
24
+ - [Build & Development](#build--development)
25
+ - [Deployment](#deployment)
26
26
 
27
27
  ---
28
28
 
@@ -35,13 +35,13 @@ This is a **hybrid monorepo** containing:
35
35
 
36
36
  ### Key Technologies
37
37
 
38
- | Category | Technologies |
39
- |----------|-------------|
38
+ | Category | Technologies |
39
+ | ------------ | -------------------------------------------------------------------- |
40
40
  | **Frontend** | React 18.2, Redux Toolkit 2.2.1, TypeScript 5.7, Webpack 5, Vite 7.2 |
41
- | **Styling** | TailwindCSS 3.4, Sass, PostCSS |
42
- | **Testing** | Jest 28, ts-jest |
43
- | **Reactive** | RxJS 7.5, Zod 3.19 |
44
- | **CLI** | Go 1.21.5, Charmbracelet (huh, lipgloss, bubbles) |
41
+ | **Styling** | TailwindCSS 3.4, Sass, PostCSS |
42
+ | **Testing** | Jest 28, ts-jest |
43
+ | **Reactive** | RxJS 7.5, Zod 3.19 |
44
+ | **CLI** | Go 1.21.5, Charmbracelet (huh, lipgloss, bubbles) |
45
45
 
46
46
  ---
47
47
 
@@ -71,14 +71,14 @@ OneSDK (index.ts)
71
71
 
72
72
  ## Module Overview
73
73
 
74
- | Module | Purpose | Vendors |
75
- |--------|---------|---------|
76
- | **IDV** | Full identity verification flow | Onfido, Sumsub, Incode, Daon, Mastercard, Truuth, OcrLabs, IDVerse |
77
- | **OCR** | Document scanning & data extraction | Onfido, Sumsub, Incode, Daon, IDVerse |
78
- | **Biometrics** | Face capture & liveness detection | Onfido, Sumsub, Incode, Daon, OcrLabs, IDVerse |
79
- | **Device** | Device fingerprinting | Sardine, ThreatMetrix |
80
- | **Federation** | Federated identity (OAuth) | Singpass |
81
- | **Form** | Data entry & review forms | Formio, React, Legacy |
74
+ | Module | Purpose | Vendors |
75
+ | -------------- | ----------------------------------- | ------------------------------------------------------------------ |
76
+ | **IDV** | Full identity verification flow | Onfido, Sumsub, Incode, Daon, Mastercard, Truuth, OcrLabs, IDVerse |
77
+ | **OCR** | Document scanning & data extraction | Onfido, Sumsub, Incode, Daon, IDVerse |
78
+ | **Biometrics** | Face capture & liveness detection | Onfido, Sumsub, Incode, Daon, OcrLabs, IDVerse |
79
+ | **Device** | Device fingerprinting | Sardine, ThreatMetrix |
80
+ | **Federation** | Federated identity (OAuth) | Singpass |
81
+ | **Form** | Data entry & review forms | Formio, React, Legacy |
82
82
 
83
83
  ---
84
84
 
@@ -88,85 +88,95 @@ OneSDK (index.ts)
88
88
 
89
89
  #### Onfido
90
90
 
91
- | Aspect | Details |
92
- |--------|---------|
93
- | **Integration Method** | Native SDK loaded from CDN |
94
- | **SDK Source** | `https://sdk.onfido.com/v{version}` |
95
- | **UI Type** | Vendor-provided UI with theme customization |
96
- | **Version Support** | v14+ (modern) and <v14 (legacy modal-based) |
91
+ | Aspect | Details |
92
+ | ---------------------- | ------------------------------------------- |
93
+ | **Integration Method** | Native SDK loaded from CDN |
94
+ | **SDK Source** | `https://sdk.onfido.com/v{version}` |
95
+ | **UI Type** | Vendor-provided UI with theme customization |
96
+ | **Version Support** | v14+ (modern) and <v14 (legacy modal-based) |
97
97
 
98
98
  **Modes:**
99
- - **OneStep Mode** (`useOneStep: true`): Combined document + face capture in single SDK instance
100
- - **Dual Component Mode**: Separate OCR → Biometrics chain
99
+
100
+ - **OneStep Mode** (`useOneStep: true`): Combined document + face capture in single SDK instance
101
+ - **Dual Component Mode**: Separate OCR → Biometrics chain
101
102
 
102
103
  **Key Features:**
103
- - Theme support: `'light'` or `'dark'` with full `customUI` configuration
104
- - Cross-device linking: QR code, copy link, SMS options
105
- - Exit button support
106
- - Analytics disabled by default
107
- - Document type configuration: Passport, Drivers License, Medicare
104
+
105
+ - Theme support: `'light'` or `'dark'` with full `customUI` configuration
106
+ - Cross-device linking: QR code, copy link, SMS options
107
+ - Exit button support
108
+ - Analytics disabled by default
109
+ - Document type configuration: Passport, Drivers License, Medicare
108
110
 
109
111
  **Events Emitted:**
110
- - `ready`, `loading`, `error`, `detection_complete`, `detection_failed`
111
- - `results`, `session_closed`, `session_interrupted`, `vendor_event`
112
+
113
+ - `ready`, `loading`, `error`, `detection_complete`, `detection_failed`
114
+ - `results`, `session_closed`, `session_interrupted`, `vendor_event`
112
115
 
113
116
  **Files:**
114
- - `modules/idv/vendors/Onfido/index.ts`
115
- - `modules/ocr/vendors/Onfido/` (onfido.init.ts, onfidoLegacy.init.ts)
116
- - `modules/biometrics/vendors/Onfido/`
117
- - `modules/common/vendors/onfido/`
117
+
118
+ - `modules/idv/vendors/Onfido/index.ts`
119
+ - `modules/ocr/vendors/Onfido/` (onfido.init.ts, onfidoLegacy.init.ts)
120
+ - `modules/biometrics/vendors/Onfido/`
121
+ - `modules/common/vendors/onfido/`
118
122
 
119
123
  ---
120
124
 
121
125
  #### Sumsub
122
126
 
123
- | Aspect | Details |
124
- |--------|---------|
125
- | **Integration Method** | SDK Library with iframe UI |
126
- | **SDK Source** | `https://static.sumsub.com/idensic/static/sns-websdk-builder.js` |
127
- | **UI Type** | Vendor-provided iframe |
128
- | **Products** | `'idv'`, `'ocr'`, `'poa'` |
127
+ | Aspect | Details |
128
+ | ---------------------- | ---------------------------------------------------------------- |
129
+ | **Integration Method** | SDK Library with iframe UI |
130
+ | **SDK Source** | `https://static.sumsub.com/idensic/static/sns-websdk-builder.js` |
131
+ | **UI Type** | Vendor-provided iframe |
132
+ | **Products** | `'idv'`, `'ocr'`, `'poa'` |
129
133
 
130
134
  **Initialization Flow:**
135
+
131
136
  ```javascript
132
- snsWebSdk.init(token, refreshTokenCallback)
133
- .withConf({ theme: 'light' })
134
- .withOptions({ addViewportTag: false, adaptIframeHeight: true })
135
- .on('idCheck.onError', errorHandler)
136
- .onMessage(messageHandler)
137
- .build()
138
- .launch(mountElement)
137
+ snsWebSdk
138
+ .init(token, refreshTokenCallback)
139
+ .withConf({ theme: 'light' })
140
+ .withOptions({ addViewportTag: false, adaptIframeHeight: true })
141
+ .on('idCheck.onError', errorHandler)
142
+ .onMessage(messageHandler)
143
+ .build()
144
+ .launch(mountElement);
139
145
  ```
140
146
 
141
147
  **Message Types:**
142
- - `idCheck.onReady` - SDK loading
143
- - `idCheck.onInitialized` - UI ready
144
- - `idCheck.onApplicantStatusChanged` - Review status changes (pending → completed)
145
- - `idCheck.onUploadError` - Upload failures
148
+
149
+ - `idCheck.onReady` - SDK loading
150
+ - `idCheck.onInitialized` - UI ready
151
+ - `idCheck.onApplicantStatusChanged` - Review status changes (pending → completed)
152
+ - `idCheck.onUploadError` - Upload failures
146
153
 
147
154
  **Files:**
148
- - `modules/idv/vendors/Sumsub/index.ts`
149
- - `modules/ocr/vendors/Sumsub/index.ts`
150
- - `modules/biometrics/vendors/Sumsub/index.ts`
151
- - `modules/common/vendors/sumsub/`
155
+
156
+ - `modules/idv/vendors/Sumsub/index.ts`
157
+ - `modules/ocr/vendors/Sumsub/index.ts`
158
+ - `modules/biometrics/vendors/Sumsub/index.ts`
159
+ - `modules/common/vendors/sumsub/`
152
160
 
153
161
  ---
154
162
 
155
163
  #### Incode
156
164
 
157
- | Aspect | Details |
158
- |--------|---------|
165
+ | Aspect | Details |
166
+ | ---------------------- | ---------------------------------------------------- |
159
167
  | **Integration Method** | Native SDK + Camera (OCR/Biometrics) or Iframe (IDV) |
160
- | **SDK Source** | `https://sdk.incode.com/sdk/onBoarding-{version}.js` |
161
- | **Default Version** | 1.75.2 |
162
- | **UI Type** | Custom camera UI with document selector |
168
+ | **SDK Source** | `https://sdk.incode.com/sdk/onBoarding-{version}.js` |
169
+ | **Default Version** | 1.75.2 |
170
+ | **UI Type** | Custom camera UI with document selector |
163
171
 
164
172
  **Camera Types:**
165
- - `'front'` - Document front side
166
- - `'back'` - Document back side
167
- - `'selfie'` - Face capture
173
+
174
+ - `'front'` - Document front side
175
+ - `'back'` - Document back side
176
+ - `'selfie'` - Face capture
168
177
 
169
178
  **Document Type Mapping:**
179
+
170
180
  ```javascript
171
181
  Passport → 'PASSPORT'
172
182
  DriversLicense → 'DRIVERS_LICENCE'
@@ -174,67 +184,79 @@ MedicalCard → 'NATIONAL_HEALTH_ID'
174
184
  ```
175
185
 
176
186
  **IDV Iframe Mode:**
177
- - PostMessage protocol with workflow messages
178
- - Success: `{ workflow: 'INCODE_COMPLETE' }`
179
- - Error: `{ workflow: 'INCODE_ERROR' }`
180
- - Session key: `interviewId`
187
+
188
+ - PostMessage protocol with workflow messages
189
+ - Success: `{ workflow: 'INCODE_COMPLETE' }`
190
+ - Error: `{ workflow: 'INCODE_ERROR' }`
191
+ - Session key: `interviewId`
181
192
 
182
193
  **Special Handling:**
183
- - Memory out of bounds error detection via console.error override
184
- - Country/region document validation
185
- - Consent reflow fix for iOS WebKit
194
+
195
+ - Memory out of bounds error detection via console.error override
196
+ - Country/region document validation
197
+ - Consent reflow fix for iOS WebKit
186
198
 
187
199
  **Files:**
188
- - `modules/idv/vendors/Incode/index.ts`
189
- - `modules/ocr/vendors/Incode/index.ts`
190
- - `modules/biometrics/vendors/Incode/index.ts`
191
- - `modules/common/vendors/incode/`
200
+
201
+ - `modules/idv/vendors/Incode/index.ts`
202
+ - `modules/ocr/vendors/Incode/index.ts`
203
+ - `modules/biometrics/vendors/Incode/index.ts`
204
+ - `modules/common/vendors/incode/`
192
205
 
193
206
  ---
194
207
 
195
208
  #### Daon
196
209
 
197
- | Aspect | Details |
198
- |--------|---------|
210
+ | Aspect | Details |
211
+ | ---------------------- | ----------------------------- |
199
212
  | **Integration Method** | Iframe + PostMessage protocol |
200
- | **UI Type** | Vendor-provided iframe |
201
- | **Modules** | IDV, OCR, Biometrics |
213
+ | **UI Type** | Vendor-provided iframe |
214
+ | **Modules** | IDV, OCR, Biometrics |
202
215
 
203
216
  **Message Format:**
217
+
204
218
  ```javascript
205
219
  // Success
206
- { workflow: 'DAON_COMPLETE' }
220
+ {
221
+ workflow: 'DAON_COMPLETE';
222
+ }
207
223
 
208
224
  // Error
209
- { workflow: 'DAON_ERROR' }
225
+ {
226
+ workflow: 'DAON_ERROR';
227
+ }
210
228
  ```
211
229
 
212
230
  **Post-Iframe Actions:**
213
- - IDV: `initProcess` (default)
214
- - OCR: `initProcessAndEvaluateResults`
215
- - Biometrics: `initProcessBiometrics` (with window event listener)
231
+
232
+ - IDV: `initProcess` (default)
233
+ - OCR: `initProcessAndEvaluateResults`
234
+ - Biometrics: `initProcessBiometrics` (with window event listener)
216
235
 
217
236
  **Check Processing Pool:**
218
- - Enabled by default for Daon
219
- - `wait_time: 5` seconds
220
- - `max_attempts: 3`
237
+
238
+ - Enabled by default for Daon
239
+ - `wait_time: 5` seconds
240
+ - `max_attempts: 3`
221
241
 
222
242
  **Files:**
223
- - `modules/idv/vendors/Daon/index.ts`
224
- - `modules/ocr/vendors/Daon/index.ts`
225
- - `modules/biometrics/vendors/Daon/index.ts`
243
+
244
+ - `modules/idv/vendors/Daon/index.ts`
245
+ - `modules/ocr/vendors/Daon/index.ts`
246
+ - `modules/biometrics/vendors/Daon/index.ts`
226
247
 
227
248
  ---
228
249
 
229
250
  #### Mastercard
230
251
 
231
- | Aspect | Details |
232
- |--------|---------|
252
+ | Aspect | Details |
253
+ | ---------------------- | ------------------------- |
233
254
  | **Integration Method** | Iframe + JSON PostMessage |
234
- | **UI Type** | Vendor-provided iframe |
235
- | **Session Key** | `workflowExecutionId` |
255
+ | **UI Type** | Vendor-provided iframe |
256
+ | **Session Key** | `workflowExecutionId` |
236
257
 
237
258
  **Message Format (Stringified JSON):**
259
+
238
260
  ```javascript
239
261
  // Loaded
240
262
  { "payload": { "value": "loaded" } }
@@ -249,50 +271,56 @@ MedicalCard → 'NATIONAL_HEALTH_ID'
249
271
  **Key Difference:** Mastercard emits its own 'loaded' message (`emitOnLoad: false`)
250
272
 
251
273
  **Files:**
252
- - `modules/idv/vendors/Mastercard/index.ts`
274
+
275
+ - `modules/idv/vendors/Mastercard/index.ts`
253
276
 
254
277
  ---
255
278
 
256
279
  #### Truuth
257
280
 
258
- | Aspect | Details |
259
- |--------|---------|
260
- | **Integration Method** | Web Component SDK (NOT iframe) |
261
- | **SDK Source** | `https://cdn.truuth.id/kyc/websdk/{version}/truuth-kyc-websdk.js` |
262
- | **UI Type** | `<truuth-kyc>` custom element |
281
+ | Aspect | Details |
282
+ | ---------------------- | ----------------------------------------------------------------- |
283
+ | **Integration Method** | Web Component SDK (NOT iframe) |
284
+ | **SDK Source** | `https://cdn.truuth.id/kyc/websdk/{version}/truuth-kyc-websdk.js` |
285
+ | **UI Type** | `<truuth-kyc>` custom element |
263
286
 
264
287
  **Event Handling:**
288
+
265
289
  ```javascript
266
- window.addEventListener('forwardedTruuthEventForOneSDK', eventListener)
290
+ window.addEventListener('forwardedTruuthEventForOneSDK', eventListener);
267
291
  ```
268
292
 
269
293
  **Event Types:**
270
- - `VERIFICATION_PROCESSING_STARTED` → loading + detection_complete + polling
271
- - `VERIFICATION_COMPLETED` → initProcess + results
272
- - `TERMS_AND_CONDITION_DECLINED` → input_required
273
- - `VERIFICATION_SUBMISSION_ABORTED` → input_required
274
- - `VERIFICATION_PROCESSING_TIMEOUT` → error
275
- - `ERROR` → detection_failed + error
294
+
295
+ - `VERIFICATION_PROCESSING_STARTED` → loading + detection_complete + polling
296
+ - `VERIFICATION_COMPLETED` → initProcess + results
297
+ - `TERMS_AND_CONDITION_DECLINED` → input_required
298
+ - `VERIFICATION_SUBMISSION_ABORTED` → input_required
299
+ - `VERIFICATION_PROCESSING_TIMEOUT` → error
300
+ - `ERROR` → detection_failed + error
276
301
 
277
302
  **Files:**
278
- - `modules/idv/vendors/Truuth/index.ts`
303
+
304
+ - `modules/idv/vendors/Truuth/index.ts`
279
305
 
280
306
  ---
281
307
 
282
308
  #### OcrLabs
283
309
 
284
- | Aspect | Details |
285
- |--------|---------|
286
- | **IDV Integration** | Server-side action workflow with persistent storage |
287
- | **Biometrics Integration** | WebSocket + WebRTC (liveness detection) |
288
- | **WebSocket URL** | `wss://engine.au.v3.liveness.idkit.io` |
310
+ | Aspect | Details |
311
+ | -------------------------- | --------------------------------------------------- |
312
+ | **IDV Integration** | Server-side action workflow with persistent storage |
313
+ | **Biometrics Integration** | WebSocket + WebRTC (liveness detection) |
314
+ | **WebSocket URL** | `wss://engine.au.v3.liveness.idkit.io` |
289
315
 
290
316
  **IDV Flow:**
317
+
291
318
  1. Check StorageClient for stored action details
292
319
  2. Workflow states: `IDV_SUCCESS` or `IDV_ERROR`
293
320
  3. Redirect to OcrLabs or start dummy flow
294
321
 
295
322
  **Biometrics Liveness Detection:**
323
+
296
324
  ```
297
325
  Face Detection → "Position your face within the frame"
298
326
  ↓
@@ -302,63 +330,71 @@ detection_complete → initProcess
302
330
  ```
303
331
 
304
332
  **UI Elements Created:**
305
- - `onesdk_idv_container` - Main container
306
- - `onesdk_idv_video` - Live video feed (mirrored)
307
- - `onesdk_idv_overlay` - Overlay container
308
- - `onesdk_idv_mask` - Oval face frame with shadow
309
- - `onesdk_idv_instructions` - Dynamic instructions
333
+
334
+ - `onesdk_idv_container` - Main container
335
+ - `onesdk_idv_video` - Live video feed (mirrored)
336
+ - `onesdk_idv_overlay` - Overlay container
337
+ - `onesdk_idv_mask` - Oval face frame with shadow
338
+ - `onesdk_idv_instructions` - Dynamic instructions
310
339
 
311
340
  **Detection Timeout:** 7.5 seconds per action
312
341
 
313
342
  **Files:**
314
- - `modules/idv/vendors/OcrLabs/`
315
- - `modules/biometrics/vendors/OcrLabs/`
343
+
344
+ - `modules/idv/vendors/OcrLabs/`
345
+ - `modules/biometrics/vendors/OcrLabs/`
316
346
 
317
347
  ---
318
348
 
319
349
  #### IDVerse
320
350
 
321
- | Aspect | Details |
322
- |--------|---------|
323
- | **Integration Method** | Web Component + Web Worker |
324
- | **SDK Source** | ESM module from CDN |
325
- | **UI Type** | `<idverse-sdk-ui>` custom element |
326
- | **Build ID** | `build_01K7RRTN6RTH4S3MGHEBDDJ3FV` |
351
+ | Aspect | Details |
352
+ | ---------------------- | ---------------------------------- |
353
+ | **Integration Method** | Web Component + Web Worker |
354
+ | **SDK Source** | ESM module from CDN |
355
+ | **UI Type** | `<idverse-sdk-ui>` custom element |
356
+ | **Build ID** | `build_01K7RRTN6RTH4S3MGHEBDDJ3FV` |
327
357
 
328
358
  **Recognizer Types:**
329
- - `'id-scan'` - Document scanning with front/back capture
330
- - `'face-scan'` - Biometric face capture with liveness
359
+
360
+ - `'id-scan'` - Document scanning with front/back capture
361
+ - `'face-scan'` - Biometric face capture with liveness
331
362
 
332
363
  **Web Worker:**
333
- - Cross-origin blob worker for image processing
334
- - Created via `URL.createObjectURL(blob)`
335
- - Manually terminated on SDK destroy
364
+
365
+ - Cross-origin blob worker for image processing
366
+ - Created via `URL.createObjectURL(blob)`
367
+ - Manually terminated on SDK destroy
336
368
 
337
369
  **Event Types:**
338
- - `authenticated` - SDK initialized
339
- - `ready` - Web component ready
340
- - `scanSuccess` - Scan completed successfully
341
- - `scanFail` - Scan failed (with error codes)
342
- - `validDocumentConfirmed` - User confirmed document
343
- - `fatalError` - Unrecoverable error
344
- - `faceScanClosed` - Face scan modal closed
370
+
371
+ - `authenticated` - SDK initialized
372
+ - `ready` - Web component ready
373
+ - `scanSuccess` - Scan completed successfully
374
+ - `scanFail` - Scan failed (with error codes)
375
+ - `validDocumentConfirmed` - User confirmed document
376
+ - `fatalError` - Unrecoverable error
377
+ - `faceScanClosed` - Face scan modal closed
345
378
 
346
379
  **Retry Logic:**
347
- - Default max retries: 3 (configurable via recipe)
348
- - `scanFail` increments counter
349
- - SDK destroyed when max retries exceeded
380
+
381
+ - Default max retries: 3 (configurable via recipe)
382
+ - `scanFail` increments counter
383
+ - SDK destroyed when max retries exceeded
350
384
 
351
385
  **Asset Bundle (~2.2 MB):**
352
- - Main bundle: 935 KB
353
- - CSS: 113 KB
354
- - Lottie animations: 700+ KB (20 animations)
355
- - Audio feedback: 75+ KB
356
- - WorkSans font: 354 KB
386
+
387
+ - Main bundle: 935 KB
388
+ - CSS: 113 KB
389
+ - Lottie animations: 700+ KB (20 animations)
390
+ - Audio feedback: 75+ KB
391
+ - WorkSans font: 354 KB
357
392
 
358
393
  **Files:**
359
- - `modules/common/vendors/idverse/index.ts`
360
- - `modules/ocr/vendors/IDVerse/index.ts`
361
- - `modules/biometrics/vendors/IDVerse/index.ts`
394
+
395
+ - `modules/common/vendors/idverse/index.ts`
396
+ - `modules/ocr/vendors/IDVerse/index.ts`
397
+ - `modules/biometrics/vendors/IDVerse/index.ts`
362
398
 
363
399
  ---
364
400
 
@@ -366,26 +402,26 @@ detection_complete → initProcess
366
402
 
367
403
  OCR vendors share implementations with IDV where applicable. Key differences:
368
404
 
369
- | Vendor | Post-Process Action | Review Screen |
370
- |--------|---------------------|---------------|
371
- | Onfido | `initProcessAndEvaluateResults` | Feature flag controlled |
372
- | Sumsub | `initProcess` (product='ocr') | Built-in |
373
- | Incode | Native camera capture | Validation callback |
374
- | Daon | `initProcessAndEvaluateResults` | Optional form attachment |
375
- | IDVerse | `initProcessAndEvaluateResults` | Feature flag controlled |
405
+ | Vendor | Post-Process Action | Review Screen |
406
+ | ------- | ------------------------------- | ------------------------ |
407
+ | Onfido | `initProcessAndEvaluateResults` | Feature flag controlled |
408
+ | Sumsub | `initProcess` (product='ocr') | Built-in |
409
+ | Incode | Native camera capture | Validation callback |
410
+ | Daon | `initProcessAndEvaluateResults` | Optional form attachment |
411
+ | IDVerse | `initProcessAndEvaluateResults` | Feature flag controlled |
376
412
 
377
413
  ---
378
414
 
379
415
  ### Biometrics
380
416
 
381
- | Vendor | Capture Method | Liveness Detection |
382
- |--------|----------------|-------------------|
383
- | **Onfido** | SDK face step | Motion, video, or standard variants |
384
- | **Sumsub** | SDK (product='idv') | Built-in |
385
- | **Incode** | Native camera selfie | SDK-managed |
386
- | **Daon** | Iframe with window events | Vendor-managed |
387
- | **OcrLabs** | WebRTC + WebSocket | Face + Smile detection |
388
- | **IDVerse** | Web Component face-scan | DFA + face matching |
417
+ | Vendor | Capture Method | Liveness Detection |
418
+ | ----------- | ------------------------- | ----------------------------------- |
419
+ | **Onfido** | SDK face step | Motion, video, or standard variants |
420
+ | **Sumsub** | SDK (product='idv') | Built-in |
421
+ | **Incode** | Native camera selfie | SDK-managed |
422
+ | **Daon** | Iframe with window events | Vendor-managed |
423
+ | **OcrLabs** | WebRTC + WebSocket | Face + Smile detection |
424
+ | **IDVerse** | Web Component face-scan | DFA + face matching |
389
425
 
390
426
  ---
391
427
 
@@ -393,59 +429,68 @@ OCR vendors share implementations with IDV where applicable. Key differences:
393
429
 
394
430
  #### Sardine
395
431
 
396
- | Aspect | Details |
397
- |--------|---------|
398
- | **Integration Method** | Remote SDK with context-based configuration |
399
- | **SDK Source** | `https://api.{domain}.sardine.ai/assets/loader.min.js` |
400
- | **Environments** | `api.sardine.ai` (production), `api.sandbox.sardine.ai` (sandbox) |
432
+ | Aspect | Details |
433
+ | ---------------------- | ----------------------------------------------------------------- |
434
+ | **Integration Method** | Remote SDK with context-based configuration |
435
+ | **SDK Source** | `https://api.{domain}.sardine.ai/assets/loader.min.js` |
436
+ | **Environments** | `api.sardine.ai` (production), `api.sandbox.sardine.ai` (sandbox) |
401
437
 
402
438
  **Configuration:**
439
+
403
440
  ```javascript
404
441
  window._Sardine.createContext({
405
- clientId,
406
- sessionKey,
407
- environment: 'production' | 'sandbox',
408
- parentElement: document.body,
409
- flow: activityType,
410
- onDeviceResponse: (data) => { /* fingerprint data */ }
411
- })
442
+ clientId,
443
+ sessionKey,
444
+ environment: 'production' | 'sandbox',
445
+ parentElement: document.body,
446
+ flow: activityType,
447
+ onDeviceResponse: (data) => {
448
+ /* fingerprint data */
449
+ },
450
+ });
412
451
  ```
413
452
 
414
453
  **Activity Types:**
415
- - `REGISTRATION` → mapped to `SIGNUP`
416
- - `LOGIN`, `CRYPTO_DEPOSIT`, `CRYPTO_WITHDRAWAL`, `FIAT_DEPOSIT`, `FIAT_WITHDRAWAL`
454
+
455
+ - `REGISTRATION` → mapped to `SIGNUP`
456
+ - `LOGIN`, `CRYPTO_DEPOSIT`, `CRYPTO_WITHDRAWAL`, `FIAT_DEPOSIT`, `FIAT_WITHDRAWAL`
417
457
 
418
458
  **Events:**
419
- - `session_data_generated`
420
- - `device_characteristics_extracted`
421
- - `value_set`
459
+
460
+ - `session_data_generated`
461
+ - `device_characteristics_extracted`
462
+ - `value_set`
422
463
 
423
464
  **Files:**
424
- - `modules/device/vendors/Sardine.ts`
465
+
466
+ - `modules/device/vendors/Sardine.ts`
425
467
 
426
468
  ---
427
469
 
428
470
  #### ThreatMetrix
429
471
 
430
- | Aspect | Details |
431
- |--------|---------|
432
- | **Integration Method** | Obfuscated SDK (intentionally hidden) |
433
- | **SDK Source** | Inline vendor file `nolint_fp-clientlib-v4.js` |
434
- | **Domain** | `h.online-metrix.net` |
472
+ | Aspect | Details |
473
+ | ---------------------- | ---------------------------------------------- |
474
+ | **Integration Method** | Obfuscated SDK (intentionally hidden) |
475
+ | **SDK Source** | Inline vendor file `nolint_fp-clientlib-v4.js` |
476
+ | **Domain** | `h.online-metrix.net` |
435
477
 
436
478
  **Initialization:**
479
+
437
480
  ```javascript
438
- threatmetrixSdk.profile('h.online-metrix.net', clientID, vendorSessionID)
481
+ threatmetrixSdk.profile('h.online-metrix.net', clientID, vendorSessionID);
439
482
  ```
440
483
 
441
484
  **Technical Details:**
442
- - Uses RTCPeerConnection with TURN servers for data collection
443
- - ClientID must be exactly 8 characters
444
- - CSP nonce handling for Content Security Policy compliance
485
+
486
+ - Uses RTCPeerConnection with TURN servers for data collection
487
+ - ClientID must be exactly 8 characters
488
+ - CSP nonce handling for Content Security Policy compliance
445
489
 
446
490
  **Files:**
447
- - `modules/device/vendors/Threatmetrix/index.ts`
448
- - `modules/device/vendors/Threatmetrix/nolint_fp-clientlib-v4.js`
491
+
492
+ - `modules/device/vendors/Threatmetrix/index.ts`
493
+ - `modules/device/vendors/Threatmetrix/nolint_fp-clientlib-v4.js`
449
494
 
450
495
  ---
451
496
 
@@ -453,12 +498,13 @@ threatmetrixSdk.profile('h.online-metrix.net', clientID, vendorSessionID)
453
498
 
454
499
  #### Singpass (MyInfo)
455
500
 
456
- | Aspect | Details |
457
- |--------|---------|
458
- | **Integration Method** | OAuth 2.0 Authorization Code Flow |
459
- | **Protocol** | Browser redirect to Singpass, then code exchange |
501
+ | Aspect | Details |
502
+ | ---------------------- | ------------------------------------------------ |
503
+ | **Integration Method** | OAuth 2.0 Authorization Code Flow |
504
+ | **Protocol** | Browser redirect to Singpass, then code exchange |
460
505
 
461
506
  **Environment URLs:**
507
+
462
508
  ```
463
509
  Sandbox: https://sandbox.api.myinfo.gov.sg/com/v3/authorise
464
510
  Test: https://test.api.myinfo.gov.sg/com/v3/authorise
@@ -466,6 +512,7 @@ Production: https://api.myinfo.gov.sg/com/v3/authorise
466
512
  ```
467
513
 
468
514
  **OAuth Flow:**
515
+
469
516
  1. Build authorization URL with `client_id`, `attributes`, `state`, `redirect_uri`, `purpose`
470
517
  2. Redirect to Singpass
471
518
  3. User authenticates and consents
@@ -476,17 +523,20 @@ Production: https://api.myinfo.gov.sg/com/v3/authorise
476
523
  8. User approves → `FederationClient.submitCachedData()`
477
524
 
478
525
  **Events:**
479
- - `results` - User data with approve callback
480
- - `data_extracted_successfully` - After approval
481
- - `error` - On failures
526
+
527
+ - `results` - User data with approve callback
528
+ - `data_extracted_successfully` - After approval
529
+ - `error` - On failures
482
530
 
483
531
  **Validation:**
484
- - State parameter must match session ID
485
- - Production `redirect_uri` must use HTTPS
486
- - No preloaded entities allowed
532
+
533
+ - State parameter must match session ID
534
+ - Production `redirect_uri` must use HTTPS
535
+ - No preloaded entities allowed
487
536
 
488
537
  **Files:**
489
- - `modules/federation/vendors/Singpass.ts`
538
+
539
+ - `modules/federation/vendors/Singpass.ts`
490
540
 
491
541
  ---
492
542
 
@@ -494,27 +544,29 @@ Production: https://api.myinfo.gov.sg/com/v3/authorise
494
544
 
495
545
  #### Form Vendors Overview
496
546
 
497
- | Vendor | Technology | Use Case |
498
- |--------|------------|----------|
499
- | **Formio** | Form.io SDK | Cloud-based form builder |
500
- | **React** | Custom React components | Modern, flexible forms |
501
- | **Legacy** | Legacy UI widgets | Backward compatibility |
547
+ | Vendor | Technology | Use Case |
548
+ | ---------- | ----------------------- | ------------------------ |
549
+ | **Formio** | Form.io SDK | Cloud-based form builder |
550
+ | **React** | Custom React components | Modern, flexible forms |
551
+ | **Legacy** | Legacy UI widgets | Backward compatibility |
502
552
 
503
553
  ---
504
554
 
505
555
  #### Formio
506
556
 
507
- | Aspect | Details |
508
- |--------|---------|
509
- | **SDK Source** | `https://cdn.form.io/formiojs/formio.full.js` |
510
- | **CSS Dependencies** | Bootstrap 4.6.1, Formio CSS, FontAwesome 4.7 |
557
+ | Aspect | Details |
558
+ | -------------------- | --------------------------------------------- |
559
+ | **SDK Source** | `https://cdn.form.io/formiojs/formio.full.js` |
560
+ | **CSS Dependencies** | Bootstrap 4.6.1, Formio CSS, FontAwesome 4.7 |
511
561
 
512
562
  **Wrapping Modes (feature flag controlled):**
513
- - **Shadow DOM** (`'shadow'`): Isolated styles via `attachShadow({ mode: 'open' })`
514
- - **Iframe** (`'iframe'`): Complete DOM/CSS isolation
515
- - **Div** (`'div'`): Direct DOM insertion (default)
563
+
564
+ - **Shadow DOM** (`'shadow'`): Isolated styles via `attachShadow({ mode: 'open' })`
565
+ - **Iframe** (`'iframe'`): Complete DOM/CSS isolation
566
+ - **Div** (`'div'`): Direct DOM insertion (default)
516
567
 
517
568
  **Data Transformation:**
569
+
518
570
  ```
519
571
  Individual Data ←→ Formio Schema
520
572
  │ │
@@ -524,28 +576,31 @@ Individual Data ←→ Formio Schema
524
576
  ```
525
577
 
526
578
  **Document Type Mapping:**
527
- - `PASSPORT` → `pass_idNumber`, `pass_idExpiry`
528
- - `DRIVERS_LICENCE` → `dl_region`, `dl_idNumber`, `dl_cardNumber`
529
- - `NATIONAL_HEALTH_ID` → `medi_idNumber`, `medi_cardPosition`, `medi_cardColour`, `medi_idExpiry`
579
+
580
+ - `PASSPORT` → `pass_idNumber`, `pass_idExpiry`
581
+ - `DRIVERS_LICENCE` → `dl_region`, `dl_idNumber`, `dl_cardNumber`
582
+ - `NATIONAL_HEALTH_ID` → `medi_idNumber`, `medi_cardPosition`, `medi_cardColour`, `medi_idExpiry`
530
583
 
531
584
  **Files:**
532
- - `modules/form/vendors/formio/`
585
+
586
+ - `modules/form/vendors/formio/`
533
587
 
534
588
  ---
535
589
 
536
590
  #### React Form
537
591
 
538
- | Aspect | Details |
539
- |--------|---------|
540
- | **Framework** | React 18 + Redux Toolkit + React Hook Form |
541
- | **Components** | 60+ form components |
542
- | **Screens** | Welcome, Consent, IdSelection, IdDetails, PersonalDetails, Review, DocumentUpload, Result |
592
+ | Aspect | Details |
593
+ | -------------- | ----------------------------------------------------------------------------------------- |
594
+ | **Framework** | React 18 + Redux Toolkit + React Hook Form |
595
+ | **Components** | 60+ form components |
596
+ | **Screens** | Welcome, Consent, IdSelection, IdDetails, PersonalDetails, Review, DocumentUpload, Result |
543
597
 
544
598
  **Key Hooks:**
545
- - `useEventContext` - Event hub context provider
546
- - `useConfigFactory` - Configuration merging
547
- - `useFormMapper` - Field component mapping
548
- - `useAddressSearch` - Google Maps autocomplete integration
599
+
600
+ - `useEventContext` - Event hub context provider
601
+ - `useConfigFactory` - Configuration merging
602
+ - `useFormMapper` - Field component mapping
603
+ - `useAddressSearch` - Google Maps autocomplete integration
549
604
 
550
605
  **Field Configuration by Document Type:**
551
606
 
@@ -559,39 +614,42 @@ Individual Data ←→ Formio Schema
559
614
  | WA | 7 numeric | 8-10 alphanumeric |
560
615
 
561
616
  **Validation Rules:**
617
+
562
618
  ```javascript
563
619
  ValidationRulesForForm = {
564
- onlyAlphabets: /^[a-zA-Z]+(\s+[a-zA-Z]+)*$/,
565
- onlyNumbers: /^[0-9]+$/,
566
- alphaNumeric: /^[a-zA-Z0-9]+$/,
567
- emailPattern: /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/
568
- }
620
+ onlyAlphabets: /^[a-zA-Z]+(\s+[a-zA-Z]+)*$/,
621
+ onlyNumbers: /^[0-9]+$/,
622
+ alphaNumeric: /^[a-zA-Z0-9]+$/,
623
+ emailPattern: /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/,
624
+ };
569
625
  ```
570
626
 
571
627
  **Screen Events:**
572
- - `form:{screenId}:ready` - Screen mounted
573
- - `form:{screenId}:loaded` - Screen loaded
574
- - `form:{screenId}:failed` - Screen error
575
- - `form:{screenId}:success` - Screen completed
628
+
629
+ - `form:{screenId}:ready` - Screen mounted
630
+ - `form:{screenId}:loaded` - Screen loaded
631
+ - `form:{screenId}:failed` - Screen error
632
+ - `form:{screenId}:success` - Screen completed
576
633
 
577
634
  **Files:**
578
- - `modules/form/vendors/react/`
635
+
636
+ - `modules/form/vendors/react/`
579
637
 
580
638
  ---
581
639
 
582
640
  ## Integration Method Reference
583
641
 
584
- | Method | Vendors | Characteristics |
585
- |--------|---------|-----------------|
586
- | **Native SDK** | Onfido, Incode | Full control, version management, CDN loading |
587
- | **Iframe + PostMessage** | Daon, Mastercard, Incode (IDV) | Sandboxed, vendor-managed UI |
588
- | **Web Component** | IDVerse, Truuth | Custom elements, event-based |
589
- | **WebSocket + WebRTC** | OcrLabs | Real-time liveness, canvas/video rendering |
590
- | **OAuth 2.0** | Singpass | Server-side, browser redirect flow |
591
- | **Remote SDK** | Sardine, Sumsub | Dynamically loaded from vendor CDN |
592
- | **Obfuscated SDK** | ThreatMetrix | Inline vendor code, hidden implementation |
593
- | **Form Builder** | Formio | Cloud service SDK with schema |
594
- | **React Components** | React Form | Custom component library |
642
+ | Method | Vendors | Characteristics |
643
+ | ------------------------ | ------------------------------ | --------------------------------------------- |
644
+ | **Native SDK** | Onfido, Incode | Full control, version management, CDN loading |
645
+ | **Iframe + PostMessage** | Daon, Mastercard, Incode (IDV) | Sandboxed, vendor-managed UI |
646
+ | **Web Component** | IDVerse, Truuth | Custom elements, event-based |
647
+ | **WebSocket + WebRTC** | OcrLabs | Real-time liveness, canvas/video rendering |
648
+ | **OAuth 2.0** | Singpass | Server-side, browser redirect flow |
649
+ | **Remote SDK** | Sardine, Sumsub | Dynamically loaded from vendor CDN |
650
+ | **Obfuscated SDK** | ThreatMetrix | Inline vendor code, hidden implementation |
651
+ | **Form Builder** | Formio | Cloud service SDK with schema |
652
+ | **React Components** | React Form | Custom component library |
595
653
 
596
654
  ---
597
655
 
@@ -616,20 +674,20 @@ npm run test # Jest test suite
616
674
 
617
675
  ### Build Outputs
618
676
 
619
- | Output | Location | Description |
620
- |--------|----------|-------------|
621
- | UMD | `dist/umd/oneSdk.umd.js` | Browser global bundle |
622
- | ESM | `dist/esm/modules/index.js` | ES Module with types |
623
- | CSS | `dist/esm/styles/f1-style.css` | TailwindCSS output |
624
- | CLI | `dist/cli/{platform}/` | Platform-specific Go binaries |
677
+ | Output | Location | Description |
678
+ | ------ | ------------------------------ | ----------------------------- |
679
+ | UMD | `dist/umd/oneSdk.umd.js` | Browser global bundle |
680
+ | ESM | `dist/esm/modules/index.js` | ES Module with types |
681
+ | CSS | `dist/esm/styles/f1-style.css` | TailwindCSS output |
682
+ | CLI | `dist/cli/{platform}/` | Platform-specific Go binaries |
625
683
 
626
684
  ### CLI Platforms
627
685
 
628
- - `darwin-amd64` (macOS Intel)
629
- - `darwin-arm64` (macOS Apple Silicon)
630
- - `linux-amd64`
631
- - `linux-arm64`
632
- - `windows-amd64`
686
+ - `darwin-amd64` (macOS Intel)
687
+ - `darwin-arm64` (macOS Apple Silicon)
688
+ - `linux-amd64`
689
+ - `linux-arm64`
690
+ - `windows-amd64`
633
691
 
634
692
  ---
635
693
 
@@ -639,15 +697,49 @@ Deployments are managed via GitHub Actions using reusable workflows.
639
697
 
640
698
  ### Workflows
641
699
 
642
- - `publish_npm.yml` - NPM publication
643
- - `feature_pr.yml` - Feature branch CI
644
- - `develop.yml` - Development branch
645
- - `main.yml` - Main branch deployment
646
- - `rollback.yml` - Deployment rollback
700
+ | Workflow | Trigger | Purpose |
701
+ | -------------------- | --------------------------------------- | ------------------------------------------------------------------ |
702
+ | `main.yml` | Push to `main` | Full pipeline: CI → build → deploy (QA → UAT → prod) → NPM publish |
703
+ | `develop.yml` | Push to `develop` | Development branch CI |
704
+ | `feature_pr.yml` | PR to `main`/`develop` | Feature branch CI |
705
+ | `publish_npm.yml` | Called by `main.yml` | Publish production release to NPM |
706
+ | `publish_npm_rc.yml` | Called by `main.yml` or manual dispatch | Publish RC (release candidate) to NPM |
707
+ | `rollback.yml` | Manual dispatch | Deployment rollback |
708
+
709
+ ### Main Pipeline (`main.yml`)
710
+
711
+ ```
712
+ ci → build → publish_artifact → bless-qa → publish-rc → deploy-qa → bless-uat → deploy-uat → bless-prod → deploy-prod → publish_npm
713
+ ```
714
+
715
+ Each `bless-*` stage requires manual environment approval before proceeding.
716
+
717
+ ### RC Publishing (`publish_npm_rc.yml`)
718
+
719
+ Publishes a release candidate to NPM under the `rc` dist-tag **before** QA deployment. This is required because the QA automated tests (`qe-ui-tests`) install the RC package to run against.
720
+
721
+ **How it works:**
722
+
723
+ 1. Reads the base version from `package.json` (e.g. `1.9.13`)
724
+ 2. Queries the NPM registry for existing RC versions matching that base
725
+ 3. Computes the next RC version:
726
+ - No existing RCs → `1.9.13-rc`
727
+ - Existing `1.9.13-rc` → `1.9.13-rc.1`
728
+ - Existing `1.9.13-rc.1` → `1.9.13-rc.2`
729
+ 4. Sets the version, builds via `scripts/build-to-npm.sh`, and publishes with `npm publish --tag rc`
730
+
731
+ **Installing an RC version:**
732
+
733
+ ```bash
734
+ npm install @frankieone/one-sdk@rc
735
+ ```
736
+
737
+ **Manual trigger:** The workflow can also be dispatched manually from the Actions tab for ad-hoc RC publishes.
647
738
 
648
739
  For detailed deployment instructions, see:
649
- - [Reusable CICD Github Actions Workflows](https://frankieone.atlassian.net/wiki/x/doCMZw)
650
- - [Rollback Frontend Deployment](https://frankieone.atlassian.net/wiki/x/FAGgZw)
740
+
741
+ - [Reusable CICD Github Actions Workflows](https://frankieone.atlassian.net/wiki/x/doCMZw)
742
+ - [Rollback Frontend Deployment](https://frankieone.atlassian.net/wiki/x/FAGgZw)
651
743
 
652
744
  ---
653
745