@wildo-ai/saas-models 1.1.0 → 1.1.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 (292) hide show
  1. package/dist/esm/applications/applications-context.schemas.d.ts +2 -0
  2. package/dist/esm/applications/applications-context.schemas.d.ts.map +1 -1
  3. package/dist/esm/billing/billing-account.shared.resources-config.schemas.d.ts +1 -1
  4. package/dist/esm/billing/billing-account.shared.resources-config.schemas.d.ts.map +1 -1
  5. package/dist/esm/billing/billing-account.shared.resources-config.schemas.js +36 -0
  6. package/dist/esm/billing/billing-account.shared.resources-config.schemas.js.map +1 -1
  7. package/dist/esm/billing/billing-account.shared.schemas.d.ts.map +1 -1
  8. package/dist/esm/billing/billing-account.shared.schemas.js +8 -1
  9. package/dist/esm/billing/billing-account.shared.schemas.js.map +1 -1
  10. package/dist/esm/billing/billing-types.shared.schemas.d.ts +2 -2
  11. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.d.ts +1 -1
  12. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.d.ts.map +1 -1
  13. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.js +39 -0
  14. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.js.map +1 -1
  15. package/dist/esm/billing/credit-pool.shared.schemas.d.ts +6 -6
  16. package/dist/esm/billing/credit-pool.shared.schemas.d.ts.map +1 -1
  17. package/dist/esm/billing/credit-pool.shared.schemas.js +8 -4
  18. package/dist/esm/billing/credit-pool.shared.schemas.js.map +1 -1
  19. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.d.ts +1 -1
  20. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.d.ts.map +1 -1
  21. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.js +35 -0
  22. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.js.map +1 -1
  23. package/dist/esm/billing/invoice-ref.shared.schemas.d.ts.map +1 -1
  24. package/dist/esm/billing/invoice-ref.shared.schemas.js +8 -3
  25. package/dist/esm/billing/invoice-ref.shared.schemas.js.map +1 -1
  26. package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts +1 -1
  27. package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts.map +1 -1
  28. package/dist/esm/billing/subscription.shared.resources-config.schemas.js +39 -0
  29. package/dist/esm/billing/subscription.shared.resources-config.schemas.js.map +1 -1
  30. package/dist/esm/billing/subscription.shared.schemas.d.ts +4 -4
  31. package/dist/esm/billing/subscription.shared.schemas.d.ts.map +1 -1
  32. package/dist/esm/billing/subscription.shared.schemas.js +6 -2
  33. package/dist/esm/billing/subscription.shared.schemas.js.map +1 -1
  34. package/dist/esm/billing/usage-record.shared.resources-config.schemas.d.ts +1 -1
  35. package/dist/esm/billing/usage-record.shared.resources-config.schemas.d.ts.map +1 -1
  36. package/dist/esm/billing/usage-record.shared.resources-config.schemas.js +39 -0
  37. package/dist/esm/billing/usage-record.shared.resources-config.schemas.js.map +1 -1
  38. package/dist/esm/billing/usage-record.shared.schemas.d.ts +4 -4
  39. package/dist/esm/billing/usage-record.shared.schemas.d.ts.map +1 -1
  40. package/dist/esm/billing/usage-record.shared.schemas.js +7 -3
  41. package/dist/esm/billing/usage-record.shared.schemas.js.map +1 -1
  42. package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.d.ts.map +1 -1
  43. package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.js +35 -2
  44. package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.js.map +1 -1
  45. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts +61 -0
  46. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts.map +1 -1
  47. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js +58 -0
  48. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js.map +1 -1
  49. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.d.ts.map +1 -1
  50. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js +14 -0
  51. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js.map +1 -1
  52. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts +49 -0
  53. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts.map +1 -1
  54. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js +124 -1
  55. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js.map +1 -1
  56. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts +11 -3
  57. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts.map +1 -1
  58. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js +11 -3
  59. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js.map +1 -1
  60. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts +93 -0
  61. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts.map +1 -0
  62. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js +116 -0
  63. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js.map +1 -0
  64. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts +67 -12
  65. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts.map +1 -1
  66. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js +95 -8
  67. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js.map +1 -1
  68. package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts +21 -1
  69. package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts.map +1 -1
  70. package/dist/esm/compliance/privacy/redaction.shared.schemas.js +20 -0
  71. package/dist/esm/compliance/privacy/redaction.shared.schemas.js.map +1 -1
  72. package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts +2 -0
  73. package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts.map +1 -1
  74. package/dist/esm/config/app-configuration-shared.shared.schemas.js +29 -0
  75. package/dist/esm/config/app-configuration-shared.shared.schemas.js.map +1 -1
  76. package/dist/esm/config/frontend/navigation.shared.schemas.d.ts +33 -0
  77. package/dist/esm/config/frontend/navigation.shared.schemas.d.ts.map +1 -1
  78. package/dist/esm/config/frontend/navigation.shared.schemas.js +32 -0
  79. package/dist/esm/config/frontend/navigation.shared.schemas.js.map +1 -1
  80. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts +12 -1
  81. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts.map +1 -1
  82. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js +12 -1
  83. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js.map +1 -1
  84. package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts +13 -0
  85. package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts.map +1 -1
  86. package/dist/esm/external-data/external-data-pipeline.shared.schemas.js.map +1 -1
  87. package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts +6 -6
  88. package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts.map +1 -1
  89. package/dist/esm/external-providers/engine-capabilities.shared.schemas.js +26 -6
  90. package/dist/esm/external-providers/engine-capabilities.shared.schemas.js.map +1 -1
  91. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.d.ts.map +1 -1
  92. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js +0 -2
  93. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js.map +1 -1
  94. package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts +1 -0
  95. package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts.map +1 -1
  96. package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts +4 -3
  97. package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts.map +1 -1
  98. package/dist/esm/external-providers/provider-capability.shared.schemas.js +4 -3
  99. package/dist/esm/external-providers/provider-capability.shared.schemas.js.map +1 -1
  100. package/dist/esm/features/user-features.shared.resources-config.schemas.d.ts +1 -1
  101. package/dist/esm/features/user-features.shared.resources-config.schemas.d.ts.map +1 -1
  102. package/dist/esm/features/user-features.shared.resources-config.schemas.js +48 -0
  103. package/dist/esm/features/user-features.shared.resources-config.schemas.js.map +1 -1
  104. package/dist/esm/files/file-upload-grant.shared.schemas.d.ts +144 -0
  105. package/dist/esm/files/file-upload-grant.shared.schemas.d.ts.map +1 -0
  106. package/dist/esm/files/file-upload-grant.shared.schemas.js +136 -0
  107. package/dist/esm/files/file-upload-grant.shared.schemas.js.map +1 -0
  108. package/dist/esm/files/files.shared.schemas.d.ts +45 -4
  109. package/dist/esm/files/files.shared.schemas.d.ts.map +1 -1
  110. package/dist/esm/files/files.shared.schemas.js +48 -4
  111. package/dist/esm/files/files.shared.schemas.js.map +1 -1
  112. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.d.ts +1 -1
  113. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.d.ts.map +1 -1
  114. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.js +33 -0
  115. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.js.map +1 -1
  116. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.d.ts.map +1 -1
  117. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.js +6 -2
  118. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.js.map +1 -1
  119. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.d.ts +1 -1
  120. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.d.ts.map +1 -1
  121. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.js +53 -0
  122. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.js.map +1 -1
  123. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.d.ts +1 -1
  124. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.d.ts.map +1 -1
  125. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.js +43 -0
  126. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.js.map +1 -1
  127. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.d.ts.map +1 -1
  128. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js +8 -3
  129. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js.map +1 -1
  130. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.d.ts +1 -1
  131. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.d.ts.map +1 -1
  132. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.js +41 -0
  133. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.js.map +1 -1
  134. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.d.ts +0 -7
  135. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.d.ts.map +1 -1
  136. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.js +23 -13
  137. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.js.map +1 -1
  138. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.d.ts +1 -1
  139. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.d.ts.map +1 -1
  140. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.js +51 -0
  141. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.js.map +1 -1
  142. package/dist/esm/guidance/guidance-state.shared.schemas.d.ts.map +1 -1
  143. package/dist/esm/guidance/guidance-state.shared.schemas.js +8 -2
  144. package/dist/esm/guidance/guidance-state.shared.schemas.js.map +1 -1
  145. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.d.ts +1 -1
  146. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.d.ts.map +1 -1
  147. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.js +51 -0
  148. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.js.map +1 -1
  149. package/dist/esm/guidance/lifecycle-state.shared.schemas.d.ts.map +1 -1
  150. package/dist/esm/guidance/lifecycle-state.shared.schemas.js +28 -3
  151. package/dist/esm/guidance/lifecycle-state.shared.schemas.js.map +1 -1
  152. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts +1 -1
  153. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts.map +1 -1
  154. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.js +51 -0
  155. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.js.map +1 -1
  156. package/dist/esm/guidance/progression-state.shared.schemas.d.ts.map +1 -1
  157. package/dist/esm/guidance/progression-state.shared.schemas.js +18 -4
  158. package/dist/esm/guidance/progression-state.shared.schemas.js.map +1 -1
  159. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts +37 -3
  160. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts.map +1 -1
  161. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js +29 -3
  162. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js.map +1 -1
  163. package/dist/esm/index.d.ts +6 -0
  164. package/dist/esm/index.d.ts.map +1 -1
  165. package/dist/esm/index.js +6 -0
  166. package/dist/esm/index.js.map +1 -1
  167. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts +70 -0
  168. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts.map +1 -0
  169. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js +71 -0
  170. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js.map +1 -0
  171. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.d.ts +1 -1
  172. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.d.ts.map +1 -1
  173. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.js +36 -0
  174. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.js.map +1 -1
  175. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts +1 -1
  176. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts.map +1 -1
  177. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.js +44 -0
  178. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.js.map +1 -1
  179. package/dist/esm/organizations/organization-members.shared.schemas.d.ts.map +1 -1
  180. package/dist/esm/organizations/organization-members.shared.schemas.js +15 -4
  181. package/dist/esm/organizations/organization-members.shared.schemas.js.map +1 -1
  182. package/dist/esm/organizations/organizations.shared.resources-config.schemas.d.ts.map +1 -1
  183. package/dist/esm/organizations/organizations.shared.resources-config.schemas.js +18 -10
  184. package/dist/esm/organizations/organizations.shared.resources-config.schemas.js.map +1 -1
  185. package/dist/esm/queue/jobs.shared.resources-config.schemas.d.ts.map +1 -1
  186. package/dist/esm/queue/jobs.shared.resources-config.schemas.js +17 -0
  187. package/dist/esm/queue/jobs.shared.resources-config.schemas.js.map +1 -1
  188. package/dist/esm/requests/websocket.shared.schemas.d.ts +59 -0
  189. package/dist/esm/requests/websocket.shared.schemas.d.ts.map +1 -1
  190. package/dist/esm/requests/websocket.shared.schemas.js +103 -0
  191. package/dist/esm/requests/websocket.shared.schemas.js.map +1 -1
  192. package/dist/esm/resources/collection-query-parameters.shared.d.ts +22 -0
  193. package/dist/esm/resources/collection-query-parameters.shared.d.ts.map +1 -0
  194. package/dist/esm/resources/collection-query-parameters.shared.js +22 -0
  195. package/dist/esm/resources/collection-query-parameters.shared.js.map +1 -0
  196. package/dist/esm/resources/resources-config.shared.factory.d.ts.map +1 -1
  197. package/dist/esm/resources/resources-config.shared.factory.js +86 -13
  198. package/dist/esm/resources/resources-config.shared.factory.js.map +1 -1
  199. package/dist/esm/resources/resources-config.shared.schemas.d.ts +162 -41
  200. package/dist/esm/resources/resources-config.shared.schemas.d.ts.map +1 -1
  201. package/dist/esm/resources/resources-config.shared.schemas.js +109 -20
  202. package/dist/esm/resources/resources-config.shared.schemas.js.map +1 -1
  203. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.d.ts.map +1 -1
  204. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js +21 -6
  205. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js.map +1 -1
  206. package/dist/esm/security/authentications/authentication.shared.schemas.d.ts +57 -0
  207. package/dist/esm/security/authentications/authentication.shared.schemas.d.ts.map +1 -1
  208. package/dist/esm/security/authentications/authentication.shared.schemas.js +64 -0
  209. package/dist/esm/security/authentications/authentication.shared.schemas.js.map +1 -1
  210. package/dist/esm/security/authentications/consumable-token.shared.schemas.d.ts +17 -1
  211. package/dist/esm/security/authentications/consumable-token.shared.schemas.d.ts.map +1 -1
  212. package/dist/esm/security/authentications/consumable-token.shared.schemas.js +16 -0
  213. package/dist/esm/security/authentications/consumable-token.shared.schemas.js.map +1 -1
  214. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts +28 -0
  215. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts.map +1 -0
  216. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js +28 -0
  217. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js.map +1 -0
  218. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts +21 -0
  219. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts.map +1 -0
  220. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js +21 -0
  221. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js.map +1 -0
  222. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts +1 -1
  223. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts.map +1 -1
  224. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js +43 -0
  225. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js.map +1 -1
  226. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts +0 -8
  227. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts.map +1 -1
  228. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js +13 -4
  229. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js.map +1 -1
  230. package/dist/esm/security/authorizations/roles.shared.schemas.d.ts +16 -1
  231. package/dist/esm/security/authorizations/roles.shared.schemas.d.ts.map +1 -1
  232. package/dist/esm/security/authorizations/roles.shared.schemas.js +16 -1
  233. package/dist/esm/security/authorizations/roles.shared.schemas.js.map +1 -1
  234. package/dist/esm/security/authorizations/roles.shared.utils.d.ts +54 -0
  235. package/dist/esm/security/authorizations/roles.shared.utils.d.ts.map +1 -1
  236. package/dist/esm/security/authorizations/roles.shared.utils.js +59 -0
  237. package/dist/esm/security/authorizations/roles.shared.utils.js.map +1 -1
  238. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts +61 -0
  239. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts.map +1 -1
  240. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js +13 -1
  241. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js.map +1 -1
  242. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.d.ts +1 -1
  243. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.d.ts.map +1 -1
  244. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.js +35 -0
  245. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.js.map +1 -1
  246. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.d.ts.map +1 -1
  247. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js +7 -1
  248. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js.map +1 -1
  249. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.d.ts +1 -1
  250. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.d.ts.map +1 -1
  251. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.js +34 -0
  252. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.js.map +1 -1
  253. package/dist/esm/users/inbound-contacts.shared.schemas.d.ts.map +1 -1
  254. package/dist/esm/users/inbound-contacts.shared.schemas.js +7 -4
  255. package/dist/esm/users/inbound-contacts.shared.schemas.js.map +1 -1
  256. package/dist/esm/users/user-credentials.shared.resources-config.schemas.d.ts +1 -1
  257. package/dist/esm/users/user-credentials.shared.resources-config.schemas.d.ts.map +1 -1
  258. package/dist/esm/users/user-credentials.shared.resources-config.schemas.js +37 -0
  259. package/dist/esm/users/user-credentials.shared.resources-config.schemas.js.map +1 -1
  260. package/dist/esm/users/user-credentials.shared.schemas.d.ts.map +1 -1
  261. package/dist/esm/users/user-credentials.shared.schemas.js +17 -2
  262. package/dist/esm/users/user-credentials.shared.schemas.js.map +1 -1
  263. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.d.ts +1 -1
  264. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.d.ts.map +1 -1
  265. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.js +36 -0
  266. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.js.map +1 -1
  267. package/dist/esm/users/user-identity-links.shared.schemas.d.ts.map +1 -1
  268. package/dist/esm/users/user-identity-links.shared.schemas.js +15 -5
  269. package/dist/esm/users/user-identity-links.shared.schemas.js.map +1 -1
  270. package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts +1 -1
  271. package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts.map +1 -1
  272. package/dist/esm/users/user-preferences.shared.resources-config.schemas.js +53 -0
  273. package/dist/esm/users/user-preferences.shared.resources-config.schemas.js.map +1 -1
  274. package/dist/esm/users/user-profiles.shared.resources-config.schemas.d.ts +1 -1
  275. package/dist/esm/users/user-profiles.shared.resources-config.schemas.d.ts.map +1 -1
  276. package/dist/esm/users/user-profiles.shared.resources-config.schemas.js +62 -0
  277. package/dist/esm/users/user-profiles.shared.resources-config.schemas.js.map +1 -1
  278. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts +1 -1
  279. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts.map +1 -1
  280. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.js +53 -0
  281. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.js.map +1 -1
  282. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.d.ts +1 -1
  283. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.d.ts.map +1 -1
  284. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.js +62 -0
  285. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.js.map +1 -1
  286. package/dist/esm/users/users.shared.schemas.d.ts +19 -0
  287. package/dist/esm/users/users.shared.schemas.d.ts.map +1 -1
  288. package/dist/esm/users/users.shared.schemas.js +41 -16
  289. package/dist/esm/users/users.shared.schemas.js.map +1 -1
  290. package/dist/tsconfig.build.tsbuildinfo +1 -1
  291. package/package.json +5 -6
  292. package/dist/esm/.builder.pid +0 -9
