@wildo-ai/saas-models 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (410) hide show
  1. package/dist/esm/applications/applications-context.schemas.d.ts +14 -10
  2. package/dist/esm/applications/applications-context.schemas.d.ts.map +1 -1
  3. package/dist/esm/applications/applications.shared.resources-config.schemas.d.ts.map +1 -1
  4. package/dist/esm/applications/applications.shared.resources-config.schemas.js +4 -3
  5. package/dist/esm/applications/applications.shared.resources-config.schemas.js.map +1 -1
  6. package/dist/esm/billing/billing-configuration.shared.schemas.d.ts +0 -4
  7. package/dist/esm/billing/billing-configuration.shared.schemas.d.ts.map +1 -1
  8. package/dist/esm/billing/billing-configuration.shared.schemas.js +59 -17
  9. package/dist/esm/billing/billing-configuration.shared.schemas.js.map +1 -1
  10. package/dist/esm/billing/billing-enums.shared.schemas.d.ts +77 -21
  11. package/dist/esm/billing/billing-enums.shared.schemas.d.ts.map +1 -1
  12. package/dist/esm/billing/billing-enums.shared.schemas.js +85 -23
  13. package/dist/esm/billing/billing-enums.shared.schemas.js.map +1 -1
  14. package/dist/esm/billing/billing-types.shared.schemas.d.ts +3 -3
  15. package/dist/esm/billing/price.shared.schemas.d.ts.map +1 -1
  16. package/dist/esm/billing/price.shared.schemas.js +7 -1
  17. package/dist/esm/billing/price.shared.schemas.js.map +1 -1
  18. package/dist/esm/billing/product-behavior-policy.shared.schemas.d.ts.map +1 -1
  19. package/dist/esm/billing/product-behavior-policy.shared.schemas.js +52 -11
  20. package/dist/esm/billing/product-behavior-policy.shared.schemas.js.map +1 -1
  21. package/dist/esm/billing/product-definition.shared.schemas.d.ts +2 -2
  22. package/dist/esm/billing/product.shared.resources-config.schemas.d.ts +2 -2
  23. package/dist/esm/billing/product.shared.schemas.d.ts +2 -2
  24. package/dist/esm/billing/product.shared.schemas.d.ts.map +1 -1
  25. package/dist/esm/billing/product.shared.schemas.js +7 -3
  26. package/dist/esm/billing/product.shared.schemas.js.map +1 -1
  27. package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts +1 -1
  28. package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts.map +1 -1
  29. package/dist/esm/billing/subscription.shared.resources-config.schemas.js +15 -1
  30. package/dist/esm/billing/subscription.shared.resources-config.schemas.js.map +1 -1
  31. package/dist/esm/billing/usage-record.shared.schemas.d.ts +7 -3
  32. package/dist/esm/billing/usage-record.shared.schemas.d.ts.map +1 -1
  33. package/dist/esm/billing/usage-record.shared.schemas.js +22 -3
  34. package/dist/esm/billing/usage-record.shared.schemas.js.map +1 -1
  35. package/dist/esm/companion/provider-discovery.shared.schemas.d.ts +69 -2
  36. package/dist/esm/companion/provider-discovery.shared.schemas.d.ts.map +1 -1
  37. package/dist/esm/companion/provider-discovery.shared.schemas.js +20 -1
  38. package/dist/esm/companion/provider-discovery.shared.schemas.js.map +1 -1
  39. package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.d.ts +85 -0
  40. package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.d.ts.map +1 -0
  41. package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.js +157 -0
  42. package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.js.map +1 -0
  43. package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.d.ts +23 -0
  44. package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.d.ts.map +1 -1
  45. package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.js +56 -0
  46. package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.js.map +1 -1
  47. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts +480 -20
  48. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts.map +1 -1
  49. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js +547 -23
  50. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js.map +1 -1
  51. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.d.ts.map +1 -1
  52. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js +82 -3
  53. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js.map +1 -1
  54. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts +31 -30
  55. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts.map +1 -1
  56. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js +98 -3
  57. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js.map +1 -1
  58. package/dist/esm/compliance/privacy/privacy.shared.schemas.d.ts +17 -0
  59. package/dist/esm/compliance/privacy/privacy.shared.schemas.d.ts.map +1 -1
  60. package/dist/esm/compliance/privacy/privacy.shared.schemas.js +27 -4
  61. package/dist/esm/compliance/privacy/privacy.shared.schemas.js.map +1 -1
  62. package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts +82 -29
  63. package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts.map +1 -1
  64. package/dist/esm/compliance/privacy/redaction.shared.schemas.js +95 -29
  65. package/dist/esm/compliance/privacy/redaction.shared.schemas.js.map +1 -1
  66. package/dist/esm/compliance/privacy/subject-export.shared.schemas.d.ts.map +1 -1
  67. package/dist/esm/compliance/privacy/subject-export.shared.schemas.js +12 -5
  68. package/dist/esm/compliance/privacy/subject-export.shared.schemas.js.map +1 -1
  69. package/dist/esm/config/analytics-value-moments.shared.schemas.d.ts +21 -0
  70. package/dist/esm/config/analytics-value-moments.shared.schemas.d.ts.map +1 -1
  71. package/dist/esm/config/analytics-value-moments.shared.schemas.js +20 -0
  72. package/dist/esm/config/analytics-value-moments.shared.schemas.js.map +1 -1
  73. package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts +7 -5
  74. package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts.map +1 -1
  75. package/dist/esm/config/auth-config-resolution.shared.utils.d.ts +8 -1
  76. package/dist/esm/config/auth-config-resolution.shared.utils.d.ts.map +1 -1
  77. package/dist/esm/config/auth-config-resolution.shared.utils.js +29 -0
  78. package/dist/esm/config/auth-config-resolution.shared.utils.js.map +1 -1
  79. package/dist/esm/config/entity-identity-config.shared.schemas.d.ts +95 -17
  80. package/dist/esm/config/entity-identity-config.shared.schemas.d.ts.map +1 -1
  81. package/dist/esm/config/entity-identity-config.shared.schemas.js +86 -8
  82. package/dist/esm/config/entity-identity-config.shared.schemas.js.map +1 -1
  83. package/dist/esm/config/frontend/chart-definition.shared.schemas.d.ts +12 -12
  84. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts +28 -0
  85. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts.map +1 -1
  86. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js +28 -0
  87. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js.map +1 -1
  88. package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts +45 -12
  89. package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts.map +1 -1
  90. package/dist/esm/external-data/external-data-pipeline.shared.schemas.js.map +1 -1
  91. package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts +103 -58
  92. package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts.map +1 -1
  93. package/dist/esm/external-providers/engine-capabilities.shared.schemas.js +176 -15
  94. package/dist/esm/external-providers/engine-capabilities.shared.schemas.js.map +1 -1
  95. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.d.ts +15 -3
  96. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.d.ts.map +1 -1
  97. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js +32 -5
  98. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js.map +1 -1
  99. package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts +83 -7
  100. package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts.map +1 -1
  101. package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.d.ts +59 -0
  102. package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.d.ts.map +1 -0
  103. package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.js +61 -0
  104. package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.js.map +1 -0
  105. package/dist/esm/external-providers/frontend-capability-runtime.shared.types.d.ts +97 -0
  106. package/dist/esm/external-providers/frontend-capability-runtime.shared.types.d.ts.map +1 -0
  107. package/dist/esm/external-providers/frontend-capability-runtime.shared.types.js +41 -0
  108. package/dist/esm/external-providers/frontend-capability-runtime.shared.types.js.map +1 -0
  109. package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.d.ts +148 -2
  110. package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.d.ts.map +1 -1
  111. package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.js +56 -1
  112. package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.js.map +1 -1
  113. package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts +5 -28
  114. package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts.map +1 -1
  115. package/dist/esm/external-providers/provider-capability.shared.schemas.js +4 -2
  116. package/dist/esm/external-providers/provider-capability.shared.schemas.js.map +1 -1
  117. package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.d.ts +18 -8
  118. package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.d.ts.map +1 -1
  119. package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.js +9 -4
  120. package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.js.map +1 -1
  121. package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.d.ts +338 -0
  122. package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.d.ts.map +1 -0
  123. package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.js +332 -0
  124. package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.js.map +1 -0
  125. package/dist/esm/external-providers/provider-metadata.shared.schemas.d.ts +178 -9
  126. package/dist/esm/external-providers/provider-metadata.shared.schemas.d.ts.map +1 -1
  127. package/dist/esm/external-providers/provider-metadata.shared.schemas.js +181 -9
  128. package/dist/esm/external-providers/provider-metadata.shared.schemas.js.map +1 -1
  129. package/dist/esm/external-providers/provider-protocol.shared.schemas.d.ts +7 -5
  130. package/dist/esm/external-providers/provider-protocol.shared.schemas.d.ts.map +1 -1
  131. package/dist/esm/external-providers/provider-protocol.shared.schemas.js +7 -5
  132. package/dist/esm/external-providers/provider-protocol.shared.schemas.js.map +1 -1
  133. package/dist/esm/external-providers/provider-tier-rule.shared.utils.d.ts +40 -0
  134. package/dist/esm/external-providers/provider-tier-rule.shared.utils.d.ts.map +1 -0
  135. package/dist/esm/external-providers/provider-tier-rule.shared.utils.js +80 -0
  136. package/dist/esm/external-providers/provider-tier-rule.shared.utils.js.map +1 -0
  137. package/dist/esm/features/core-feature-definitions.shared.d.ts.map +1 -1
  138. package/dist/esm/features/core-feature-definitions.shared.js +7 -1
  139. package/dist/esm/features/core-feature-definitions.shared.js.map +1 -1
  140. package/dist/esm/features/feature-builders.shared.d.ts +32 -0
  141. package/dist/esm/features/feature-builders.shared.d.ts.map +1 -1
  142. package/dist/esm/features/feature-builders.shared.js +32 -0
  143. package/dist/esm/features/feature-builders.shared.js.map +1 -1
  144. package/dist/esm/files/file-upload-grant.shared.schemas.d.ts +14 -2
  145. package/dist/esm/files/file-upload-grant.shared.schemas.d.ts.map +1 -1
  146. package/dist/esm/files/file-upload-grant.shared.schemas.js +44 -5
  147. package/dist/esm/files/file-upload-grant.shared.schemas.js.map +1 -1
  148. package/dist/esm/files/files.shared.schemas.d.ts +15 -8
  149. package/dist/esm/files/files.shared.schemas.d.ts.map +1 -1
  150. package/dist/esm/files/files.shared.schemas.js +15 -8
  151. package/dist/esm/files/files.shared.schemas.js.map +1 -1
  152. package/dist/esm/flows-actors/actors.shared.schemas.d.ts.map +1 -1
  153. package/dist/esm/flows-actors/actors.shared.schemas.js +3 -2
  154. package/dist/esm/flows-actors/actors.shared.schemas.js.map +1 -1
  155. package/dist/esm/flows-actors/agents.shared.schemas.d.ts +54 -5
  156. package/dist/esm/flows-actors/agents.shared.schemas.d.ts.map +1 -1
  157. package/dist/esm/flows-actors/agents.shared.schemas.js.map +1 -1
  158. package/dist/esm/flows-actors/apps-blueprint/apps-blueprint.shared.schemas.d.ts +6 -6
  159. package/dist/esm/flows-actors/deliberation.shared.schemas.d.ts +0 -3
  160. package/dist/esm/flows-actors/deliberation.shared.schemas.d.ts.map +1 -1
  161. package/dist/esm/flows-actors/deliberation.shared.schemas.js +0 -5
  162. package/dist/esm/flows-actors/deliberation.shared.schemas.js.map +1 -1
  163. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.d.ts +14 -0
  164. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.d.ts.map +1 -1
  165. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js +40 -3
  166. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js.map +1 -1
  167. package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.d.ts +19 -0
  168. package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.d.ts.map +1 -1
  169. package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.js +33 -0
  170. package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.js.map +1 -1
  171. package/dist/esm/flows-actors/flows-actors.io.shared.schemas.d.ts +14 -9
  172. package/dist/esm/flows-actors/flows-actors.io.shared.schemas.d.ts.map +1 -1
  173. package/dist/esm/flows-actors/flows-actors.io.shared.schemas.js +14 -9
  174. package/dist/esm/flows-actors/flows-actors.io.shared.schemas.js.map +1 -1
  175. package/dist/esm/flows-actors/flows-actors.system.shared.schemas.d.ts.map +1 -1
  176. package/dist/esm/flows-actors/flows-actors.system.shared.schemas.js +3 -2
  177. package/dist/esm/flows-actors/flows-actors.system.shared.schemas.js.map +1 -1
  178. package/dist/esm/flows-actors/flows.shared.schemas.d.ts.map +1 -1
  179. package/dist/esm/flows-actors/flows.shared.schemas.js +3 -2
  180. package/dist/esm/flows-actors/flows.shared.schemas.js.map +1 -1
  181. package/dist/esm/flows-actors/mcp-servers.shared.schemas.d.ts +128 -0
  182. package/dist/esm/flows-actors/mcp-servers.shared.schemas.d.ts.map +1 -0
  183. package/dist/esm/flows-actors/mcp-servers.shared.schemas.js +142 -0
  184. package/dist/esm/flows-actors/mcp-servers.shared.schemas.js.map +1 -0
  185. package/dist/esm/flows-actors/meta-workflows/budget-authority.meta-workflows.shared.schemas.d.ts +0 -3
  186. package/dist/esm/flows-actors/meta-workflows/budget-authority.meta-workflows.shared.schemas.d.ts.map +1 -1
  187. package/dist/esm/flows-actors/meta-workflows/budget-authority.meta-workflows.shared.schemas.js +1 -4
  188. package/dist/esm/flows-actors/meta-workflows/budget-authority.meta-workflows.shared.schemas.js.map +1 -1
  189. package/dist/esm/flows-actors/meta-workflows/context-selection.meta-workflows.shared.schemas.d.ts +0 -16
  190. package/dist/esm/flows-actors/meta-workflows/context-selection.meta-workflows.shared.schemas.d.ts.map +1 -1
  191. package/dist/esm/flows-actors/meta-workflows/context-selection.meta-workflows.shared.schemas.js +1 -17
  192. package/dist/esm/flows-actors/meta-workflows/context-selection.meta-workflows.shared.schemas.js.map +1 -1
  193. package/dist/esm/flows-actors/meta-workflows/decisions.meta-workflows.shared.schemas.d.ts +3 -3
  194. package/dist/esm/flows-actors/meta-workflows/decisions.meta-workflows.shared.schemas.js +3 -3
  195. package/dist/esm/flows-actors/meta-workflows/decisions.meta-workflows.shared.schemas.js.map +1 -1
  196. package/dist/esm/flows-actors/meta-workflows/execution-binding-common.meta-workflows.shared.schemas.d.ts +2 -8
  197. package/dist/esm/flows-actors/meta-workflows/execution-binding-common.meta-workflows.shared.schemas.d.ts.map +1 -1
  198. package/dist/esm/flows-actors/meta-workflows/execution-binding-common.meta-workflows.shared.schemas.js +4 -15
  199. package/dist/esm/flows-actors/meta-workflows/execution-binding-common.meta-workflows.shared.schemas.js.map +1 -1
  200. package/dist/esm/guidance/guidance-state.shared.utils.d.ts.map +1 -1
  201. package/dist/esm/guidance/guidance-state.shared.utils.js +1 -0
  202. package/dist/esm/guidance/guidance-state.shared.utils.js.map +1 -1
  203. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts +8 -0
  204. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts.map +1 -1
  205. package/dist/esm/guidance/progression-state.shared.schemas.d.ts +46 -0
  206. package/dist/esm/guidance/progression-state.shared.schemas.d.ts.map +1 -1
  207. package/dist/esm/guidance/progression-state.shared.schemas.js +49 -0
  208. package/dist/esm/guidance/progression-state.shared.schemas.js.map +1 -1
  209. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts +320 -50
  210. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts.map +1 -1
  211. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js +137 -36
  212. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js.map +1 -1
  213. package/dist/esm/index.d.ts +9 -0
  214. package/dist/esm/index.d.ts.map +1 -1
  215. package/dist/esm/index.js +9 -0
  216. package/dist/esm/index.js.map +1 -1
  217. package/dist/esm/notifications/email/email-template-registry.shared.schemas.d.ts +11 -2
  218. package/dist/esm/notifications/email/email-template-registry.shared.schemas.d.ts.map +1 -1
  219. package/dist/esm/notifications/email/email-template-registry.shared.schemas.js.map +1 -1
  220. package/dist/esm/notifications/email/email-template.shared.enums.d.ts +15 -0
  221. package/dist/esm/notifications/email/email-template.shared.enums.d.ts.map +1 -1
  222. package/dist/esm/notifications/email/email-template.shared.enums.js +15 -0
  223. package/dist/esm/notifications/email/email-template.shared.enums.js.map +1 -1
  224. package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.d.ts +1 -0
  225. package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.d.ts.map +1 -1
  226. package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.js +19 -0
  227. package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.js.map +1 -1
  228. package/dist/esm/notifications/m2m/webhook-config.shared.schemas.d.ts +30 -0
  229. package/dist/esm/notifications/m2m/webhook-config.shared.schemas.d.ts.map +1 -1
  230. package/dist/esm/notifications/m2m/webhook-config.shared.schemas.js +65 -1
  231. package/dist/esm/notifications/m2m/webhook-config.shared.schemas.js.map +1 -1
  232. package/dist/esm/notifications/notification-badges.core.definitions.d.ts +6 -4
  233. package/dist/esm/notifications/notification-badges.core.definitions.d.ts.map +1 -1
  234. package/dist/esm/notifications/notification-badges.core.definitions.js +6 -4
  235. package/dist/esm/notifications/notification-badges.core.definitions.js.map +1 -1
  236. package/dist/esm/notifications/notification-badges.schemas.d.ts +167 -5
  237. package/dist/esm/notifications/notification-badges.schemas.d.ts.map +1 -1
  238. package/dist/esm/notifications/notification-badges.schemas.js +191 -6
  239. package/dist/esm/notifications/notification-badges.schemas.js.map +1 -1
  240. package/dist/esm/notifications/notifications.shared.schemas.d.ts +107 -0
  241. package/dist/esm/notifications/notifications.shared.schemas.d.ts.map +1 -1
  242. package/dist/esm/notifications/notifications.shared.schemas.js +149 -1
  243. package/dist/esm/notifications/notifications.shared.schemas.js.map +1 -1
  244. package/dist/esm/organizations/organization-notifications.shared.schemas.d.ts.map +1 -1
  245. package/dist/esm/organizations/organization-notifications.shared.schemas.js +22 -1
  246. package/dist/esm/organizations/organization-notifications.shared.schemas.js.map +1 -1
  247. package/dist/esm/organizations/organization-preferences.shared.schemas.d.ts +26 -0
  248. package/dist/esm/organizations/organization-preferences.shared.schemas.d.ts.map +1 -1
  249. package/dist/esm/organizations/organization-preferences.shared.schemas.js +25 -0
  250. package/dist/esm/organizations/organization-preferences.shared.schemas.js.map +1 -1
  251. package/dist/esm/organizations/organization-profile.shared.schemas.d.ts +25 -0
  252. package/dist/esm/organizations/organization-profile.shared.schemas.d.ts.map +1 -1
  253. package/dist/esm/organizations/organization-profile.shared.schemas.js +42 -17
  254. package/dist/esm/organizations/organization-profile.shared.schemas.js.map +1 -1
  255. package/dist/esm/organizations/organization-unit-narrowing.shared.d.ts +3 -2
  256. package/dist/esm/organizations/organization-unit-narrowing.shared.d.ts.map +1 -1
  257. package/dist/esm/organizations/organization-unit-narrowing.shared.js +9 -2
  258. package/dist/esm/organizations/organization-unit-narrowing.shared.js.map +1 -1
  259. package/dist/esm/organizations/organizations.shared.resources-config.schemas.d.ts.map +1 -1
  260. package/dist/esm/organizations/organizations.shared.resources-config.schemas.js +18 -3
  261. package/dist/esm/organizations/organizations.shared.resources-config.schemas.js.map +1 -1
  262. package/dist/esm/public-runtime/index.d.ts +49 -2
  263. package/dist/esm/public-runtime/index.d.ts.map +1 -1
  264. package/dist/esm/public-runtime/index.js +48 -1
  265. package/dist/esm/public-runtime/index.js.map +1 -1
  266. package/dist/esm/queue/jobs.shared.resources-config.schemas.d.ts +6 -5
  267. package/dist/esm/queue/jobs.shared.resources-config.schemas.d.ts.map +1 -1
  268. package/dist/esm/queue/jobs.shared.resources-config.schemas.js +6 -5
  269. package/dist/esm/queue/jobs.shared.resources-config.schemas.js.map +1 -1
  270. package/dist/esm/queue/jobs.shared.schemas.d.ts +16 -3
  271. package/dist/esm/queue/jobs.shared.schemas.d.ts.map +1 -1
  272. package/dist/esm/queue/jobs.shared.schemas.js +16 -3
  273. package/dist/esm/queue/jobs.shared.schemas.js.map +1 -1
  274. package/dist/esm/requests/manual-controllers-routes-documentation.d.ts +137 -0
  275. package/dist/esm/requests/manual-controllers-routes-documentation.d.ts.map +1 -0
  276. package/dist/esm/requests/manual-controllers-routes-documentation.js +1201 -0
  277. package/dist/esm/requests/manual-controllers-routes-documentation.js.map +1 -0
  278. package/dist/esm/requests/manual-controllers-routes-urls.d.ts +67 -0
  279. package/dist/esm/requests/manual-controllers-routes-urls.d.ts.map +1 -1
  280. package/dist/esm/requests/manual-controllers-routes-urls.js +78 -0
  281. package/dist/esm/requests/manual-controllers-routes-urls.js.map +1 -1
  282. package/dist/esm/requests/rate-limits.shared.schemas.d.ts +11 -1
  283. package/dist/esm/requests/rate-limits.shared.schemas.d.ts.map +1 -1
  284. package/dist/esm/requests/rate-limits.shared.schemas.js +11 -1
  285. package/dist/esm/requests/rate-limits.shared.schemas.js.map +1 -1
  286. package/dist/esm/requests/websocket.shared.schemas.d.ts +27 -4
  287. package/dist/esm/requests/websocket.shared.schemas.d.ts.map +1 -1
  288. package/dist/esm/requests/websocket.shared.schemas.js +35 -0
  289. package/dist/esm/requests/websocket.shared.schemas.js.map +1 -1
  290. package/dist/esm/resources/resources-config.shared.factory.d.ts +1 -0
  291. package/dist/esm/resources/resources-config.shared.factory.d.ts.map +1 -1
  292. package/dist/esm/resources/resources-config.shared.factory.js +105 -20
  293. package/dist/esm/resources/resources-config.shared.factory.js.map +1 -1
  294. package/dist/esm/resources/resources-config.shared.schemas.d.ts +254 -72
  295. package/dist/esm/resources/resources-config.shared.schemas.d.ts.map +1 -1
  296. package/dist/esm/resources/resources-config.shared.schemas.js.map +1 -1
  297. package/dist/esm/resources/resources-registry.shared.core.definitions.d.ts.map +1 -1
  298. package/dist/esm/resources/resources-registry.shared.core.definitions.js +97 -5
  299. package/dist/esm/resources/resources-registry.shared.core.definitions.js.map +1 -1
  300. package/dist/esm/resources/resources-relationships.shared.factory.d.ts.map +1 -1
  301. package/dist/esm/resources/resources-relationships.shared.factory.js +15 -0
  302. package/dist/esm/resources/resources-relationships.shared.factory.js.map +1 -1
  303. package/dist/esm/resources/resources.shared.core.definitions.d.ts +37 -0
  304. package/dist/esm/resources/resources.shared.core.definitions.d.ts.map +1 -1
  305. package/dist/esm/resources/resources.shared.core.definitions.js +51 -0
  306. package/dist/esm/resources/resources.shared.core.definitions.js.map +1 -1
  307. package/dist/esm/resources/resources.shared.schemas.d.ts +11 -2
  308. package/dist/esm/resources/resources.shared.schemas.d.ts.map +1 -1
  309. package/dist/esm/resources/resources.shared.schemas.js +34 -3
  310. package/dist/esm/resources/resources.shared.schemas.js.map +1 -1
  311. package/dist/esm/resources/utils/field-value-disclosure.utils.d.ts +51 -0
  312. package/dist/esm/resources/utils/field-value-disclosure.utils.d.ts.map +1 -0
  313. package/dist/esm/resources/utils/field-value-disclosure.utils.js +53 -0
  314. package/dist/esm/resources/utils/field-value-disclosure.utils.js.map +1 -0
  315. package/dist/esm/resources/utils/resources-summary.utils.d.ts +16 -2
  316. package/dist/esm/resources/utils/resources-summary.utils.d.ts.map +1 -1
  317. package/dist/esm/resources/utils/resources-summary.utils.js +19 -5
  318. package/dist/esm/resources/utils/resources-summary.utils.js.map +1 -1
  319. package/dist/esm/resources/utils/shared-persistence-collection.utils.d.ts.map +1 -1
  320. package/dist/esm/resources/utils/shared-persistence-collection.utils.js +11 -0
  321. package/dist/esm/resources/utils/shared-persistence-collection.utils.js.map +1 -1
  322. package/dist/esm/runtime/domain-module.shared.definitions.d.ts +25 -0
  323. package/dist/esm/runtime/domain-module.shared.definitions.d.ts.map +1 -1
  324. package/dist/esm/runtime/domain-module.shared.definitions.js.map +1 -1
  325. package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.d.ts +1 -0
  326. package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.d.ts.map +1 -1
  327. package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.js +38 -0
  328. package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.js.map +1 -1
  329. package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.d.ts +1 -0
  330. package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.d.ts.map +1 -1
  331. package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.js +38 -0
  332. package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.js.map +1 -1
  333. package/dist/esm/security/authentications/authentication.shared.dto.schemas.d.ts +4 -11
  334. package/dist/esm/security/authentications/authentication.shared.dto.schemas.d.ts.map +1 -1
  335. package/dist/esm/security/authentications/authentication.shared.dto.schemas.js +0 -1
  336. package/dist/esm/security/authentications/authentication.shared.dto.schemas.js.map +1 -1
  337. package/dist/esm/security/authentications/authentication.shared.schemas.d.ts +84 -5
  338. package/dist/esm/security/authentications/authentication.shared.schemas.d.ts.map +1 -1
  339. package/dist/esm/security/authentications/authentication.shared.schemas.js +83 -3
  340. package/dist/esm/security/authentications/authentication.shared.schemas.js.map +1 -1
  341. package/dist/esm/security/authentications/registration.shared.dto.schemas.d.ts +1 -0
  342. package/dist/esm/security/authentications/registration.shared.dto.schemas.d.ts.map +1 -1
  343. package/dist/esm/security/authentications/registration.shared.dto.schemas.js +11 -0
  344. package/dist/esm/security/authentications/registration.shared.dto.schemas.js.map +1 -1
  345. package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.d.ts +15 -0
  346. package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.d.ts.map +1 -1
  347. package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.js +21 -4
  348. package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.js.map +1 -1
  349. package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.d.ts +61 -1
  350. package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.d.ts.map +1 -1
  351. package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.js +208 -6
  352. package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.js.map +1 -1
  353. package/dist/esm/security/authentications/sso/sso-config.shared.schemas.d.ts +37 -27
  354. package/dist/esm/security/authentications/sso/sso-config.shared.schemas.d.ts.map +1 -1
  355. package/dist/esm/security/authentications/sso/sso-config.shared.schemas.js +134 -12
  356. package/dist/esm/security/authentications/sso/sso-config.shared.schemas.js.map +1 -1
  357. package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.d.ts +0 -6
  358. package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.d.ts.map +1 -1
  359. package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.js +17 -8
  360. package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.js.map +1 -1
  361. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts.map +1 -1
  362. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js +27 -0
  363. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js.map +1 -1
  364. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts +52 -7
  365. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts.map +1 -1
  366. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js +45 -8
  367. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js.map +1 -1
  368. package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.d.ts +31 -0
  369. package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.d.ts.map +1 -0
  370. package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.js +198 -0
  371. package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.js.map +1 -0
  372. package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.d.ts +31 -0
  373. package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.d.ts.map +1 -0
  374. package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.js +191 -0
  375. package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.js.map +1 -0
  376. package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.d.ts +250 -0
  377. package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.d.ts.map +1 -0
  378. package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.js +486 -0
  379. package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.js.map +1 -0
  380. package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.d.ts +4 -1
  381. package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.d.ts.map +1 -1
  382. package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.js +29 -0
  383. package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.js.map +1 -1
  384. package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.d.ts +4 -1
  385. package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.d.ts.map +1 -1
  386. package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.js +29 -0
  387. package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.js.map +1 -1
  388. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts +6 -0
  389. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts.map +1 -1
  390. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js +31 -0
  391. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js.map +1 -1
  392. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.d.ts +13 -0
  393. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.d.ts.map +1 -1
  394. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js +24 -3
  395. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js.map +1 -1
  396. package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts +4 -4
  397. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts +4 -4
  398. package/dist/esm/users/user-self.shared.resources-config.schemas.d.ts.map +1 -1
  399. package/dist/esm/users/user-self.shared.resources-config.schemas.js +33 -3
  400. package/dist/esm/users/user-self.shared.resources-config.schemas.js.map +1 -1
  401. package/dist/esm/users/users.shared.resources-config.schemas.d.ts +17 -1
  402. package/dist/esm/users/users.shared.resources-config.schemas.d.ts.map +1 -1
  403. package/dist/esm/users/users.shared.resources-config.schemas.js +136 -5
  404. package/dist/esm/users/users.shared.resources-config.schemas.js.map +1 -1
  405. package/dist/esm/users/users.shared.schemas.d.ts +43 -12
  406. package/dist/esm/users/users.shared.schemas.d.ts.map +1 -1
  407. package/dist/esm/users/users.shared.schemas.js +38 -7
  408. package/dist/esm/users/users.shared.schemas.js.map +1 -1
  409. package/dist/tsconfig.build.tsbuildinfo +1 -1
  410. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"redaction.shared.schemas.js","sourceRoot":"","sources":["../../../../../src/compliance/privacy/redaction.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,oDAAoD,CAAC;AAEjF;;;;;;;;;;;GAWG;AACH,MAAM,CAAN,IAAY,aA+BX;AA/BD,WAAY,aAAa;IACvB,mDAAmD;IACnD,8BAAa,CAAA;IACb,qEAAqE;IACrE,kCAAiB,CAAA;IACjB,kDAAkD;IAClD,8BAAa,CAAA;IACb,4DAA4D;IAC5D,oCAAmB,CAAA;IACnB,uGAAuG;IACvG,8BAAa,CAAA;IACb;;;;;;;;;;;;;;;;;;OAkBG;IACH,gCAAe,CAAA;AACjB,CAAC,EA/BW,aAAa,KAAb,aAAa,QA+BxB;AAGD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,4DAA4D;IACrG,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;IACpC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\nimport { RolesSchema } from \"../../security/authorizations/roles.shared.schemas\";\n\n/**\n * Field-treatment vocabulary, shared by two consumers (D9 — \"one authority axis\"):\n * - flow-actors `redactionRules` (log / response redaction), and\n * - the impersonalization `.impersonalizeWith()` per-field treatment (erasure scrub —\n * scrub a person out of a record that must be retained).\n *\n * Adding members is additive for both consumers (no exhaustive switches read it).\n * `KEEP` is meaningful only for impersonalization (never scrub this field) — the\n * never-scrub scope-FK floor relies on it. Reversible tokenization is intentionally\n * NOT in v1 (D6 = irreversible); `ENCRYPT` remains the existing reversible option, and a\n * dedicated `TOKENIZE` member can be added additively if a vault-backed mode ships later.\n */\nexport enum RedactionType {\n /** Replace with a fixed mask (e.g. `••••••••`). */\n MASK = 'mask',\n /** Remove / null the value. Impersonalization: the default scrub. */\n REMOVE = 'remove',\n /** Replace with a one-way hash — irreversible. */\n HASH = 'hash',\n /** Replace with a reversible ciphertext (key-dependent). */\n ENCRYPT = 'encrypt',\n /** Impersonalization only: retain the field as-is (never scrub). The scope-FK KEEP-floor uses this. */\n KEEP = 'keep',\n /**\n * Impersonalization only: reset the field to its OWN schema default.\n *\n * The treatment for a field that is non-nullable and carries a `.default()` where neither of the\n * other two reaches. `REMOVE` writes null, which fails the strict re-parse of the row erasure just\n * wrote; `MASK` cannot express the value, because `maskValue` is typed `string` while these fields\n * are arrays, records, numbers, dates and objects.\n *\n * That is not a rare shape. Measured 2026-08-31 across the engine schemas still owed an erasure\n * posture, ELEVEN categorized fields were of it and NONE was scrubbable — behavioural counters,\n * stage histories, notification preferences, regional settings carrying LOCATION. Those resources\n * could declare no honest posture at all: `RETAIN_AND_IMPERSONALIZE` is refused when nothing would\n * be scrubbed, and `RETAIN_ONLY` would assert they hold no personal data, which is false.\n *\n * The value comes from the schema rather than from the author, deliberately. A second copy of every\n * default would drift from the first, and \"what this field is when nobody has set it\" is a question\n * the schema already answers — for a person's settings and counters that is exactly what erasure\n * should leave behind.\n */\n RESET = 'reset',\n}\n\n\nexport const RedationRulesSchema = z.object({\n fieldPath: z.string(),\n isRecursive: z.boolean().default(false), // default false - if true, will redaction all nested fields\n redactionType: z.enum(RedactionType),\n forRoles: z.array(RolesSchema).optional(),\n});\n\nexport type RedationRules = z.infer<typeof RedationRulesSchema>;\n"]}
