@defra/forms-engine-plugin 1.0.0 → 1.0.2

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 (47) hide show
  1. package/.server/server/plugins/engine/README.md +56 -0
  2. package/.server/server/plugins/engine/configureEnginePlugin.d.ts +2 -1
  3. package/.server/server/plugins/engine/configureEnginePlugin.js +1 -1
  4. package/.server/server/plugins/engine/configureEnginePlugin.js.map +1 -1
  5. package/.server/server/plugins/engine/plugin.d.ts +2 -27
  6. package/.server/server/plugins/engine/plugin.js +17 -594
  7. package/.server/server/plugins/engine/plugin.js.map +1 -1
  8. package/.server/server/plugins/engine/registrationOptions.d.ts +1 -0
  9. package/.server/server/plugins/engine/registrationOptions.js +2 -0
  10. package/.server/server/plugins/engine/registrationOptions.js.map +1 -0
  11. package/.server/server/plugins/engine/routes/file-upload.d.ts +4 -0
  12. package/.server/server/plugins/engine/routes/file-upload.js +41 -0
  13. package/.server/server/plugins/engine/routes/file-upload.js.map +1 -0
  14. package/.server/server/plugins/engine/routes/index.d.ts +7 -0
  15. package/.server/server/plugins/engine/routes/index.js +141 -0
  16. package/.server/server/plugins/engine/routes/index.js.map +1 -0
  17. package/.server/server/plugins/engine/routes/questions.d.ts +3 -0
  18. package/.server/server/plugins/engine/routes/questions.js +168 -0
  19. package/.server/server/plugins/engine/routes/questions.js.map +1 -0
  20. package/.server/server/plugins/engine/routes/repeaters/item-delete.d.ts +3 -0
  21. package/.server/server/plugins/engine/routes/repeaters/item-delete.js +106 -0
  22. package/.server/server/plugins/engine/routes/repeaters/item-delete.js.map +1 -0
  23. package/.server/server/plugins/engine/routes/repeaters/summary.d.ts +3 -0
  24. package/.server/server/plugins/engine/routes/repeaters/summary.js +98 -0
  25. package/.server/server/plugins/engine/routes/repeaters/summary.js.map +1 -0
  26. package/.server/server/plugins/engine/types.d.ts +19 -1
  27. package/.server/server/plugins/engine/types.js.map +1 -1
  28. package/.server/server/plugins/engine/vision.d.ts +12 -0
  29. package/.server/server/plugins/engine/vision.js +55 -0
  30. package/.server/server/plugins/engine/vision.js.map +1 -0
  31. package/.server/server/services/cacheService.d.ts +12 -3
  32. package/.server/server/services/cacheService.js +35 -8
  33. package/.server/server/services/cacheService.js.map +1 -1
  34. package/package.json +3 -3
  35. package/src/server/plugins/engine/README.md +56 -0
  36. package/src/server/plugins/engine/configureEnginePlugin.ts +3 -5
  37. package/src/server/plugins/engine/plugin.ts +35 -765
  38. package/src/server/plugins/engine/registrationOptions.ts +0 -0
  39. package/src/server/plugins/engine/routes/file-upload.ts +54 -0
  40. package/src/server/plugins/engine/routes/index.ts +187 -0
  41. package/src/server/plugins/engine/routes/questions.ts +208 -0
  42. package/src/server/plugins/engine/routes/repeaters/item-delete.ts +157 -0
  43. package/src/server/plugins/engine/routes/repeaters/summary.ts +137 -0
  44. package/src/server/plugins/engine/types.ts +26 -1
  45. package/src/server/plugins/engine/vision.ts +95 -0
  46. package/src/server/services/cacheService.test.ts +98 -2
  47. package/src/server/services/cacheService.ts +57 -8
@@ -85,3 +85,59 @@ There are a number of `LiquidJS` filters available to you from within the templa
85
85
  }
86
86
  ]
87
87
  ```
88
+
89
+ ## Session Rehydration
90
+
91
+ To support Save and Return functionality, this application now supports session rehydration. This allows user session state to be recovered across browser sessions or devices — even after the in-memory Redis session has expired.
92
+
93
+ ### How it works
94
+
95
+ To support session rehydration from a backend (e.g. for Save & Return), the consuming application must provide two functions when registering the DXT engine plugin:
96
+
97
+ ```
98
+ export interface PluginOptions {
99
+ ...
100
+ keyGenerator?: (request) => string
101
+ sessionHydrator?: (request) => Promise<FormSubmissionState | null>
102
+ ...
103
+ }
104
+
105
+ ```
106
+
107
+ 1. `keyGenerator(request)`
108
+
109
+ This generates a stable and consistent cache key used to store and retrieve user state. It should return a string based on persistent identifiers such as userId, businessId, and grantId — i.e., something like:
110
+
111
+ ```
112
+ const keyGenerator = request => {
113
+ const { userId, businessId, grantId } = request.app.userContext
114
+ return `${userId}:${businessId}:${grantId}`
115
+ }
116
+ ```
117
+
118
+ 2. `sessionHydrator(request, key)`
119
+
120
+ This function is called when no session state is found in Redis. It should fetch saved state (e.g., from an API) using the provided key and return it in the same structure expected by the form engine:
121
+
122
+ ```
123
+ const sessionHydrator = async (request, key) => {
124
+ const response = await fetch(`https://backend.api/state/${key}`)
125
+ if (!response.ok) return null
126
+ return await response.json() // Must match form engine state shape
127
+ }
128
+ ```
129
+
130
+ #### Session flow
131
+
132
+ - When user resumes a journey and Redis session data is missing or expired, DXT will use `keyGenerator` and `sessionHydrator` to fetch the saved state from an external API (e.g. `/state` endpoint).
133
+ - The fetched state is written back into Redis and used to continue the user journey.
134
+ - The rehydrated state must include enough information to satisfy schema validation on the current or next page.
135
+ - To properly resume a session, users should be redirected to the `/summary` page. This ensures the UI has all required answers preloaded and avoids invalid transitions from deep links.
136
+
137
+ ### Additional notes
138
+
139
+ Flash messaging and other ephemeral session data still rely on yar.id.
140
+
141
+ If the restored state does not satisfy the schema for the current page, the user will be redirected to the first incomplete step.
142
+
143
+ In development, a mock identity and /state response can be used to simulate a persisted session.
@@ -4,13 +4,11 @@ import { type FormDefinition } from '@defra/forms-model'
4
4
 
5
5
  import { FORM_PREFIX } from '~/src/server/constants.js'
6
6
  import { FormModel } from '~/src/server/plugins/engine/models/FormModel.js'
7
- import {
8
- plugin,
9
- type PluginOptions
10
- } from '~/src/server/plugins/engine/plugin.js'
11
- import { findPackageRoot } from '~/src/server/plugins/engine/plugin.js'
7
+ import { plugin } from '~/src/server/plugins/engine/plugin.js'
12
8
  import * as defaultServices from '~/src/server/plugins/engine/services/index.js'
13
9
  import { formsService } from '~/src/server/plugins/engine/services/localFormsService.js'
10
+ import { type PluginOptions } from '~/src/server/plugins/engine/types.js'
11
+ import { findPackageRoot } from '~/src/server/plugins/engine/vision.js'
14
12
  import { devtoolContext } from '~/src/server/plugins/nunjucks/context.js'
15
13
  import { type RouteConfig } from '~/src/server/types.js'
16
14