@@ -15,6 +15,7 @@ import { createResourceConfiguration_Initialization } from '../resources/resourc
15
15
  import { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas.js';
16
16
  import { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas.js';
17
17
  import { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas.js';
18
+ import { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas.js';
18
19
  export const userGuidanceStateResourceConfiguration_InitializationFactory = (resourcesRelationships) => createResourceConfiguration_Initialization({
19
20
  mainSchema: UserGuidanceStateSchema,
20
21
  resourceIdentifier: CoreResourceType.USER_GUIDANCE_STATE,
@@ -27,6 +28,28 @@ export const userGuidanceStateResourceConfiguration_InitializationFactory = (res
27
28
  exportSubject: ResourceSystemAccessMode.ALLOWED, create: ResourceSystemAccessMode.ALLOWED
28
29
  },
29
30
  portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.OBSERVED },
31
+ /**
32
+ * Subject erasure RETAINS this row and RESETS the per-flow guidance progress map to the schema's own defaults.
33
+ *
34
+ * The USAGE categories on this resource are accurate — these are observations the product made about a
35
+ * named person — so `RETAIN_ONLY` would be a false assertion and the factory refuses it. Until
36
+ * `RedactionType.RESET` existed no treatment could reach these fields at all: they are non-nullable WITH
37
+ * a `.default()`, so REMOVE (needs clearable) and MASK (needs a string) both refuse. RESET returns each
38
+ * to what it is when nobody has set it, which for a behavioural record is exactly what erasure should
39
+ * leave behind.
40
+ *
41
+ * The primary scope FK is preserved — severing it is refused outright, because it would leave the
42
+ * retained row with no tenant anchor, unreachable even to the audited see-through read.
43
+ */
44
+ retentionPolicy: {
45
+ mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,
46
+ },
47
+ /**
48
+ * Erasing one of these rows revokes NO session. The row is state ABOUT a person rather than the person,
49
+ * and its primary scope FK anchors it — the enum prescribes `NO_PRINCIPAL` for that shape. The subject's
50
+ * own session ends through the `USERS` row.
51
+ */
52
+ dataSubjectPolicy: { kind: ResourceDataSubjectKind.NO_PRINCIPAL },
30
53
  coreOperations: [
31
54
  CoreResourceOperation.READ,
32
55
  CoreResourceOperation.SEARCH,
@@ -37,9 +60,37 @@ export const userGuidanceStateResourceConfiguration_InitializationFactory = (res
37
60
  // when its owning scope is deleted. Without it the cascade throws
38
61
  // ErrorType.CONFIGURATION on any scope that has a materialized row.
39
62
  CoreResourceOperation.DELETE,
63
+ // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY (READ is above).
64
+ CoreResourceOperation.LIST,
65
+ CoreResourceOperation.UPDATE_MANY,
40
66
  ],
41
67
  customOperation: {},
42
68
  operationsConfiguration: {
69
+ /*
70
+
71
+ * Route-less retention plumbing — INTERNAL_CALL registers no route and must not be REPOSITORY_ONLY:
72
+
73
+ * the retention primitives resolve through `getServiceOperationPathDefault`, which matches only
74
+
75
+ * INTERNAL_CALL / API_CALL. UPDATE_MANY is the verb the impersonalize writer uses.
76
+
77
+ */
78
+ [CoreResourceOperation.LIST]: {
79
+ variants: [{
80
+ variantType: ResourceOperationVariantType.INTERNAL_CALL,
81
+ isDefault: true,
82
+ roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
83
+ riskLevel: ResourceOperationRiskLevel.LOW,
84
+ }],
85
+ },
86
+ [CoreResourceOperation.UPDATE_MANY]: {
87
+ variants: [{
88
+ variantType: ResourceOperationVariantType.INTERNAL_CALL,
89
+ isDefault: true,
90
+ roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
91
+ riskLevel: ResourceOperationRiskLevel.CRITICAL,
92
+ }],
93
+ },
43
94
  [CoreResourceOperation.READ]: {
44
95
  variants: [
45
96
  {
@@ -1 +1 @@
1
- {"version":3,"file":"guidance-state.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/guidance/guidance-state.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Guidance State Shared Resource Configurations\n *\n * Resource configurations for dual-scope guidance state management (USER / ORGANIZATION).\n * Each scope stores flow-level and element-level guidance progress.\n * The shared payload schema stays scope-agnostic, while the schema file also owns\n * the scope-aware persisted variants used by these resource configurations.\n */\n\nimport {\n GuidanceStateSchema,\n UserGuidanceStateSchema,\n OrganizationGuidanceStateSchema,\n} from './guidance-state.shared.schemas';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } from '../resources/resources.shared.schemas';\nimport { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationVariantType } from '../resources/resources.shared.schemas';\nimport { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\nimport { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\n\n// ─── USER GUIDANCE STATE ─────────────────────────────────────────────────────\n\ntype UserGuidanceStateCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE;\n\nexport const userGuidanceStateResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n UserGuidanceStateCoreOperations,\n typeof UserGuidanceStateSchema\n>({\n mainSchema: UserGuidanceStateSchema,\n resourceIdentifier: CoreResourceType.USER_GUIDANCE_STATE,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_GUIDANCE_STATE],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n // onParentCreate eager-seeding writes through createAsSystem → opt into the\n // fail-closed system-write policy (composition-oncreate-lifecycle plan).\n systemAccessPolicy: {\n exportSubject: ResourceSystemAccessMode.ALLOWED, create: ResourceSystemAccessMode.ALLOWED },\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.OBSERVED },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): powers the composition\n // onParentDelete cascade so the self-healing state row is physically removed\n // when its owning scope is deleted. Without it the cascade throws\n // ErrorType.CONFIGURATION on any scope that has a materialized row.\n CoreResourceOperation.DELETE,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n requestDto: GuidanceStateSchema.partial(),\n }\n ],\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n requestDto: GuidanceStateSchema,\n }\n ],\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: false,\n searchableFields: [],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: [],\n maxPaginatedResultPerPageLimit: 50,\n }],\n },\n\n // Internal-only (REPOSITORY_ONLY, no HTTP route): powers the composition\n // onParentDelete cascade so this self-healing state row is physically removed\n // when its owning user is deleted. Without a DELETE op the cascade\n // (deleteChildrenImmediate) throws ErrorType.CONFIGURATION on any user that\n // has a materialized row — these rows self-heal on first READ, so most active\n // users have one. Super-admin/HIGH: a privileged teardown, not the APP_USER\n // self-write. See composition-oncreate-lifecycle plan (systemic DELETE gap).\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n },\n});\n\n// ─── ORGANIZATION GUIDANCE STATE ─────────────────────────────────────────────\n\ntype OrganizationGuidanceStateCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE;\n\nexport const organizationGuidanceStateResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n OrganizationGuidanceStateCoreOperations,\n typeof OrganizationGuidanceStateSchema\n>({\n mainSchema: OrganizationGuidanceStateSchema,\n resourceIdentifier: CoreResourceType.ORGANIZATION_GUIDANCE_STATE,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.ORGANIZATION_GUIDANCE_STATE],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n // onParentCreate eager-seeding writes through createAsSystem → opt into the\n // fail-closed system-write policy (composition-oncreate-lifecycle plan).\n systemAccessPolicy: { create: ResourceSystemAccessMode.ALLOWED },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): powers the composition\n // onParentDelete cascade so the self-healing state row is physically removed\n // when its owning scope is deleted. Without it the cascade throws\n // ErrorType.CONFIGURATION on any scope that has a materialized row.\n CoreResourceOperation.DELETE,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN, CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n requestDto: GuidanceStateSchema.partial(),\n }\n ],\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN, CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n requestDto: GuidanceStateSchema,\n }\n ],\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: false,\n searchableFields: [],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: [],\n maxPaginatedResultPerPageLimit: 50,\n }],\n },\n\n // Internal-only (REPOSITORY_ONLY, no HTTP route): powers the composition\n // onParentDelete cascade so this self-healing state row is physically removed\n // when its owning organization is deleted. Without a DELETE op the cascade\n // (deleteChildrenImmediate) throws ErrorType.CONFIGURATION on any org that has\n // a materialized row — these rows self-heal on first READ, so most active orgs\n // have one. ORG_ADMIN/HIGH: the org-scope admin tier for a privileged teardown.\n // See composition-oncreate-lifecycle plan (systemic DELETE gap).\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n },\n});\n"]}
1
+ {"version":3,"file":"guidance-state.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/guidance/guidance-state.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Guidance State Shared Resource Configurations\n *\n * Resource configurations for dual-scope guidance state management (USER / ORGANIZATION).\n * Each scope stores flow-level and element-level guidance progress.\n * The shared payload schema stays scope-agnostic, while the schema file also owns\n * the scope-aware persisted variants used by these resource configurations.\n */\n\nimport {\n GuidanceStateSchema,\n UserGuidanceStateSchema,\n OrganizationGuidanceStateSchema,\n} from './guidance-state.shared.schemas';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } from '../resources/resources.shared.schemas';\nimport { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationVariantType } from '../resources/resources.shared.schemas';\nimport { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\nimport { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\nimport { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas';\n\n// ─── USER GUIDANCE STATE ─────────────────────────────────────────────────────\n\ntype UserGuidanceStateCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE\n // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY.\n | CoreResourceOperation.LIST\n | CoreResourceOperation.UPDATE_MANY;\n\nexport const userGuidanceStateResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n UserGuidanceStateCoreOperations,\n typeof UserGuidanceStateSchema\n>({\n mainSchema: UserGuidanceStateSchema,\n resourceIdentifier: CoreResourceType.USER_GUIDANCE_STATE,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_GUIDANCE_STATE],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n // onParentCreate eager-seeding writes through createAsSystem → opt into the\n // fail-closed system-write policy (composition-oncreate-lifecycle plan).\n systemAccessPolicy: {\n exportSubject: ResourceSystemAccessMode.ALLOWED, create: ResourceSystemAccessMode.ALLOWED },\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.OBSERVED },\n\n /**\n * Subject erasure RETAINS this row and RESETS the per-flow guidance progress map to the schema's own defaults.\n *\n * The USAGE categories on this resource are accurate — these are observations the product made about a\n * named person — so `RETAIN_ONLY` would be a false assertion and the factory refuses it. Until\n * `RedactionType.RESET` existed no treatment could reach these fields at all: they are non-nullable WITH\n * a `.default()`, so REMOVE (needs clearable) and MASK (needs a string) both refuse. RESET returns each\n * to what it is when nobody has set it, which for a behavioural record is exactly what erasure should\n * leave behind.\n *\n * The primary scope FK is preserved — severing it is refused outright, because it would leave the\n * retained row with no tenant anchor, unreachable even to the audited see-through read.\n */\n retentionPolicy: {\n mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,\n },\n\n /**\n * Erasing one of these rows revokes NO session. The row is state ABOUT a person rather than the person,\n * and its primary scope FK anchors it — the enum prescribes `NO_PRINCIPAL` for that shape. The subject's\n * own session ends through the `USERS` row.\n */\n dataSubjectPolicy: { kind: ResourceDataSubjectKind.NO_PRINCIPAL },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): powers the composition\n // onParentDelete cascade so the self-healing state row is physically removed\n // when its owning scope is deleted. Without it the cascade throws\n // ErrorType.CONFIGURATION on any scope that has a materialized row.\n CoreResourceOperation.DELETE,\n // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY (READ is above).\n CoreResourceOperation.LIST,\n CoreResourceOperation.UPDATE_MANY,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n\n /*\n\n * Route-less retention plumbing — INTERNAL_CALL registers no route and must not be REPOSITORY_ONLY:\n\n * the retention primitives resolve through `getServiceOperationPathDefault`, which matches only\n\n * INTERNAL_CALL / API_CALL. UPDATE_MANY is the verb the impersonalize writer uses.\n\n */\n\n [CoreResourceOperation.LIST]: {\n\n variants: [{\n\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n\n isDefault: true,\n\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n\n riskLevel: ResourceOperationRiskLevel.LOW,\n\n }],\n\n },\n\n [CoreResourceOperation.UPDATE_MANY]: {\n\n variants: [{\n\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n\n isDefault: true,\n\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n\n }],\n\n },\n\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n requestDto: GuidanceStateSchema.partial(),\n }\n ],\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n requestDto: GuidanceStateSchema,\n }\n ],\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: false,\n searchableFields: [],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: [],\n maxPaginatedResultPerPageLimit: 50,\n }],\n },\n\n // Internal-only (REPOSITORY_ONLY, no HTTP route): powers the composition\n // onParentDelete cascade so this self-healing state row is physically removed\n // when its owning user is deleted. Without a DELETE op the cascade\n // (deleteChildrenImmediate) throws ErrorType.CONFIGURATION on any user that\n // has a materialized row — these rows self-heal on first READ, so most active\n // users have one. Super-admin/HIGH: a privileged teardown, not the APP_USER\n // self-write. See composition-oncreate-lifecycle plan (systemic DELETE gap).\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n },\n});\n\n// ─── ORGANIZATION GUIDANCE STATE ─────────────────────────────────────────────\n\ntype OrganizationGuidanceStateCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE;\n\nexport const organizationGuidanceStateResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n OrganizationGuidanceStateCoreOperations,\n typeof OrganizationGuidanceStateSchema\n>({\n mainSchema: OrganizationGuidanceStateSchema,\n resourceIdentifier: CoreResourceType.ORGANIZATION_GUIDANCE_STATE,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.ORGANIZATION_GUIDANCE_STATE],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n // onParentCreate eager-seeding writes through createAsSystem → opt into the\n // fail-closed system-write policy (composition-oncreate-lifecycle plan).\n systemAccessPolicy: { create: ResourceSystemAccessMode.ALLOWED },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): powers the composition\n // onParentDelete cascade so the self-healing state row is physically removed\n // when its owning scope is deleted. Without it the cascade throws\n // ErrorType.CONFIGURATION on any scope that has a materialized row.\n CoreResourceOperation.DELETE,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN, CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n requestDto: GuidanceStateSchema.partial(),\n }\n ],\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN, CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n requestDto: GuidanceStateSchema,\n }\n ],\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: false,\n searchableFields: [],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: [],\n maxPaginatedResultPerPageLimit: 50,\n }],\n },\n\n // Internal-only (REPOSITORY_ONLY, no HTTP route): powers the composition\n // onParentDelete cascade so this self-healing state row is physically removed\n // when its owning organization is deleted. Without a DELETE op the cascade\n // (deleteChildrenImmediate) throws ErrorType.CONFIGURATION on any org that has\n // a materialized row — these rows self-heal on first READ, so most active orgs\n // have one. ORG_ADMIN/HIGH: the org-scope admin tier for a privileged teardown.\n // See composition-oncreate-lifecycle plan (systemic DELETE gap).\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"guidance-state.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/guidance/guidance-state.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AAEhF;;oEAEoE;AAEpE,mCAAmC;AACnC,eAAO,MAAM,0BAA0B;;;;;iBASrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E;;oEAEoE;AAEpE,qBAAqB;AACrB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;iBASlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE;;oEAEoE;AAEpE;;wDAEwD;AACxD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;iBAM9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;iBAElC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;iBAE1C,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAExF,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,GAAG,yBAAyB,CAAC"}
1
+ {"version":3,"file":"guidance-state.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/guidance/guidance-state.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AAIhF;;oEAEoE;AAEpE,mCAAmC;AACnC,eAAO,MAAM,0BAA0B;;;;;iBASrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E;;oEAEoE;AAEpE,qBAAqB;AACrB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;iBASlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE;;oEAEoE;AAEpE;;wDAEwD;AACxD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;iBAa9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;iBAElC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;iBAE1C,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAExF,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,GAAG,yBAAyB,CAAC"}
@@ -1,6 +1,8 @@
1
1
  import { z } from 'zod';
2
2
  import { PersonalDataCategory } from '../compliance/privacy/personal-data-category.shared.schemas.js';
3
3
  import { OnboardingStatus } from '../config/frontend/onboarding.shared.schemas.js';
4
+ import { RedactionType } from '../compliance/privacy/redaction.shared.schemas.js';
5
+ import { addImpersonalizeWith } from '@wildo-ai/zod-decorators';
4
6
  /** ──────────────────────────────────────────────────────────────
5
7
  * Guidance State — Per-Element State
6
8
  * ────────────────────────────────────────────────────────────── */
@@ -39,8 +41,12 @@ export const GuidanceStateSchema = z.object({
39
41
  /** Map of flowRef → flow state */
40
42
  // USAGE — which guidance flows this person has seen and how far through. A record of what they
41
43
  // did in the product, held per user, so a notice must enumerate it.
42
- flows: z.record(z.string(), GuidanceFlowStateSchema).default({}).isSummaryField()
43
- .dataCategories(PersonalDataCategory.USAGE),
44
+ // RESET on erasure — returns this field to its schema default. It holds the per-flow progress map — which guidance flows this person saw and how far through each,
45
+ // which the category above correctly declares as personal data. RESET rather than REMOVE or MASK
46
+ // because the field is non-nullable WITH a `.default()`: REMOVE needs a clearable field and MASK
47
+ // needs a string. The value comes from the schema, so there is no second copy to drift.
48
+ flows: addImpersonalizeWith(z.record(z.string(), GuidanceFlowStateSchema).default({}).isSummaryField()
49
+ .dataCategories(PersonalDataCategory.USAGE), RedactionType.RESET),
44
50
  });
45
51
  export const UserGuidanceStateSchema = GuidanceStateSchema.extend({
46
52
  userId: z.string().min(1).isDBIndexed().isForeignKey().isSummaryField().excludeFromUpdate(),
@@ -1 +1 @@
1
- {"version":3,"file":"guidance-state.shared.schemas.js","sourceRoot":"","sources":["../../../../src/guidance/guidance-state.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,6DAA6D,CAAC;AACnG,OAAO,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AAEhF;;oEAEoE;AAEpE,mCAAmC;AACnC,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC;IAChC;wGACoG;IACpG,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IACvC,qCAAqC;IACrC,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACnH,2CAA2C;IAC3C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;CAC3C,CAAC,CAAC;AAGH;;oEAEoE;AAEpE,qBAAqB;AACrB,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC;IAChC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IACrC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IACvC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IACvC,+CAA+C;IAC/C,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,0BAA0B,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACtE,kDAAkD;IAClD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;CAC1C,CAAC,CAAC;AAGH;;oEAEoE;AAEpE;;wDAEwD;AACxD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,kCAAkC;IAClC,+FAA+F;IAC/F,oEAAoE;IACpE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,uBAAuB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,cAAc,EAAE;SAC9E,cAAc,CAAC,oBAAoB,CAAC,KAAK,CAAC;CAC9C,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,uBAAuB,GAAG,mBAAmB,CAAC,MAAM,CAAC;IAChE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,YAAY,EAAE,CAAC,cAAc,EAAE,CAAC,iBAAiB,EAAE;CAC5F,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,+BAA+B,GAAG,mBAAmB,CAAC,MAAM,CAAC;IACxE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,YAAY,EAAE,CAAC,cAAc,EAAE,CAAC,iBAAiB,EAAE;CACpG,CAAC,CAAC","sourcesContent":["import { z } from 'zod';\nimport { PersonalDataCategory } from '../compliance/privacy/personal-data-category.shared.schemas';\nimport { OnboardingStatus } from '../config/frontend/onboarding.shared.schemas';\n\n/** ──────────────────────────────────────────────────────────────\n * Guidance State — Per-Element State\n * ────────────────────────────────────────────────────────────── */\n\n/** Per-element completion state */\nexport const GuidanceElementStateSchema = z.object({\n status: z.enum(OnboardingStatus),\n /** Timestamp when this element was completed.\n * Uses z.coerce.date() to handle string → Date coercion on parse (stored as ISO strings in DB). */\n completedAt: z.coerce.date().optional(),\n /** For surveys: submitted answers */\n surveyAnswers: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), z.array(z.string())])).optional(),\n /** For tours: last completed step index */\n lastStepIndex: z.number().int().optional(),\n});\nexport type GuidanceElementState = z.infer<typeof GuidanceElementStateSchema>;\n\n/** ──────────────────────────────────────────────────────────────\n * Guidance State — Per-Flow State\n * ────────────────────────────────────────────────────────────── */\n\n/** Per-flow state */\nexport const GuidanceFlowStateSchema = z.object({\n status: z.enum(OnboardingStatus),\n startedAt: z.coerce.date().optional(),\n completedAt: z.coerce.date().optional(),\n dismissedAt: z.coerce.date().optional(),\n /** Element-level state keyed by element ref */\n elements: z.record(z.string(), GuidanceElementStateSchema).default({}),\n /** How many times this flow has been triggered */\n triggerCount: z.number().int().default(0),\n});\nexport type GuidanceFlowState = z.infer<typeof GuidanceFlowStateSchema>;\n\n/** ──────────────────────────────────────────────────────────────\n * Guidance State — Top-Level Document\n * ────────────────────────────────────────────────────────────── */\n\n/** Shared guidance state payload body.\n * Scope-specific state resources extend this schema with their owning FK\n * (`userId` / `organizationId`) before persistence. */\nexport const GuidanceStateSchema = z.object({\n /** Map of flowRef → flow state */\n // USAGE — which guidance flows this person has seen and how far through. A record of what they\n // did in the product, held per user, so a notice must enumerate it.\n flows: z.record(z.string(), GuidanceFlowStateSchema).default({}).isSummaryField()\n .dataCategories(PersonalDataCategory.USAGE),\n});\nexport type GuidanceState = z.infer<typeof GuidanceStateSchema>;\n\nexport const UserGuidanceStateSchema = GuidanceStateSchema.extend({\n userId: z.string().min(1).isDBIndexed().isForeignKey().isSummaryField().excludeFromUpdate(),\n});\nexport type UserGuidanceState = z.infer<typeof UserGuidanceStateSchema>;\n\nexport const OrganizationGuidanceStateSchema = GuidanceStateSchema.extend({\n organizationId: z.string().min(1).isDBIndexed().isForeignKey().isSummaryField().excludeFromUpdate(),\n});\nexport type OrganizationGuidanceState = z.infer<typeof OrganizationGuidanceStateSchema>;\n\nexport type PersistedGuidanceState = UserGuidanceState | OrganizationGuidanceState;\n"]}
1
+ {"version":3,"file":"guidance-state.shared.schemas.js","sourceRoot":"","sources":["../../../../src/guidance/guidance-state.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport { PersonalDataCategory } from '../compliance/privacy/personal-data-category.shared.schemas';\nimport { OnboardingStatus } from '../config/frontend/onboarding.shared.schemas';\nimport { RedactionType } from '../compliance/privacy/redaction.shared.schemas';\nimport { addImpersonalizeWith } from '@wildo-ai/zod-decorators';\n\n/** ──────────────────────────────────────────────────────────────\n * Guidance State — Per-Element State\n * ────────────────────────────────────────────────────────────── */\n\n/** Per-element completion state */\nexport const GuidanceElementStateSchema = z.object({\n status: z.enum(OnboardingStatus),\n /** Timestamp when this element was completed.\n * Uses z.coerce.date() to handle string → Date coercion on parse (stored as ISO strings in DB). */\n completedAt: z.coerce.date().optional(),\n /** For surveys: submitted answers */\n surveyAnswers: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), z.array(z.string())])).optional(),\n /** For tours: last completed step index */\n lastStepIndex: z.number().int().optional(),\n});\nexport type GuidanceElementState = z.infer<typeof GuidanceElementStateSchema>;\n\n/** ──────────────────────────────────────────────────────────────\n * Guidance State — Per-Flow State\n * ────────────────────────────────────────────────────────────── */\n\n/** Per-flow state */\nexport const GuidanceFlowStateSchema = z.object({\n status: z.enum(OnboardingStatus),\n startedAt: z.coerce.date().optional(),\n completedAt: z.coerce.date().optional(),\n dismissedAt: z.coerce.date().optional(),\n /** Element-level state keyed by element ref */\n elements: z.record(z.string(), GuidanceElementStateSchema).default({}),\n /** How many times this flow has been triggered */\n triggerCount: z.number().int().default(0),\n});\nexport type GuidanceFlowState = z.infer<typeof GuidanceFlowStateSchema>;\n\n/** ──────────────────────────────────────────────────────────────\n * Guidance State — Top-Level Document\n * ────────────────────────────────────────────────────────────── */\n\n/** Shared guidance state payload body.\n * Scope-specific state resources extend this schema with their owning FK\n * (`userId` / `organizationId`) before persistence. */\nexport const GuidanceStateSchema = z.object({\n /** Map of flowRef → flow state */\n // USAGE — which guidance flows this person has seen and how far through. A record of what they\n // did in the product, held per user, so a notice must enumerate it.\n // RESET on erasure — returns this field to its schema default. It holds the per-flow progress map — which guidance flows this person saw and how far through each,\n // which the category above correctly declares as personal data. RESET rather than REMOVE or MASK\n // because the field is non-nullable WITH a `.default()`: REMOVE needs a clearable field and MASK\n // needs a string. The value comes from the schema, so there is no second copy to drift.\n flows: addImpersonalizeWith(\n z.record(z.string(), GuidanceFlowStateSchema).default({}).isSummaryField()\n .dataCategories(PersonalDataCategory.USAGE),\n RedactionType.RESET,\n ),\n});\nexport type GuidanceState = z.infer<typeof GuidanceStateSchema>;\n\nexport const UserGuidanceStateSchema = GuidanceStateSchema.extend({\n userId: z.string().min(1).isDBIndexed().isForeignKey().isSummaryField().excludeFromUpdate(),\n});\nexport type UserGuidanceState = z.infer<typeof UserGuidanceStateSchema>;\n\nexport const OrganizationGuidanceStateSchema = GuidanceStateSchema.extend({\n organizationId: z.string().min(1).isDBIndexed().isForeignKey().isSummaryField().excludeFromUpdate(),\n});\nexport type OrganizationGuidanceState = z.infer<typeof OrganizationGuidanceStateSchema>;\n\nexport type PersistedGuidanceState = UserGuidanceState | OrganizationGuidanceState;\n"]}
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { CoreResourceOperation } from '../resources/resources.shared.core.definitions';
10
10
  import { ResourceRelationship } from '../resources/resources.shared.schemas';
11
- type UserLifecycleStateCoreOperations = CoreResourceOperation.READ | CoreResourceOperation.SEARCH | CoreResourceOperation.UPDATE | CoreResourceOperation.CREATE | CoreResourceOperation.DELETE;
11
+ type UserLifecycleStateCoreOperations = CoreResourceOperation.READ | CoreResourceOperation.SEARCH | CoreResourceOperation.UPDATE | CoreResourceOperation.CREATE | CoreResourceOperation.DELETE | CoreResourceOperation.LIST | CoreResourceOperation.UPDATE_MANY;
12
12
  export declare const userLifecycleStateResourceConfiguration_InitializationFactory: (resourcesRelationships: ResourceRelationship[]) => import("..").ResourceConfiguration<Record<string, never>, UserLifecycleStateCoreOperations, import("zod").ZodObject<{
13
13
  currentStage: import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("zod").ZodDefault<import("zod").ZodEnum<typeof import("./lifecycle-state.shared.schemas").LifecycleStage>>>>;
14
14
  stageEnteredAt: import("zod").ZodDefault<import("zod").ZodCoercedDate<unknown>>;
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle-state.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/guidance/lifecycle-state.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,EAA8B,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAUzG,KAAK,gCAAgC,GACjC,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,CAAC;AAEjC,eAAO,MAAM,6DAA6D,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;;;;;;;;;;iCAsG1H,CAAC;AAIH,KAAK,wCAAwC,GACzC,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,CAAC;AAEjC,eAAO,MAAM,qEAAqE,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;;;;;;;;;;iCAoGlI,CAAC"}
1
+ {"version":3,"file":"lifecycle-state.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/guidance/lifecycle-state.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,EAA8B,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAWzG,KAAK,gCAAgC,GACjC,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAE5B,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,WAAW,CAAC;AAEtC,eAAO,MAAM,6DAA6D,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;;;;;;;;;;iCA4K1H,CAAC;AAIH,KAAK,wCAAwC,GACzC,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,CAAC;AAEjC,eAAO,MAAM,qEAAqE,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;;;;;;;;;;iCAoGlI,CAAC"}
@@ -15,6 +15,7 @@ import { createResourceConfiguration_Initialization } from '../resources/resourc
15
15
  import { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas.js';
16
16
  import { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas.js';
17
17
  import { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas.js';
18
+ import { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas.js';
18
19
  export const userLifecycleStateResourceConfiguration_InitializationFactory = (resourcesRelationships) => createResourceConfiguration_Initialization({
19
20
  mainSchema: UserLifecycleStateSchema,
20
21
  resourceIdentifier: CoreResourceType.USER_LIFECYCLE_STATE,
@@ -27,6 +28,28 @@ export const userLifecycleStateResourceConfiguration_InitializationFactory = (re
27
28
  exportSubject: ResourceSystemAccessMode.ALLOWED, create: ResourceSystemAccessMode.ALLOWED
28
29
  },
29
30
  portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.DERIVED },
31
+ /**
32
+ * Subject erasure RETAINS this row and RESETS the stage, its transition history and the last-active timestamp to the schema's own defaults.
33
+ *
34
+ * The USAGE categories on this resource are accurate — these are observations the product made about a
35
+ * named person — so `RETAIN_ONLY` would be a false assertion and the factory refuses it. Until
36
+ * `RedactionType.RESET` existed no treatment could reach these fields at all: they are non-nullable WITH
37
+ * a `.default()`, so REMOVE (needs clearable) and MASK (needs a string) both refuse. RESET returns each
38
+ * to what it is when nobody has set it, which for a behavioural record is exactly what erasure should
39
+ * leave behind.
40
+ *
41
+ * The primary scope FK is preserved — severing it is refused outright, because it would leave the
42
+ * retained row with no tenant anchor, unreachable even to the audited see-through read.
43
+ */
44
+ retentionPolicy: {
45
+ mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,
46
+ },
47
+ /**
48
+ * Erasing one of these rows revokes NO session. The row is state ABOUT a person rather than the person,
49
+ * and its primary scope FK anchors it — the enum prescribes `NO_PRINCIPAL` for that shape. The subject's
50
+ * own session ends through the `USERS` row.
51
+ */
52
+ dataSubjectPolicy: { kind: ResourceDataSubjectKind.NO_PRINCIPAL },
30
53
  coreOperations: [
31
54
  CoreResourceOperation.READ,
32
55
  CoreResourceOperation.SEARCH,
@@ -37,9 +60,37 @@ export const userLifecycleStateResourceConfiguration_InitializationFactory = (re
37
60
  // when its owning scope is deleted. Without it the cascade throws
38
61
  // ErrorType.CONFIGURATION on any scope that has a materialized row.
39
62
  CoreResourceOperation.DELETE,
63
+ // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY (READ is above).
64
+ CoreResourceOperation.LIST,
65
+ CoreResourceOperation.UPDATE_MANY,
40
66
  ],
41
67
  customOperation: {},
42
68
  operationsConfiguration: {
69
+ /*
70
+
71
+ * Route-less retention plumbing — INTERNAL_CALL registers no route and must not be REPOSITORY_ONLY:
72
+
73
+ * the retention primitives resolve through `getServiceOperationPathDefault`, which matches only
74
+
75
+ * INTERNAL_CALL / API_CALL. UPDATE_MANY is the verb the impersonalize writer uses.
76
+
77
+ */
78
+ [CoreResourceOperation.LIST]: {
79
+ variants: [{
80
+ variantType: ResourceOperationVariantType.INTERNAL_CALL,
81
+ isDefault: true,
82
+ roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
83
+ riskLevel: ResourceOperationRiskLevel.LOW,
84
+ }],
85
+ },
86
+ [CoreResourceOperation.UPDATE_MANY]: {
87
+ variants: [{
88
+ variantType: ResourceOperationVariantType.INTERNAL_CALL,
89
+ isDefault: true,
90
+ roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
91
+ riskLevel: ResourceOperationRiskLevel.CRITICAL,
92
+ }],
93
+ },
43
94
  [CoreResourceOperation.READ]: {
44
95
  variants: [
45
96
  {
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle-state.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/guidance/lifecycle-state.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Lifecycle State Shared Resource Configurations\n *\n * Resource configurations for dual-scope lifecycle state management (USER / ORGANIZATION).\n * Each scope tracks lifecycle stage progression (signed_up → activated → engaged → dormant → reactivated).\n * The shared payload schema stays scope-agnostic, while the schema file also owns\n * the scope-aware persisted variants used by these resource configurations.\n */\n\nimport {\n LifecycleStateSchema,\n UserLifecycleStateSchema,\n OrganizationLifecycleStateSchema,\n} from './lifecycle-state.shared.schemas';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } from '../resources/resources.shared.schemas';\nimport { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationVariantType } from '../resources/resources.shared.schemas';\nimport { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\nimport { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\n\n// ─── USER LIFECYCLE STATE ─────────────────────────────────────────────────────\n\ntype UserLifecycleStateCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE;\n\nexport const userLifecycleStateResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n UserLifecycleStateCoreOperations,\n typeof UserLifecycleStateSchema\n>({\n mainSchema: UserLifecycleStateSchema,\n resourceIdentifier: CoreResourceType.USER_LIFECYCLE_STATE,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_LIFECYCLE_STATE],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n // onParentCreate eager-seeding writes through createAsSystem → opt into the\n // fail-closed system-write policy (see composition-oncreate-lifecycle plan).\n systemAccessPolicy: {\n exportSubject: ResourceSystemAccessMode.ALLOWED, create: ResourceSystemAccessMode.ALLOWED },\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.DERIVED },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): powers the composition\n // onParentDelete cascade so the self-healing state row is physically removed\n // when its owning scope is deleted. Without it the cascade throws\n // ErrorType.CONFIGURATION on any scope that has a materialized row.\n CoreResourceOperation.DELETE,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: false,\n searchableFields: [],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: [],\n maxPaginatedResultPerPageLimit: 50,\n }],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n // INTERNAL_CALL (not REPOSITORY_ONLY): the onParentCreate seed's\n // `createAsSystem` resolves the CREATE op via the service tier, which\n // rejects REPOSITORY_ONLY → OPERATION_PATH_NOT_FOUND, silent no-seed. See\n // the org-preferences config + composition-oncreate plan for the rationale.\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n // Internal-only (REPOSITORY_ONLY, no HTTP route): powers the composition\n // onParentDelete cascade so this self-healing state row is physically removed\n // when its owning user is deleted. Without a DELETE op the cascade\n // (deleteChildrenImmediate) throws ErrorType.CONFIGURATION on any user that\n // has a materialized row — these rows self-heal on first READ, so most active\n // users have one. Super-admin/HIGH: a privileged teardown, not the APP_USER\n // self-write. See composition-oncreate-lifecycle plan (systemic DELETE gap).\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n },\n\n});\n\n// ─── ORGANIZATION LIFECYCLE STATE ─────────────────────────────────────────────\n\ntype OrganizationLifecycleStateCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE;\n\nexport const organizationLifecycleStateResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n OrganizationLifecycleStateCoreOperations,\n typeof OrganizationLifecycleStateSchema\n>({\n mainSchema: OrganizationLifecycleStateSchema,\n resourceIdentifier: CoreResourceType.ORGANIZATION_LIFECYCLE_STATE,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.ORGANIZATION_LIFECYCLE_STATE],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n // onParentCreate eager-seeding writes through createAsSystem → opt into the\n // fail-closed system-write policy (see composition-oncreate-lifecycle plan).\n systemAccessPolicy: { create: ResourceSystemAccessMode.ALLOWED },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): powers the composition\n // onParentDelete cascade so the self-healing state row is physically removed\n // when its owning scope is deleted. Without it the cascade throws\n // ErrorType.CONFIGURATION on any scope that has a materialized row.\n CoreResourceOperation.DELETE,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: false,\n searchableFields: [],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: [],\n maxPaginatedResultPerPageLimit: 50,\n }],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n // INTERNAL_CALL (not REPOSITORY_ONLY): the onParentCreate seed's\n // `createAsSystem` resolves the CREATE op via the service tier, which\n // rejects REPOSITORY_ONLY → OPERATION_PATH_NOT_FOUND, silent no-seed. See\n // the org-preferences config + composition-oncreate plan for the rationale.\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n // Internal-only (REPOSITORY_ONLY, no HTTP route): powers the composition\n // onParentDelete cascade so this self-healing state row is physically removed\n // when its owning organization is deleted. Without a DELETE op the cascade\n // (deleteChildrenImmediate) throws ErrorType.CONFIGURATION on any org that has\n // a materialized row — these rows self-heal on first READ, so most active orgs\n // have one. ORG_ADMIN/HIGH: the org-scope admin tier for a privileged teardown.\n // See composition-oncreate-lifecycle plan (systemic DELETE gap).\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n },\n\n});\n"]}
1
+ {"version":3,"file":"lifecycle-state.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/guidance/lifecycle-state.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Lifecycle State Shared Resource Configurations\n *\n * Resource configurations for dual-scope lifecycle state management (USER / ORGANIZATION).\n * Each scope tracks lifecycle stage progression (signed_up → activated → engaged → dormant → reactivated).\n * The shared payload schema stays scope-agnostic, while the schema file also owns\n * the scope-aware persisted variants used by these resource configurations.\n */\n\nimport {\n LifecycleStateSchema,\n UserLifecycleStateSchema,\n OrganizationLifecycleStateSchema,\n} from './lifecycle-state.shared.schemas';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } from '../resources/resources.shared.schemas';\nimport { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationVariantType } from '../resources/resources.shared.schemas';\nimport { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\nimport { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\nimport { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas';\n\n// ─── USER LIFECYCLE STATE ─────────────────────────────────────────────────────\n\ntype UserLifecycleStateCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE\n // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY.\n | CoreResourceOperation.LIST\n | CoreResourceOperation.UPDATE_MANY;\n\nexport const userLifecycleStateResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n UserLifecycleStateCoreOperations,\n typeof UserLifecycleStateSchema\n>({\n mainSchema: UserLifecycleStateSchema,\n resourceIdentifier: CoreResourceType.USER_LIFECYCLE_STATE,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_LIFECYCLE_STATE],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n // onParentCreate eager-seeding writes through createAsSystem → opt into the\n // fail-closed system-write policy (see composition-oncreate-lifecycle plan).\n systemAccessPolicy: {\n exportSubject: ResourceSystemAccessMode.ALLOWED, create: ResourceSystemAccessMode.ALLOWED },\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.DERIVED },\n\n /**\n * Subject erasure RETAINS this row and RESETS the stage, its transition history and the last-active timestamp to the schema's own defaults.\n *\n * The USAGE categories on this resource are accurate — these are observations the product made about a\n * named person — so `RETAIN_ONLY` would be a false assertion and the factory refuses it. Until\n * `RedactionType.RESET` existed no treatment could reach these fields at all: they are non-nullable WITH\n * a `.default()`, so REMOVE (needs clearable) and MASK (needs a string) both refuse. RESET returns each\n * to what it is when nobody has set it, which for a behavioural record is exactly what erasure should\n * leave behind.\n *\n * The primary scope FK is preserved — severing it is refused outright, because it would leave the\n * retained row with no tenant anchor, unreachable even to the audited see-through read.\n */\n retentionPolicy: {\n mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,\n },\n\n /**\n * Erasing one of these rows revokes NO session. The row is state ABOUT a person rather than the person,\n * and its primary scope FK anchors it — the enum prescribes `NO_PRINCIPAL` for that shape. The subject's\n * own session ends through the `USERS` row.\n */\n dataSubjectPolicy: { kind: ResourceDataSubjectKind.NO_PRINCIPAL },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): powers the composition\n // onParentDelete cascade so the self-healing state row is physically removed\n // when its owning scope is deleted. Without it the cascade throws\n // ErrorType.CONFIGURATION on any scope that has a materialized row.\n CoreResourceOperation.DELETE,\n // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY (READ is above).\n CoreResourceOperation.LIST,\n CoreResourceOperation.UPDATE_MANY,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n\n /*\n\n * Route-less retention plumbing — INTERNAL_CALL registers no route and must not be REPOSITORY_ONLY:\n\n * the retention primitives resolve through `getServiceOperationPathDefault`, which matches only\n\n * INTERNAL_CALL / API_CALL. UPDATE_MANY is the verb the impersonalize writer uses.\n\n */\n\n [CoreResourceOperation.LIST]: {\n\n variants: [{\n\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n\n isDefault: true,\n\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n\n riskLevel: ResourceOperationRiskLevel.LOW,\n\n }],\n\n },\n\n [CoreResourceOperation.UPDATE_MANY]: {\n\n variants: [{\n\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n\n isDefault: true,\n\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n\n }],\n\n },\n\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: false,\n searchableFields: [],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: [],\n maxPaginatedResultPerPageLimit: 50,\n }],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n // INTERNAL_CALL (not REPOSITORY_ONLY): the onParentCreate seed's\n // `createAsSystem` resolves the CREATE op via the service tier, which\n // rejects REPOSITORY_ONLY → OPERATION_PATH_NOT_FOUND, silent no-seed. See\n // the org-preferences config + composition-oncreate plan for the rationale.\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n // Internal-only (REPOSITORY_ONLY, no HTTP route): powers the composition\n // onParentDelete cascade so this self-healing state row is physically removed\n // when its owning user is deleted. Without a DELETE op the cascade\n // (deleteChildrenImmediate) throws ErrorType.CONFIGURATION on any user that\n // has a materialized row — these rows self-heal on first READ, so most active\n // users have one. Super-admin/HIGH: a privileged teardown, not the APP_USER\n // self-write. See composition-oncreate-lifecycle plan (systemic DELETE gap).\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n },\n\n});\n\n// ─── ORGANIZATION LIFECYCLE STATE ─────────────────────────────────────────────\n\ntype OrganizationLifecycleStateCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE;\n\nexport const organizationLifecycleStateResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n OrganizationLifecycleStateCoreOperations,\n typeof OrganizationLifecycleStateSchema\n>({\n mainSchema: OrganizationLifecycleStateSchema,\n resourceIdentifier: CoreResourceType.ORGANIZATION_LIFECYCLE_STATE,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.ORGANIZATION_LIFECYCLE_STATE],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n // onParentCreate eager-seeding writes through createAsSystem → opt into the\n // fail-closed system-write policy (see composition-oncreate-lifecycle plan).\n systemAccessPolicy: { create: ResourceSystemAccessMode.ALLOWED },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): powers the composition\n // onParentDelete cascade so the self-healing state row is physically removed\n // when its owning scope is deleted. Without it the cascade throws\n // ErrorType.CONFIGURATION on any scope that has a materialized row.\n CoreResourceOperation.DELETE,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: false,\n searchableFields: [],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: [],\n maxPaginatedResultPerPageLimit: 50,\n }],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n // INTERNAL_CALL (not REPOSITORY_ONLY): the onParentCreate seed's\n // `createAsSystem` resolves the CREATE op via the service tier, which\n // rejects REPOSITORY_ONLY → OPERATION_PATH_NOT_FOUND, silent no-seed. See\n // the org-preferences config + composition-oncreate plan for the rationale.\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n // Internal-only (REPOSITORY_ONLY, no HTTP route): powers the composition\n // onParentDelete cascade so this self-healing state row is physically removed\n // when its owning organization is deleted. Without a DELETE op the cascade\n // (deleteChildrenImmediate) throws ErrorType.CONFIGURATION on any org that has\n // a materialized row — these rows self-heal on first READ, so most active orgs\n // have one. ORG_ADMIN/HIGH: the org-scope admin tier for a privileged teardown.\n // See composition-oncreate-lifecycle plan (systemic DELETE gap).\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n },\n\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle-state.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/guidance/lifecycle-state.shared.schemas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lifecycle-state.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/guidance/lifecycle-state.shared.schemas.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  import { z } from 'zod';
2
2
  import { PersonalDataCategory } from '../compliance/privacy/personal-data-category.shared.schemas.js';
3
3
  import { CoreResourceType } from '../resources/resources.shared.core.definitions.js';
4
+ import { RedactionType } from '../compliance/privacy/redaction.shared.schemas.js';
5
+ import { addImpersonalizeWith } from '@wildo-ai/zod-decorators';
4
6
  /** ──────────────────────────────────────────────────────────────
5
7
  * Lifecycle Stage — Ordered Progression with Dormancy/Reactivation Branches
6
8
  * ────────────────────────────────────────────────────────────── */
@@ -138,18 +140,41 @@ export const LifecycleStateSchema = z.object({
138
140
  /** Current lifecycle stage */
139
141
  // USAGE across the block below — a lifecycle stage, its history, and an engagement score are all
140
142
  // observations the product made ABOUT this person's behaviour.
141
- currentStage: z.enum(LifecycleStage).default(LifecycleStage.SIGNED_UP).isSummaryField()
142
- .dataCategories(PersonalDataCategory.USAGE),
143
+ // RESET on erasure — returns this field to its schema default. It holds the lifecycle stage this person reached,
144
+ // which the category above correctly declares as personal data. RESET rather than REMOVE or MASK
145
+ // because the field is non-nullable WITH a `.default()`: REMOVE needs a clearable field and MASK
146
+ // needs a string. The value comes from the schema, so there is no second copy to drift.
147
+ currentStage: addImpersonalizeWith(z.enum(LifecycleStage).default(LifecycleStage.SIGNED_UP).isSummaryField()
148
+ .dataCategories(PersonalDataCategory.USAGE), RedactionType.RESET),
143
149
  /** When the current stage was entered. `.default(now)` so the row is
144
150
  * eager-seedable via onParentCreate (the evaluator still supplies it explicitly). */
145
151
  stageEnteredAt: z.coerce.date().default(() => new Date()),
146
152
  /** History of stage transitions (most recent first, capped at last 20) */
147
- stageHistory: z.array(LifecycleStageTransitionSchema).default([]).dataCategories(PersonalDataCategory.USAGE),
153
+ // RESET on erasure — returns this field to its schema default. It holds the transition history — when they moved between stages,
154
+ // which the category above correctly declares as personal data. RESET rather than REMOVE or MASK
155
+ // because the field is non-nullable WITH a `.default()`: REMOVE needs a clearable field and MASK
156
+ // needs a string. The value comes from the schema, so there is no second copy to drift.
157
+ stageHistory: addImpersonalizeWith(z.array(LifecycleStageTransitionSchema).default([]).dataCategories(PersonalDataCategory.USAGE), RedactionType.RESET),
148
158
  /** Deduplicated set of all stages ever visited (survives stageHistory cap).
149
159
  * Used by `hasReachedStage()` for reliable stage visitation checks. */
150
160
  stagesVisited: z.array(z.enum(LifecycleStage)).default([]),
151
161
  /** Last activity timestamp (updated on operations, debounced ~30 min).
152
162
  * `.default(now)` so the row is eager-seedable via onParentCreate. */
163
+ // NO treatment, deliberately — and this is a CHOICE the RESET guard forced rather than an omission.
164
+ //
165
+ // This field's default reads the clock (`.default(() => new Date())`, so a row is eager-seedable via
166
+ // onParentCreate). RESET would therefore write a value generated BY the erasure, recording the erased
167
+ // person as active at the moment they were erased — fabricating information rather than removing it.
168
+ // The guard refuses that outright.
169
+ //
170
+ // Of its two suggested remedies, neither is right here. A static `new Date(0)` default would change
171
+ // what every LIVE row means, not just erased ones — the lifecycle evaluator reads this to decide
172
+ // engagement, so a new member would read as inactive since 1970. Making it nullable + REMOVE pushes
173
+ // an `undefined` onto every consumer of a field that has always held a value.
174
+ //
175
+ // So the timestamp is RETAINED, and the notice can say so plainly. The mode is satisfied by
176
+ // `currentStage` and `stageHistory`, which carry the behavioural detail; a bare timestamp attached to
177
+ // a subject whose identity row has been scrubbed discloses very little on its own.
153
178
  lastActiveAt: z.coerce.date().default(() => new Date()).dataCategories(PersonalDataCategory.USAGE),
154
179
  /** Which activation criteria have been met (keyed by criterion ref) */
155
180
  activationCriteriaMet: z.record(z.string(), z.boolean()).default({}),
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle-state.shared.schemas.js","sourceRoot":"","sources":["../../../../src/guidance/lifecycle-state.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport { PersonalDataCategory } from '../compliance/privacy/personal-data-category.shared.schemas';\nimport { CoreResourceType } from '../resources/resources.shared.core.definitions';\n\n/** ──────────────────────────────────────────────────────────────\n * Lifecycle Stage — Ordered Progression with Dormancy/Reactivation Branches\n * ────────────────────────────────────────────────────────────── */\n\n/** Lifecycle stages — ordered progression with dormancy/reactivation branches */\nexport enum LifecycleStage {\n /** User has signed up but hasn't met activation criteria */\n SIGNED_UP = 'signed_up',\n /** User has met activation criteria (reached product value) */\n ACTIVATED = 'activated',\n /** User shows sustained engagement (optional — requires engagementThreshold config) */\n ENGAGED = 'engaged',\n /** User has been inactive past the dormancy threshold */\n DORMANT = 'dormant',\n /** Previously dormant user has returned */\n REACTIVATED = 'reactivated',\n /** User has churned (billing-triggered — deferred) */\n CHURNED = 'churned',\n /** User has been fully offboarded (deferred) */\n OFFBOARDED = 'offboarded',\n}\n\n/** ──────────────────────────────────────────────────────────────\n * Lifecycle Scope — Bi-Scope (same as guidance/progression)\n * ────────────────────────────────────────────────────────────── */\n\n/** Lifecycle state scope — bi-scope (same as guidance/progression) */\nexport enum LifecycleScope {\n USER = 'user',\n ORGANIZATION = 'organization',\n}\n\n/** ──────────────────────────────────────────────────────────────\n * Const Maps — State Machine, Stage Sets, Scope Mappings\n * ────────────────────────────────────────────────────────────── */\n\n/** \"Happy path\" progression weight — used ONLY for the linear happy path.\n * The lifecycle is NOT a linear progression (it branches at dormancy/reactivation).\n * `hasReachedStage()` uses stagesVisited instead — see below. */\nexport const LIFECYCLE_HAPPY_PATH_WEIGHT: Readonly<Record<LifecycleStage, number>> = {\n [LifecycleStage.SIGNED_UP]: 0,\n [LifecycleStage.ACTIVATED]: 1,\n [LifecycleStage.ENGAGED]: 2,\n [LifecycleStage.REACTIVATED]: 2, // Same weight as ENGAGED — reactivated users regain engaged-level access\n [LifecycleStage.DORMANT]: -1, // Not on happy path\n [LifecycleStage.CHURNED]: -2, // Terminal negative\n [LifecycleStage.OFFBOARDED]: -3, // Terminal negative\n} as const;\n\n/** Valid state transitions — the lifecycle state machine.\n * Key = source stage, Value = valid target stages. */\nexport const LIFECYCLE_VALID_TRANSITIONS: Readonly<Record<LifecycleStage, readonly LifecycleStage[]>> = {\n [LifecycleStage.SIGNED_UP]: [LifecycleStage.ACTIVATED],\n [LifecycleStage.ACTIVATED]: [LifecycleStage.ENGAGED, LifecycleStage.DORMANT],\n [LifecycleStage.ENGAGED]: [LifecycleStage.DORMANT],\n [LifecycleStage.DORMANT]: [LifecycleStage.REACTIVATED, LifecycleStage.CHURNED],\n [LifecycleStage.REACTIVATED]: [LifecycleStage.ENGAGED, LifecycleStage.DORMANT],\n [LifecycleStage.CHURNED]: [LifecycleStage.OFFBOARDED],\n [LifecycleStage.OFFBOARDED]: [],\n} as const;\n\n/** Stages that represent an \"active\" user (not dormant/churned/offboarded) */\nexport const LIFECYCLE_ACTIVE_STAGES = [\n LifecycleStage.SIGNED_UP,\n LifecycleStage.ACTIVATED,\n LifecycleStage.ENGAGED,\n LifecycleStage.REACTIVATED,\n] as const;\n\n/** Stages from which a user can become dormant (all active stages except SIGNED_UP) */\nexport const LIFECYCLE_DORMANCY_SOURCE_STAGES = [\n LifecycleStage.ACTIVATED,\n LifecycleStage.ENGAGED,\n LifecycleStage.REACTIVATED,\n] as const;\n\n/** Stages eligible for engagement threshold evaluation (can transition to ENGAGED) */\nexport const LIFECYCLE_ENGAGEMENT_ELIGIBLE_STAGES = [\n LifecycleStage.ACTIVATED,\n LifecycleStage.REACTIVATED,\n] as const;\n\n/** Maps LifecycleScope → corresponding CoreResourceType for lifecycle state storage */\nexport const LIFECYCLE_SCOPE_TO_RESOURCE: Readonly<Record<LifecycleScope, CoreResourceType>> = {\n [LifecycleScope.USER]: CoreResourceType.USER_LIFECYCLE_STATE,\n [LifecycleScope.ORGANIZATION]: CoreResourceType.ORGANIZATION_LIFECYCLE_STATE,\n} as const;\n\n/** Maps LifecycleScope → corresponding Progression resource type (for activation criteria eval).\n * Named to avoid collision with existing PROGRESSION_SCOPE_TO_RESOURCE in milestone-definition.shared.schemas.ts\n * (which is keyed by ProgressionScope, not LifecycleScope). */\nexport const LIFECYCLE_TO_PROGRESSION_RESOURCE: Readonly<Record<LifecycleScope, CoreResourceType>> = {\n [LifecycleScope.USER]: CoreResourceType.USER_PROGRESSION_STATE,\n [LifecycleScope.ORGANIZATION]: CoreResourceType.ORGANIZATION_PROGRESSION_STATE,\n} as const;\n\n/** Maps LifecycleScope → corresponding Guidance state resource type (for GUIDANCE_COMPLETED activation criteria). */\nexport const LIFECYCLE_TO_GUIDANCE_RESOURCE: Readonly<Record<LifecycleScope, CoreResourceType>> = {\n [LifecycleScope.USER]: CoreResourceType.USER_GUIDANCE_STATE,\n [LifecycleScope.ORGANIZATION]: CoreResourceType.ORGANIZATION_GUIDANCE_STATE,\n} as const;\n\n/** All lifecycle resource types — for conditional exclusion when lifecycle disabled\n * (same pattern as BILLING_RESOURCE_TYPES in resources.shared.core.definitions.ts) */\nexport const LIFECYCLE_RESOURCE_TYPES: ReadonlySet<CoreResourceType> = new Set([\n CoreResourceType.USER_LIFECYCLE_STATE,\n CoreResourceType.ORGANIZATION_LIFECYCLE_STATE,\n]);\n\n/** Guidance state resource types — used to detect guidance state updates for activation criteria */\nexport const GUIDANCE_STATE_RESOURCE_TYPES: ReadonlySet<CoreResourceType> = new Set([\n CoreResourceType.USER_GUIDANCE_STATE,\n CoreResourceType.ORGANIZATION_GUIDANCE_STATE,\n]);\n\n/** ──────────────────────────────────────────────────────────────\n * Utility Functions\n * ────────────────────────────────────────────────────────────── */\n\n/** Validate if a lifecycle transition is valid per the state machine. */\nexport function isValidLifecycleTransition(from: LifecycleStage, to: LifecycleStage): boolean {\n return LIFECYCLE_VALID_TRANSITIONS[from]?.includes(to) ?? false;\n}\n\n/** ──────────────────────────────────────────────────────────────\n * Zod Schemas — Lifecycle State Document\n * ────────────────────────────────────────────────────────────── */\n\n/** Record of a single stage transition */\nexport const LifecycleStageTransitionSchema = z.object({\n /** Stage that was entered */\n stage: z.enum(LifecycleStage),\n /** When this stage was entered */\n enteredAt: z.coerce.date(),\n /** When this stage was exited (undefined if current) */\n exitedAt: z.coerce.date().optional(),\n /** What triggered this transition (milestone ref, cron, operation, etc.) */\n trigger: z.string().optional(),\n});\nexport type LifecycleStageTransition = z.infer<typeof LifecycleStageTransitionSchema>;\n\n/** Engagement metrics tracked while user is ACTIVATED */\nexport const LifecycleEngagementSchema = z.object({\n /** Total operations since activation */\n operationsSinceActivation: z.number().int().default(0),\n /** Distinct active dates since activation (YYYY-MM-DD strings) */\n activeDates: z.array(z.string()).default([]),\n});\nexport type LifecycleEngagement = z.infer<typeof LifecycleEngagementSchema>;\n\n/** Shared lifecycle state payload body.\n * Scope-specific state resources extend this schema with their owning FK\n * (`userId` / `organizationId`) before persistence. */\nexport const LifecycleStateSchema = z.object({\n /** Current lifecycle stage */\n // USAGE across the block below — a lifecycle stage, its history, and an engagement score are all\n // observations the product made ABOUT this person's behaviour.\n currentStage: z.enum(LifecycleStage).default(LifecycleStage.SIGNED_UP).isSummaryField()\n .dataCategories(PersonalDataCategory.USAGE),\n /** When the current stage was entered. `.default(now)` so the row is\n * eager-seedable via onParentCreate (the evaluator still supplies it explicitly). */\n stageEnteredAt: z.coerce.date().default(() => new Date()),\n /** History of stage transitions (most recent first, capped at last 20) */\n stageHistory: z.array(LifecycleStageTransitionSchema).default([]).dataCategories(PersonalDataCategory.USAGE),\n /** Deduplicated set of all stages ever visited (survives stageHistory cap).\n * Used by `hasReachedStage()` for reliable stage visitation checks. */\n stagesVisited: z.array(z.enum(LifecycleStage)).default([]),\n /** Last activity timestamp (updated on operations, debounced ~30 min).\n * `.default(now)` so the row is eager-seedable via onParentCreate. */\n lastActiveAt: z.coerce.date().default(() => new Date()).dataCategories(PersonalDataCategory.USAGE),\n /** Which activation criteria have been met (keyed by criterion ref) */\n activationCriteriaMet: z.record(z.string(), z.boolean()).default({}),\n /** Engagement metrics (tracked while ACTIVATED, used for ENGAGED transition) */\n engagement: LifecycleEngagementSchema.default({\n operationsSinceActivation: 0,\n activeDates: [],\n }),\n});\nexport type LifecycleState = z.infer<typeof LifecycleStateSchema>;\n\nexport const UserLifecycleStateSchema = LifecycleStateSchema.extend({\n // `.isUnique()` = idempotency backstop for onParentCreate seeding (one row per user;\n // the evaluator's read-then-create already tolerates the unique conflict).\n userId: z.string().min(1).isDBIndexed().isUnique().isForeignKey().isSummaryField().excludeFromUpdate(),\n});\nexport type UserLifecycleState = z.infer<typeof UserLifecycleStateSchema>;\n\nexport const OrganizationLifecycleStateSchema = LifecycleStateSchema.extend({\n // `.isUnique()` = idempotency backstop for onParentCreate seeding (one row per org).\n organizationId: z.string().min(1).isDBIndexed().isUnique().isForeignKey().isSummaryField().excludeFromUpdate(),\n});\nexport type OrganizationLifecycleState = z.infer<typeof OrganizationLifecycleStateSchema>;\n\nexport type PersistedLifecycleState = UserLifecycleState | OrganizationLifecycleState;\n\n/** ──────────────────────────────────────────────────────────────\n * Stage History Utility\n * ────────────────────────────────────────────────────────────── */\n\n/** Check if the user has ACTUALLY visited a given stage (not a linear comparison).\n * Uses `stagesVisited` for reliable lookups that survive the stageHistory cap.\n * Falls back to `stageHistory` for documents created before `stagesVisited` was added. */\nexport function hasReachedStage(state: LifecycleState, targetStage: LifecycleStage): boolean {\n if (state.currentStage === targetStage) return true;\n if (state.stagesVisited?.length) {\n return state.stagesVisited.includes(targetStage);\n }\n return state.stageHistory.some(entry => entry.stage === targetStage);\n}\n"]}
1
+ {"version":3,"file":"lifecycle-state.shared.schemas.js","sourceRoot":"","sources":["../../../../src/guidance/lifecycle-state.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport { PersonalDataCategory } from '../compliance/privacy/personal-data-category.shared.schemas';\nimport { CoreResourceType } from '../resources/resources.shared.core.definitions';\nimport { RedactionType } from '../compliance/privacy/redaction.shared.schemas';\nimport { addImpersonalizeWith } from '@wildo-ai/zod-decorators';\n\n/** ──────────────────────────────────────────────────────────────\n * Lifecycle Stage — Ordered Progression with Dormancy/Reactivation Branches\n * ────────────────────────────────────────────────────────────── */\n\n/** Lifecycle stages — ordered progression with dormancy/reactivation branches */\nexport enum LifecycleStage {\n /** User has signed up but hasn't met activation criteria */\n SIGNED_UP = 'signed_up',\n /** User has met activation criteria (reached product value) */\n ACTIVATED = 'activated',\n /** User shows sustained engagement (optional — requires engagementThreshold config) */\n ENGAGED = 'engaged',\n /** User has been inactive past the dormancy threshold */\n DORMANT = 'dormant',\n /** Previously dormant user has returned */\n REACTIVATED = 'reactivated',\n /** User has churned (billing-triggered — deferred) */\n CHURNED = 'churned',\n /** User has been fully offboarded (deferred) */\n OFFBOARDED = 'offboarded',\n}\n\n/** ──────────────────────────────────────────────────────────────\n * Lifecycle Scope — Bi-Scope (same as guidance/progression)\n * ────────────────────────────────────────────────────────────── */\n\n/** Lifecycle state scope — bi-scope (same as guidance/progression) */\nexport enum LifecycleScope {\n USER = 'user',\n ORGANIZATION = 'organization',\n}\n\n/** ──────────────────────────────────────────────────────────────\n * Const Maps — State Machine, Stage Sets, Scope Mappings\n * ────────────────────────────────────────────────────────────── */\n\n/** \"Happy path\" progression weight — used ONLY for the linear happy path.\n * The lifecycle is NOT a linear progression (it branches at dormancy/reactivation).\n * `hasReachedStage()` uses stagesVisited instead — see below. */\nexport const LIFECYCLE_HAPPY_PATH_WEIGHT: Readonly<Record<LifecycleStage, number>> = {\n [LifecycleStage.SIGNED_UP]: 0,\n [LifecycleStage.ACTIVATED]: 1,\n [LifecycleStage.ENGAGED]: 2,\n [LifecycleStage.REACTIVATED]: 2, // Same weight as ENGAGED — reactivated users regain engaged-level access\n [LifecycleStage.DORMANT]: -1, // Not on happy path\n [LifecycleStage.CHURNED]: -2, // Terminal negative\n [LifecycleStage.OFFBOARDED]: -3, // Terminal negative\n} as const;\n\n/** Valid state transitions — the lifecycle state machine.\n * Key = source stage, Value = valid target stages. */\nexport const LIFECYCLE_VALID_TRANSITIONS: Readonly<Record<LifecycleStage, readonly LifecycleStage[]>> = {\n [LifecycleStage.SIGNED_UP]: [LifecycleStage.ACTIVATED],\n [LifecycleStage.ACTIVATED]: [LifecycleStage.ENGAGED, LifecycleStage.DORMANT],\n [LifecycleStage.ENGAGED]: [LifecycleStage.DORMANT],\n [LifecycleStage.DORMANT]: [LifecycleStage.REACTIVATED, LifecycleStage.CHURNED],\n [LifecycleStage.REACTIVATED]: [LifecycleStage.ENGAGED, LifecycleStage.DORMANT],\n [LifecycleStage.CHURNED]: [LifecycleStage.OFFBOARDED],\n [LifecycleStage.OFFBOARDED]: [],\n} as const;\n\n/** Stages that represent an \"active\" user (not dormant/churned/offboarded) */\nexport const LIFECYCLE_ACTIVE_STAGES = [\n LifecycleStage.SIGNED_UP,\n LifecycleStage.ACTIVATED,\n LifecycleStage.ENGAGED,\n LifecycleStage.REACTIVATED,\n] as const;\n\n/** Stages from which a user can become dormant (all active stages except SIGNED_UP) */\nexport const LIFECYCLE_DORMANCY_SOURCE_STAGES = [\n LifecycleStage.ACTIVATED,\n LifecycleStage.ENGAGED,\n LifecycleStage.REACTIVATED,\n] as const;\n\n/** Stages eligible for engagement threshold evaluation (can transition to ENGAGED) */\nexport const LIFECYCLE_ENGAGEMENT_ELIGIBLE_STAGES = [\n LifecycleStage.ACTIVATED,\n LifecycleStage.REACTIVATED,\n] as const;\n\n/** Maps LifecycleScope → corresponding CoreResourceType for lifecycle state storage */\nexport const LIFECYCLE_SCOPE_TO_RESOURCE: Readonly<Record<LifecycleScope, CoreResourceType>> = {\n [LifecycleScope.USER]: CoreResourceType.USER_LIFECYCLE_STATE,\n [LifecycleScope.ORGANIZATION]: CoreResourceType.ORGANIZATION_LIFECYCLE_STATE,\n} as const;\n\n/** Maps LifecycleScope → corresponding Progression resource type (for activation criteria eval).\n * Named to avoid collision with existing PROGRESSION_SCOPE_TO_RESOURCE in milestone-definition.shared.schemas.ts\n * (which is keyed by ProgressionScope, not LifecycleScope). */\nexport const LIFECYCLE_TO_PROGRESSION_RESOURCE: Readonly<Record<LifecycleScope, CoreResourceType>> = {\n [LifecycleScope.USER]: CoreResourceType.USER_PROGRESSION_STATE,\n [LifecycleScope.ORGANIZATION]: CoreResourceType.ORGANIZATION_PROGRESSION_STATE,\n} as const;\n\n/** Maps LifecycleScope → corresponding Guidance state resource type (for GUIDANCE_COMPLETED activation criteria). */\nexport const LIFECYCLE_TO_GUIDANCE_RESOURCE: Readonly<Record<LifecycleScope, CoreResourceType>> = {\n [LifecycleScope.USER]: CoreResourceType.USER_GUIDANCE_STATE,\n [LifecycleScope.ORGANIZATION]: CoreResourceType.ORGANIZATION_GUIDANCE_STATE,\n} as const;\n\n/** All lifecycle resource types — for conditional exclusion when lifecycle disabled\n * (same pattern as BILLING_RESOURCE_TYPES in resources.shared.core.definitions.ts) */\nexport const LIFECYCLE_RESOURCE_TYPES: ReadonlySet<CoreResourceType> = new Set([\n CoreResourceType.USER_LIFECYCLE_STATE,\n CoreResourceType.ORGANIZATION_LIFECYCLE_STATE,\n]);\n\n/** Guidance state resource types — used to detect guidance state updates for activation criteria */\nexport const GUIDANCE_STATE_RESOURCE_TYPES: ReadonlySet<CoreResourceType> = new Set([\n CoreResourceType.USER_GUIDANCE_STATE,\n CoreResourceType.ORGANIZATION_GUIDANCE_STATE,\n]);\n\n/** ──────────────────────────────────────────────────────────────\n * Utility Functions\n * ────────────────────────────────────────────────────────────── */\n\n/** Validate if a lifecycle transition is valid per the state machine. */\nexport function isValidLifecycleTransition(from: LifecycleStage, to: LifecycleStage): boolean {\n return LIFECYCLE_VALID_TRANSITIONS[from]?.includes(to) ?? false;\n}\n\n/** ──────────────────────────────────────────────────────────────\n * Zod Schemas — Lifecycle State Document\n * ────────────────────────────────────────────────────────────── */\n\n/** Record of a single stage transition */\nexport const LifecycleStageTransitionSchema = z.object({\n /** Stage that was entered */\n stage: z.enum(LifecycleStage),\n /** When this stage was entered */\n enteredAt: z.coerce.date(),\n /** When this stage was exited (undefined if current) */\n exitedAt: z.coerce.date().optional(),\n /** What triggered this transition (milestone ref, cron, operation, etc.) */\n trigger: z.string().optional(),\n});\nexport type LifecycleStageTransition = z.infer<typeof LifecycleStageTransitionSchema>;\n\n/** Engagement metrics tracked while user is ACTIVATED */\nexport const LifecycleEngagementSchema = z.object({\n /** Total operations since activation */\n operationsSinceActivation: z.number().int().default(0),\n /** Distinct active dates since activation (YYYY-MM-DD strings) */\n activeDates: z.array(z.string()).default([]),\n});\nexport type LifecycleEngagement = z.infer<typeof LifecycleEngagementSchema>;\n\n/** Shared lifecycle state payload body.\n * Scope-specific state resources extend this schema with their owning FK\n * (`userId` / `organizationId`) before persistence. */\nexport const LifecycleStateSchema = z.object({\n /** Current lifecycle stage */\n // USAGE across the block below — a lifecycle stage, its history, and an engagement score are all\n // observations the product made ABOUT this person's behaviour.\n // RESET on erasure — returns this field to its schema default. It holds the lifecycle stage this person reached,\n // which the category above correctly declares as personal data. RESET rather than REMOVE or MASK\n // because the field is non-nullable WITH a `.default()`: REMOVE needs a clearable field and MASK\n // needs a string. The value comes from the schema, so there is no second copy to drift.\n currentStage: addImpersonalizeWith(\n z.enum(LifecycleStage).default(LifecycleStage.SIGNED_UP).isSummaryField()\n .dataCategories(PersonalDataCategory.USAGE),\n RedactionType.RESET,\n ),\n /** When the current stage was entered. `.default(now)` so the row is\n * eager-seedable via onParentCreate (the evaluator still supplies it explicitly). */\n stageEnteredAt: z.coerce.date().default(() => new Date()),\n /** History of stage transitions (most recent first, capped at last 20) */\n // RESET on erasure — returns this field to its schema default. It holds the transition history — when they moved between stages,\n // which the category above correctly declares as personal data. RESET rather than REMOVE or MASK\n // because the field is non-nullable WITH a `.default()`: REMOVE needs a clearable field and MASK\n // needs a string. The value comes from the schema, so there is no second copy to drift.\n stageHistory: addImpersonalizeWith(\n z.array(LifecycleStageTransitionSchema).default([]).dataCategories(PersonalDataCategory.USAGE),\n RedactionType.RESET,\n ),\n /** Deduplicated set of all stages ever visited (survives stageHistory cap).\n * Used by `hasReachedStage()` for reliable stage visitation checks. */\n stagesVisited: z.array(z.enum(LifecycleStage)).default([]),\n /** Last activity timestamp (updated on operations, debounced ~30 min).\n * `.default(now)` so the row is eager-seedable via onParentCreate. */\n // NO treatment, deliberately — and this is a CHOICE the RESET guard forced rather than an omission.\n //\n // This field's default reads the clock (`.default(() => new Date())`, so a row is eager-seedable via\n // onParentCreate). RESET would therefore write a value generated BY the erasure, recording the erased\n // person as active at the moment they were erased — fabricating information rather than removing it.\n // The guard refuses that outright.\n //\n // Of its two suggested remedies, neither is right here. A static `new Date(0)` default would change\n // what every LIVE row means, not just erased ones — the lifecycle evaluator reads this to decide\n // engagement, so a new member would read as inactive since 1970. Making it nullable + REMOVE pushes\n // an `undefined` onto every consumer of a field that has always held a value.\n //\n // So the timestamp is RETAINED, and the notice can say so plainly. The mode is satisfied by\n // `currentStage` and `stageHistory`, which carry the behavioural detail; a bare timestamp attached to\n // a subject whose identity row has been scrubbed discloses very little on its own.\n lastActiveAt: z.coerce.date().default(() => new Date()).dataCategories(PersonalDataCategory.USAGE),\n /** Which activation criteria have been met (keyed by criterion ref) */\n activationCriteriaMet: z.record(z.string(), z.boolean()).default({}),\n /** Engagement metrics (tracked while ACTIVATED, used for ENGAGED transition) */\n engagement: LifecycleEngagementSchema.default({\n operationsSinceActivation: 0,\n activeDates: [],\n }),\n});\nexport type LifecycleState = z.infer<typeof LifecycleStateSchema>;\n\nexport const UserLifecycleStateSchema = LifecycleStateSchema.extend({\n // `.isUnique()` = idempotency backstop for onParentCreate seeding (one row per user;\n // the evaluator's read-then-create already tolerates the unique conflict).\n userId: z.string().min(1).isDBIndexed().isUnique().isForeignKey().isSummaryField().excludeFromUpdate(),\n});\nexport type UserLifecycleState = z.infer<typeof UserLifecycleStateSchema>;\n\nexport const OrganizationLifecycleStateSchema = LifecycleStateSchema.extend({\n // `.isUnique()` = idempotency backstop for onParentCreate seeding (one row per org).\n organizationId: z.string().min(1).isDBIndexed().isUnique().isForeignKey().isSummaryField().excludeFromUpdate(),\n});\nexport type OrganizationLifecycleState = z.infer<typeof OrganizationLifecycleStateSchema>;\n\nexport type PersistedLifecycleState = UserLifecycleState | OrganizationLifecycleState;\n\n/** ──────────────────────────────────────────────────────────────\n * Stage History Utility\n * ────────────────────────────────────────────────────────────── */\n\n/** Check if the user has ACTUALLY visited a given stage (not a linear comparison).\n * Uses `stagesVisited` for reliable lookups that survive the stageHistory cap.\n * Falls back to `stageHistory` for documents created before `stagesVisited` was added. */\nexport function hasReachedStage(state: LifecycleState, targetStage: LifecycleStage): boolean {\n if (state.currentStage === targetStage) return true;\n if (state.stagesVisited?.length) {\n return state.stagesVisited.includes(targetStage);\n }\n return state.stageHistory.some(entry => entry.stage === targetStage);\n}\n"]}
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { CoreResourceOperation } from '../resources/resources.shared.core.definitions';
10
10
  import { ResourceRelationship } from '../resources/resources.shared.schemas';
11
- type UserProgressionStateCoreOperations = CoreResourceOperation.READ | CoreResourceOperation.SEARCH | CoreResourceOperation.UPDATE | CoreResourceOperation.CREATE | CoreResourceOperation.DELETE;
11
+ type UserProgressionStateCoreOperations = CoreResourceOperation.READ | CoreResourceOperation.SEARCH | CoreResourceOperation.UPDATE | CoreResourceOperation.CREATE | CoreResourceOperation.DELETE | CoreResourceOperation.LIST | CoreResourceOperation.UPDATE_MANY;
12
12
  export declare const userProgressionStateResourceConfiguration_InitializationFactory: (resourcesRelationships: ResourceRelationship[]) => import("..").ResourceConfiguration<Record<string, never>, UserProgressionStateCoreOperations, import("zod").ZodObject<{
13
13
  milestonesAchieved: import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodObject<{
14
14
  achievedAt: import("zod").ZodCoercedDate<unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"progression-state.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/guidance/progression-state.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,EAA8B,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAUzG,KAAK,kCAAkC,GACnC,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,CAAC;AAEjC,eAAO,MAAM,+DAA+D,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;;;;;iCAqG5H,CAAC;AAIH,KAAK,0CAA0C,GAC3C,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,CAAC;AAEjC,eAAO,MAAM,uEAAuE,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;;;;;iCAoGpI,CAAC"}
1
+ {"version":3,"file":"progression-state.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/guidance/progression-state.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,EAA8B,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAWzG,KAAK,kCAAkC,GACnC,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAE5B,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,WAAW,CAAC;AAEtC,eAAO,MAAM,+DAA+D,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;;;;;iCA2K5H,CAAC;AAIH,KAAK,0CAA0C,GAC3C,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,CAAC;AAEjC,eAAO,MAAM,uEAAuE,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;;;;;iCAoGpI,CAAC"}