1
+ {"version":3,"file":"redaction.shared.schemas.js","sourceRoot":"","sources":["../../../../../src/compliance/privacy/redaction.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,oDAAoD,CAAC;AAEjF;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,MAAM,CAAN,IAAY,aA0BX;AA1BD,WAAY,aAAa;IACvB,sJAAsJ;IACtJ,8BAAa,CAAA;IACb,0GAA0G;IAC1G,kCAAiB,CAAA;IACjB,4JAA4J;IAC5J,8BAAa,CAAA;IACb,iJAAiJ;IACjJ,oCAAmB,CAAA;IACnB,wGAAwG;IACxG,8BAAa,CAAA;IACb;;;;;;;;;;;;;OAaG;IACH,gCAAe,CAAA;AACjB,CAAC,EA1BW,aAAa,KAAb,aAAa,QA0BxB;AACD,sEAAsE;AAGtE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,4DAA4D;IACrG,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;IACpC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\nimport { RolesSchema } from \"../../security/authorizations/roles.shared.schemas\";\n\n/*\n * MAINTAINER NOTE — not part of the anchored, application-facing block below.\n *\n * One authority axis (D9): this vocabulary is shared by flow-actors `redactionRules` and by the\n * impersonalization `.impersonalizeWith()` treatment, deliberately, so the two cannot drift into two\n * spellings of the same idea. Adding a member is additive for both consumers no exhaustive switch\n * reads it EXCEPT `buildImpersonalizeScrubPatch`, whose `default` arm throws on purpose so a new\n * member fails loud in an erasure rather than being silently skipped.\n *\n * Reversible tokenization is intentionally NOT in v1 (D6 = irreversible). `ENCRYPT` stays the\n * existing reversible option for redaction, and a vault-backed `TOKENIZE` member can be added\n * additively if such a mode ships.\n */\n\n/**\n * @wildo_source:part:start saas.models.privacy.redaction-treatments facet:layer:shared facet:audience:app-developer\n *\n * How one field's value is replaced when it is redacted or scrubbed.\n *\n * Imported from `@wildo-ai/saas-models`.\n *\n * ## Two consumers, and only one of them accepts every member\n *\n * | consumer | what it does | accepts |\n * |---|---|---|\n * | flow-actors `redactionRules` | hides a value in a LOG or an API RESPONSE; the stored row is untouched | every member |\n * | `.impersonalizeWith(...)` on a schema field | ERASURE scrub: permanently rewrites the stored value when the person is erased and the row is retained | `REMOVE` · `MASK` · `RESET` · `KEEP` only |\n *\n * **`HASH` and `ENCRYPT` are accepted by the type and REFUSED at erasure time.** An erasure scrub is\n * one static write shared by every row in the batch, so `HASH` — which would have to hash each row's\n * own value — cannot be expressed and throws. `ENCRYPT` is reversible, and an erasure that can be\n * undone is not an erasure, so it is forbidden here and stays a redaction-only option. Both throw\n * when the erasure runs, not when you author the field, so choosing one leaves a resource that\n * configures cleanly and fails the first time somebody is erased.\n *\n * ## Choosing a treatment for an erasure scrub\n *\n * | the field | treatment |\n * |---|---|\n * | nullable, or `.nullish()` | `REMOVE` writes `null`. The default choice. |\n * | a constrained string that cannot hold the default mask (`z.email()`, `z.uuid()`, `.min(n)`) | `MASK` with an explicit `maskValue` that satisfies the field's own schema |\n * | NON-nullable and carries a `.default()`a counter, a settings object, a stage history, an array | `RESET` — writes what the schema says the field is when nobody has set it |\n * | the row's link to its tenant or its creator | nothing: the never-scrub floor already protects it |\n *\n * `RESET` is the one to reach for when the other two do not fit, and that case is common rather than\n * exotic: `REMOVE` writes `null`, which fails the strict re-parse of the row the erasure just wrote,\n * and `MASK` writes a string, which cannot express an array, a record, a number or a date.\n *\n * ⚠️ **`RESET` refuses a default that reads the clock.** `.default(() => new Date())` — or a literal\n * `.default(new Date())` evaluated when the module loads — makes the erasure write its OWN timestamp,\n * so a field such as `lastActiveAt` would record the erased person as active at the moment they were\n * erased. That fabricates information rather than removing it. Give the field a static neutral\n * default such as `new Date(0)`, which asserts \"no recorded value\", or make it nullable and use\n * `REMOVE`, which asserts \"unknown\". Those are different claims about a person; choose deliberately.\n *\n * ## The never-scrub floor\n *\n * A row's link to the organization or application it belongs to, and its `createdByUserId`, are\n * never scrubbed — even when a treatment is declared on them. They connect the retained row to the\n * tenant that must keep it, and nulling them would orphan the record the retention exists to\n * preserve. `KEEP` is the way to say the same thing explicitly about any other field.\n *\n * A field with NO `.impersonalizeWith()` is left untouched by an erasure. Declaring nothing is how a\n * legally required value — an invoice line, an amount, a date — survives the erasure of the person\n * the record names.\n *\n * @example Scrubbing a person out of a retained record\n * ```ts\n * import { RedactionType } from '@wildo-ai/saas-models';\n *\n * const contactSchema = z.object({\n * // nullable → REMOVE\n * phone: z.string().nullish().impersonalizeWith(RedactionType.REMOVE),\n * // constrained string → MASK with a value the field's own schema accepts\n * email: z.email().impersonalizeWith(RedactionType.MASK, { maskValue: 'erased@erased.invalid' }),\n * // non-nullable with a default → RESET\n * preferences: z.object({ digest: z.boolean() }).default({ digest: false })\n * .impersonalizeWith(RedactionType.RESET),\n * // no treatment → survives the erasure, deliberately\n * invoicedAmount: z.number(),\n * });\n * ```\n */\nexport enum RedactionType {\n /** Replace with a fixed mask. In an erasure scrub the value must satisfy the field's own schema — pass `maskValue` when the default mask does not. */\n MASK = 'mask',\n /** Remove / null the value. The default erasure scrub; requires a field that can actually hold `null`. */\n REMOVE = 'remove',\n /** Replace with a one-way hash. Redaction only **throws** if an erasure scrub reaches it, because a scrub is one static write and cannot hash per row. */\n HASH = 'hash',\n /** Replace with a reversible ciphertext. Redaction only — **forbidden** for an erasure scrub, because a reversible erasure is not an erasure. */\n ENCRYPT = 'encrypt',\n /** Erasure scrub only: keep this field exactly as it is. The explicit form of the never-scrub floor. */\n KEEP = 'keep',\n /**\n * Erasure scrub only: reset the field to its OWN schema default.\n *\n * The treatment for a field that is non-nullable and carries a `.default()`, where neither of the\n * others reaches: `REMOVE` writes `null`, which fails the strict re-parse of the row the erasure\n * just wrote, and `MASK` writes a string, while these fields are arrays, records, numbers, dates\n * and objects.\n *\n * The value is read from the schema rather than authored a second time, so it cannot drift from\n * the default the field already declares and for a person's counters and settings, \"what this is\n * when nobody has set it\" is exactly what an erasure should leave behind.\n *\n * Refused when the field declares no `.default()`, and refused when that default reads the clock.\n */\n RESET = 'reset',\n}\n/** @wildo_source:part:end saas.models.privacy.redaction-treatments */\n\n\nexport const RedationRulesSchema = z.object({\n fieldPath: z.string(),\n isRecursive: z.boolean().default(false), // default false - if true, will redaction all nested fields\n redactionType: z.enum(RedactionType),\n forRoles: z.array(RolesSchema).optional(),\n});\n\nexport type RedationRules = z.infer<typeof RedationRulesSchema>;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"subject-export.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../../src/compliance/privacy/subject-export.shared.schemas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"subject-export.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../../src/compliance/privacy/subject-export.shared.schemas.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { getPortabilityProvenance, isBackendOnlyField, isWriteOnlySecretField } from '@wildo-ai/zod-decorators';
1
+ import { getPortabilityProvenance } from '@wildo-ai/zod-decorators';
2
+ import { isNonDisclosableFieldValue } from '../../resources/utils/field-value-disclosure.utils.js';
2
3
  import { RelationshipLifecycleModel, } from '../../resources/resources.shared.schemas.js';
3
4
  import { Resources_SharedUtils } from '../../resources/resources.shared.utils.js';
4
5
  const compareCanonicalText = (left, right) => (left < right ? -1 : left > right ? 1 : 0);
@@ -410,10 +411,16 @@ function resolvePortabilityFieldScope(provenance) {
410
411
  * assurance-control: WILDO.PRIVACY.SUBJECT_DATA_EXPORT
411
412
  */
412
413
  export function isFieldWithheldFromSubjectExport(fieldSchema) {
413
- // `isWriteOnlySecret` is checked explicitly rather than assumed to imply backend-only: they are
414
- // separate decorators, and a future authoring form that sets one without the other must not
415
- // silently open a disclosure path.
416
- return isBackendOnlyField(fieldSchema) || isWriteOnlySecretField(fieldSchema);
414
+ // Delegated to the ONE field-value disclosure rule rather than restated. The reasoning that used
415
+ // to sit here that `isWriteOnlySecret` is checked explicitly rather than assumed to imply
416
+ // backend-only, because they are separate decorators and a future authoring form may set one
417
+ // without the other — moved WITH the rule, and is now the shared module's own justification.
418
+ //
419
+ // This function keeps its own name and its own assurance marker deliberately: subject export is a
420
+ // distinct obligation from model disclosure, its own docstring anticipates a per-field opt-in that
421
+ // would apply HERE and nowhere else, and merging the two names would make that extension
422
+ // unexpressible. What is shared is the rule, not the concept.
423
+ return isNonDisclosableFieldValue(fieldSchema);
417
424
  }
418
425
  /** Every legal {@link DataPortabilityProvenance} value, for validating an opaque decorator string. */
419
426
  const KNOWN_PORTABILITY_PROVENANCES = new Set(Object.values(DataPortabilityProvenance));
@@ -1 +1 @@
1
- {"version":3,"file":"subject-export.shared.schemas.js","sourceRoot":"","sources":["../../../../../src/compliance/privacy/subject-export.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import type { z } from 'zod';\nimport { getPortabilityProvenance, isBackendOnlyField, isWriteOnlySecretField } from '@wildo-ai/zod-decorators';\nimport {\n RelationshipLifecycleModel,\n type ResourceRelationship,\n} from '../../resources/resources.shared.schemas';\nimport { Resources_SharedUtils } from '../../resources/resources.shared.utils';\nimport type { ResourceType } from '../../resources/resources.shared.core.definitions';\n\nconst compareCanonicalText = (left: string, right: string): number => (left < right ? -1 : left > right ? 1 : 0);\n\n/**\n * WHICH data-subject right an export is answering.\n *\n * ## Why this is an enum and not a boolean flag on one bundle\n *\n * GDPR Art. 15 (right of access) and Art. 20 (right to data portability) are DIFFERENT rights over\n * DIFFERENT data, and conflating them is the defect this capability was built to correct: the four\n * routed export operations removed on 2026-08-01 declared themselves \"portability / GDPR\" while\n * their actual options (`includeActivityData`, `includeOrganizationData`) described an *access*\n * bundle. One output with a flag would reproduce that merge.\n *\n * - **Access** is a disclosure obligation: everything the controller holds *concerning* the subject,\n * including data the controller itself derived about them, in any readable form.\n * - **Portability** is a transfer obligation: only the data the subject *provided* — actively, or by\n * using the service — and it must be machine-readable and re-importable elsewhere. Data the\n * controller inferred is deliberately OUT of scope; a competitor must not receive a rival's\n * analytics through a subject's portability request.\n *\n * The two therefore diverge at BOTH levels this module classifies: per-edge (see\n * {@link classifySubjectExportDisposition}) and per-field (see\n * {@link resolveSubjectExportFieldScope}).\n *\n * assurance-control: WILDO.PRIVACY.SUBJECT_DATA_EXPORT\n */\nexport enum SubjectExportPurpose {\n /**\n * Art. 15 — right of access. The broadest bundle: every row concerning the subject, whoever\n * produced it, including rows the subject does not own (an audit log about them, a membership an\n * administrator created).\n */\n ACCESS_ART_15 = 'access_art_15',\n\n /**\n * Art. 20 — right to data portability. Narrower on purpose: only data the subject supplied or\n * generated by using the service, and only from rows the subject owns. Controller-derived data is\n * excluded by {@link DataPortabilityProvenance.DERIVED}.\n */\n PORTABILITY_ART_20 = 'portability_art_20',\n}\n\n/**\n * WHERE one field's value came from — the axis that decides Art. 20 scope.\n *\n * ## Why three values and not `isSubjectProvided: boolean`\n *\n * EDPB/WP29 guidance splits \"provided by the data subject\" into data supplied *knowingly* and data\n * *observed* from the subject's use of the service, and puts BOTH in Art. 20 scope while excluding\n * data the controller *inferred*. A boolean forces `OBSERVED` to be mis-filed against whichever\n * side the author guesses — and it is the member most often got wrong, because \"the user did not\n * type it\" reads as \"the user did not provide it\", which is precisely the wrong conclusion.\n *\n * ## Why this is per-FIELD and not per-resource\n *\n * A single row routinely mixes the two: a user profile holds `firstName` (supplied) beside a\n * controller-computed status or score. A resource-level answer would have to round one way for the\n * whole row. The resource-level declaration exists only as a DEFAULT\n * (`portabilityPolicy.defaultProvenance`) so that annotating a resource stays a one-line cost; the\n * per-field decorator overrides it where a field differs.\n *\n * ⚠️ NOT a redaction or scrub concept. This says where a value CAME FROM, for a disclosure\n * decision. What happens to a value on ERASURE is `.impersonalizeWith()` / `RedactionType`, a\n * different axis entirely — a field can be `SUBJECT_PROVIDED` and also masked on erasure.\n */\nexport enum DataPortabilityProvenance {\n /**\n * The subject actively and knowingly supplied this value — form input, an uploaded file, a\n * setting they chose. Unambiguously in scope for both rights.\n */\n SUBJECT_PROVIDED = 'subject_provided',\n\n /**\n * Generated by the subject's USE of the service rather than typed by them — activity timestamps,\n * event history, usage counters, telemetry. **In scope for Art. 20**, which is the whole reason\n * this member exists separately from {@link DERIVED}.\n */\n OBSERVED = 'observed',\n\n /**\n * Produced BY the controller about the subject — inferred classifications, computed scores,\n * risk or segmentation labels, server-assigned lifecycle state. Disclosed under Art. 15 (the\n * subject may see what we concluded about them) but **excluded from Art. 20** (a portability\n * request is not a channel for exporting the controller's own analysis).\n */\n DERIVED = 'derived',\n}\n\n/**\n * What an export does with ONE child-direction edge of the subject.\n *\n * ## Why this is NOT `SubjectErasureDisposition`\n *\n * Erasure and export share a traversal and answer opposite questions — *what do I destroy?* versus\n * *what must I disclose?* — and they diverge on exactly the edges erasure calls `NOT_OWNED`.\n *\n * Erasure leaves audit logs, memberships and job executions alone, correctly: you do not delete an\n * audit log because a user exercised a right. But those same rows hold personal data CONCERNING the\n * subject, and Art. 15 covers \"all personal data concerning him or her\" — not \"rows he owns\".\n * Reusing erasure's vocabulary verbatim would have silently omitted the data an access request most\n * often targets. Hence {@link INCLUDED_REFERENCES_SUBJECT}, a case erasure has no use for.\n *\n * The two classifiers still read the SAME upstream authority for what an edge *says*\n * (`requireResolvedRelationshipSemantics`), so they can never disagree about ownership — only about\n * what to do with it.\n *\n * ## Why there is no blocking disposition here\n *\n * Erasure refuses up-front on `UNCLASSIFIED` / `UNSUPPORTED_DEFERRED` because it is about to\n * WRITE, cannot half-destroy a subject, and needs a teardown declaration nobody made. An export\n * writes nothing: ownership alone answers the edge question, a deferred teardown is irrelevant to a\n * read, and a cross-adapter dependent is merely a second query rather than a broken transaction.\n * The one genuine refusal in an export is field-level and Art. 20-only — see\n * {@link SubjectExportFieldScope.UNDECLARED}. Manufacturing an edge-level blocker for symmetry\n * would be false symmetry.\n */\nexport enum SubjectExportEdgeDisposition {\n /**\n * The subject OWNS this dependent (`lifecycleModelMode: DEPENDENT`), so its rows are the\n * subject's own data. Included for both purposes — for Art. 20 the per-field provenance filter\n * still applies to what comes back.\n */\n INCLUDED_OWNED = 'included_owned',\n\n /**\n * The subject does NOT own these rows, but they REFERENCE the subject — the far side carries a\n * foreign key back to them (an audit log, an organization membership, a job execution).\n *\n * **Art. 15 only.** These are personal data concerning the subject, so an access request must\n * disclose them. A portability request must not: the subject did not provide a row that a third\n * party or the controller created about them, and shipping them would export the controller's\n * operational records under a transfer right. For `PORTABILITY_ART_20` this same edge classifies\n * as {@link EXCLUDED_NOT_SUBJECT_PROVIDED}.\n */\n INCLUDED_REFERENCES_SUBJECT = 'included_references_subject',\n\n /**\n * The edge carries no personal data of the subject at all: an independent or link-only\n * relationship whose far side does not even reference them, or a disabled relationship that is\n * not part of the live graph. Out of scope for both rights.\n */\n EXCLUDED_NOT_SUBJECT_DATA = 'excluded_not_subject_data',\n\n /**\n * In scope for access, but excluded from THIS export because the export is a portability request\n * and the rows were not provided by the subject. Kept as its own member rather than collapsing\n * into {@link EXCLUDED_NOT_SUBJECT_DATA}: a reviewer asking \"why is my audit trail missing from\n * my portability export?\" needs \"because Art. 20 does not cover controller records\" and \"because\n * that edge holds nothing about you\" to be different answers, and only the first is a legal\n * position someone took.\n */\n EXCLUDED_NOT_SUBJECT_PROVIDED = 'excluded_not_subject_provided',\n\n /**\n * The rows ARE the subject's data and the right covers them, but the resource is declared\n * `systemAccessPolicy.exportSubject = FORBIDDEN` — someone decided it must never reach a data\n * subject (an authentication-credential store, a security audit trail).\n *\n * ## Why this excludes rather than refusing\n *\n * An UNDECLARED resource refuses the whole export, because nobody has decided yet and refusing is\n * what forces the decision. A FORBIDDEN one is the opposite: the decision exists, and refusing\n * would make it permanent sabotage — a `USERS` access export whose graph touches a credential\n * store could then NEVER run, no matter how many other resources opted in. Honouring the\n * declaration means leaving those rows out and saying so.\n *\n * ⚠️ This applies to EDGES only. A subject whose OWN resource is FORBIDDEN still refuses: there is\n * no export of a person whose identity row may not be disclosed, and silently returning an\n * edges-only bundle would be a disclosure that omits its own subject.\n */\n EXCLUDED_NOT_DISCLOSABLE = 'excluded_not_disclosable',\n}\n\n/** Whether an edge disposition puts the far side's rows INTO the bundle. */\nexport function isIncludedSubjectExportEdgeDisposition(\n disposition: SubjectExportEdgeDisposition,\n): boolean {\n return disposition === SubjectExportEdgeDisposition.INCLUDED_OWNED\n || disposition === SubjectExportEdgeDisposition.INCLUDED_REFERENCES_SUBJECT;\n}\n\n/** The classification of ONE child-direction edge of an export subject. */\nexport interface SubjectExportEdgeClassification {\n /** The related resource on the far side of the edge. */\n relatedResourceType: ResourceType;\n /** Whether, and why, this edge's rows join the bundle. */\n disposition: SubjectExportEdgeDisposition;\n /**\n * Human-readable justification quoting the configuration that produced it. Surfaced in the export\n * report so a data-protection reviewer never has to re-derive WHY a resource was included or\n * left out — which, for a disclosure obligation, is the evidence that matters.\n */\n reason: string;\n}\n\n/**\n * Classify what an export must do with ONE child-direction edge — the disclose-vs-omit decision,\n * DERIVED FROM CONFIGURATION rather than a hardcoded list of resource types.\n *\n * ## Where the answer comes from\n *\n * Two declarations the author already makes, read through the same shared authorities the delete\n * cascade and the erasure orchestrator read, so the three can never disagree about what an edge is:\n *\n * 1. **`handling.lifecycleModelMode`** — does the subject own this related resource's lifecycle?\n * `DEPENDENT` means the rows are the subject's own data.\n * 2. **Foreign-key topology** (`resolveForeignKeyHolderResourceType`, cardinality-only and\n * therefore pure) — for a NON-owned edge, does the far side nonetheless carry a reference back\n * to the subject? If it does, its rows are *about* the subject and Art. 15 must disclose them.\n *\n * ## The `purpose` parameter, and why it is a parameter\n *\n * Art. 15 and Art. 20 diverge on exactly one edge case — the referencing-but-not-owned edge — and\n * keeping that divergence in ONE switch here is what stops two near-identical classifiers from\n * drifting apart. Exposing `classifyForAccess` / `classifyForPortability` would duplicate the\n * ownership logic, and the day someone fixes a bug in one they would miss the other.\n *\n * ## Caller contract\n *\n * `relationship.resourceType2` MUST be the far side and `resourceType1` the subject — the same\n * child-direction normalization {@link classifySubjectErasureDisposition} requires. The caller\n * filters to child-direction edges before classifying.\n *\n * Pure and side-effect free — no registry lookups, no I/O, no row reads — so it is equally usable\n * from a runtime orchestrator and from a boot-time coherence guard.\n */\nexport function classifySubjectExportDisposition(\n relationship: ResourceRelationship,\n purpose: SubjectExportPurpose,\n): SubjectExportEdgeClassification {\n const relatedResourceType = relationship.resourceType2 as ResourceType;\n const classify = (\n disposition: SubjectExportEdgeDisposition,\n reason: string,\n ): SubjectExportEdgeClassification => ({ relatedResourceType, disposition, reason });\n\n // A disabled relationship is not part of the live graph — the runtime never traverses it, so\n // there are no rows behind it to disclose.\n if (relationship.isDisabled === true) {\n return classify(\n SubjectExportEdgeDisposition.EXCLUDED_NOT_SUBJECT_DATA,\n 'the relationship is disabled (isDisabled: true), so it is not part of the live graph',\n );\n }\n\n const semantics = Resources_SharedUtils.requireResolvedRelationshipSemantics(relationship);\n const lifecycleModel = semantics.handling.lifecycleModelMode;\n\n if (lifecycleModel === RelationshipLifecycleModel.DEPENDENT) {\n return classify(\n SubjectExportEdgeDisposition.INCLUDED_OWNED,\n 'lifecycleModelMode is DEPENDENT: the subject owns these rows, so they are the subject\\'s '\n + 'own data and belong in the bundle',\n );\n }\n\n // NOT owned from here on. The rows still count as personal data if they POINT AT the subject —\n // which is the Art. 15 / Art. 20 fork.\n const foreignKeyHolder = Resources_SharedUtils.resolveForeignKeyHolderResourceType(relationship);\n const farSideReferencesSubject = foreignKeyHolder === relationship.resourceType2;\n\n if (!farSideReferencesSubject) {\n return classify(\n SubjectExportEdgeDisposition.EXCLUDED_NOT_SUBJECT_DATA,\n `lifecycleModelMode is '${lifecycleModel}' (not DEPENDENT) and the far side does not hold a `\n + 'foreign key to the subject, so these rows are neither owned by nor about the subject',\n );\n }\n\n switch (purpose) {\n case SubjectExportPurpose.ACCESS_ART_15:\n return classify(\n SubjectExportEdgeDisposition.INCLUDED_REFERENCES_SUBJECT,\n `lifecycleModelMode is '${lifecycleModel}' (not DEPENDENT), but the far side holds a `\n + 'foreign key to the subject, so these rows are personal data CONCERNING the subject '\n + 'and Art. 15 requires disclosing them',\n );\n\n case SubjectExportPurpose.PORTABILITY_ART_20:\n return classify(\n SubjectExportEdgeDisposition.EXCLUDED_NOT_SUBJECT_PROVIDED,\n `lifecycleModelMode is '${lifecycleModel}' (not DEPENDENT): these rows reference the `\n + 'subject but were created by the controller or a third party rather than provided by '\n + 'the subject, so Art. 20 does not cover them (they ARE disclosed under Art. 15)',\n );\n\n default: {\n // Compile-time exhaustiveness: a new SubjectExportPurpose without an arm here is a TYPE\n // error, not a silent runtime discovery on someone's disclosure request.\n const _exhaustivePurposeCheck: never = purpose;\n throw new Error(\n `classifySubjectExportDisposition has no arm for export purpose `\n + `'${String(_exhaustivePurposeCheck)}'`,\n );\n }\n }\n}\n\n/**\n * The three relationship buckets exposed by a compiled resource configuration.\n *\n * Kept structural here so the privacy compiler does not import resource configuration schemas:\n * those schemas already import this module for {@link DataPortabilityProvenance}.\n */\nexport interface SubjectExportRelationshipBuckets {\n readonly parentRelationships: readonly ResourceRelationship[];\n readonly childRelationships: readonly ResourceRelationship[];\n readonly selfRelationships: readonly ResourceRelationship[];\n}\n\n/** One graph edge normalized so the export subject is always `resourceType1`. */\nexport interface SubjectExportRelationshipTraversal {\n /** Original compiled relationship; runtime adapters use it to resolve the real FK field. */\n readonly relationship: ResourceRelationship;\n /** Direction-normalized relationship consumed by the shared legal-scope classifier. */\n readonly normalizedRelationship: ResourceRelationship;\n readonly classification: SubjectExportEdgeClassification;\n}\n\n/**\n * Enumerate every edge touching one export subject, including child-first reference declarations.\n *\n * Resource configurations deliberately preserve parent/child/self buckets. Subject disclosure is\n * different: personal data can point *to* the subject from either authored orientation. This helper\n * joins both directional buckets, includes self edges once, and swaps only the positional topology\n * needed by {@link classifySubjectExportDisposition}. It preserves the original compiled edge for\n * FK resolution and never collapses multiple foreign keys between the same resource pair.\n */\nexport function enumerateSubjectExportRelationshipTraversals(\n subjectResourceType: ResourceType,\n relationships: SubjectExportRelationshipBuckets,\n purpose: SubjectExportPurpose,\n): SubjectExportRelationshipTraversal[] {\n const touchingRelationships = [\n ...relationships.childRelationships,\n ...relationships.parentRelationships,\n ...relationships.selfRelationships,\n ];\n return touchingRelationships\n .map((relationship): SubjectExportRelationshipTraversal => {\n if (relationship.resourceType1 !== subjectResourceType && relationship.resourceType2 !== subjectResourceType) {\n throw new Error(\n `Subject-export relationship traversal for ${String(subjectResourceType)} received unrelated edge `\n + `${String(relationship.resourceType1)} -> ${String(relationship.resourceType2)}.`,\n );\n }\n const normalizedRelationship = relationship.resourceType1 === subjectResourceType\n ? relationship\n : {\n ...relationship,\n resourceType1: relationship.resourceType2,\n resourceType2: relationship.resourceType1,\n cardinality1: relationship.cardinality2,\n cardinality2: relationship.cardinality1,\n };\n return {\n relationship,\n normalizedRelationship,\n classification: classifySubjectExportDisposition(normalizedRelationship, purpose),\n };\n })\n .sort((left, right) => compareCanonicalText(subjectExportRelationshipTraversalKey(left), subjectExportRelationshipTraversalKey(right)));\n}\n\n/** Stable identity retaining distinct foreign keys between otherwise identical resource pairs. */\nexport function subjectExportRelationshipTraversalKey(traversal: SubjectExportRelationshipTraversal): string {\n const relationship = traversal.normalizedRelationship;\n return [\n relationship.resourceType1,\n relationship.resourceType2,\n relationship.cardinality1,\n relationship.cardinality2,\n relationship.nature,\n relationship.foreignKeyField ?? '',\n traversal.classification.disposition,\n ].join('\\0');\n}\n\n/**\n * Whether ONE field's value joins the bundle, for a given purpose.\n *\n * Separate from {@link SubjectExportEdgeDisposition} because the two answer different questions at\n * different granularities: an edge decides whether a RESOURCE's rows are in scope at all, a field\n * scope decides which COLUMNS of an in-scope row survive the Art. 20 narrowing.\n */\nexport enum SubjectExportFieldScope {\n /** The field's value belongs in this bundle. */\n INCLUDED = 'included',\n\n /**\n * Excluded because the value is controller-DERIVED and this is a portability request. Never\n * reached for `ACCESS_ART_15`, which discloses derived data.\n */\n EXCLUDED_DERIVED = 'excluded_derived',\n\n /**\n * ⛔ NO ANSWER — the field carries no provenance declaration and none is inherited from its\n * resource, while the export is a portability request that needs one.\n *\n * The export REFUSES rather than guessing, because both guesses are harmful and neither is the\n * conservative one: excluding an undeclared field UNDER-DELIVERS a legal right the subject is\n * owed, and including it OVER-SHARES data the controller derived. There is no safe default to\n * fall back on, which is exactly the condition that justifies failing loud — the same reasoning\n * that makes `SubjectErasureDisposition.UNCLASSIFIED` refuse an erasure.\n *\n * `ACCESS_ART_15` never produces this: access includes every field regardless of provenance, so\n * an application can serve access requests before annotating anything.\n */\n UNDECLARED = 'undeclared',\n}\n\n/** Whether a field scope must ABORT the export rather than merely omitting a value. */\nexport function isBlockingSubjectExportFieldScope(scope: SubjectExportFieldScope): boolean {\n return scope === SubjectExportFieldScope.UNDECLARED;\n}\n\n/**\n * Decide whether one field's value belongs in the bundle.\n *\n * `provenance` is the field's EFFECTIVE provenance — its own `.portabilityProvenance()` declaration\n * if it carries one, otherwise the resource's `portabilityPolicy.defaultProvenance`, otherwise\n * `undefined`. Resolving that fallback chain is the factory's job (Phase 0B); this function only\n * judges the resolved value, which keeps it pure and independently testable.\n */\nexport function resolveSubjectExportFieldScope(\n provenance: DataPortabilityProvenance | undefined,\n purpose: SubjectExportPurpose,\n): SubjectExportFieldScope {\n switch (purpose) {\n // Access discloses everything concerning the subject, so provenance is simply not a question it\n // asks — an unannotated application can still answer an Art. 15 request in full.\n case SubjectExportPurpose.ACCESS_ART_15:\n return SubjectExportFieldScope.INCLUDED;\n\n case SubjectExportPurpose.PORTABILITY_ART_20:\n return resolvePortabilityFieldScope(provenance);\n\n default: {\n // Compile-time exhaustiveness on the PURPOSE axis too. Without this arm a third right added\n // to the enum would silently inherit the portability narrowing — a disclosure boundary\n // decided by fall-through rather than by anyone.\n const _exhaustivePurposeCheck: never = purpose;\n throw new Error(\n `resolveSubjectExportFieldScope has no arm for export purpose `\n + `'${String(_exhaustivePurposeCheck)}'`,\n );\n }\n }\n}\n\n/**\n * The Art. 20 narrowing, split out so {@link resolveSubjectExportFieldScope} can switch\n * exhaustively on `purpose` while this switches exhaustively on `provenance`. Module-private: the\n * purpose gate is not optional, and a caller reaching this directly would bypass it.\n */\nfunction resolvePortabilityFieldScope(\n provenance: DataPortabilityProvenance | undefined,\n): SubjectExportFieldScope {\n if (provenance === undefined) {\n return SubjectExportFieldScope.UNDECLARED;\n }\n\n switch (provenance) {\n // Both are \"provided by the data subject\" in the Art. 20 sense — OBSERVED is data generated by\n // the subject's USE of the service, which the guidance places in scope even though the subject\n // never typed it.\n case DataPortabilityProvenance.SUBJECT_PROVIDED:\n case DataPortabilityProvenance.OBSERVED:\n return SubjectExportFieldScope.INCLUDED;\n\n case DataPortabilityProvenance.DERIVED:\n return SubjectExportFieldScope.EXCLUDED_DERIVED;\n\n default: {\n // Compile-time exhaustiveness: a new provenance member without an arm is a TYPE error here.\n const _exhaustiveProvenanceCheck: never = provenance;\n throw new Error(\n `resolvePortabilityFieldScope has no arm for provenance `\n + `'${String(_exhaustiveProvenanceCheck)}'`,\n );\n }\n }\n}\n\n/**\n * Is this field withheld from EVERY subject export, whatever right is being answered?\n *\n * ## Why this exists at all — the layering trap it closes\n *\n * The export orchestrator collects rows at the REPOSITORY layer, which sits BELOW the service-layer\n * DTO projection that normally strips `.isBackendOnly()` fields on their way to a client. Without an\n * explicit check here, a subject export would disclose exactly the values that projection exists to\n * hide — `passwordHash` and `backupCodesHashed` on `USER_CREDENTIALS` are the motivating case, and\n * the config change that exposed them would have looked entirely routine.\n *\n * ## Why it is deliberately CONSERVATIVE\n *\n * This withholds every backend-only field, not only the secrets. Some backend-only fields are\n * genuinely disclosable under Art. 15 (`passwordChangedAt`, `firstMfaPromptAt` — facts about the\n * subject they may ask for), so this errs toward withholding.\n *\n * That asymmetry is intentional. Under-disclosing produces a complaint that is answerable and\n * fixable; disclosing an authentication secret is neither, and it degrades the security of\n * processing the framework is separately obliged to maintain (GDPR Art. 32). Between an\n * over-cautious bundle and a leaked credential, only one is recoverable.\n *\n * The withheld fields are REPORTED (`SubjectExportReport.fieldsWithheldAsNonDisclosable`) so the\n * caution is visible rather than silent. When a resource needs a specific backend-only field\n * disclosed, the expressible extension is a per-field opt-in on this predicate — NOT loosening it\n * wholesale.\n *\n * assurance-control: WILDO.PRIVACY.SUBJECT_DATA_EXPORT\n */\nexport function isFieldWithheldFromSubjectExport(fieldSchema: z.ZodTypeAny): boolean {\n // `isWriteOnlySecret` is checked explicitly rather than assumed to imply backend-only: they are\n // separate decorators, and a future authoring form that sets one without the other must not\n // silently open a disclosure path.\n return isBackendOnlyField(fieldSchema) || isWriteOnlySecretField(fieldSchema);\n}\n\n/** Every legal {@link DataPortabilityProvenance} value, for validating an opaque decorator string. */\nconst KNOWN_PORTABILITY_PROVENANCES: ReadonlySet<string> = new Set(\n Object.values(DataPortabilityProvenance),\n);\n\n/**\n * Resolve ONE field's EFFECTIVE provenance by joining the two declaration levels.\n *\n * ## The fallback chain, and why it has exactly two rungs\n *\n * 1. the field's own `.portabilityProvenance()` declaration, if it carries one;\n * 2. otherwise the resource's `portabilityPolicy.defaultProvenance`;\n * 3. otherwise `undefined` — which {@link resolveSubjectExportFieldScope} turns into a REFUSAL for\n * an Art. 20 export and ignores entirely for Art. 15.\n *\n * Two rungs is what makes the fail-loud rule adoptable: without the resource default, every field of\n * every resource would need a decorator before a single portability request could be answered, and a\n * capability that expensive to adopt does not get adopted. With it, annotating a resource is one\n * line and only the exceptions carry a decorator.\n *\n * ## Why the enum check lives HERE\n *\n * `zod-decorators` sits below this package and cannot import {@link DataPortabilityProvenance}, so\n * it stores whatever non-empty string it was given — it can reject a BLANK but not a WRONG value.\n * This is the first layer that knows the vocabulary, so it is where a typo'd `'subject-provided'`\n * (hyphen, not underscore) must fail rather than silently resolving to `undefined` and turning a\n * declared field into a refusal — or worse, into a silent omission if the caller treats unknown as\n * derived. Mirrors how `RedactionType` validity is checked in this layer for `.impersonalizeWith()`.\n *\n * @param fieldSchema the field's Zod schema; the reader walks wrapper types, so a declaration made\n * before or after `.optional()` / `.nullish()` / `.default()` is observed either way.\n * @param resourceDefaultProvenance the owning resource's `portabilityPolicy.defaultProvenance`.\n * Taken as a bare value rather than the policy object so this module stays free of the\n * resource-config import (which imports THIS module for the enum).\n * @param fieldLocator `resourceType.fieldName`, used only to make a rejection actionable.\n */\nexport function resolveEffectiveFieldPortabilityProvenance(\n fieldSchema: z.ZodTypeAny,\n resourceDefaultProvenance: DataPortabilityProvenance | undefined,\n fieldLocator: string,\n): DataPortabilityProvenance | undefined {\n const declared = getPortabilityProvenance(fieldSchema);\n\n if (declared === undefined) {\n return resourceDefaultProvenance;\n }\n\n if (!KNOWN_PORTABILITY_PROVENANCES.has(declared)) {\n throw new Error(\n `[${fieldLocator}] portabilityProvenance('${declared}') is not a DataPortabilityProvenance `\n + `value. Expected one of: ${[...KNOWN_PORTABILITY_PROVENANCES].join(', ')}. An unrecognised `\n + `value would resolve as UNDECLARED and make an Art. 20 export refuse, hiding the typo `\n + `behind what looks like a deliberate omission.`,\n );\n }\n\n return declared as DataPortabilityProvenance;\n}\n\n/** Why a compiled leaf-field decision has its effective export meaning. */\nexport enum SubjectExportFieldDecisionBasis {\n FIELD_DECLARATION = 'field_declaration',\n RESOURCE_DEFAULT = 'resource_default',\n WITHHELD_NON_DISCLOSABLE = 'withheld_non_disclosable',\n UNDECLARED = 'undeclared',\n DEPTH_LIMIT = 'depth_limit',\n}\n\n/** Canonical, runtime-effective decision for one leaf path in one export purpose. */\nexport interface SubjectExportFieldDecision {\n readonly locator: string;\n readonly purpose: SubjectExportPurpose;\n readonly scope: SubjectExportFieldScope | null;\n readonly provenance: DataPortabilityProvenance | null;\n readonly basis: SubjectExportFieldDecisionBasis;\n}\n\nconst SUBJECT_EXPORT_FIELD_MAX_DEPTH = 10;\n\n/**\n * Resolve an object shape through the same bounded wrapper protocol used by subject export.\n * Returning `undefined` means the value is a leaf. Reaching the bound is handled fail-closed by\n * {@link compileSubjectExportFieldDecisions}, never as an implicit leaf inclusion.\n */\nexport function resolveSubjectExportObjectShapeThroughWrappers(schema: unknown): Record<string, unknown> | undefined {\n let current: any = schema;\n for (let unwrapDepth = 0; current && unwrapDepth < SUBJECT_EXPORT_FIELD_MAX_DEPTH; unwrapDepth += 1) {\n if (current.shape && typeof current.shape === 'object') return current.shape as Record<string, unknown>;\n const inner = current.def?.innerType ?? current._def?.innerType;\n if (!inner) return undefined;\n current = inner;\n }\n return undefined;\n}\n\n/**\n * Compile every runtime-effective leaf-field decision for one resource and right.\n *\n * Both the backend executor and application authority proof consume this function. A field-level\n * decorator, inherited default, withheld marker, wrapper layout or depth refusal therefore changes\n * one shared decision inventory instead of two independently maintained interpretations.\n */\nexport function compileSubjectExportFieldDecisions(input: {\n readonly resourceType: ResourceType;\n readonly mainSchema: unknown;\n readonly defaultProvenance: DataPortabilityProvenance | undefined;\n readonly purpose: SubjectExportPurpose;\n}): SubjectExportFieldDecision[] {\n const rootShape = resolveSubjectExportObjectShapeThroughWrappers(input.mainSchema);\n if (!rootShape) return [];\n const decisions: SubjectExportFieldDecision[] = [];\n\n const visit = (shape: Record<string, unknown>, locatorPrefix: string, depth: number): void => {\n for (const [fieldName, fieldSchema] of Object.entries(shape)) {\n const locator = `${locatorPrefix}.${fieldName}`;\n if (depth >= SUBJECT_EXPORT_FIELD_MAX_DEPTH) {\n decisions.push({\n locator,\n purpose: input.purpose,\n scope: SubjectExportFieldScope.UNDECLARED,\n provenance: null,\n basis: SubjectExportFieldDecisionBasis.DEPTH_LIMIT,\n });\n continue;\n }\n if (isFieldWithheldFromSubjectExport(fieldSchema as z.ZodTypeAny)) {\n decisions.push({\n locator,\n purpose: input.purpose,\n scope: null,\n provenance: null,\n basis: SubjectExportFieldDecisionBasis.WITHHELD_NON_DISCLOSABLE,\n });\n continue;\n }\n const nestedShape = resolveSubjectExportObjectShapeThroughWrappers(fieldSchema);\n if (nestedShape) {\n visit(nestedShape, locator, depth + 1);\n continue;\n }\n const declared = getPortabilityProvenance(fieldSchema as z.ZodTypeAny);\n const provenance = resolveEffectiveFieldPortabilityProvenance(fieldSchema as z.ZodTypeAny, input.defaultProvenance, locator);\n decisions.push({\n locator,\n purpose: input.purpose,\n scope: resolveSubjectExportFieldScope(provenance, input.purpose),\n provenance: provenance ?? null,\n basis: declared !== undefined\n ? SubjectExportFieldDecisionBasis.FIELD_DECLARATION\n : provenance !== undefined\n ? SubjectExportFieldDecisionBasis.RESOURCE_DEFAULT\n : SubjectExportFieldDecisionBasis.UNDECLARED,\n });\n }\n };\n\n visit(rootShape, String(input.resourceType), 0);\n return decisions.sort((left, right) => compareCanonicalText(left.locator, right.locator));\n}\n\n/** Per-edge outcome of an executed export — the classification plus what actually happened. */\nexport interface SubjectExportEdgeOutcome extends SubjectExportEdgeClassification {\n /**\n * `true` when the export actually queried this edge. Note this reports that the read RAN, not\n * that rows existed — an included edge with no rows for this subject is a legitimate empty\n * result, and {@link recordCount} distinguishes the two.\n */\n collected: boolean;\n /** How many rows this edge contributed. `0` on an included edge means the subject had none. */\n recordCount: number;\n}\n\n/**\n * What one subject export produced — the compliance artifact of an Art. 15 or Art. 20 request.\n *\n * Returned to the caller (rather than only logged) so the flow fronting the request can record or\n * surface it: every edge of the subject appears exactly once with the disposition applied and the\n * configuration that justified it. For a disclosure obligation, the record of what was DELIBERATELY\n * LEFT OUT — and on what legal basis — matters as much as the data returned.\n */\nexport interface SubjectExportReport {\n /** Which right this export answered. */\n purpose: SubjectExportPurpose;\n /** The exported subject's resource type. */\n subjectResourceType: ResourceType;\n /** The exported subject rows. */\n subjectIds: string[];\n /** Every child-direction edge of the subject, classified, in registry order. */\n edges: SubjectExportEdgeOutcome[];\n /**\n * Fields omitted from the bundle as controller-DERIVED, as `resourceType.fieldName`. Populated\n * only for `PORTABILITY_ART_20`. Recorded rather than silently dropped so the subject can see\n * that derived data exists and request it under Art. 15 instead.\n */\n fieldsExcludedAsDerived: string[];\n /**\n * Fields withheld as NON-DISCLOSABLE regardless of purpose — see\n * {@link isFieldWithheldFromSubjectExport}. Populated for BOTH rights, because a password hash is\n * no more disclosable under Art. 15 than under Art. 20.\n *\n * Recorded rather than silently dropped for the same reason as the derived list, and one more: a\n * reviewer auditing why an export looks thin needs to see that the framework withheld something\n * deliberately, not that a resource was missed.\n */\n fieldsWithheldAsNonDisclosable: string[];\n /** Total rows across every collected edge, including the subject's own row(s). */\n totalRecordCount: number;\n}\n\n/** One resource's contribution to an export bundle. */\nexport interface SubjectExportResourceSlice {\n resourceType: ResourceType;\n /**\n * The rows, already narrowed to the fields in scope for the export's purpose. For\n * `PORTABILITY_ART_20` the controller-derived columns are gone; for `ACCESS_ART_15` every column\n * the subject is entitled to see is present.\n */\n rows: Record<string, unknown>[];\n}\n\n/**\n * What an export ACTUALLY produced — the data, paired with the report that justifies its shape.\n *\n * ## Why the data and the report are one return value but two types\n *\n * {@link SubjectExportReport} is the compliance artifact: it survives the request, is safe to log\n * and persist, and contains NO personal data — only per-edge dispositions and counts. The slices\n * are the personal data itself, which must NOT be logged and whose lifetime ends when the artifact\n * is written.\n *\n * Returning them together keeps the caller from having to correlate two results, while the type\n * split keeps \"safe to record\" and \"must be handled carefully\" visibly distinct — a caller writing\n * `logger.info({ report })` is correct, and the same line with `bundle` would be a leak. Fusing\n * them into one flat object would erase exactly that distinction.\n */\nexport interface SubjectExportBundle {\n report: SubjectExportReport;\n slices: SubjectExportResourceSlice[];\n}\n"]}
1
+ {"version":3,"file":"subject-export.shared.schemas.js","sourceRoot":"","sources":["../../../../../src/compliance/privacy/subject-export.shared.schemas.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,0BAA0B,EAAE,MAAM,oDAAoD,CAAC;AAChG,OAAO,EACL,0BAA0B,GAE3B,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAG/E,MAAM,oBAAoB,GAAG,CAAC,IAAY,EAAE,KAAa,EAAU,EAAE,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEjH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAN,IAAY,oBAcX;AAdD,WAAY,oBAAoB;IAC9B;;;;OAIG;IACH,uDAA+B,CAAA;IAE/B;;;;OAIG;IACH,iEAAyC,CAAA;AAC3C,CAAC,EAdW,oBAAoB,KAApB,oBAAoB,QAc/B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAN,IAAY,yBAqBX;AArBD,WAAY,yBAAyB;IACnC;;;OAGG;IACH,kEAAqC,CAAA;IAErC;;;;OAIG;IACH,kDAAqB,CAAA;IAErB;;;;;OAKG;IACH,gDAAmB,CAAA;AACrB,CAAC,EArBW,yBAAyB,KAAzB,yBAAyB,QAqBpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,CAAN,IAAY,4BAuDX;AAvDD,WAAY,4BAA4B;IACtC;;;;OAIG;IACH,iEAAiC,CAAA;IAEjC;;;;;;;;;OASG;IACH,2FAA2D,CAAA;IAE3D;;;;OAIG;IACH,uFAAuD,CAAA;IAEvD;;;;;;;OAOG;IACH,+FAA+D,CAAA;IAE/D;;;;;;;;;;;;;;;;OAgBG;IACH,qFAAqD,CAAA;AACvD,CAAC,EAvDW,4BAA4B,KAA5B,4BAA4B,QAuDvC;AAED,4EAA4E;AAC5E,MAAM,UAAU,sCAAsC,CACpD,WAAyC;IAEzC,OAAO,WAAW,KAAK,4BAA4B,CAAC,cAAc;WAC7D,WAAW,KAAK,4BAA4B,CAAC,2BAA2B,CAAC;AAChF,CAAC;AAgBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,gCAAgC,CAC9C,YAAkC,EAClC,OAA6B;IAE7B,MAAM,mBAAmB,GAAG,YAAY,CAAC,aAA6B,CAAC;IACvE,MAAM,QAAQ,GAAG,CACf,WAAyC,EACzC,MAAc,EACmB,EAAE,CAAC,CAAC,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;IAErF,6FAA6F;IAC7F,2CAA2C;IAC3C,IAAI,YAAY,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;QACrC,OAAO,QAAQ,CACb,4BAA4B,CAAC,yBAAyB,EACtD,sFAAsF,CACvF,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,qBAAqB,CAAC,oCAAoC,CAAC,YAAY,CAAC,CAAC;IAC3F,MAAM,cAAc,GAAG,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAE7D,IAAI,cAAc,KAAK,0BAA0B,CAAC,SAAS,EAAE,CAAC;QAC5D,OAAO,QAAQ,CACb,4BAA4B,CAAC,cAAc,EAC3C,2FAA2F;cACvF,mCAAmC,CACxC,CAAC;IACJ,CAAC;IAED,+FAA+F;IAC/F,uCAAuC;IACvC,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,mCAAmC,CAAC,YAAY,CAAC,CAAC;IACjG,MAAM,wBAAwB,GAAG,gBAAgB,KAAK,YAAY,CAAC,aAAa,CAAC;IAEjF,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAC9B,OAAO,QAAQ,CACb,4BAA4B,CAAC,yBAAyB,EACtD,0BAA0B,cAAc,qDAAqD;cACzF,sFAAsF,CAC3F,CAAC;IACJ,CAAC;IAED,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,oBAAoB,CAAC,aAAa;YACrC,OAAO,QAAQ,CACb,4BAA4B,CAAC,2BAA2B,EACxD,0BAA0B,cAAc,8CAA8C;kBAClF,qFAAqF;kBACrF,sCAAsC,CAC3C,CAAC;QAEJ,KAAK,oBAAoB,CAAC,kBAAkB;YAC1C,OAAO,QAAQ,CACb,4BAA4B,CAAC,6BAA6B,EAC1D,0BAA0B,cAAc,8CAA8C;kBAClF,sFAAsF;kBACtF,gFAAgF,CACrF,CAAC;QAEJ,OAAO,CAAC,CAAC,CAAC;YACR,wFAAwF;YACxF,yEAAyE;YACzE,MAAM,uBAAuB,GAAU,OAAO,CAAC;YAC/C,MAAM,IAAI,KAAK,CACb,iEAAiE;kBAC7D,IAAI,MAAM,CAAC,uBAAuB,CAAC,GAAG,CAC3C,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAuBD;;;;;;;;GAQG;AACH,MAAM,UAAU,4CAA4C,CAC1D,mBAAiC,EACjC,aAA+C,EAC/C,OAA6B;IAE7B,MAAM,qBAAqB,GAAG;QAC5B,GAAG,aAAa,CAAC,kBAAkB;QACnC,GAAG,aAAa,CAAC,mBAAmB;QACpC,GAAG,aAAa,CAAC,iBAAiB;KACnC,CAAC;IACF,OAAO,qBAAqB;SACzB,GAAG,CAAC,CAAC,YAAY,EAAsC,EAAE;QACxD,IAAI,YAAY,CAAC,aAAa,KAAK,mBAAmB,IAAI,YAAY,CAAC,aAAa,KAAK,mBAAmB,EAAE,CAAC;YAC7G,MAAM,IAAI,KAAK,CACb,6CAA6C,MAAM,CAAC,mBAAmB,CAAC,2BAA2B;kBAC/F,GAAG,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,OAAO,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,GAAG,CACtF,CAAC;QACJ,CAAC;QACD,MAAM,sBAAsB,GAAG,YAAY,CAAC,aAAa,KAAK,mBAAmB;YAC/E,CAAC,CAAC,YAAY;YACd,CAAC,CAAC;gBACE,GAAG,YAAY;gBACf,aAAa,EAAE,YAAY,CAAC,aAAa;gBACzC,aAAa,EAAE,YAAY,CAAC,aAAa;gBACzC,YAAY,EAAE,YAAY,CAAC,YAAY;gBACvC,YAAY,EAAE,YAAY,CAAC,YAAY;aACxC,CAAC;QACN,OAAO;YACL,YAAY;YACZ,sBAAsB;YACtB,cAAc,EAAE,gCAAgC,CAAC,sBAAsB,EAAE,OAAO,CAAC;SAClF,CAAC;IACJ,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,oBAAoB,CAAC,qCAAqC,CAAC,IAAI,CAAC,EAAE,qCAAqC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC5I,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,qCAAqC,CAAC,SAA6C;IACjG,MAAM,YAAY,GAAG,SAAS,CAAC,sBAAsB,CAAC;IACtD,OAAO;QACL,YAAY,CAAC,aAAa;QAC1B,YAAY,CAAC,aAAa;QAC1B,YAAY,CAAC,YAAY;QACzB,YAAY,CAAC,YAAY;QACzB,YAAY,CAAC,MAAM;QACnB,YAAY,CAAC,eAAe,IAAI,EAAE;QAClC,SAAS,CAAC,cAAc,CAAC,WAAW;KACrC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAN,IAAY,uBAwBX;AAxBD,WAAY,uBAAuB;IACjC,gDAAgD;IAChD,gDAAqB,CAAA;IAErB;;;OAGG;IACH,gEAAqC,CAAA;IAErC;;;;;;;;;;;;OAYG;IACH,oDAAyB,CAAA;AAC3B,CAAC,EAxBW,uBAAuB,KAAvB,uBAAuB,QAwBlC;AAED,uFAAuF;AACvF,MAAM,UAAU,iCAAiC,CAAC,KAA8B;IAC9E,OAAO,KAAK,KAAK,uBAAuB,CAAC,UAAU,CAAC;AACtD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,8BAA8B,CAC5C,UAAiD,EACjD,OAA6B;IAE7B,QAAQ,OAAO,EAAE,CAAC;QAChB,gGAAgG;QAChG,iFAAiF;QACjF,KAAK,oBAAoB,CAAC,aAAa;YACrC,OAAO,uBAAuB,CAAC,QAAQ,CAAC;QAE1C,KAAK,oBAAoB,CAAC,kBAAkB;YAC1C,OAAO,4BAA4B,CAAC,UAAU,CAAC,CAAC;QAElD,OAAO,CAAC,CAAC,CAAC;YACR,4FAA4F;YAC5F,uFAAuF;YACvF,iDAAiD;YACjD,MAAM,uBAAuB,GAAU,OAAO,CAAC;YAC/C,MAAM,IAAI,KAAK,CACb,+DAA+D;kBAC3D,IAAI,MAAM,CAAC,uBAAuB,CAAC,GAAG,CAC3C,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,4BAA4B,CACnC,UAAiD;IAEjD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,uBAAuB,CAAC,UAAU,CAAC;IAC5C,CAAC;IAED,QAAQ,UAAU,EAAE,CAAC;QACnB,+FAA+F;QAC/F,+FAA+F;QAC/F,kBAAkB;QAClB,KAAK,yBAAyB,CAAC,gBAAgB,CAAC;QAChD,KAAK,yBAAyB,CAAC,QAAQ;YACrC,OAAO,uBAAuB,CAAC,QAAQ,CAAC;QAE1C,KAAK,yBAAyB,CAAC,OAAO;YACpC,OAAO,uBAAuB,CAAC,gBAAgB,CAAC;QAElD,OAAO,CAAC,CAAC,CAAC;YACR,4FAA4F;YAC5F,MAAM,0BAA0B,GAAU,UAAU,CAAC;YACrD,MAAM,IAAI,KAAK,CACb,yDAAyD;kBACrD,IAAI,MAAM,CAAC,0BAA0B,CAAC,GAAG,CAC9C,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,gCAAgC,CAAC,WAAyB;IACxE,iGAAiG;IACjG,4FAA4F;IAC5F,6FAA6F;IAC7F,6FAA6F;IAC7F,EAAE;IACF,kGAAkG;IAClG,mGAAmG;IACnG,yFAAyF;IACzF,8DAA8D;IAC9D,OAAO,0BAA0B,CAAC,WAAW,CAAC,CAAC;AACjD,CAAC;AAED,sGAAsG;AACtG,MAAM,6BAA6B,GAAwB,IAAI,GAAG,CAChE,MAAM,CAAC,MAAM,CAAC,yBAAyB,CAAC,CACzC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,0CAA0C,CACxD,WAAyB,EACzB,yBAAgE,EAChE,YAAoB;IAEpB,MAAM,QAAQ,GAAG,wBAAwB,CAAC,WAAW,CAAC,CAAC;IAEvD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,yBAAyB,CAAC;IACnC,CAAC;IAED,IAAI,CAAC,6BAA6B,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CACb,IAAI,YAAY,4BAA4B,QAAQ,wCAAwC;cACxF,2BAA2B,CAAC,GAAG,6BAA6B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB;cAC5F,uFAAuF;cACvF,+CAA+C,CACpD,CAAC;IACJ,CAAC;IAED,OAAO,QAAqC,CAAC;AAC/C,CAAC;AAED,2EAA2E;AAC3E,MAAM,CAAN,IAAY,+BAMX;AAND,WAAY,+BAA+B;IACzC,0EAAuC,CAAA;IACvC,wEAAqC,CAAA;IACrC,wFAAqD,CAAA;IACrD,4DAAyB,CAAA;IACzB,8DAA2B,CAAA;AAC7B,CAAC,EANW,+BAA+B,KAA/B,+BAA+B,QAM1C;AAWD,MAAM,8BAA8B,GAAG,EAAE,CAAC;AAE1C;;;;GAIG;AACH,MAAM,UAAU,8CAA8C,CAAC,MAAe;IAC5E,IAAI,OAAO,GAAQ,MAAM,CAAC;IAC1B,KAAK,IAAI,WAAW,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,GAAG,8BAA8B,EAAE,WAAW,IAAI,CAAC,EAAE,CAAC;QACpG,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ;YAAE,OAAO,OAAO,CAAC,KAAgC,CAAC;QACxG,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,SAAS,IAAI,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;QAChE,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,OAAO,GAAG,KAAK,CAAC;IAClB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kCAAkC,CAAC,KAKlD;IACC,MAAM,SAAS,GAAG,8CAA8C,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACnF,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,CAAC;IAC1B,MAAM,SAAS,GAAiC,EAAE,CAAC;IAEnD,MAAM,KAAK,GAAG,CAAC,KAA8B,EAAE,aAAqB,EAAE,KAAa,EAAQ,EAAE;QAC3F,KAAK,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7D,MAAM,OAAO,GAAG,GAAG,aAAa,IAAI,SAAS,EAAE,CAAC;YAChD,IAAI,KAAK,IAAI,8BAA8B,EAAE,CAAC;gBAC5C,SAAS,CAAC,IAAI,CAAC;oBACb,OAAO;oBACP,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,KAAK,EAAE,uBAAuB,CAAC,UAAU;oBACzC,UAAU,EAAE,IAAI;oBAChB,KAAK,EAAE,+BAA+B,CAAC,WAAW;iBACnD,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YACD,IAAI,gCAAgC,CAAC,WAA2B,CAAC,EAAE,CAAC;gBAClE,SAAS,CAAC,IAAI,CAAC;oBACb,OAAO;oBACP,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,KAAK,EAAE,IAAI;oBACX,UAAU,EAAE,IAAI;oBAChB,KAAK,EAAE,+BAA+B,CAAC,wBAAwB;iBAChE,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YACD,MAAM,WAAW,GAAG,8CAA8C,CAAC,WAAW,CAAC,CAAC;YAChF,IAAI,WAAW,EAAE,CAAC;gBAChB,KAAK,CAAC,WAAW,EAAE,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBACvC,SAAS;YACX,CAAC;YACD,MAAM,QAAQ,GAAG,wBAAwB,CAAC,WAA2B,CAAC,CAAC;YACvE,MAAM,UAAU,GAAG,0CAA0C,CAAC,WAA2B,EAAE,KAAK,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;YAC7H,SAAS,CAAC,IAAI,CAAC;gBACb,OAAO;gBACP,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,KAAK,EAAE,8BAA8B,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC;gBAChE,UAAU,EAAE,UAAU,IAAI,IAAI;gBAC9B,KAAK,EAAE,QAAQ,KAAK,SAAS;oBAC3B,CAAC,CAAC,+BAA+B,CAAC,iBAAiB;oBACnD,CAAC,CAAC,UAAU,KAAK,SAAS;wBACxB,CAAC,CAAC,+BAA+B,CAAC,gBAAgB;wBAClD,CAAC,CAAC,+BAA+B,CAAC,UAAU;aACjD,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;IAEF,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC;IAChD,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC5F,CAAC","sourcesContent":["import type { z } from 'zod';\nimport { getPortabilityProvenance } from '@wildo-ai/zod-decorators';\nimport { isNonDisclosableFieldValue } from '../../resources/utils/field-value-disclosure.utils';\nimport {\n RelationshipLifecycleModel,\n type ResourceRelationship,\n} from '../../resources/resources.shared.schemas';\nimport { Resources_SharedUtils } from '../../resources/resources.shared.utils';\nimport type { ResourceType } from '../../resources/resources.shared.core.definitions';\n\nconst compareCanonicalText = (left: string, right: string): number => (left < right ? -1 : left > right ? 1 : 0);\n\n/**\n * WHICH data-subject right an export is answering.\n *\n * ## Why this is an enum and not a boolean flag on one bundle\n *\n * GDPR Art. 15 (right of access) and Art. 20 (right to data portability) are DIFFERENT rights over\n * DIFFERENT data, and conflating them is the defect this capability was built to correct: the four\n * routed export operations removed on 2026-08-01 declared themselves \"portability / GDPR\" while\n * their actual options (`includeActivityData`, `includeOrganizationData`) described an *access*\n * bundle. One output with a flag would reproduce that merge.\n *\n * - **Access** is a disclosure obligation: everything the controller holds *concerning* the subject,\n * including data the controller itself derived about them, in any readable form.\n * - **Portability** is a transfer obligation: only the data the subject *provided* — actively, or by\n * using the service — and it must be machine-readable and re-importable elsewhere. Data the\n * controller inferred is deliberately OUT of scope; a competitor must not receive a rival's\n * analytics through a subject's portability request.\n *\n * The two therefore diverge at BOTH levels this module classifies: per-edge (see\n * {@link classifySubjectExportDisposition}) and per-field (see\n * {@link resolveSubjectExportFieldScope}).\n *\n * assurance-control: WILDO.PRIVACY.SUBJECT_DATA_EXPORT\n */\nexport enum SubjectExportPurpose {\n /**\n * Art. 15 — right of access. The broadest bundle: every row concerning the subject, whoever\n * produced it, including rows the subject does not own (an audit log about them, a membership an\n * administrator created).\n */\n ACCESS_ART_15 = 'access_art_15',\n\n /**\n * Art. 20 — right to data portability. Narrower on purpose: only data the subject supplied or\n * generated by using the service, and only from rows the subject owns. Controller-derived data is\n * excluded by {@link DataPortabilityProvenance.DERIVED}.\n */\n PORTABILITY_ART_20 = 'portability_art_20',\n}\n\n/**\n * WHERE one field's value came from — the axis that decides Art. 20 scope.\n *\n * ## Why three values and not `isSubjectProvided: boolean`\n *\n * EDPB/WP29 guidance splits \"provided by the data subject\" into data supplied *knowingly* and data\n * *observed* from the subject's use of the service, and puts BOTH in Art. 20 scope while excluding\n * data the controller *inferred*. A boolean forces `OBSERVED` to be mis-filed against whichever\n * side the author guesses — and it is the member most often got wrong, because \"the user did not\n * type it\" reads as \"the user did not provide it\", which is precisely the wrong conclusion.\n *\n * ## Why this is per-FIELD and not per-resource\n *\n * A single row routinely mixes the two: a user profile holds `firstName` (supplied) beside a\n * controller-computed status or score. A resource-level answer would have to round one way for the\n * whole row. The resource-level declaration exists only as a DEFAULT\n * (`portabilityPolicy.defaultProvenance`) so that annotating a resource stays a one-line cost; the\n * per-field decorator overrides it where a field differs.\n *\n * ⚠️ NOT a redaction or scrub concept. This says where a value CAME FROM, for a disclosure\n * decision. What happens to a value on ERASURE is `.impersonalizeWith()` / `RedactionType`, a\n * different axis entirely — a field can be `SUBJECT_PROVIDED` and also masked on erasure.\n */\nexport enum DataPortabilityProvenance {\n /**\n * The subject actively and knowingly supplied this value — form input, an uploaded file, a\n * setting they chose. Unambiguously in scope for both rights.\n */\n SUBJECT_PROVIDED = 'subject_provided',\n\n /**\n * Generated by the subject's USE of the service rather than typed by them — activity timestamps,\n * event history, usage counters, telemetry. **In scope for Art. 20**, which is the whole reason\n * this member exists separately from {@link DERIVED}.\n */\n OBSERVED = 'observed',\n\n /**\n * Produced BY the controller about the subject — inferred classifications, computed scores,\n * risk or segmentation labels, server-assigned lifecycle state. Disclosed under Art. 15 (the\n * subject may see what we concluded about them) but **excluded from Art. 20** (a portability\n * request is not a channel for exporting the controller's own analysis).\n */\n DERIVED = 'derived',\n}\n\n/**\n * What an export does with ONE child-direction edge of the subject.\n *\n * ## Why this is NOT `SubjectErasureDisposition`\n *\n * Erasure and export share a traversal and answer opposite questions — *what do I destroy?* versus\n * *what must I disclose?* — and they diverge on exactly the edges erasure calls `NOT_OWNED`.\n *\n * Erasure leaves audit logs, memberships and job executions alone, correctly: you do not delete an\n * audit log because a user exercised a right. But those same rows hold personal data CONCERNING the\n * subject, and Art. 15 covers \"all personal data concerning him or her\" — not \"rows he owns\".\n * Reusing erasure's vocabulary verbatim would have silently omitted the data an access request most\n * often targets. Hence {@link INCLUDED_REFERENCES_SUBJECT}, a case erasure has no use for.\n *\n * The two classifiers still read the SAME upstream authority for what an edge *says*\n * (`requireResolvedRelationshipSemantics`), so they can never disagree about ownership — only about\n * what to do with it.\n *\n * ## Why there is no blocking disposition here\n *\n * Erasure refuses up-front on `UNCLASSIFIED` / `UNSUPPORTED_DEFERRED` because it is about to\n * WRITE, cannot half-destroy a subject, and needs a teardown declaration nobody made. An export\n * writes nothing: ownership alone answers the edge question, a deferred teardown is irrelevant to a\n * read, and a cross-adapter dependent is merely a second query rather than a broken transaction.\n * The one genuine refusal in an export is field-level and Art. 20-only — see\n * {@link SubjectExportFieldScope.UNDECLARED}. Manufacturing an edge-level blocker for symmetry\n * would be false symmetry.\n */\nexport enum SubjectExportEdgeDisposition {\n /**\n * The subject OWNS this dependent (`lifecycleModelMode: DEPENDENT`), so its rows are the\n * subject's own data. Included for both purposes — for Art. 20 the per-field provenance filter\n * still applies to what comes back.\n */\n INCLUDED_OWNED = 'included_owned',\n\n /**\n * The subject does NOT own these rows, but they REFERENCE the subject — the far side carries a\n * foreign key back to them (an audit log, an organization membership, a job execution).\n *\n * **Art. 15 only.** These are personal data concerning the subject, so an access request must\n * disclose them. A portability request must not: the subject did not provide a row that a third\n * party or the controller created about them, and shipping them would export the controller's\n * operational records under a transfer right. For `PORTABILITY_ART_20` this same edge classifies\n * as {@link EXCLUDED_NOT_SUBJECT_PROVIDED}.\n */\n INCLUDED_REFERENCES_SUBJECT = 'included_references_subject',\n\n /**\n * The edge carries no personal data of the subject at all: an independent or link-only\n * relationship whose far side does not even reference them, or a disabled relationship that is\n * not part of the live graph. Out of scope for both rights.\n */\n EXCLUDED_NOT_SUBJECT_DATA = 'excluded_not_subject_data',\n\n /**\n * In scope for access, but excluded from THIS export because the export is a portability request\n * and the rows were not provided by the subject. Kept as its own member rather than collapsing\n * into {@link EXCLUDED_NOT_SUBJECT_DATA}: a reviewer asking \"why is my audit trail missing from\n * my portability export?\" needs \"because Art. 20 does not cover controller records\" and \"because\n * that edge holds nothing about you\" to be different answers, and only the first is a legal\n * position someone took.\n */\n EXCLUDED_NOT_SUBJECT_PROVIDED = 'excluded_not_subject_provided',\n\n /**\n * The rows ARE the subject's data and the right covers them, but the resource is declared\n * `systemAccessPolicy.exportSubject = FORBIDDEN` — someone decided it must never reach a data\n * subject (an authentication-credential store, a security audit trail).\n *\n * ## Why this excludes rather than refusing\n *\n * An UNDECLARED resource refuses the whole export, because nobody has decided yet and refusing is\n * what forces the decision. A FORBIDDEN one is the opposite: the decision exists, and refusing\n * would make it permanent sabotage — a `USERS` access export whose graph touches a credential\n * store could then NEVER run, no matter how many other resources opted in. Honouring the\n * declaration means leaving those rows out and saying so.\n *\n * ⚠️ This applies to EDGES only. A subject whose OWN resource is FORBIDDEN still refuses: there is\n * no export of a person whose identity row may not be disclosed, and silently returning an\n * edges-only bundle would be a disclosure that omits its own subject.\n */\n EXCLUDED_NOT_DISCLOSABLE = 'excluded_not_disclosable',\n}\n\n/** Whether an edge disposition puts the far side's rows INTO the bundle. */\nexport function isIncludedSubjectExportEdgeDisposition(\n disposition: SubjectExportEdgeDisposition,\n): boolean {\n return disposition === SubjectExportEdgeDisposition.INCLUDED_OWNED\n || disposition === SubjectExportEdgeDisposition.INCLUDED_REFERENCES_SUBJECT;\n}\n\n/** The classification of ONE child-direction edge of an export subject. */\nexport interface SubjectExportEdgeClassification {\n /** The related resource on the far side of the edge. */\n relatedResourceType: ResourceType;\n /** Whether, and why, this edge's rows join the bundle. */\n disposition: SubjectExportEdgeDisposition;\n /**\n * Human-readable justification quoting the configuration that produced it. Surfaced in the export\n * report so a data-protection reviewer never has to re-derive WHY a resource was included or\n * left out — which, for a disclosure obligation, is the evidence that matters.\n */\n reason: string;\n}\n\n/**\n * Classify what an export must do with ONE child-direction edge — the disclose-vs-omit decision,\n * DERIVED FROM CONFIGURATION rather than a hardcoded list of resource types.\n *\n * ## Where the answer comes from\n *\n * Two declarations the author already makes, read through the same shared authorities the delete\n * cascade and the erasure orchestrator read, so the three can never disagree about what an edge is:\n *\n * 1. **`handling.lifecycleModelMode`** — does the subject own this related resource's lifecycle?\n * `DEPENDENT` means the rows are the subject's own data.\n * 2. **Foreign-key topology** (`resolveForeignKeyHolderResourceType`, cardinality-only and\n * therefore pure) — for a NON-owned edge, does the far side nonetheless carry a reference back\n * to the subject? If it does, its rows are *about* the subject and Art. 15 must disclose them.\n *\n * ## The `purpose` parameter, and why it is a parameter\n *\n * Art. 15 and Art. 20 diverge on exactly one edge case — the referencing-but-not-owned edge — and\n * keeping that divergence in ONE switch here is what stops two near-identical classifiers from\n * drifting apart. Exposing `classifyForAccess` / `classifyForPortability` would duplicate the\n * ownership logic, and the day someone fixes a bug in one they would miss the other.\n *\n * ## Caller contract\n *\n * `relationship.resourceType2` MUST be the far side and `resourceType1` the subject — the same\n * child-direction normalization {@link classifySubjectErasureDisposition} requires. The caller\n * filters to child-direction edges before classifying.\n *\n * Pure and side-effect free — no registry lookups, no I/O, no row reads — so it is equally usable\n * from a runtime orchestrator and from a boot-time coherence guard.\n */\nexport function classifySubjectExportDisposition(\n relationship: ResourceRelationship,\n purpose: SubjectExportPurpose,\n): SubjectExportEdgeClassification {\n const relatedResourceType = relationship.resourceType2 as ResourceType;\n const classify = (\n disposition: SubjectExportEdgeDisposition,\n reason: string,\n ): SubjectExportEdgeClassification => ({ relatedResourceType, disposition, reason });\n\n // A disabled relationship is not part of the live graph — the runtime never traverses it, so\n // there are no rows behind it to disclose.\n if (relationship.isDisabled === true) {\n return classify(\n SubjectExportEdgeDisposition.EXCLUDED_NOT_SUBJECT_DATA,\n 'the relationship is disabled (isDisabled: true), so it is not part of the live graph',\n );\n }\n\n const semantics = Resources_SharedUtils.requireResolvedRelationshipSemantics(relationship);\n const lifecycleModel = semantics.handling.lifecycleModelMode;\n\n if (lifecycleModel === RelationshipLifecycleModel.DEPENDENT) {\n return classify(\n SubjectExportEdgeDisposition.INCLUDED_OWNED,\n 'lifecycleModelMode is DEPENDENT: the subject owns these rows, so they are the subject\\'s '\n + 'own data and belong in the bundle',\n );\n }\n\n // NOT owned from here on. The rows still count as personal data if they POINT AT the subject —\n // which is the Art. 15 / Art. 20 fork.\n const foreignKeyHolder = Resources_SharedUtils.resolveForeignKeyHolderResourceType(relationship);\n const farSideReferencesSubject = foreignKeyHolder === relationship.resourceType2;\n\n if (!farSideReferencesSubject) {\n return classify(\n SubjectExportEdgeDisposition.EXCLUDED_NOT_SUBJECT_DATA,\n `lifecycleModelMode is '${lifecycleModel}' (not DEPENDENT) and the far side does not hold a `\n + 'foreign key to the subject, so these rows are neither owned by nor about the subject',\n );\n }\n\n switch (purpose) {\n case SubjectExportPurpose.ACCESS_ART_15:\n return classify(\n SubjectExportEdgeDisposition.INCLUDED_REFERENCES_SUBJECT,\n `lifecycleModelMode is '${lifecycleModel}' (not DEPENDENT), but the far side holds a `\n + 'foreign key to the subject, so these rows are personal data CONCERNING the subject '\n + 'and Art. 15 requires disclosing them',\n );\n\n case SubjectExportPurpose.PORTABILITY_ART_20:\n return classify(\n SubjectExportEdgeDisposition.EXCLUDED_NOT_SUBJECT_PROVIDED,\n `lifecycleModelMode is '${lifecycleModel}' (not DEPENDENT): these rows reference the `\n + 'subject but were created by the controller or a third party rather than provided by '\n + 'the subject, so Art. 20 does not cover them (they ARE disclosed under Art. 15)',\n );\n\n default: {\n // Compile-time exhaustiveness: a new SubjectExportPurpose without an arm here is a TYPE\n // error, not a silent runtime discovery on someone's disclosure request.\n const _exhaustivePurposeCheck: never = purpose;\n throw new Error(\n `classifySubjectExportDisposition has no arm for export purpose `\n + `'${String(_exhaustivePurposeCheck)}'`,\n );\n }\n }\n}\n\n/**\n * The three relationship buckets exposed by a compiled resource configuration.\n *\n * Kept structural here so the privacy compiler does not import resource configuration schemas:\n * those schemas already import this module for {@link DataPortabilityProvenance}.\n */\nexport interface SubjectExportRelationshipBuckets {\n readonly parentRelationships: readonly ResourceRelationship[];\n readonly childRelationships: readonly ResourceRelationship[];\n readonly selfRelationships: readonly ResourceRelationship[];\n}\n\n/** One graph edge normalized so the export subject is always `resourceType1`. */\nexport interface SubjectExportRelationshipTraversal {\n /** Original compiled relationship; runtime adapters use it to resolve the real FK field. */\n readonly relationship: ResourceRelationship;\n /** Direction-normalized relationship consumed by the shared legal-scope classifier. */\n readonly normalizedRelationship: ResourceRelationship;\n readonly classification: SubjectExportEdgeClassification;\n}\n\n/**\n * Enumerate every edge touching one export subject, including child-first reference declarations.\n *\n * Resource configurations deliberately preserve parent/child/self buckets. Subject disclosure is\n * different: personal data can point *to* the subject from either authored orientation. This helper\n * joins both directional buckets, includes self edges once, and swaps only the positional topology\n * needed by {@link classifySubjectExportDisposition}. It preserves the original compiled edge for\n * FK resolution and never collapses multiple foreign keys between the same resource pair.\n */\nexport function enumerateSubjectExportRelationshipTraversals(\n subjectResourceType: ResourceType,\n relationships: SubjectExportRelationshipBuckets,\n purpose: SubjectExportPurpose,\n): SubjectExportRelationshipTraversal[] {\n const touchingRelationships = [\n ...relationships.childRelationships,\n ...relationships.parentRelationships,\n ...relationships.selfRelationships,\n ];\n return touchingRelationships\n .map((relationship): SubjectExportRelationshipTraversal => {\n if (relationship.resourceType1 !== subjectResourceType && relationship.resourceType2 !== subjectResourceType) {\n throw new Error(\n `Subject-export relationship traversal for ${String(subjectResourceType)} received unrelated edge `\n + `${String(relationship.resourceType1)} -> ${String(relationship.resourceType2)}.`,\n );\n }\n const normalizedRelationship = relationship.resourceType1 === subjectResourceType\n ? relationship\n : {\n ...relationship,\n resourceType1: relationship.resourceType2,\n resourceType2: relationship.resourceType1,\n cardinality1: relationship.cardinality2,\n cardinality2: relationship.cardinality1,\n };\n return {\n relationship,\n normalizedRelationship,\n classification: classifySubjectExportDisposition(normalizedRelationship, purpose),\n };\n })\n .sort((left, right) => compareCanonicalText(subjectExportRelationshipTraversalKey(left), subjectExportRelationshipTraversalKey(right)));\n}\n\n/** Stable identity retaining distinct foreign keys between otherwise identical resource pairs. */\nexport function subjectExportRelationshipTraversalKey(traversal: SubjectExportRelationshipTraversal): string {\n const relationship = traversal.normalizedRelationship;\n return [\n relationship.resourceType1,\n relationship.resourceType2,\n relationship.cardinality1,\n relationship.cardinality2,\n relationship.nature,\n relationship.foreignKeyField ?? '',\n traversal.classification.disposition,\n ].join('\\0');\n}\n\n/**\n * Whether ONE field's value joins the bundle, for a given purpose.\n *\n * Separate from {@link SubjectExportEdgeDisposition} because the two answer different questions at\n * different granularities: an edge decides whether a RESOURCE's rows are in scope at all, a field\n * scope decides which COLUMNS of an in-scope row survive the Art. 20 narrowing.\n */\nexport enum SubjectExportFieldScope {\n /** The field's value belongs in this bundle. */\n INCLUDED = 'included',\n\n /**\n * Excluded because the value is controller-DERIVED and this is a portability request. Never\n * reached for `ACCESS_ART_15`, which discloses derived data.\n */\n EXCLUDED_DERIVED = 'excluded_derived',\n\n /**\n * ⛔ NO ANSWER — the field carries no provenance declaration and none is inherited from its\n * resource, while the export is a portability request that needs one.\n *\n * The export REFUSES rather than guessing, because both guesses are harmful and neither is the\n * conservative one: excluding an undeclared field UNDER-DELIVERS a legal right the subject is\n * owed, and including it OVER-SHARES data the controller derived. There is no safe default to\n * fall back on, which is exactly the condition that justifies failing loud — the same reasoning\n * that makes `SubjectErasureDisposition.UNCLASSIFIED` refuse an erasure.\n *\n * `ACCESS_ART_15` never produces this: access includes every field regardless of provenance, so\n * an application can serve access requests before annotating anything.\n */\n UNDECLARED = 'undeclared',\n}\n\n/** Whether a field scope must ABORT the export rather than merely omitting a value. */\nexport function isBlockingSubjectExportFieldScope(scope: SubjectExportFieldScope): boolean {\n return scope === SubjectExportFieldScope.UNDECLARED;\n}\n\n/**\n * Decide whether one field's value belongs in the bundle.\n *\n * `provenance` is the field's EFFECTIVE provenance — its own `.portabilityProvenance()` declaration\n * if it carries one, otherwise the resource's `portabilityPolicy.defaultProvenance`, otherwise\n * `undefined`. Resolving that fallback chain is the factory's job (Phase 0B); this function only\n * judges the resolved value, which keeps it pure and independently testable.\n */\nexport function resolveSubjectExportFieldScope(\n provenance: DataPortabilityProvenance | undefined,\n purpose: SubjectExportPurpose,\n): SubjectExportFieldScope {\n switch (purpose) {\n // Access discloses everything concerning the subject, so provenance is simply not a question it\n // asks — an unannotated application can still answer an Art. 15 request in full.\n case SubjectExportPurpose.ACCESS_ART_15:\n return SubjectExportFieldScope.INCLUDED;\n\n case SubjectExportPurpose.PORTABILITY_ART_20:\n return resolvePortabilityFieldScope(provenance);\n\n default: {\n // Compile-time exhaustiveness on the PURPOSE axis too. Without this arm a third right added\n // to the enum would silently inherit the portability narrowing — a disclosure boundary\n // decided by fall-through rather than by anyone.\n const _exhaustivePurposeCheck: never = purpose;\n throw new Error(\n `resolveSubjectExportFieldScope has no arm for export purpose `\n + `'${String(_exhaustivePurposeCheck)}'`,\n );\n }\n }\n}\n\n/**\n * The Art. 20 narrowing, split out so {@link resolveSubjectExportFieldScope} can switch\n * exhaustively on `purpose` while this switches exhaustively on `provenance`. Module-private: the\n * purpose gate is not optional, and a caller reaching this directly would bypass it.\n */\nfunction resolvePortabilityFieldScope(\n provenance: DataPortabilityProvenance | undefined,\n): SubjectExportFieldScope {\n if (provenance === undefined) {\n return SubjectExportFieldScope.UNDECLARED;\n }\n\n switch (provenance) {\n // Both are \"provided by the data subject\" in the Art. 20 sense — OBSERVED is data generated by\n // the subject's USE of the service, which the guidance places in scope even though the subject\n // never typed it.\n case DataPortabilityProvenance.SUBJECT_PROVIDED:\n case DataPortabilityProvenance.OBSERVED:\n return SubjectExportFieldScope.INCLUDED;\n\n case DataPortabilityProvenance.DERIVED:\n return SubjectExportFieldScope.EXCLUDED_DERIVED;\n\n default: {\n // Compile-time exhaustiveness: a new provenance member without an arm is a TYPE error here.\n const _exhaustiveProvenanceCheck: never = provenance;\n throw new Error(\n `resolvePortabilityFieldScope has no arm for provenance `\n + `'${String(_exhaustiveProvenanceCheck)}'`,\n );\n }\n }\n}\n\n/**\n * Is this field withheld from EVERY subject export, whatever right is being answered?\n *\n * ## Why this exists at all — the layering trap it closes\n *\n * The export orchestrator collects rows at the REPOSITORY layer, which sits BELOW the service-layer\n * DTO projection that normally strips `.isBackendOnly()` fields on their way to a client. Without an\n * explicit check here, a subject export would disclose exactly the values that projection exists to\n * hide — `passwordHash` and `backupCodesHashed` on `USER_CREDENTIALS` are the motivating case, and\n * the config change that exposed them would have looked entirely routine.\n *\n * ## Why it is deliberately CONSERVATIVE\n *\n * This withholds every backend-only field, not only the secrets. Some backend-only fields are\n * genuinely disclosable under Art. 15 (`passwordChangedAt`, `firstMfaPromptAt` — facts about the\n * subject they may ask for), so this errs toward withholding.\n *\n * That asymmetry is intentional. Under-disclosing produces a complaint that is answerable and\n * fixable; disclosing an authentication secret is neither, and it degrades the security of\n * processing the framework is separately obliged to maintain (GDPR Art. 32). Between an\n * over-cautious bundle and a leaked credential, only one is recoverable.\n *\n * The withheld fields are REPORTED (`SubjectExportReport.fieldsWithheldAsNonDisclosable`) so the\n * caution is visible rather than silent. When a resource needs a specific backend-only field\n * disclosed, the expressible extension is a per-field opt-in on this predicate — NOT loosening it\n * wholesale.\n *\n * assurance-control: WILDO.PRIVACY.SUBJECT_DATA_EXPORT\n */\nexport function isFieldWithheldFromSubjectExport(fieldSchema: z.ZodTypeAny): boolean {\n // Delegated to the ONE field-value disclosure rule rather than restated. The reasoning that used\n // to sit here — that `isWriteOnlySecret` is checked explicitly rather than assumed to imply\n // backend-only, because they are separate decorators and a future authoring form may set one\n // without the other — moved WITH the rule, and is now the shared module's own justification.\n //\n // This function keeps its own name and its own assurance marker deliberately: subject export is a\n // distinct obligation from model disclosure, its own docstring anticipates a per-field opt-in that\n // would apply HERE and nowhere else, and merging the two names would make that extension\n // unexpressible. What is shared is the rule, not the concept.\n return isNonDisclosableFieldValue(fieldSchema);\n}\n\n/** Every legal {@link DataPortabilityProvenance} value, for validating an opaque decorator string. */\nconst KNOWN_PORTABILITY_PROVENANCES: ReadonlySet<string> = new Set(\n Object.values(DataPortabilityProvenance),\n);\n\n/**\n * Resolve ONE field's EFFECTIVE provenance by joining the two declaration levels.\n *\n * ## The fallback chain, and why it has exactly two rungs\n *\n * 1. the field's own `.portabilityProvenance()` declaration, if it carries one;\n * 2. otherwise the resource's `portabilityPolicy.defaultProvenance`;\n * 3. otherwise `undefined` — which {@link resolveSubjectExportFieldScope} turns into a REFUSAL for\n * an Art. 20 export and ignores entirely for Art. 15.\n *\n * Two rungs is what makes the fail-loud rule adoptable: without the resource default, every field of\n * every resource would need a decorator before a single portability request could be answered, and a\n * capability that expensive to adopt does not get adopted. With it, annotating a resource is one\n * line and only the exceptions carry a decorator.\n *\n * ## Why the enum check lives HERE\n *\n * `zod-decorators` sits below this package and cannot import {@link DataPortabilityProvenance}, so\n * it stores whatever non-empty string it was given — it can reject a BLANK but not a WRONG value.\n * This is the first layer that knows the vocabulary, so it is where a typo'd `'subject-provided'`\n * (hyphen, not underscore) must fail rather than silently resolving to `undefined` and turning a\n * declared field into a refusal — or worse, into a silent omission if the caller treats unknown as\n * derived. Mirrors how `RedactionType` validity is checked in this layer for `.impersonalizeWith()`.\n *\n * @param fieldSchema the field's Zod schema; the reader walks wrapper types, so a declaration made\n * before or after `.optional()` / `.nullish()` / `.default()` is observed either way.\n * @param resourceDefaultProvenance the owning resource's `portabilityPolicy.defaultProvenance`.\n * Taken as a bare value rather than the policy object so this module stays free of the\n * resource-config import (which imports THIS module for the enum).\n * @param fieldLocator `resourceType.fieldName`, used only to make a rejection actionable.\n */\nexport function resolveEffectiveFieldPortabilityProvenance(\n fieldSchema: z.ZodTypeAny,\n resourceDefaultProvenance: DataPortabilityProvenance | undefined,\n fieldLocator: string,\n): DataPortabilityProvenance | undefined {\n const declared = getPortabilityProvenance(fieldSchema);\n\n if (declared === undefined) {\n return resourceDefaultProvenance;\n }\n\n if (!KNOWN_PORTABILITY_PROVENANCES.has(declared)) {\n throw new Error(\n `[${fieldLocator}] portabilityProvenance('${declared}') is not a DataPortabilityProvenance `\n + `value. Expected one of: ${[...KNOWN_PORTABILITY_PROVENANCES].join(', ')}. An unrecognised `\n + `value would resolve as UNDECLARED and make an Art. 20 export refuse, hiding the typo `\n + `behind what looks like a deliberate omission.`,\n );\n }\n\n return declared as DataPortabilityProvenance;\n}\n\n/** Why a compiled leaf-field decision has its effective export meaning. */\nexport enum SubjectExportFieldDecisionBasis {\n FIELD_DECLARATION = 'field_declaration',\n RESOURCE_DEFAULT = 'resource_default',\n WITHHELD_NON_DISCLOSABLE = 'withheld_non_disclosable',\n UNDECLARED = 'undeclared',\n DEPTH_LIMIT = 'depth_limit',\n}\n\n/** Canonical, runtime-effective decision for one leaf path in one export purpose. */\nexport interface SubjectExportFieldDecision {\n readonly locator: string;\n readonly purpose: SubjectExportPurpose;\n readonly scope: SubjectExportFieldScope | null;\n readonly provenance: DataPortabilityProvenance | null;\n readonly basis: SubjectExportFieldDecisionBasis;\n}\n\nconst SUBJECT_EXPORT_FIELD_MAX_DEPTH = 10;\n\n/**\n * Resolve an object shape through the same bounded wrapper protocol used by subject export.\n * Returning `undefined` means the value is a leaf. Reaching the bound is handled fail-closed by\n * {@link compileSubjectExportFieldDecisions}, never as an implicit leaf inclusion.\n */\nexport function resolveSubjectExportObjectShapeThroughWrappers(schema: unknown): Record<string, unknown> | undefined {\n let current: any = schema;\n for (let unwrapDepth = 0; current && unwrapDepth < SUBJECT_EXPORT_FIELD_MAX_DEPTH; unwrapDepth += 1) {\n if (current.shape && typeof current.shape === 'object') return current.shape as Record<string, unknown>;\n const inner = current.def?.innerType ?? current._def?.innerType;\n if (!inner) return undefined;\n current = inner;\n }\n return undefined;\n}\n\n/**\n * Compile every runtime-effective leaf-field decision for one resource and right.\n *\n * Both the backend executor and application authority proof consume this function. A field-level\n * decorator, inherited default, withheld marker, wrapper layout or depth refusal therefore changes\n * one shared decision inventory instead of two independently maintained interpretations.\n */\nexport function compileSubjectExportFieldDecisions(input: {\n readonly resourceType: ResourceType;\n readonly mainSchema: unknown;\n readonly defaultProvenance: DataPortabilityProvenance | undefined;\n readonly purpose: SubjectExportPurpose;\n}): SubjectExportFieldDecision[] {\n const rootShape = resolveSubjectExportObjectShapeThroughWrappers(input.mainSchema);\n if (!rootShape) return [];\n const decisions: SubjectExportFieldDecision[] = [];\n\n const visit = (shape: Record<string, unknown>, locatorPrefix: string, depth: number): void => {\n for (const [fieldName, fieldSchema] of Object.entries(shape)) {\n const locator = `${locatorPrefix}.${fieldName}`;\n if (depth >= SUBJECT_EXPORT_FIELD_MAX_DEPTH) {\n decisions.push({\n locator,\n purpose: input.purpose,\n scope: SubjectExportFieldScope.UNDECLARED,\n provenance: null,\n basis: SubjectExportFieldDecisionBasis.DEPTH_LIMIT,\n });\n continue;\n }\n if (isFieldWithheldFromSubjectExport(fieldSchema as z.ZodTypeAny)) {\n decisions.push({\n locator,\n purpose: input.purpose,\n scope: null,\n provenance: null,\n basis: SubjectExportFieldDecisionBasis.WITHHELD_NON_DISCLOSABLE,\n });\n continue;\n }\n const nestedShape = resolveSubjectExportObjectShapeThroughWrappers(fieldSchema);\n if (nestedShape) {\n visit(nestedShape, locator, depth + 1);\n continue;\n }\n const declared = getPortabilityProvenance(fieldSchema as z.ZodTypeAny);\n const provenance = resolveEffectiveFieldPortabilityProvenance(fieldSchema as z.ZodTypeAny, input.defaultProvenance, locator);\n decisions.push({\n locator,\n purpose: input.purpose,\n scope: resolveSubjectExportFieldScope(provenance, input.purpose),\n provenance: provenance ?? null,\n basis: declared !== undefined\n ? SubjectExportFieldDecisionBasis.FIELD_DECLARATION\n : provenance !== undefined\n ? SubjectExportFieldDecisionBasis.RESOURCE_DEFAULT\n : SubjectExportFieldDecisionBasis.UNDECLARED,\n });\n }\n };\n\n visit(rootShape, String(input.resourceType), 0);\n return decisions.sort((left, right) => compareCanonicalText(left.locator, right.locator));\n}\n\n/** Per-edge outcome of an executed export — the classification plus what actually happened. */\nexport interface SubjectExportEdgeOutcome extends SubjectExportEdgeClassification {\n /**\n * `true` when the export actually queried this edge. Note this reports that the read RAN, not\n * that rows existed — an included edge with no rows for this subject is a legitimate empty\n * result, and {@link recordCount} distinguishes the two.\n */\n collected: boolean;\n /** How many rows this edge contributed. `0` on an included edge means the subject had none. */\n recordCount: number;\n}\n\n/**\n * What one subject export produced — the compliance artifact of an Art. 15 or Art. 20 request.\n *\n * Returned to the caller (rather than only logged) so the flow fronting the request can record or\n * surface it: every edge of the subject appears exactly once with the disposition applied and the\n * configuration that justified it. For a disclosure obligation, the record of what was DELIBERATELY\n * LEFT OUT — and on what legal basis — matters as much as the data returned.\n */\nexport interface SubjectExportReport {\n /** Which right this export answered. */\n purpose: SubjectExportPurpose;\n /** The exported subject's resource type. */\n subjectResourceType: ResourceType;\n /** The exported subject rows. */\n subjectIds: string[];\n /** Every child-direction edge of the subject, classified, in registry order. */\n edges: SubjectExportEdgeOutcome[];\n /**\n * Fields omitted from the bundle as controller-DERIVED, as `resourceType.fieldName`. Populated\n * only for `PORTABILITY_ART_20`. Recorded rather than silently dropped so the subject can see\n * that derived data exists and request it under Art. 15 instead.\n */\n fieldsExcludedAsDerived: string[];\n /**\n * Fields withheld as NON-DISCLOSABLE regardless of purpose — see\n * {@link isFieldWithheldFromSubjectExport}. Populated for BOTH rights, because a password hash is\n * no more disclosable under Art. 15 than under Art. 20.\n *\n * Recorded rather than silently dropped for the same reason as the derived list, and one more: a\n * reviewer auditing why an export looks thin needs to see that the framework withheld something\n * deliberately, not that a resource was missed.\n */\n fieldsWithheldAsNonDisclosable: string[];\n /** Total rows across every collected edge, including the subject's own row(s). */\n totalRecordCount: number;\n}\n\n/** One resource's contribution to an export bundle. */\nexport interface SubjectExportResourceSlice {\n resourceType: ResourceType;\n /**\n * The rows, already narrowed to the fields in scope for the export's purpose. For\n * `PORTABILITY_ART_20` the controller-derived columns are gone; for `ACCESS_ART_15` every column\n * the subject is entitled to see is present.\n */\n rows: Record<string, unknown>[];\n}\n\n/**\n * What an export ACTUALLY produced — the data, paired with the report that justifies its shape.\n *\n * ## Why the data and the report are one return value but two types\n *\n * {@link SubjectExportReport} is the compliance artifact: it survives the request, is safe to log\n * and persist, and contains NO personal data — only per-edge dispositions and counts. The slices\n * are the personal data itself, which must NOT be logged and whose lifetime ends when the artifact\n * is written.\n *\n * Returning them together keeps the caller from having to correlate two results, while the type\n * split keeps \"safe to record\" and \"must be handled carefully\" visibly distinct — a caller writing\n * `logger.info({ report })` is correct, and the same line with `bundle` would be a leak. Fusing\n * them into one flat object would erase exactly that distinction.\n */\nexport interface SubjectExportBundle {\n report: SubjectExportReport;\n slices: SubjectExportResourceSlice[];\n}\n"]}
@@ -84,6 +84,26 @@ export declare const ValueSignalSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
84
84
  threshold: z.ZodOptional<z.ZodNumber>;
85
85
  }, z.core.$strip>], "signalType">;
86
86
  export type ValueSignal = z.infer<typeof ValueSignalSchema>;
87
+ /**
88
+ * @wildo_source:part:start saas.models.analytics.value-moments facet:layer:shared facet:audience:app-developer
89
+ *
90
+ * A VALUE MOMENT is something meaningful happening in a person's journey — first value reached, an
91
+ * aha moment, an activation stage, or an anti-pattern worth noticing. An application declares them
92
+ * as `analytics.valueMoments`, and reads `achievedMoments` from the analytics context to drive an
93
+ * onboarding surface.
94
+ *
95
+ * ⚠️ **They need the ANALYTICS capability enabled.** `analytics.enabled` is a master switch —
96
+ * `false` means no analytics at all, whatever a user consented to — so a declared value moment with
97
+ * analytics off is evaluated by nothing and the surface reading `achievedMoments` renders empty.
98
+ * Enabling analytics with an EMPTY provider list is how an application gets the internal progression
99
+ * plane without telemetry leaving it.
100
+ *
101
+ * The `role` is the load-bearing field, because it changes three things at once — event naming,
102
+ * whether the moment PERSISTS once achieved, and how the engine evaluates it. In particular
103
+ * `ANTI_PATTERN` is deliberately NOT persisted and is the only role for which `cooldownMs` and
104
+ * `beforeStage` mean anything: it is meant to re-fire while the behaviour continues and to stop
105
+ * permanently once the person reaches the stage that makes it moot.
106
+ */
87
107
  export declare enum ValueMomentMode {
88
108
  /** ANY signal in the list triggers the moment (OR logic) */
89
109
  ANY = "ANY",
@@ -162,5 +182,6 @@ export declare const ValueMomentSchema: z.ZodObject<{
162
182
  backendHandler: z.ZodOptional<z.ZodString>;
163
183
  }, z.core.$strip>>;
164
184
  }, z.core.$strip>;
185
+ /** @wildo_source:part:end saas.models.analytics.value-moments */
165
186
  export type ValueMoment = z.infer<typeof ValueMomentSchema>;
166
187
  //# sourceMappingURL=analytics-value-moments.shared.schemas.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"analytics-value-moments.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/config/analytics-value-moments.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB;;;GAGG;AACH,oBAAY,kBAAkB;IAC5B,SAAS,cAAc;IACvB,kBAAkB,uBAAuB;IACzC,KAAK,UAAU;IACf,UAAU,eAAe;IACzB,WAAW,gBAAgB;IAC3B,mBAAmB,wBAAwB;IAC3C,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,gBAAgB,qBAAqB;CACtC;AAED,mHAAmH;AACnH,eAAO,MAAM,yBAAyB,EAAG,cAAuB,CAAC;AAEjE,6DAA6D;AAC7D,eAAO,MAAM,iCAAiC,EAAG,eAAwB,CAAC;AAE1E,2DAA2D;AAC3D,oBAAY,sBAAsB;IAChC,QAAQ,aAAa;IACrB,OAAO,YAAY;CACpB;AAED,0DAA0D;AAC1D,oBAAY,kBAAkB;IAC5B,YAAY,iBAAiB;IAC7B,cAAc,mBAAmB;IACjC,aAAa,kBAAkB;IAC/B,cAAc,mBAAmB;IACjC,cAAc,mBAAmB;CAClC;AAED,sEAAsE;AACtE,eAAO,MAAM,qCAAqC,EAAG,2BAAoC,CAAC;AAI1F,oBAAY,eAAe;IACzB,kBAAkB,uBAAuB;IACzC,cAAc,mBAAmB;IACjC,UAAU,eAAe;IACzB,cAAc,mBAAmB;IACjC,YAAY,iBAAiB;CAC9B;AAID;;;GAGG;AACH,eAAO,MAAM,wBAAwB,oGAGpC,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAuD1E,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAM5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAI5D,oBAAY,eAAe;IACzB,4DAA4D;IAC5D,GAAG,QAAQ;IACX,+CAA+C;IAC/C,GAAG,QAAQ;CACZ;AAED;;;GAGG;AACH,oBAAY,eAAe;IACzB,qFAAqF;IACrF,IAAI,SAAS;IACb,sDAAsD;IACtD,UAAU,eAAe;IACzB,+CAA+C;IAC/C,UAAU,eAAe;IACzB,uEAAuE;IACvE,YAAY,iBAAiB;CAC9B;AAED;;;GAGG;AACH,oBAAY,gBAAgB;IAC1B,sCAAsC;IACtC,IAAI,SAAS;IACb,oCAAoC;IACpC,YAAY,iBAAiB;CAC9B;AAID,eAAO,MAAM,yBAAyB;;;iBAWpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAI5E,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiD5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
1
+ {"version":3,"file":"analytics-value-moments.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/config/analytics-value-moments.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB;;;GAGG;AACH,oBAAY,kBAAkB;IAC5B,SAAS,cAAc;IACvB,kBAAkB,uBAAuB;IACzC,KAAK,UAAU;IACf,UAAU,eAAe;IACzB,WAAW,gBAAgB;IAC3B,mBAAmB,wBAAwB;IAC3C,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,gBAAgB,qBAAqB;CACtC;AAED,mHAAmH;AACnH,eAAO,MAAM,yBAAyB,EAAG,cAAuB,CAAC;AAEjE,6DAA6D;AAC7D,eAAO,MAAM,iCAAiC,EAAG,eAAwB,CAAC;AAE1E,2DAA2D;AAC3D,oBAAY,sBAAsB;IAChC,QAAQ,aAAa;IACrB,OAAO,YAAY;CACpB;AAED,0DAA0D;AAC1D,oBAAY,kBAAkB;IAC5B,YAAY,iBAAiB;IAC7B,cAAc,mBAAmB;IACjC,aAAa,kBAAkB;IAC/B,cAAc,mBAAmB;IACjC,cAAc,mBAAmB;CAClC;AAED,sEAAsE;AACtE,eAAO,MAAM,qCAAqC,EAAG,2BAAoC,CAAC;AAI1F,oBAAY,eAAe;IACzB,kBAAkB,uBAAuB;IACzC,cAAc,mBAAmB;IACjC,UAAU,eAAe;IACzB,cAAc,mBAAmB;IACjC,YAAY,iBAAiB;CAC9B;AAID;;;GAGG;AACH,eAAO,MAAM,wBAAwB,oGAGpC,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAuD1E,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAM5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAI5D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,oBAAY,eAAe;IACzB,4DAA4D;IAC5D,GAAG,QAAQ;IACX,+CAA+C;IAC/C,GAAG,QAAQ;CACZ;AAED;;;GAGG;AACH,oBAAY,eAAe;IACzB,qFAAqF;IACrF,IAAI,SAAS;IACb,sDAAsD;IACtD,UAAU,eAAe;IACzB,+CAA+C;IAC/C,UAAU,eAAe;IACzB,uEAAuE;IACvE,YAAY,iBAAiB;CAC9B;AAED;;;GAGG;AACH,oBAAY,gBAAgB;IAC1B,sCAAsC;IACtC,IAAI,SAAS;IACb,oCAAoC;IACpC,YAAY,iBAAiB;CAC9B;AAID,eAAO,MAAM,yBAAyB;;;iBAWpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAI5E,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiD5B,CAAC;AACH,iEAAiE;AACjE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
@@ -123,6 +123,26 @@ export const ValueSignalSchema = z.discriminatedUnion('signalType', [
123
123
  ValueSignal_CustomEventSchema,
124
124
  ]);
125
125
  // ─── Value Moment Enums ─────────────────────────────────────────
126
+ /**
127
+ * @wildo_source:part:start saas.models.analytics.value-moments facet:layer:shared facet:audience:app-developer
128
+ *
129
+ * A VALUE MOMENT is something meaningful happening in a person's journey — first value reached, an
130
+ * aha moment, an activation stage, or an anti-pattern worth noticing. An application declares them
131
+ * as `analytics.valueMoments`, and reads `achievedMoments` from the analytics context to drive an
132
+ * onboarding surface.
133
+ *
134
+ * ⚠️ **They need the ANALYTICS capability enabled.** `analytics.enabled` is a master switch —
135
+ * `false` means no analytics at all, whatever a user consented to — so a declared value moment with
136
+ * analytics off is evaluated by nothing and the surface reading `achievedMoments` renders empty.
137
+ * Enabling analytics with an EMPTY provider list is how an application gets the internal progression
138
+ * plane without telemetry leaving it.
139
+ *
140
+ * The `role` is the load-bearing field, because it changes three things at once — event naming,
141
+ * whether the moment PERSISTS once achieved, and how the engine evaluates it. In particular
142
+ * `ANTI_PATTERN` is deliberately NOT persisted and is the only role for which `cooldownMs` and
143
+ * `beforeStage` mean anything: it is meant to re-fire while the behaviour continues and to stop
144
+ * permanently once the person reaches the stage that makes it moot.
145
+ */
126
146
  export var ValueMomentMode;
127
147
  (function (ValueMomentMode) {
128
148
  /** ANY signal in the list triggers the moment (OR logic) */
@@ -1 +1 @@
1
- {"version":3,"file":"analytics-value-moments.shared.schemas.js","sourceRoot":"","sources":["../../../../src/config/analytics-value-moments.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Analytics Value Moment Schemas\n * \n * Defines value signals and value moments for the analytics system.\n * Value moments represent meaningful milestones in a user's journey\n * (TTFV, aha moments, activation stages, anti-patterns).\n */\n\nimport { z } from 'zod';\n\n/** Navigation content type values for VIEW_VISIT signals. Inlined here — canonical enum lives in saas-frontend-lib (navigation-v3.schemas). */\nconst NAVIGATION_CONTENT_TYPES = [\n 'resource_operation',\n 'composite_view',\n 'chart_view',\n 'full_custom_view',\n 'flows_actors_view',\n 'custom',\n] as const;\n\n// ─── Analytics Event Names (auto-instrumentation) ───────────────\n\n/**\n * Built-in analytics track event names used by auto-instrumentation.\n * App-custom events use arbitrary strings via track(name, properties).\n */\nexport enum AnalyticsEventName {\n PAGE_VIEW = 'page_view',\n RESOURCE_OPERATION = 'resource_operation',\n ERROR = 'error',\n USER_LOGIN = 'user_login',\n USER_LOGOUT = 'user_logout',\n USER_STATUS_CHANGED = 'user_status_changed',\n NOTIFICATION = 'notification',\n HOTKEY_USED = 'hotkey_used',\n FEATURE_ACCESSED = 'feature_accessed',\n}\n\n/** Event name prefix for value moments (TTFV, aha, activation). Anti-pattern uses ValueMomentRole.ANTI_PATTERN. */\nexport const VALUE_MOMENT_EVENT_PREFIX = 'value_moment' as const;\n\n/** Signal type value when ALL mode signals are completed. */\nexport const VALUE_MOMENT_SIGNAL_ALL_COMPLETED = 'all_completed' as const;\n\n/** Trigger source for ANALYTICS_MOMENT_ACHIEVED events. */\nexport enum AnalyticsTriggerSource {\n FRONTEND = 'frontend',\n BACKEND = 'backend',\n}\n\n/** Hotkey key values for HOTKEY_USED analytics events. */\nexport enum AnalyticsHotkeyKey {\n COMMAND_MENU = 'command_menu',\n SIDEBAR_TOGGLE = 'sidebar_toggle',\n NOTIFICATIONS = 'notifications',\n QUICK_SWITCHER = 'quick_switcher',\n SHORTCUTS_HELP = 'shortcuts_help',\n}\n\n/** Storage key prefix for achieved moments (suffixed with userId). */\nexport const ANALYTICS_ACHIEVED_STORAGE_KEY_PREFIX = 'wildo_analytics_achieved_' as const;\n\n// ─── Signal Types ───────────────────────────────────────────────\n\nexport enum ValueSignalType {\n RESOURCE_OPERATION = 'resource_operation',\n RESOURCE_STATE = 'resource_state',\n VIEW_VISIT = 'view_visit',\n FEATURE_ACCESS = 'feature_access',\n CUSTOM_EVENT = 'custom_event',\n}\n\n// ─── Primitive filter (shallow equality matching only) ──────────\n\n/**\n * Only primitive values supported — no nested objects or arrays.\n * The engine evaluates: Object.entries(filter).every(([k, v]) => resource[k] === v)\n */\nexport const ValueSignal_FilterSchema = z.record(\n z.string(),\n z.union([z.string(), z.number(), z.boolean(), z.null()])\n);\nexport type ValueSignal_Filter = z.infer<typeof ValueSignal_FilterSchema>;\n\n// ─── Signal variant schemas (discriminated union on `signalType` — avoids Mongoose reserved `type`) ─────\n\nconst ValueSignal_ResourceOperationSchema = z.object({\n signalType: z.literal(ValueSignalType.RESOURCE_OPERATION),\n /** Resource type identifier (e.g., 'PROJECTS', 'REPORTS') */\n resourceType: z.string().min(1),\n /** Operation identifier (e.g., CoreResourceOperation.CREATE) */\n operation: z.string().min(1),\n /**\n * Optional resource field filter. Only operations on resources matching this\n * filter count. Filter evaluation requires the NOTIFY_RESOURCE_SUCCESS event\n * to carry a `resultSummary` field.\n */\n filter: ValueSignal_FilterSchema.optional(),\n /**\n * Minimum occurrence count required. When omitted (or 1), the first matching event fires.\n * When > 1, the engine counts matching events and fires at the N-th occurrence.\n */\n threshold: z.number().min(1).optional(),\n});\n\nconst ValueSignal_ResourceStateSchema = z.object({\n signalType: z.literal(ValueSignalType.RESOURCE_STATE),\n /** Resource type to count */\n resourceType: z.string().min(1),\n /** Field filter for counting */\n filter: ValueSignal_FilterSchema.optional(),\n /** Minimum count required to satisfy this signal */\n threshold: z.number().min(1),\n});\n\nconst ValueSignal_ViewVisitSchema = z.object({\n signalType: z.literal(ValueSignalType.VIEW_VISIT),\n /** Navigation content type (e.g., COMPOSITE_VIEW, CHART_VIEW) */\n contentType: z.enum(NAVIGATION_CONTENT_TYPES),\n /** Specific view reference. If omitted, any view of this contentType qualifies. */\n viewRef: z.string().optional(),\n});\n\nconst ValueSignal_FeatureAccessSchema = z.object({\n signalType: z.literal(ValueSignalType.FEATURE_ACCESS),\n /** Feature identifier from FeatureDefinition */\n featureId: z.string().min(1),\n});\n\nconst ValueSignal_CustomEventSchema = z.object({\n signalType: z.literal(ValueSignalType.CUSTOM_EVENT),\n /** Custom event name (tracked via useAnalytics().track() or backend emitSignal()) */\n eventName: z.string().min(1),\n /** Threshold: number of occurrences before the signal fires. Default: 1 */\n threshold: z.number().min(1).optional(),\n});\n\nexport const ValueSignalSchema = z.discriminatedUnion('signalType', [\n ValueSignal_ResourceOperationSchema,\n ValueSignal_ResourceStateSchema,\n ValueSignal_ViewVisitSchema,\n ValueSignal_FeatureAccessSchema,\n ValueSignal_CustomEventSchema,\n]);\nexport type ValueSignal = z.infer<typeof ValueSignalSchema>;\n\n// ─── Value Moment Enums ─────────────────────────────────────────\n\nexport enum ValueMomentMode {\n /** ANY signal in the list triggers the moment (OR logic) */\n ANY = 'ANY',\n /** ALL signals must be achieved (AND logic) */\n ALL = 'ALL',\n}\n\n/**\n * Semantic role of a value moment.\n * Determines event naming, persistence behavior, and how the system treats the moment.\n */\nexport enum ValueMomentRole {\n /** Time to First Value — the primary metric. Exactly 0 or 1 per scope per config. */\n TTFV = 'ttfv',\n /** Aha moment — behavior correlated with retention */\n AHA_MOMENT = 'aha_moment',\n /** Activation stage — progression milestone */\n ACTIVATION = 'activation',\n /** Anti-pattern — negative signal correlated with churn/frustration */\n ANTI_PATTERN = 'anti_pattern',\n}\n\n/**\n * Scope entity for the value moment.\n * Determines whose journey is being measured and where achieved state is persisted.\n */\nexport enum ValueMomentScope {\n /** Per-user value moment (default) */\n USER = 'user',\n /** Per-organization value moment */\n ORGANIZATION = 'organization',\n}\n\n// ─── Value Moment Callback ──────────────────────────────────────\n\nexport const ValueMomentCallbackSchema = z.object({\n /**\n * Frontend: when true, emits FrontendEvents.ANALYTICS_MOMENT_ACHIEVED on achievement.\n * App-custom code subscribes and filters by momentIdentifier for custom reactions.\n */\n frontendEvent: z.boolean().default(false),\n /**\n * Backend: Registered handler identifier to invoke when achieved.\n * Handler resolved from a registry (similar to resource custom service implementations).\n */\n backendHandler: z.string().optional(),\n});\nexport type ValueMomentCallback = z.infer<typeof ValueMomentCallbackSchema>;\n\n// ─── Value Moment Definition ────────────────────────────────────\n\nexport const ValueMomentSchema = z.object({\n /** Unique identifier (used as analytics event name prefix + persistence key) */\n identifier: z.string().min(1),\n\n /**\n * Semantic role. Determines:\n * - Event naming: TTFV/AHA_MOMENT/ACTIVATION emit 'value_moment.{id}', ANTI_PATTERN emits 'anti_pattern.{id}'\n * - Persistence: TTFV/AHA_MOMENT/ACTIVATION are persisted once achieved. ANTI_PATTERN is NOT persisted.\n * - Engine behavior: ANTI_PATTERN uses cooldownMs + beforeStage.\n */\n role: z.enum(ValueMomentRole),\n\n /**\n * Scope entity. Determines whose journey is measured.\n * USER: per-user (default). ORGANIZATION: per-org.\n */\n scope: z.enum(ValueMomentScope).default(ValueMomentScope.USER),\n\n /** Signals that compose this value moment */\n signals: z.array(ValueSignalSchema).min(1),\n\n /** Composition mode: ANY = first signal wins, ALL = all signals required */\n mode: z.enum(ValueMomentMode).default(ValueMomentMode.ANY),\n\n /**\n * Prerequisite moment identifiers. This moment only starts evaluating\n * AFTER all prerequisite moments have been achieved.\n */\n requires: z.array(z.string()).optional(),\n\n /**\n * Inverse prerequisite: this moment only evaluates BEFORE the specified\n * stage(s) have been achieved. Once any beforeStage moment is achieved,\n * this moment is permanently suppressed. Primarily used for ANTI_PATTERN role.\n */\n beforeStage: z.array(z.string()).optional(),\n\n /**\n * Cooldown in milliseconds between re-firings (only meaningful for ANTI_PATTERN role).\n * Default: 300_000 (5 minutes) for ANTI_PATTERN, ignored for other roles.\n */\n cooldownMs: z.number().min(0).optional(),\n\n /**\n * Callback hooks triggered when the moment is achieved.\n * - frontendEvent: emits ANALYTICS_MOMENT_ACHIEVED on the EventBus\n * - backendHandler: invokes a registered handler\n */\n onAchieved: ValueMomentCallbackSchema.optional(),\n});\nexport type ValueMoment = z.infer<typeof ValueMomentSchema>;\n"]}
1
+ {"version":3,"file":"analytics-value-moments.shared.schemas.js","sourceRoot":"","sources":["../../../../src/config/analytics-value-moments.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Analytics Value Moment Schemas\n * \n * Defines value signals and value moments for the analytics system.\n * Value moments represent meaningful milestones in a user's journey\n * (TTFV, aha moments, activation stages, anti-patterns).\n */\n\nimport { z } from 'zod';\n\n/** Navigation content type values for VIEW_VISIT signals. Inlined here — canonical enum lives in saas-frontend-lib (navigation-v3.schemas). */\nconst NAVIGATION_CONTENT_TYPES = [\n 'resource_operation',\n 'composite_view',\n 'chart_view',\n 'full_custom_view',\n 'flows_actors_view',\n 'custom',\n] as const;\n\n// ─── Analytics Event Names (auto-instrumentation) ───────────────\n\n/**\n * Built-in analytics track event names used by auto-instrumentation.\n * App-custom events use arbitrary strings via track(name, properties).\n */\nexport enum AnalyticsEventName {\n PAGE_VIEW = 'page_view',\n RESOURCE_OPERATION = 'resource_operation',\n ERROR = 'error',\n USER_LOGIN = 'user_login',\n USER_LOGOUT = 'user_logout',\n USER_STATUS_CHANGED = 'user_status_changed',\n NOTIFICATION = 'notification',\n HOTKEY_USED = 'hotkey_used',\n FEATURE_ACCESSED = 'feature_accessed',\n}\n\n/** Event name prefix for value moments (TTFV, aha, activation). Anti-pattern uses ValueMomentRole.ANTI_PATTERN. */\nexport const VALUE_MOMENT_EVENT_PREFIX = 'value_moment' as const;\n\n/** Signal type value when ALL mode signals are completed. */\nexport const VALUE_MOMENT_SIGNAL_ALL_COMPLETED = 'all_completed' as const;\n\n/** Trigger source for ANALYTICS_MOMENT_ACHIEVED events. */\nexport enum AnalyticsTriggerSource {\n FRONTEND = 'frontend',\n BACKEND = 'backend',\n}\n\n/** Hotkey key values for HOTKEY_USED analytics events. */\nexport enum AnalyticsHotkeyKey {\n COMMAND_MENU = 'command_menu',\n SIDEBAR_TOGGLE = 'sidebar_toggle',\n NOTIFICATIONS = 'notifications',\n QUICK_SWITCHER = 'quick_switcher',\n SHORTCUTS_HELP = 'shortcuts_help',\n}\n\n/** Storage key prefix for achieved moments (suffixed with userId). */\nexport const ANALYTICS_ACHIEVED_STORAGE_KEY_PREFIX = 'wildo_analytics_achieved_' as const;\n\n// ─── Signal Types ───────────────────────────────────────────────\n\nexport enum ValueSignalType {\n RESOURCE_OPERATION = 'resource_operation',\n RESOURCE_STATE = 'resource_state',\n VIEW_VISIT = 'view_visit',\n FEATURE_ACCESS = 'feature_access',\n CUSTOM_EVENT = 'custom_event',\n}\n\n// ─── Primitive filter (shallow equality matching only) ──────────\n\n/**\n * Only primitive values supported — no nested objects or arrays.\n * The engine evaluates: Object.entries(filter).every(([k, v]) => resource[k] === v)\n */\nexport const ValueSignal_FilterSchema = z.record(\n z.string(),\n z.union([z.string(), z.number(), z.boolean(), z.null()])\n);\nexport type ValueSignal_Filter = z.infer<typeof ValueSignal_FilterSchema>;\n\n// ─── Signal variant schemas (discriminated union on `signalType` — avoids Mongoose reserved `type`) ─────\n\nconst ValueSignal_ResourceOperationSchema = z.object({\n signalType: z.literal(ValueSignalType.RESOURCE_OPERATION),\n /** Resource type identifier (e.g., 'PROJECTS', 'REPORTS') */\n resourceType: z.string().min(1),\n /** Operation identifier (e.g., CoreResourceOperation.CREATE) */\n operation: z.string().min(1),\n /**\n * Optional resource field filter. Only operations on resources matching this\n * filter count. Filter evaluation requires the NOTIFY_RESOURCE_SUCCESS event\n * to carry a `resultSummary` field.\n */\n filter: ValueSignal_FilterSchema.optional(),\n /**\n * Minimum occurrence count required. When omitted (or 1), the first matching event fires.\n * When > 1, the engine counts matching events and fires at the N-th occurrence.\n */\n threshold: z.number().min(1).optional(),\n});\n\nconst ValueSignal_ResourceStateSchema = z.object({\n signalType: z.literal(ValueSignalType.RESOURCE_STATE),\n /** Resource type to count */\n resourceType: z.string().min(1),\n /** Field filter for counting */\n filter: ValueSignal_FilterSchema.optional(),\n /** Minimum count required to satisfy this signal */\n threshold: z.number().min(1),\n});\n\nconst ValueSignal_ViewVisitSchema = z.object({\n signalType: z.literal(ValueSignalType.VIEW_VISIT),\n /** Navigation content type (e.g., COMPOSITE_VIEW, CHART_VIEW) */\n contentType: z.enum(NAVIGATION_CONTENT_TYPES),\n /** Specific view reference. If omitted, any view of this contentType qualifies. */\n viewRef: z.string().optional(),\n});\n\nconst ValueSignal_FeatureAccessSchema = z.object({\n signalType: z.literal(ValueSignalType.FEATURE_ACCESS),\n /** Feature identifier from FeatureDefinition */\n featureId: z.string().min(1),\n});\n\nconst ValueSignal_CustomEventSchema = z.object({\n signalType: z.literal(ValueSignalType.CUSTOM_EVENT),\n /** Custom event name (tracked via useAnalytics().track() or backend emitSignal()) */\n eventName: z.string().min(1),\n /** Threshold: number of occurrences before the signal fires. Default: 1 */\n threshold: z.number().min(1).optional(),\n});\n\nexport const ValueSignalSchema = z.discriminatedUnion('signalType', [\n ValueSignal_ResourceOperationSchema,\n ValueSignal_ResourceStateSchema,\n ValueSignal_ViewVisitSchema,\n ValueSignal_FeatureAccessSchema,\n ValueSignal_CustomEventSchema,\n]);\nexport type ValueSignal = z.infer<typeof ValueSignalSchema>;\n\n// ─── Value Moment Enums ─────────────────────────────────────────\n\n/**\n * @wildo_source:part:start saas.models.analytics.value-moments facet:layer:shared facet:audience:app-developer\n *\n * A VALUE MOMENT is something meaningful happening in a person's journey — first value reached, an\n * aha moment, an activation stage, or an anti-pattern worth noticing. An application declares them\n * as `analytics.valueMoments`, and reads `achievedMoments` from the analytics context to drive an\n * onboarding surface.\n *\n * ⚠️ **They need the ANALYTICS capability enabled.** `analytics.enabled` is a master switch —\n * `false` means no analytics at all, whatever a user consented to — so a declared value moment with\n * analytics off is evaluated by nothing and the surface reading `achievedMoments` renders empty.\n * Enabling analytics with an EMPTY provider list is how an application gets the internal progression\n * plane without telemetry leaving it.\n *\n * The `role` is the load-bearing field, because it changes three things at once — event naming,\n * whether the moment PERSISTS once achieved, and how the engine evaluates it. In particular\n * `ANTI_PATTERN` is deliberately NOT persisted and is the only role for which `cooldownMs` and\n * `beforeStage` mean anything: it is meant to re-fire while the behaviour continues and to stop\n * permanently once the person reaches the stage that makes it moot.\n */\nexport enum ValueMomentMode {\n /** ANY signal in the list triggers the moment (OR logic) */\n ANY = 'ANY',\n /** ALL signals must be achieved (AND logic) */\n ALL = 'ALL',\n}\n\n/**\n * Semantic role of a value moment.\n * Determines event naming, persistence behavior, and how the system treats the moment.\n */\nexport enum ValueMomentRole {\n /** Time to First Value — the primary metric. Exactly 0 or 1 per scope per config. */\n TTFV = 'ttfv',\n /** Aha moment — behavior correlated with retention */\n AHA_MOMENT = 'aha_moment',\n /** Activation stage — progression milestone */\n ACTIVATION = 'activation',\n /** Anti-pattern — negative signal correlated with churn/frustration */\n ANTI_PATTERN = 'anti_pattern',\n}\n\n/**\n * Scope entity for the value moment.\n * Determines whose journey is being measured and where achieved state is persisted.\n */\nexport enum ValueMomentScope {\n /** Per-user value moment (default) */\n USER = 'user',\n /** Per-organization value moment */\n ORGANIZATION = 'organization',\n}\n\n// ─── Value Moment Callback ──────────────────────────────────────\n\nexport const ValueMomentCallbackSchema = z.object({\n /**\n * Frontend: when true, emits FrontendEvents.ANALYTICS_MOMENT_ACHIEVED on achievement.\n * App-custom code subscribes and filters by momentIdentifier for custom reactions.\n */\n frontendEvent: z.boolean().default(false),\n /**\n * Backend: Registered handler identifier to invoke when achieved.\n * Handler resolved from a registry (similar to resource custom service implementations).\n */\n backendHandler: z.string().optional(),\n});\nexport type ValueMomentCallback = z.infer<typeof ValueMomentCallbackSchema>;\n\n// ─── Value Moment Definition ────────────────────────────────────\n\nexport const ValueMomentSchema = z.object({\n /** Unique identifier (used as analytics event name prefix + persistence key) */\n identifier: z.string().min(1),\n\n /**\n * Semantic role. Determines:\n * - Event naming: TTFV/AHA_MOMENT/ACTIVATION emit 'value_moment.{id}', ANTI_PATTERN emits 'anti_pattern.{id}'\n * - Persistence: TTFV/AHA_MOMENT/ACTIVATION are persisted once achieved. ANTI_PATTERN is NOT persisted.\n * - Engine behavior: ANTI_PATTERN uses cooldownMs + beforeStage.\n */\n role: z.enum(ValueMomentRole),\n\n /**\n * Scope entity. Determines whose journey is measured.\n * USER: per-user (default). ORGANIZATION: per-org.\n */\n scope: z.enum(ValueMomentScope).default(ValueMomentScope.USER),\n\n /** Signals that compose this value moment */\n signals: z.array(ValueSignalSchema).min(1),\n\n /** Composition mode: ANY = first signal wins, ALL = all signals required */\n mode: z.enum(ValueMomentMode).default(ValueMomentMode.ANY),\n\n /**\n * Prerequisite moment identifiers. This moment only starts evaluating\n * AFTER all prerequisite moments have been achieved.\n */\n requires: z.array(z.string()).optional(),\n\n /**\n * Inverse prerequisite: this moment only evaluates BEFORE the specified\n * stage(s) have been achieved. Once any beforeStage moment is achieved,\n * this moment is permanently suppressed. Primarily used for ANTI_PATTERN role.\n */\n beforeStage: z.array(z.string()).optional(),\n\n /**\n * Cooldown in milliseconds between re-firings (only meaningful for ANTI_PATTERN role).\n * Default: 300_000 (5 minutes) for ANTI_PATTERN, ignored for other roles.\n */\n cooldownMs: z.number().min(0).optional(),\n\n /**\n * Callback hooks triggered when the moment is achieved.\n * - frontendEvent: emits ANALYTICS_MOMENT_ACHIEVED on the EventBus\n * - backendHandler: invokes a registered handler\n */\n onAchieved: ValueMomentCallbackSchema.optional(),\n});\n/** @wildo_source:part:end saas.models.analytics.value-moments */\nexport type ValueMoment = z.infer<typeof ValueMomentSchema>;\n"]}
@@ -326,6 +326,11 @@ export declare const AppConfiguration_Shared_Schema: z.ZodObject<{
326
326
  requireSpecialChars: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
327
327
  expiryDays: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
328
328
  }, z.core.$strip>>;
329
+ stepUpAuth: z.ZodOptional<z.ZodObject<{
330
+ enabled: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
331
+ maxAgeSeconds: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
332
+ methods: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodEnum<typeof AuthMethod>>>>;
333
+ }, z.core.$strip>>;
329
334
  }, z.core.$strip>>;
330
335
  scimProvisioning: z.ZodOptional<z.ZodObject<{
331
336
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -345,10 +350,6 @@ export declare const AppConfiguration_Shared_Schema: z.ZodObject<{
345
350
  billing: z.ZodOptional<z.ZodObject<{
346
351
  enabled: z.ZodDefault<z.ZodBoolean>;
347
352
  providerRef: z.ZodOptional<z.ZodString>;
348
- webhooks: z.ZodOptional<z.ZodObject<{
349
- path: z.ZodDefault<z.ZodString>;
350
- signingSecretRef: z.ZodOptional<z.ZodString>;
351
- }, z.core.$strip>>;
352
353
  defaultCurrency: z.ZodDefault<z.ZodUnion<[z.ZodEnum<typeof import("@wildo-ai/zod-decorators").AvailableCurrency>, z.ZodString]>>;
353
354
  supportedCurrencies: z.ZodDefault<z.ZodArray<z.ZodUnion<[z.ZodEnum<typeof import("@wildo-ai/zod-decorators").AvailableCurrency>, z.ZodString]>>>;
354
355
  tax: z.ZodDefault<z.ZodObject<{
@@ -367,7 +368,7 @@ export declare const AppConfiguration_Shared_Schema: z.ZodObject<{
367
368
  defaultTrialDays: z.ZodDefault<z.ZodNumber>;
368
369
  paymentGracePeriodDays: z.ZodDefault<z.ZodNumber>;
369
370
  maxPaymentRetries: z.ZodDefault<z.ZodNumber>;
370
- defaultProration: z.ZodDefault<z.ZodEnum<typeof import("..").ProrationBehavior>>;
371
+ defaultProration: z.ZodDefault<z.ZodEnum<typeof import("@wildo-ai/external-connectors-models").ProrationBehavior>>;
371
372
  defaultCancellation: z.ZodDefault<z.ZodEnum<typeof import("..").BillingTiming>>;
372
373
  }, z.core.$strip>>;
373
374
  }, z.core.$strip>>;
@@ -470,6 +471,7 @@ export declare const AppConfiguration_Shared_Schema: z.ZodObject<{
470
471
  }, z.core.$strip>>;
471
472
  auditTrail: z.ZodOptional<z.ZodObject<{
472
473
  archiveAfterDays: z.ZodOptional<z.ZodNumber>;
474
+ allowPrivateNetworkSiemCollectors: z.ZodOptional<z.ZodBoolean>;
473
475
  }, z.core.$strip>>;
474
476
  }, z.core.$strip>;
475
477
  export type AppConfiguration_Shared_Compliance = z.infer<typeof AppConfiguration_Shared_ComplianceSchema>;
@@ -1 +1 @@
1
- {"version":3,"file":"app-configuration-shared.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/config/app-configuration-shared.shared.schemas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app-configuration-shared.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/config/app-configuration-shared.shared.schemas.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { AuthMethod } from '../security/authentications/authentication.shared.schemas';
10
10
  import { OrgAuthMethodPolicy } from './entity-identity-config.shared.schemas';
11
- import type { UserTypeAuthPolicy, OrgTypeAuthOverrides, MfaPolicyConfig, PasswordPolicyConfig } from './entity-identity-config.shared.schemas';
11
+ import type { UserTypeAuthPolicy, OrgTypeAuthOverrides, MfaPolicyConfig, PasswordPolicyConfig, StepUpAuthConfig } from './entity-identity-config.shared.schemas';
12
12
  export type AuthMethodsMap = Partial<Record<AuthMethod, boolean | {
13
13
  enabled: boolean;
14
14
  }>>;
@@ -22,6 +22,13 @@ export interface ResolvedAuthConfig {
22
22
  authMethodsEnabled: AuthMethodsMap;
23
23
  mfaPolicy: MfaPolicyConfig;
24
24
  passwordPolicy: PasswordPolicyConfig;
25
+ /**
26
+ * Re-authentication freshness (#527). `undefined` when the user type declares no step-up policy —
27
+ * an organisation cannot introduce step-up for a user type that has none, because there is no base
28
+ * to be more restrictive THAN, and inventing one would let a tenant enable a gate the application
29
+ * never configured.
30
+ */
31
+ stepUpAuth: StepUpAuthConfig | undefined;
25
32
  }
26
33
  export declare function getEnabledMethods(map: AuthMethodsMap | undefined): Set<AuthMethod>;
27
34
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"auth-config-resolution.shared.utils.d.ts","sourceRoot":"","sources":["../../../../src/config/auth-config-resolution.shared.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,2DAA2D,CAAC;AACvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAE/I,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,CAAC;AAEzF,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,kBAAkB,CAAC;IACjC,YAAY,EAAE,oBAAoB,EAAE,CAAC;IACrC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,oBAAoB,CAAC,EAAE,UAAU,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,EAAE,cAAc,CAAC;IACnC,SAAS,EAAE,eAAe,CAAC;IAC3B,cAAc,EAAE,oBAAoB,CAAC;CACtC;AAQD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC,CAOlF;AAYD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,yCAAyC,EAAE,SAAS,UAAU,EAK1E,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,mCAAmC,CAAC,kBAAkB,EAAE,cAAc,GAAG,cAAc,CAMtG;AA8MD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,yBAAyB,GAAG,kBAAkB,CAwBtF"}
1
+ {"version":3,"file":"auth-config-resolution.shared.utils.d.ts","sourceRoot":"","sources":["../../../../src/config/auth-config-resolution.shared.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,2DAA2D,CAAC;AACvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,eAAe,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAEjK,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,CAAC;AAEzF,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,kBAAkB,CAAC;IACjC,YAAY,EAAE,oBAAoB,EAAE,CAAC;IACrC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,oBAAoB,CAAC,EAAE,UAAU,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,EAAE,cAAc,CAAC;IACnC,SAAS,EAAE,eAAe,CAAC;IAC3B,cAAc,EAAE,oBAAoB,CAAC;IACrC;;;;;OAKG;IACH,UAAU,EAAE,gBAAgB,GAAG,SAAS,CAAC;CAC1C;AAQD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC,CAOlF;AAYD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,yCAAyC,EAAE,SAAS,UAAU,EAK1E,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,mCAAmC,CAAC,kBAAkB,EAAE,cAAc,GAAG,cAAc,CAMtG;AA8OD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,yBAAyB,GAAG,kBAAkB,CA0BtF"}