@wildo-ai/saas-models 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. package/dist/esm/applications/applications-context.schemas.d.ts +2 -0
  2. package/dist/esm/applications/applications-context.schemas.d.ts.map +1 -1
  3. package/dist/esm/billing/billing-account.shared.resources-config.schemas.d.ts +1 -1
  4. package/dist/esm/billing/billing-account.shared.resources-config.schemas.d.ts.map +1 -1
  5. package/dist/esm/billing/billing-account.shared.resources-config.schemas.js +36 -0
  6. package/dist/esm/billing/billing-account.shared.resources-config.schemas.js.map +1 -1
  7. package/dist/esm/billing/billing-account.shared.schemas.d.ts.map +1 -1
  8. package/dist/esm/billing/billing-account.shared.schemas.js +8 -1
  9. package/dist/esm/billing/billing-account.shared.schemas.js.map +1 -1
  10. package/dist/esm/billing/billing-types.shared.schemas.d.ts +2 -2
  11. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.d.ts +1 -1
  12. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.d.ts.map +1 -1
  13. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.js +39 -0
  14. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.js.map +1 -1
  15. package/dist/esm/billing/credit-pool.shared.schemas.d.ts +6 -6
  16. package/dist/esm/billing/credit-pool.shared.schemas.d.ts.map +1 -1
  17. package/dist/esm/billing/credit-pool.shared.schemas.js +8 -4
  18. package/dist/esm/billing/credit-pool.shared.schemas.js.map +1 -1
  19. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.d.ts +1 -1
  20. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.d.ts.map +1 -1
  21. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.js +35 -0
  22. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.js.map +1 -1
  23. package/dist/esm/billing/invoice-ref.shared.schemas.d.ts.map +1 -1
  24. package/dist/esm/billing/invoice-ref.shared.schemas.js +8 -3
  25. package/dist/esm/billing/invoice-ref.shared.schemas.js.map +1 -1
  26. package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts +1 -1
  27. package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts.map +1 -1
  28. package/dist/esm/billing/subscription.shared.resources-config.schemas.js +39 -0
  29. package/dist/esm/billing/subscription.shared.resources-config.schemas.js.map +1 -1
  30. package/dist/esm/billing/subscription.shared.schemas.d.ts +4 -4
  31. package/dist/esm/billing/subscription.shared.schemas.d.ts.map +1 -1
  32. package/dist/esm/billing/subscription.shared.schemas.js +6 -2
  33. package/dist/esm/billing/subscription.shared.schemas.js.map +1 -1
  34. package/dist/esm/billing/usage-record.shared.resources-config.schemas.d.ts +1 -1
  35. package/dist/esm/billing/usage-record.shared.resources-config.schemas.d.ts.map +1 -1
  36. package/dist/esm/billing/usage-record.shared.resources-config.schemas.js +39 -0
  37. package/dist/esm/billing/usage-record.shared.resources-config.schemas.js.map +1 -1
  38. package/dist/esm/billing/usage-record.shared.schemas.d.ts +4 -4
  39. package/dist/esm/billing/usage-record.shared.schemas.d.ts.map +1 -1
  40. package/dist/esm/billing/usage-record.shared.schemas.js +7 -3
  41. package/dist/esm/billing/usage-record.shared.schemas.js.map +1 -1
  42. package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.d.ts.map +1 -1
  43. package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.js +35 -2
  44. package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.js.map +1 -1
  45. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts +61 -0
  46. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts.map +1 -1
  47. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js +58 -0
  48. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js.map +1 -1
  49. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.d.ts.map +1 -1
  50. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js +14 -0
  51. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js.map +1 -1
  52. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts +49 -0
  53. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts.map +1 -1
  54. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js +124 -1
  55. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js.map +1 -1
  56. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts +11 -3
  57. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts.map +1 -1
  58. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js +11 -3
  59. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js.map +1 -1
  60. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts +93 -0
  61. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts.map +1 -0
  62. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js +116 -0
  63. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js.map +1 -0
  64. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts +67 -12
  65. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts.map +1 -1
  66. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js +95 -8
  67. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js.map +1 -1
  68. package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts +21 -1
  69. package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts.map +1 -1
  70. package/dist/esm/compliance/privacy/redaction.shared.schemas.js +20 -0
  71. package/dist/esm/compliance/privacy/redaction.shared.schemas.js.map +1 -1
  72. package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts +2 -0
  73. package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts.map +1 -1
  74. package/dist/esm/config/app-configuration-shared.shared.schemas.js +29 -0
  75. package/dist/esm/config/app-configuration-shared.shared.schemas.js.map +1 -1
  76. package/dist/esm/config/frontend/navigation.shared.schemas.d.ts +33 -0
  77. package/dist/esm/config/frontend/navigation.shared.schemas.d.ts.map +1 -1
  78. package/dist/esm/config/frontend/navigation.shared.schemas.js +32 -0
  79. package/dist/esm/config/frontend/navigation.shared.schemas.js.map +1 -1
  80. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts +12 -1
  81. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts.map +1 -1
  82. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js +12 -1
  83. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js.map +1 -1
  84. package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts +13 -0
  85. package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts.map +1 -1
  86. package/dist/esm/external-data/external-data-pipeline.shared.schemas.js.map +1 -1
  87. package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts +6 -6
  88. package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts.map +1 -1
  89. package/dist/esm/external-providers/engine-capabilities.shared.schemas.js +26 -6
  90. package/dist/esm/external-providers/engine-capabilities.shared.schemas.js.map +1 -1
  91. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.d.ts.map +1 -1
  92. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js +0 -2
  93. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js.map +1 -1
  94. package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts +1 -0
  95. package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts.map +1 -1
  96. package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts +4 -3
  97. package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts.map +1 -1
  98. package/dist/esm/external-providers/provider-capability.shared.schemas.js +4 -3
  99. package/dist/esm/external-providers/provider-capability.shared.schemas.js.map +1 -1
  100. package/dist/esm/features/user-features.shared.resources-config.schemas.d.ts +1 -1
  101. package/dist/esm/features/user-features.shared.resources-config.schemas.d.ts.map +1 -1
  102. package/dist/esm/features/user-features.shared.resources-config.schemas.js +48 -0
  103. package/dist/esm/features/user-features.shared.resources-config.schemas.js.map +1 -1
  104. package/dist/esm/files/file-upload-grant.shared.schemas.d.ts +144 -0
  105. package/dist/esm/files/file-upload-grant.shared.schemas.d.ts.map +1 -0
  106. package/dist/esm/files/file-upload-grant.shared.schemas.js +136 -0
  107. package/dist/esm/files/file-upload-grant.shared.schemas.js.map +1 -0
  108. package/dist/esm/files/files.shared.schemas.d.ts +45 -4
  109. package/dist/esm/files/files.shared.schemas.d.ts.map +1 -1
  110. package/dist/esm/files/files.shared.schemas.js +48 -4
  111. package/dist/esm/files/files.shared.schemas.js.map +1 -1
  112. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.d.ts +1 -1
  113. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.d.ts.map +1 -1
  114. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.js +33 -0
  115. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.js.map +1 -1
  116. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.d.ts.map +1 -1
  117. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.js +6 -2
  118. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.js.map +1 -1
  119. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.d.ts +1 -1
  120. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.d.ts.map +1 -1
  121. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.js +53 -0
  122. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.js.map +1 -1
  123. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.d.ts +1 -1
  124. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.d.ts.map +1 -1
  125. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.js +43 -0
  126. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.js.map +1 -1
  127. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.d.ts.map +1 -1
  128. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js +8 -3
  129. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js.map +1 -1
  130. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.d.ts +1 -1
  131. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.d.ts.map +1 -1
  132. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.js +41 -0
  133. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.js.map +1 -1
  134. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.d.ts +0 -7
  135. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.d.ts.map +1 -1
  136. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.js +23 -13
  137. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.js.map +1 -1
  138. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.d.ts +1 -1
  139. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.d.ts.map +1 -1
  140. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.js +51 -0
  141. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.js.map +1 -1
  142. package/dist/esm/guidance/guidance-state.shared.schemas.d.ts.map +1 -1
  143. package/dist/esm/guidance/guidance-state.shared.schemas.js +8 -2
  144. package/dist/esm/guidance/guidance-state.shared.schemas.js.map +1 -1
  145. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.d.ts +1 -1
  146. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.d.ts.map +1 -1
  147. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.js +51 -0
  148. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.js.map +1 -1
  149. package/dist/esm/guidance/lifecycle-state.shared.schemas.d.ts.map +1 -1
  150. package/dist/esm/guidance/lifecycle-state.shared.schemas.js +28 -3
  151. package/dist/esm/guidance/lifecycle-state.shared.schemas.js.map +1 -1
  152. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts +1 -1
  153. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts.map +1 -1
  154. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.js +51 -0
  155. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.js.map +1 -1
  156. package/dist/esm/guidance/progression-state.shared.schemas.d.ts.map +1 -1
  157. package/dist/esm/guidance/progression-state.shared.schemas.js +18 -4
  158. package/dist/esm/guidance/progression-state.shared.schemas.js.map +1 -1
  159. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts +37 -3
  160. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts.map +1 -1
  161. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js +29 -3
  162. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js.map +1 -1
  163. package/dist/esm/index.d.ts +6 -0
  164. package/dist/esm/index.d.ts.map +1 -1
  165. package/dist/esm/index.js +6 -0
  166. package/dist/esm/index.js.map +1 -1
  167. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts +70 -0
  168. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts.map +1 -0
  169. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js +71 -0
  170. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js.map +1 -0
  171. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.d.ts +1 -1
  172. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.d.ts.map +1 -1
  173. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.js +36 -0
  174. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.js.map +1 -1
  175. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts +1 -1
  176. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts.map +1 -1
  177. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.js +44 -0
  178. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.js.map +1 -1
  179. package/dist/esm/organizations/organization-members.shared.schemas.d.ts.map +1 -1
  180. package/dist/esm/organizations/organization-members.shared.schemas.js +15 -4
  181. package/dist/esm/organizations/organization-members.shared.schemas.js.map +1 -1
  182. package/dist/esm/organizations/organizations.shared.resources-config.schemas.d.ts.map +1 -1
  183. package/dist/esm/organizations/organizations.shared.resources-config.schemas.js +18 -10
  184. package/dist/esm/organizations/organizations.shared.resources-config.schemas.js.map +1 -1
  185. package/dist/esm/queue/jobs.shared.resources-config.schemas.d.ts.map +1 -1
  186. package/dist/esm/queue/jobs.shared.resources-config.schemas.js +17 -0
  187. package/dist/esm/queue/jobs.shared.resources-config.schemas.js.map +1 -1
  188. package/dist/esm/requests/websocket.shared.schemas.d.ts +59 -0
  189. package/dist/esm/requests/websocket.shared.schemas.d.ts.map +1 -1
  190. package/dist/esm/requests/websocket.shared.schemas.js +103 -0
  191. package/dist/esm/requests/websocket.shared.schemas.js.map +1 -1
  192. package/dist/esm/resources/collection-query-parameters.shared.d.ts +22 -0
  193. package/dist/esm/resources/collection-query-parameters.shared.d.ts.map +1 -0
  194. package/dist/esm/resources/collection-query-parameters.shared.js +22 -0
  195. package/dist/esm/resources/collection-query-parameters.shared.js.map +1 -0
  196. package/dist/esm/resources/resources-config.shared.factory.d.ts.map +1 -1
  197. package/dist/esm/resources/resources-config.shared.factory.js +86 -13
  198. package/dist/esm/resources/resources-config.shared.factory.js.map +1 -1
  199. package/dist/esm/resources/resources-config.shared.schemas.d.ts +162 -41
  200. package/dist/esm/resources/resources-config.shared.schemas.d.ts.map +1 -1
  201. package/dist/esm/resources/resources-config.shared.schemas.js +109 -20
  202. package/dist/esm/resources/resources-config.shared.schemas.js.map +1 -1
  203. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.d.ts.map +1 -1
  204. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js +21 -6
  205. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js.map +1 -1
  206. package/dist/esm/security/authentications/authentication.shared.schemas.d.ts +57 -0
  207. package/dist/esm/security/authentications/authentication.shared.schemas.d.ts.map +1 -1
  208. package/dist/esm/security/authentications/authentication.shared.schemas.js +64 -0
  209. package/dist/esm/security/authentications/authentication.shared.schemas.js.map +1 -1
  210. package/dist/esm/security/authentications/consumable-token.shared.schemas.d.ts +17 -1
  211. package/dist/esm/security/authentications/consumable-token.shared.schemas.d.ts.map +1 -1
  212. package/dist/esm/security/authentications/consumable-token.shared.schemas.js +16 -0
  213. package/dist/esm/security/authentications/consumable-token.shared.schemas.js.map +1 -1
  214. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts +28 -0
  215. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts.map +1 -0
  216. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js +28 -0
  217. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js.map +1 -0
  218. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts +21 -0
  219. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts.map +1 -0
  220. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js +21 -0
  221. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js.map +1 -0
  222. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts +1 -1
  223. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts.map +1 -1
  224. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js +43 -0
  225. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js.map +1 -1
  226. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts +0 -8
  227. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts.map +1 -1
  228. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js +13 -4
  229. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js.map +1 -1
  230. package/dist/esm/security/authorizations/roles.shared.schemas.d.ts +16 -1
  231. package/dist/esm/security/authorizations/roles.shared.schemas.d.ts.map +1 -1
  232. package/dist/esm/security/authorizations/roles.shared.schemas.js +16 -1
  233. package/dist/esm/security/authorizations/roles.shared.schemas.js.map +1 -1
  234. package/dist/esm/security/authorizations/roles.shared.utils.d.ts +54 -0
  235. package/dist/esm/security/authorizations/roles.shared.utils.d.ts.map +1 -1
  236. package/dist/esm/security/authorizations/roles.shared.utils.js +59 -0
  237. package/dist/esm/security/authorizations/roles.shared.utils.js.map +1 -1
  238. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts +61 -0
  239. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts.map +1 -1
  240. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js +13 -1
  241. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js.map +1 -1
  242. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.d.ts +1 -1
  243. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.d.ts.map +1 -1
  244. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.js +35 -0
  245. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.js.map +1 -1
  246. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.d.ts.map +1 -1
  247. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js +7 -1
  248. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js.map +1 -1
  249. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.d.ts +1 -1
  250. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.d.ts.map +1 -1
  251. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.js +34 -0
  252. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.js.map +1 -1
  253. package/dist/esm/users/inbound-contacts.shared.schemas.d.ts.map +1 -1
  254. package/dist/esm/users/inbound-contacts.shared.schemas.js +7 -4
  255. package/dist/esm/users/inbound-contacts.shared.schemas.js.map +1 -1
  256. package/dist/esm/users/user-credentials.shared.resources-config.schemas.d.ts +1 -1
  257. package/dist/esm/users/user-credentials.shared.resources-config.schemas.d.ts.map +1 -1
  258. package/dist/esm/users/user-credentials.shared.resources-config.schemas.js +37 -0
  259. package/dist/esm/users/user-credentials.shared.resources-config.schemas.js.map +1 -1
  260. package/dist/esm/users/user-credentials.shared.schemas.d.ts.map +1 -1
  261. package/dist/esm/users/user-credentials.shared.schemas.js +17 -2
  262. package/dist/esm/users/user-credentials.shared.schemas.js.map +1 -1
  263. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.d.ts +1 -1
  264. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.d.ts.map +1 -1
  265. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.js +36 -0
  266. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.js.map +1 -1
  267. package/dist/esm/users/user-identity-links.shared.schemas.d.ts.map +1 -1
  268. package/dist/esm/users/user-identity-links.shared.schemas.js +15 -5
  269. package/dist/esm/users/user-identity-links.shared.schemas.js.map +1 -1
  270. package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts +1 -1
  271. package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts.map +1 -1
  272. package/dist/esm/users/user-preferences.shared.resources-config.schemas.js +53 -0
  273. package/dist/esm/users/user-preferences.shared.resources-config.schemas.js.map +1 -1
  274. package/dist/esm/users/user-profiles.shared.resources-config.schemas.d.ts +1 -1
  275. package/dist/esm/users/user-profiles.shared.resources-config.schemas.d.ts.map +1 -1
  276. package/dist/esm/users/user-profiles.shared.resources-config.schemas.js +62 -0
  277. package/dist/esm/users/user-profiles.shared.resources-config.schemas.js.map +1 -1
  278. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts +1 -1
  279. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts.map +1 -1
  280. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.js +53 -0
  281. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.js.map +1 -1
  282. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.d.ts +1 -1
  283. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.d.ts.map +1 -1
  284. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.js +62 -0
  285. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.js.map +1 -1
  286. package/dist/esm/users/users.shared.schemas.d.ts +19 -0
  287. package/dist/esm/users/users.shared.schemas.d.ts.map +1 -1
  288. package/dist/esm/users/users.shared.schemas.js +41 -16
  289. package/dist/esm/users/users.shared.schemas.js.map +1 -1
  290. package/dist/tsconfig.build.tsbuildinfo +1 -1
  291. package/package.json +5 -6
  292. package/dist/esm/.builder.pid +0 -9
@@ -1 +1 @@
1
- {"version":3,"file":"user-self-profiles.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/users/user-self-profiles.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,EAAE,0BAA0B,EAAwB,MAAM,uCAAuC,CAAC;AACzG,OAAO,EAAE,gBAAgB,EAAE,kCAAkC,EAAE,MAAM,gDAAgD,CAAC;AACtH,OAAO,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AACrF,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AAExH,OAAO,EAAE,0CAA0C,EAAE,MAAM,8CAA8C,CAAC;AAE1G,OAAO,EAAE,cAAc,EAAE,MAAM,iDAAiD,CAAC;AACjF,OAAO,EAAE,wBAAwB,EAAE,MAAM,8CAA8C,CAAC;AACxF,OAAO,EAAE,yBAAyB,EAAE,MAAM,qDAAqD,CAAC;AAWhG;;EAEE;AACF,MAAM,CAAC,MAAM,2DAA2D,GAAG,CAAC,sBAA8C,EAAE,EAAE,CAAC,0CAA0C,CAIvK;IACA,UAAU,EAAE,iBAAiB;IAC7B,kBAAkB,EAAE,gBAAgB,CAAC,kBAAkB;IACvD,uBAAuB,EAAE,kCAAkC,CAAC,gBAAgB,CAAC,kBAAkB,CAAC;IAChG,qBAAqB,EAAE,sBAAsB;IAC7C,gBAAgB,EAAE,IAAI,EAAE,2CAA2C;IAEnE;;OAEG;IACH,kBAAkB,EAAE,EAAE,aAAa,EAAE,wBAAwB,CAAC,OAAO,EAAE;IAEvE;;OAEG;IACH,iBAAiB,EAAE,EAAE,iBAAiB,EAAE,yBAAyB,CAAC,gBAAgB,EAAE;IAEpF,cAAc,EAAE;QACd,qBAAqB,CAAC,IAAI;QAC1B,qBAAqB,CAAC,MAAM;QAC5B,qBAAqB,CAAC,MAAM;KAC7B;IAED,eAAe,EAAE,EAA2B;IAE5C,uBAAuB,EAAE;QACvB,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE;YAC5B,QAAQ,EAAE;gBACR;oBACE,WAAW,EAAE,4BAA4B,CAAC,QAAQ;oBAClD,SAAS,EAAE,IAAI;oBACf,KAAK,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,uCAAuC;oBACzE,SAAS,EAAE,0BAA0B,CAAC,GAAG;iBAC1C;aACF;SACF;QAED,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE;YAC9B,QAAQ,EAAE;gBACR;oBACE,WAAW,EAAE,4BAA4B,CAAC,QAAQ;oBAClD,SAAS,EAAE,IAAI;oBACf,KAAK,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,yCAAyC;oBAC3E,SAAS,EAAE,0BAA0B,CAAC,GAAG;oBACzC,0CAA0C;iBAC3C;aACF;YACD,iBAAiB,EAAE;gBACjB;oBACE,MAAM,EAAE,0BAA0B,CAAC,SAAS;oBAC5C,OAAO,EAAE,2BAA2B,CAAC,iBAAiB;iBACvD;aACF;SACF;QAED,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE;YAC9B,QAAQ,EAAE;gBACR;oBACE,WAAW,EAAE,4BAA4B,CAAC,QAAQ;oBAClD,SAAS,EAAE,IAAI;oBACf,KAAK,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,yCAAyC;oBAC3E,SAAS,EAAE,0BAA0B,CAAC,GAAG;oBACzC,0CAA0C;iBAC3C;aACF;YACD,iBAAiB,EAAE;gBACjB;oBACE,MAAM,EAAE,0BAA0B,CAAC,SAAS;oBAC5C,OAAO,EAAE,2BAA2B,CAAC,iBAAiB;iBACvD;aACF;SACF;KACF;CACF,CAAC,CAAC","sourcesContent":["/**\n * User Self Profiles Shared Resource Configuration\n *\n * Resource configuration for user self profile management operations.\n * Handles profile information that users can manage for themselves only.\n * Separated from USER_PROFILES for strict access control.\n */\n\nimport { UserProfileSchema } from './users.shared.schemas';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } from '../resources/resources.shared.schemas';\nimport { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationVariantType } from '../resources/resources.shared.schemas';\nimport { CoreUserNotificationTarget, CoreUserNotificationChannel } from '../notifications/notifications.shared.schemas';\n\nimport { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory';\n\nimport { CORE_APP_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\n\n// USER_SELF_PROFILES has NO custom operations — profile fields are edited through\n// the generic UPDATE form. The former granular update ops (avatar / contact info /\n// phone verify / personal info) were removed as redundant with UPDATE; phone-factor\n// MFA lives in the Security panel's enrollment flow, not on this resource.\ntype UserSelfProfilesCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE;\n\n/*\nUser Self Profiles Resource Configuration Factory\n*/\nexport const userSelfProfilesResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n UserSelfProfilesCoreOperations,\n typeof UserProfileSchema\n>({\n mainSchema: UserProfileSchema,\n resourceIdentifier: CoreResourceType.USER_SELF_PROFILES,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_SELF_PROFILES],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true, // Self-scoped resource - same user context\n\n /**\n * Subject-export disclosure. Name, bio, avatar — supplied by the user.\n */\n systemAccessPolicy: { exportSubject: ResourceSystemAccessMode.ALLOWED },\n\n /**\n * Subject-export disclosure. Name, bio, avatar — supplied by the user.\n */\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.SUBJECT_PROVIDED },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Only self can read their own profile\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Only self can create their own profile\n riskLevel: ResourceOperationRiskLevel.LOW,\n // requestDto auto-derived from decorators\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Only self can update their own profile\n riskLevel: ResourceOperationRiskLevel.LOW,\n // requestDto auto-derived from decorators\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n },\n});\n"]}
1
+ {"version":3,"file":"user-self-profiles.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/users/user-self-profiles.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User Self Profiles Shared Resource Configuration\n *\n * Resource configuration for user self profile management operations.\n * Handles profile information that users can manage for themselves only.\n * Separated from USER_PROFILES for strict access control.\n */\n\nimport { UserProfileSchema } from './users.shared.schemas';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } from '../resources/resources.shared.schemas';\nimport { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationVariantType } from '../resources/resources.shared.schemas';\nimport { CoreUserNotificationTarget, CoreUserNotificationChannel } from '../notifications/notifications.shared.schemas';\n\nimport { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory';\n\nimport { CORE_APP_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\nimport { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\n\n// USER_SELF_PROFILES has NO custom operations — profile fields are edited through\n// the generic UPDATE form. The former granular update ops (avatar / contact info /\n// phone verify / personal info) were removed as redundant with UPDATE; phone-factor\n// MFA lives in the Security panel's enrollment flow, not on this resource.\ntype UserSelfProfilesCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.LIST\n | CoreResourceOperation.UPDATE_MANY;\n\n/*\nUser Self Profiles Resource Configuration Factory\n*/\nexport const userSelfProfilesResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n UserSelfProfilesCoreOperations,\n typeof UserProfileSchema\n>({\n mainSchema: UserProfileSchema,\n resourceIdentifier: CoreResourceType.USER_SELF_PROFILES,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_SELF_PROFILES],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true, // Self-scoped resource - same user context\n\n /**\n * Subject-export disclosure. Name, bio, avatar — supplied by the user.\n */\n systemAccessPolicy: { exportSubject: ResourceSystemAccessMode.ALLOWED },\n\n /**\n * Subject-export disclosure. Name, bio, avatar — supplied by the user.\n */\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.SUBJECT_PROVIDED },\n\n /**\n * Subject erasure scrubs-and-RETAINS the profile row rather than deleting it.\n *\n * `RETAIN_AND_IMPERSONALIZE` because this row holds personal data of its OWN — names, avatar, bio,\n * phone, title — which the treatments on the shared `UserProfileSchema` mask or remove. The two\n * required name fields MASK to `ERASED_USER_NAME` rather than REMOVE: they are `min(1)`, so nulling\n * them would leave a row the schema rejects on the next read.\n *\n * RETAIN rather than delete, to match the identity row. `USERS` is retained so the financial records\n * whose foreign keys point at it stay resolvable; a profile deleted out from under a retained user\n * would leave that user's 1:1 composition dangling. Retaining and scrubbing keeps the collection's\n * contract coherent and removes the personal data, which is what the obligation actually asks.\n *\n * ⚠️ `USER_SELF_PROFILES` declares the SAME policy on purpose — a second config over the SAME\n * collection and the SAME `UserProfileSchema`. Both must inject the same marker and emit the same\n * partial index, exactly as `USERS` / `USER_SELF` do. Change the two together.\n */\n retentionPolicy: {\n mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,\n },\n\n /**\n * The subject IS the person this profile describes, reached through its `userId` composition parent.\n */\n dataSubjectPolicy: { kind: ResourceDataSubjectKind.SELF_PRINCIPAL },\n\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n // LIST + UPDATE_MANY exist for the retention capability ONLY, as INTERNAL_CALL variants that\n // register no route. `retentionPolicy` requires UPDATE_MANY (the in-place scrub via\n // `updateManyAsSystem`) plus READ + LIST (the audited see-through read of retained rows).\n CoreResourceOperation.LIST,\n CoreResourceOperation.UPDATE_MANY,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n /*\n * Route-less retention plumbing. Both are INTERNAL_CALL, *not* REPOSITORY_ONLY: the retention\n * primitives resolve through `getServiceOperationPathDefault`, which matches INTERNAL_CALL /\n * API_CALL / API_CALL_WITH_CALLBACK and deliberately excludes REPOSITORY_ONLY — so a\n * REPOSITORY_ONLY variant satisfies the factory's boot-time \"operation exists\" guard and then\n * FAILS TO RESOLVE when an erasure actually runs. `roles` is inert on a non-URL-bearing variant;\n * the real gate is the derived `systemAccessPolicy` grant the trusted writer fails closed on.\n */\n [CoreResourceOperation.LIST]: {\n variants: [\n {\n // LOW, matching `USER_SELF`'s retention LIST. A read-shaped operation may not be declared\n // HIGH/CRITICAL — the audit contract pairs that band with an emission obligation, and it is\n // checked over the real engine catalogue. Declaring HIGH here failed both halves of that\n // check at once: an unemitted HIGH, and a read at a write's risk band.\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n },\n ],\n },\n [CoreResourceOperation.UPDATE_MANY]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n },\n ],\n },\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Only self can read their own profile\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Only self can create their own profile\n riskLevel: ResourceOperationRiskLevel.LOW,\n // requestDto auto-derived from decorators\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER], // Only self can update their own profile\n riskLevel: ResourceOperationRiskLevel.LOW,\n // requestDto auto-derived from decorators\n }\n ],\n userNotifications: [\n {\n target: CoreUserNotificationTarget.USER_SELF,\n channel: CoreUserNotificationChannel.FRONT_END_SUCCESS,\n }\n ]\n },\n },\n});\n"]}
@@ -17,6 +17,25 @@ import { AvailableLanguage, DateFormat, TimeFormat } from '@wildo-ai/presets-com
17
17
  * an erased subject without duplicating the literal.
18
18
  */
19
19
  export declare const ERASED_USER_EMAIL = "erased@erased.invalid";
20
+ /**
21
+ * What a REQUIRED name field becomes when the subject is erased.
22
+ *
23
+ * `firstName` and `lastName` are `min(1)`, so REMOVE is not available to them — nulling a required
24
+ * field would leave a row the schema itself rejects on the next read. MASK with a value that is
25
+ * obviously not a name keeps the row parseable while carrying no information about the person.
26
+ *
27
+ * Deliberately the same placeholder as `ERASED_FILE_NAME_PLACEHOLDER`: a reader meeting `[erased]`
28
+ * in an export or an admin view should not have to learn a second vocabulary to recognise it.
29
+ */
30
+ export declare const ERASED_USER_NAME = "[erased]";
31
+ /**
32
+ * What an erased EXTERNAL identifier becomes — a provider's own id for the person.
33
+ *
34
+ * Distinct from `ERASED_USER_NAME` despite the same literal, because the two answer different
35
+ * questions and will diverge: a name is displayed to a human, an external id is matched against a
36
+ * provider's records. Merging them would make a future change to either silently change the other.
37
+ */
38
+ export declare const ERASED_IDENTITY_VALUE = "[erased]";
20
39
  export declare enum UserStatus {
21
40
  ACTIVE = "ACTIVE",
22
41
  INACTIVE = "INACTIVE",
@@ -1 +1 @@
1
- {"version":3,"file":"users.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/users/users.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAkB,cAAc,EAAE,MAAM,iDAAiD,CAAC;AAGjG,OAAO,EAAE,iBAAiB,EAAkB,UAAU,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAKhH;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,0BAA0B,CAAC;AAEzD,oBAAY,UAAU;IACpB,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,SAAS,cAAc;IACvB,oBAAoB,yBAAyB;IAC7C,kBAAkB,uBAAuB;IACzC,OAAO,YAAY;CACpB;AAED,oBAAY,SAAS;IACnB,KAAK,UAAU;IACf,IAAI,SAAS;IACb,IAAI,SAAS;CACd;AAED,eAAO,MAAM,UAAU;;;;;;;;;iBAoGrB,CAAC;AACH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAE9C,eAAO,MAAM,6BAA6B;;;;;iBASxC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,iBAAiB;;;;;;;;;;iBA+C5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,mCAAmC;;;;;iBAK9C,CAAC;AACH,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAEhG,eAAO,MAAM,8BAA8B;;iBAEzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF,eAAO,MAAM,8BAA8B;;;;;iBAQzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF;;;;;;;;;;;;;;;;GAgBG;AACH,oBAAY,mBAAmB;IAC7B,aAAa,kBAAkB;IAC/B,OAAO,YAAY;IACnB,EAAE,OAAO;IACT,QAAQ,aAAa;IACrB,QAAQ,wBAAwB;CACjC;AAED,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyChC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAK5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
1
+ {"version":3,"file":"users.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/users/users.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAkB,cAAc,EAAE,MAAM,iDAAiD,CAAC;AAGjG,OAAO,EAAE,iBAAiB,EAAkB,UAAU,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAKhH;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,0BAA0B,CAAC;AAEzD;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,aAAa,CAAC;AAE3C;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,aAAa,CAAC;AAEhD,oBAAY,UAAU;IACpB,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,SAAS,cAAc;IACvB,oBAAoB,yBAAyB;IAC7C,kBAAkB,uBAAuB;IACzC,OAAO,YAAY;CACpB;AAED,oBAAY,SAAS;IACnB,KAAK,UAAU;IACf,IAAI,SAAS;IACb,IAAI,SAAS;CACd;AAED,eAAO,MAAM,UAAU;;;;;;;;;iBAoGrB,CAAC;AACH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAE9C,eAAO,MAAM,6BAA6B;;;;;iBASxC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,iBAAiB;;;;;;;;;;iBA0E5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,mCAAmC;;;;;iBAK9C,CAAC;AACH,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAEhG,eAAO,MAAM,8BAA8B;;iBAEzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF,eAAO,MAAM,8BAA8B;;;;;iBAQzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF;;;;;;;;;;;;;;;;GAgBG;AACH,oBAAY,mBAAmB;IAC7B,aAAa,kBAAkB;IAC/B,OAAO,YAAY;IACnB,EAAE,OAAO;IACT,QAAQ,aAAa;IACrB,QAAQ,wBAAwB;CACjC;AAED,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuDhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAK5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
@@ -22,6 +22,25 @@ import { PersonalDataCategory } from '../compliance/privacy/personal-data-catego
22
22
  * an erased subject without duplicating the literal.
23
23
  */
24
24
  export const ERASED_USER_EMAIL = 'erased@erased.invalid';
25
+ /**
26
+ * What a REQUIRED name field becomes when the subject is erased.
27
+ *
28
+ * `firstName` and `lastName` are `min(1)`, so REMOVE is not available to them — nulling a required
29
+ * field would leave a row the schema itself rejects on the next read. MASK with a value that is
30
+ * obviously not a name keeps the row parseable while carrying no information about the person.
31
+ *
32
+ * Deliberately the same placeholder as `ERASED_FILE_NAME_PLACEHOLDER`: a reader meeting `[erased]`
33
+ * in an export or an admin view should not have to learn a second vocabulary to recognise it.
34
+ */
35
+ export const ERASED_USER_NAME = '[erased]';
36
+ /**
37
+ * What an erased EXTERNAL identifier becomes — a provider's own id for the person.
38
+ *
39
+ * Distinct from `ERASED_USER_NAME` despite the same literal, because the two answer different
40
+ * questions and will diverge: a name is displayed to a human, an external id is matched against a
41
+ * provider's records. Merging them would make a future change to either silently change the other.
42
+ */
43
+ export const ERASED_IDENTITY_VALUE = '[erased]';
25
44
  export var UserStatus;
26
45
  (function (UserStatus) {
27
46
  UserStatus["ACTIVE"] = "ACTIVE";
@@ -148,9 +167,9 @@ export const UserProfileSchema = z.object({
148
167
  // `onParentCreate` seed + the provisioning paths against a concurrent
149
168
  // double-create — the durable idempotency guarantee behind the declarative seed.
150
169
  userId: z.string().min(1).isDBIndexed().isUnique().isForeignKey().isSummaryField().excludeFromUpdate(),
151
- firstName: z.string().min(1).max(50).isSummaryField().dataCategories(PersonalDataCategory.IDENTITY),
152
- lastName: z.string().min(1).max(50).isSummaryField().dataCategories(PersonalDataCategory.IDENTITY),
153
- displayName: z.string().max(100).optional().isSummaryField().dataCategories(PersonalDataCategory.IDENTITY),
170
+ firstName: addImpersonalizeWith(z.string().min(1).max(50).isSummaryField().dataCategories(PersonalDataCategory.IDENTITY), RedactionType.MASK, { maskValue: ERASED_USER_NAME }),
171
+ lastName: addImpersonalizeWith(z.string().min(1).max(50).isSummaryField().dataCategories(PersonalDataCategory.IDENTITY), RedactionType.MASK, { maskValue: ERASED_USER_NAME }),
172
+ displayName: addImpersonalizeWith(z.string().max(100).optional().isSummaryField().dataCategories(PersonalDataCategory.IDENTITY), RedactionType.REMOVE),
154
173
  /**
155
174
  * Profile avatar — a single uploaded square image (≤ 2 MB, ≤ 1024px), stored
156
175
  * as the standard file reference `{ fileId, updatedAt }` and rendered as a
@@ -159,7 +178,11 @@ export const UserProfileSchema = z.object({
159
178
  * `aspectRatio 1:1` constraint enforces the square crop. Upload-only — there
160
179
  * is no external-URL branch.
161
180
  */
162
- avatar: z_file({
181
+ // REMOVE nulls the stored `{ fileId, updatedAt }` reference, which is what erasure can honestly
182
+ // promise here: the profile stops pointing at the person's face. It does NOT delete the underlying
183
+ // stored object — file bytes are owned by the file resource and its own lifecycle, and claiming
184
+ // otherwise in a schema comment would be the kind of unverified assertion this lane exists to stop.
185
+ avatar: addImpersonalizeWith(z_file({
163
186
  nature: FileNature.IMAGE,
164
187
  allowedMimeTypes: 'Images',
165
188
  maxSize: 2 * 1024 * 1024,
@@ -169,12 +192,12 @@ export const UserProfileSchema = z.object({
169
192
  aspectRatio: { width: 1, height: 1 },
170
193
  generateThumbnails: true,
171
194
  },
172
- }).optional().dataCategories(PersonalDataCategory.IDENTITY),
195
+ }).optional().dataCategories(PersonalDataCategory.IDENTITY), RedactionType.REMOVE),
173
196
  // Free prose the person wrote about themselves. USER_CONTENT says what the field is FOR, never
174
197
  // what it will contain — a bio is a classic surface where a special category (a health condition,
175
198
  // a religious observance, a political affiliation) arrives unannounced, and no schema certifies
176
199
  // otherwise. Nothing here is a claim that it does NOT contain one.
177
- bio: z.string().max(500).optional().dataCategories(PersonalDataCategory.USER_CONTENT),
200
+ bio: addImpersonalizeWith(z.string().max(500).optional().dataCategories(PersonalDataCategory.USER_CONTENT), RedactionType.REMOVE),
178
201
  /**
179
202
  * E.164 phone number (e.g. "+33123456789"). `z_phone()` carries the phone
180
203
  * metadata that drives the international phone INPUT on edit (country selector +
@@ -187,8 +210,8 @@ export const UserProfileSchema = z.object({
187
210
  // prototype-installed decorators at all (a decorator-WIDE gap, not specific to this one). A phone
188
211
  // number is contact-detail personal data by definition, so the escape hatch is load-bearing here
189
212
  // rather than a curiosity.
190
- phoneNumber: addDataCategories(z_phone().optional(), PersonalDataCategory.CONTACT_DETAILS),
191
- title: z.string().max(100).optional().dataCategories(PersonalDataCategory.PROFESSIONAL)
213
+ phoneNumber: addImpersonalizeWith(addDataCategories(z_phone().optional(), PersonalDataCategory.CONTACT_DETAILS), RedactionType.REMOVE),
214
+ title: addImpersonalizeWith(z.string().max(100).optional().dataCategories(PersonalDataCategory.PROFESSIONAL), RedactionType.REMOVE)
192
215
  });
193
216
  export const UserPreferences_NotificationsSchema = z.object({
194
217
  email: z.boolean().default(true),
@@ -258,18 +281,20 @@ export const UserPreferencesSchema = z.object({
258
281
  // USAGE rather than a preference-specific category. The vocabulary is deliberately coarse where it
259
282
  // is ours: a member per settings screen is a granularity nobody maintains, and it would tell a
260
283
  // reader nothing the word "preferences" does not.
261
- notifications: UserPreferences_NotificationsSchema.default(UserPreferences_NotificationsSchema.parse({}))
262
- .dataCategories(PersonalDataCategory.USAGE),
263
- privacy: UserPrivacySchema.default(UserPrivacySchema.parse({}))
264
- .dataCategories(PersonalDataCategory.USAGE),
284
+ notifications: addImpersonalizeWith(UserPreferences_NotificationsSchema.default(UserPreferences_NotificationsSchema.parse({}))
285
+ .dataCategories(PersonalDataCategory.USAGE), RedactionType.RESET),
286
+ privacy: addImpersonalizeWith(UserPrivacySchema.default(UserPrivacySchema.parse({}))
287
+ .dataCategories(PersonalDataCategory.USAGE), RedactionType.RESET),
265
288
  ui: UserPreferences_UI_ThemeSchema.default(UserPreferences_UI_ThemeSchema.parse({})).isSummaryField(),
266
289
  // Timezone and locale are the two that most clearly identify something about the person rather
267
290
  // than about the session — a timezone narrows where they are, which is why LOCATION rides here.
268
- regional: UserPreferences_RegionalSchema.default(UserPreferences_RegionalSchema.parse({})).isSummaryField()
269
- .dataCategories([PersonalDataCategory.USAGE, PersonalDataCategory.LOCATION]),
291
+ // LOCATION as well as USAGE — a timezone and a locale narrow where a person is. RESET returns the
292
+ // application's own defaults, which is what a person who never chose still has.
293
+ regional: addImpersonalizeWith(UserPreferences_RegionalSchema.default(UserPreferences_RegionalSchema.parse({})).isSummaryField()
294
+ .dataCategories([PersonalDataCategory.USAGE, PersonalDataCategory.LOCATION]), RedactionType.RESET),
270
295
  // Enhanced language preferences
271
- languagePreferences: UserLanguagePreferencesSchema.default(UserLanguagePreferencesSchema.parse({})).isSummaryField()
272
- .dataCategories(PersonalDataCategory.USAGE)
296
+ languagePreferences: addImpersonalizeWith(UserLanguagePreferencesSchema.default(UserLanguagePreferencesSchema.parse({})).isSummaryField()
297
+ .dataCategories(PersonalDataCategory.USAGE), RedactionType.RESET)
273
298
  });
274
299
  export const UserContextSchema = UserSchema.extend({
275
300
  // New relationship-based field names (matching auto-generated context)
@@ -1 +1 @@
1
- {"version":3,"file":"users.shared.schemas.js","sourceRoot":"","sources":["../../../../src/users/users.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User Shared Schemas\n * \n * Shared user schemas for frontend and backend with MongoDB compatibility\n */\n\nimport { z } from 'zod';\n\nimport { AppRolesSchema, CORE_APP_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { UserPrivacySchema } from '../compliance/privacy/privacy.shared.schemas';\nimport { OrganizationMemberSchema } from '../organizations/organization-members.shared.schemas';\nimport { AvailableLanguage, TimezoneSchema, DateFormat, TimeFormat } from '@wildo-ai/presets-components-models';\nimport { EnumEditMode, z_phone, z_file, FileNature, addDataCategories, addImpersonalizeWith } from '@wildo-ai/zod-decorators';\nimport { RedactionType } from '../compliance/privacy/redaction.shared.schemas';\nimport { PersonalDataCategory } from '../compliance/privacy/personal-data-category.shared.schemas';\n\n/**\n * The address written over a user's `email` when the subject is erased and the row retained.\n *\n * `.invalid` is an RFC 2606 reserved TLD: it can never be registered and never resolves, so an\n * erased address cannot be delivered to, cannot be confused with a live account, and cannot become\n * a real identity if a stray code path ever re-mails it.\n *\n * Exported as ONE named source so the erasure orchestrator, tests and any operator query recognize\n * an erased subject without duplicating the literal.\n */\nexport const ERASED_USER_EMAIL = 'erased@erased.invalid';\n\nexport enum UserStatus {\n ACTIVE = 'ACTIVE',\n INACTIVE = 'INACTIVE',\n SUSPENDED = 'SUSPENDED',\n PENDING_VERIFICATION = 'PENDING_VERIFICATION',\n PENDING_INVITATION = 'PENDING_INVITATION',\n DELETED = 'DELETED'\n}\n\nexport enum UserTheme {\n LIGHT = 'LIGHT',\n DARK = 'DARK',\n AUTO = 'AUTO'\n}\n\nexport const UserSchema = z.object({\n _id: z.string().min(1).isPrimaryKey().isSummaryField(),\n /**\n * Email is the STRICT unique identity anchor — there is never more than one\n * `User` per email. `.isUnique()` is the fail-closed DB backstop; every\n * provisioning path (self-registration, org-admin invite, SSO JIT, SCIM,\n * anonymous transposition) MUST find-or-create by this normalized value rather\n * than blind-create, and recover from the duplicate-key `409` on the rare\n * concurrent race (e.g. an invite and an SSO JIT landing at once). `.toLowerCase()`\n * normalizes before both the lookup and the unique check so casing can't fork an\n * identity. `.excludeFromUpdate()` keeps the anchor immutable.\n *\n * **It is also the ONLY personal datum on this row** (the rest is `_id`, status, roles, types and\n * timestamps; names / bio / phone / avatar all live on `USER_PROFILES`). So it is what a subject\n * erasure scrubs — `MASK` to {@link ERASED_USER_EMAIL}, which keeps the row resolvable as an\n * anonymized subject for the retained billing records whose foreign keys point at it.\n *\n * `MASK` with an explicit value rather than `REMOVE`: `REMOVE` writes `null`, which this schema\n * rejects, so it would force `.nullish()` here — widening the identity anchor to\n * `string | null | undefined` for ~20+ consumers (auth registration, password reset, JWT guard,\n * SCIM, SSO provisioning, org invites) AND making it optional at CREATE, to represent a state only\n * the audited see-through reader can ever observe, since a retained row is hidden from every\n * normal read. The default mask constant cannot be used either — it is not a valid email.\n * Every erased user shares this one address; that cannot collide, because the unique index on a\n * retention-governed resource covers only non-retained rows and the scrub flips the row to\n * `RETAINED` in the same write.\n */\n email: addDataCategories(\n addImpersonalizeWith(\n z.email().isDBIndexed().isUnique().toLowerCase().isSummaryField().excludeFromUpdate(),\n RedactionType.MASK,\n { maskValue: ERASED_USER_EMAIL },\n ),\n // Declared because the engine owes its OWN inventory. Without it, every generated application's\n // privacy notice would name `users.email` as an outstanding category gap — the field carries a\n // scrub treatment, which is the application saying it holds personal data, so the missing\n // category would be a provable omission the framework left for each app to fix. CONTACT_DETAILS\n // rather than IDENTITY: it is how the person is reached. That it also serves as the identity\n // anchor is a property of this schema, not of the datum.\n PersonalDataCategory.CONTACT_DETAILS,\n ),\n // The three fields below carry `.isAuditEvidence()`: their VALUES are recorded before-and-after on\n // the `resource_operation_performed` audit event. All three decide what the principal may do, and\n // all three hold closed vocabulary rather than personal data — so recording them is both necessary\n // as authorization evidence and free of personal data whose erasure obligations could reach the\n // immutable ledger.\n //\n // Contrast `email` directly above, which is deliberately NOT marked: it is the identity anchor and\n // is `.impersonalizeWith(MASK)`, i.e. a value the framework must be able to scrub on erasure.\n // Copying it into an unscrubbable audit row would defeat that capability. That is the whole D4\n // boundary in one file — mark what decides authority, never what identifies a person.\n /**\n * Account lifecycle and access posture.\n *\n * `.excludeFromUpdate()` since 2026-08-01. Lifecycle transitions belong to the dedicated verbs —\n * `users | suspend_user` / `unsuspend_user` and `user_self | deactivate_account` /\n * `reactivate_account` — which own the state machine, the reason, the audit event and the\n * administrative-continuity floors. A generic field patch reproduces none of that, so accepting\n * `status` on the ordinary UPDATE contract meant an administrator could retire an account through\n * a door that asked none of those questions. Mirrors `OrganizationMemberSchema.status`, whose\n * JSDoc has described the same rule for the same reason since before these verbs existed.\n *\n * ⚠️ The trusted server-side writers must therefore use `updateAsSystem`, which re-attaches the\n * field past the repository's strict request-DTO re-parse — email verification\n * (`PENDING_VERIFICATION → ACTIVE`), SCIM re-activation, and SCIM/IdP deprovisioning. All four\n * were migrated in the same change, and `USERS` opts into `systemAccessPolicy.update` for exactly\n * them. A NEW trusted writer that reaches for `servicesRegistryHandler.update` here will be\n * SILENTLY stripped — the account simply never changes state, with no error and no signal.\n *\n * assurance-control: WILDO.IDENTITY.LIFECYCLE — a change to whether a principal may authenticate\n * runs through one guarded, evidenced authority.\n */\n status: z.enum(UserStatus).default(UserStatus.ACTIVE).isDBIndexed().isSummaryField().isAuditEvidence().excludeFromUpdate(),\n appRoles: z.array(AppRolesSchema).default([CORE_APP_ROLES.APP_USER]).isDBIndexed().isAuditEvidence(),\n /** User types from config (e.g. 'user', 'admin', 'consumer'). Determines auth policy, registration context. */\n userTypes: z.array(z.string()).default([]).isDBIndexed().isAuditEvidence(),\n /**\n * When an automated sweep must return this account to `ACTIVE`.\n *\n * Written only by `users | suspend_user`, whose contract takes `suspensionDuration` in DAYS. The\n * transition hook resolves that duration to an absolute instant before persisting, because a\n * duration is only meaningful relative to a moment the row does not otherwise record.\n *\n * Voluntary `user_self | deactivate_account` deliberately has no schedule: an INACTIVE account\n * returns only when its subject calls `reactivate_account`. Absent therefore means an indefinite\n * admin suspension or a non-scheduled lifecycle state.\n *\n * Server-owned (`.excludeFromCreate().excludeFromUpdate()`) so the transition verbs are the only\n * writers, and indexed because the reactivation sweep queries exactly \"rows whose scheduled\n * reactivation has passed\". Deliberately NOT `.isAuditEvidence()`: unlike the three fields above\n * it does not decide what the principal may do — it is a scheduling detail, and the transition's\n * own audit event already records the reason and the resulting status.\n *\n * ⚠️ For admin suspension, the value is a PROMISE the reactivation batch keeps. Persisting it without that sweep would\n * be the same defect as a verb answering success while writing nothing: an authored intention\n * that nothing honors.\n */\n scheduledReactivationAt: z.date().optional().isDBIndexed().excludeFromCreate().excludeFromUpdate(),\n createdAt: z.date().default(() => new Date()).isDBIndexed().isSummaryField().excludeFromCreate().excludeFromUpdate(),\n updatedAt: z.date().default(() => new Date()).isDBIndexed().excludeFromCreate().excludeFromUpdate()\n});\nexport type User = z.infer<typeof UserSchema>;\n\nexport const UserLanguagePreferencesSchema = z.object({\n primaryLanguage: z.enum(AvailableLanguage).systemEnum('AvailableLanguage').default(AvailableLanguage.EN).isSummaryField(),\n // Compact multi-select: render as a chips combobox (searchable popover) instead\n // of a full inline checkbox column — `editMode: COMBOBOX` on the array item is the\n // opt-in that `FormFieldArray` reads to render `ComboboxMultiple`. Fits a\n // settings-row layout where the long language list would otherwise overflow.\n fallbackLanguages: z.array(z.enum(AvailableLanguage).systemEnum('AvailableLanguage').enumUI({ edit: { editMode: EnumEditMode.COMBOBOX } })).default([AvailableLanguage.EN]),\n autoDetect: z.boolean().default(true),\n useOrganizationDefault: z.boolean().default(false),\n});\nexport type UserLanguagePreferences = z.infer<typeof UserLanguagePreferencesSchema>;\n\nexport const UserProfileSchema = z.object({\n _id: z.string().min(1).isPrimaryKey().isSummaryField(),\n // `.isUnique()`: one profile per user (1:1 composition). Backstops the eager\n // `onParentCreate` seed + the provisioning paths against a concurrent\n // double-create — the durable idempotency guarantee behind the declarative seed.\n userId: z.string().min(1).isDBIndexed().isUnique().isForeignKey().isSummaryField().excludeFromUpdate(),\n firstName: z.string().min(1).max(50).isSummaryField().dataCategories(PersonalDataCategory.IDENTITY),\n lastName: z.string().min(1).max(50).isSummaryField().dataCategories(PersonalDataCategory.IDENTITY),\n displayName: z.string().max(100).optional().isSummaryField().dataCategories(PersonalDataCategory.IDENTITY),\n /**\n * Profile avatar — a single uploaded square image (≤ 2 MB, ≤ 1024px), stored\n * as the standard file reference `{ fileId, updatedAt }` and rendered as a\n * square avatar. Uses the plain `z_file()` image pipeline (upload / storage /\n * DTO / persistence / metadata population) with no bespoke field type; the\n * `aspectRatio 1:1` constraint enforces the square crop. Upload-only — there\n * is no external-URL branch.\n */\n avatar: z_file({\n nature: FileNature.IMAGE,\n allowedMimeTypes: 'Images',\n maxSize: 2 * 1024 * 1024,\n imageConstraints: {\n maxWidth: 1024,\n maxHeight: 1024,\n aspectRatio: { width: 1, height: 1 },\n generateThumbnails: true,\n },\n }).optional().dataCategories(PersonalDataCategory.IDENTITY),\n // Free prose the person wrote about themselves. USER_CONTENT says what the field is FOR, never\n // what it will contain — a bio is a classic surface where a special category (a health condition,\n // a religious observance, a political affiliation) arrives unannounced, and no schema certifies\n // otherwise. Nothing here is a claim that it does NOT contain one.\n bio: z.string().max(500).optional().dataCategories(PersonalDataCategory.USER_CONTENT),\n /**\n * E.164 phone number (e.g. \"+33123456789\"). `z_phone()` carries the phone\n * metadata that drives the international phone INPUT on edit (country selector +\n * national number) and the formatted international DISPLAY on read — replacing\n * the old raw `z.string().regex(...)` that surfaced the regex to the user.\n * Stored value is still a plain E.164 string, so DTO/persistence are unchanged.\n */\n //\n // `addDataCategories` rather than the fluent form: `z_phone()` returns a ZodPipe, which carries no\n // prototype-installed decorators at all (a decorator-WIDE gap, not specific to this one). A phone\n // number is contact-detail personal data by definition, so the escape hatch is load-bearing here\n // rather than a curiosity.\n phoneNumber: addDataCategories(z_phone().optional(), PersonalDataCategory.CONTACT_DETAILS),\n title: z.string().max(100).optional().dataCategories(PersonalDataCategory.PROFESSIONAL)\n});\nexport type UserProfile = z.infer<typeof UserProfileSchema>;\n\nexport const UserPreferences_NotificationsSchema = z.object({\n email: z.boolean().default(true),\n push: z.boolean().default(true),\n sms: z.boolean().default(false),\n inApp: z.boolean().default(true)\n});\nexport type UserPreferences_Notifications = z.infer<typeof UserPreferences_NotificationsSchema>;\n\nexport const UserPreferences_UI_ThemeSchema = z.object({\n theme: z.enum(UserTheme).default(UserTheme.AUTO).isSummaryField(),\n});\nexport type UserPreferences_UI_Theme = z.infer<typeof UserPreferences_UI_ThemeSchema>;\n\nexport const UserPreferences_RegionalSchema = z.object({\n timezone: TimezoneSchema.default('UTC').isSummaryField(),\n // LOCALE_DEFAULT (not ISO_8601): \"no expressed preference\" must mean locale-driven\n // rendering. A stored ISO_8601 default materializes at parse and masks the frontend's\n // locale fallback (I18nContext), pinning every preference-less user to `YYYY-MM-DD`.\n dateFormat: z.enum(DateFormat).systemEnum('DateFormat').default(DateFormat.LOCALE_DEFAULT),\n timeFormat: z.enum(TimeFormat).systemEnum('TimeFormat').default(TimeFormat.TWENTY_FOUR_HOUR),\n locale: z.enum(AvailableLanguage).systemEnum('AvailableLanguage').default(AvailableLanguage.EN).isSummaryField()\n});\nexport type UserPreferences_Regional = z.infer<typeof UserPreferences_RegionalSchema>;\n\n/**\n * The preference blocks a caller can address as a unit — the closed vocabulary behind\n * `reset_to_defaults` on USER_SELF_PREFERENCES.\n *\n * **Every value IS the persisted field name on {@link UserPreferencesSchema}.** That is the\n * point of the enum, not a coincidence: it lets the reset patch be DERIVED from the vocabulary\n * instead of routed through a hand-written flag-to-field map. The previous contract was six\n * booleans (`resetNotifications`, `resetUI`, …) that named no schema path, so the whole request\n * was stripped before persistence and the route answered 200 having reset nothing.\n *\n * Adding a preference group to the schema means adding a member here; the mapped type in\n * `user-preferences-reset.shared.utils.ts` then refuses to compile until the group declares how\n * it resets. Renaming a group field without renaming the value fails the same way.\n *\n * Note `LANGUAGE = 'languagePreferences'` — the member reads as the concept, the value is the\n * field. Do not \"tidy\" the value to `language`; it is an address, not a label.\n */\nexport enum UserPreferenceGroup {\n NOTIFICATIONS = 'notifications',\n PRIVACY = 'privacy',\n UI = 'ui',\n REGIONAL = 'regional',\n LANGUAGE = 'languagePreferences',\n}\n\nexport const UserPreferencesSchema = z.object({\n _id: z.string().min(1).isPrimaryKey().isSummaryField(),\n // `.isUnique()` is the idempotency backstop for onParentCreate seeding: the eager\n // seed (and any retry) is deduplicated at the DB layer — a second seed for the same\n // user fails the unique constraint and is swallowed, guaranteeing exactly one\n // preferences row per user. (Prod migration note: dedupe any pre-existing duplicate\n // userId rows before this index builds; preferences was seeded nowhere pre-feature,\n // so duplicates are unexpected.)\n userId: z.string().min(1).isDBIndexed().isUnique().isForeignKey().isSummaryField().excludeFromUpdate(),\n // ── Which preference blocks are data ABOUT the person, and which are rendering state ──\n //\n // Declared at the BLOCK, not on the leaves inside it. The resolver walks TOP-LEVEL fields only —\n // the same limit the subject-export compiler and the impersonalize writer have — so a category on\n // `regional.timezone` would be invisible. That is not a workaround: a notice enumerates KINDS, and\n // \"communication preferences\" is the kind, not \"the sms boolean\".\n //\n // `ui` is deliberately NOT declared. A theme choice is about how the SYSTEM renders for someone,\n // not a fact about them — the same line that keeps job executions, entitlement limits and unread\n // counters out of the inventory. The three below are the other side of it: how the person wants to\n // be CONTACTED, what they decided about their own privacy, and where and in what language they\n // are — each a fact about them that a notice owes an answer on.\n //\n // USAGE rather than a preference-specific category. The vocabulary is deliberately coarse where it\n // is ours: a member per settings screen is a granularity nobody maintains, and it would tell a\n // reader nothing the word \"preferences\" does not.\n notifications: UserPreferences_NotificationsSchema.default(UserPreferences_NotificationsSchema.parse({}))\n .dataCategories(PersonalDataCategory.USAGE),\n \n privacy: UserPrivacySchema.default(UserPrivacySchema.parse({}))\n .dataCategories(PersonalDataCategory.USAGE),\n \n ui: UserPreferences_UI_ThemeSchema.default(UserPreferences_UI_ThemeSchema.parse({})).isSummaryField(),\n \n // Timezone and locale are the two that most clearly identify something about the person rather\n // than about the session — a timezone narrows where they are, which is why LOCATION rides here.\n regional: UserPreferences_RegionalSchema.default(UserPreferences_RegionalSchema.parse({})).isSummaryField()\n .dataCategories([PersonalDataCategory.USAGE, PersonalDataCategory.LOCATION]),\n \n // Enhanced language preferences\n languagePreferences: UserLanguagePreferencesSchema.default(UserLanguagePreferencesSchema.parse({})).isSummaryField()\n .dataCategories(PersonalDataCategory.USAGE)\n});\nexport type UserPreferences = z.infer<typeof UserPreferencesSchema>;\n\nexport const UserContextSchema = UserSchema.extend({\n // New relationship-based field names (matching auto-generated context)\n userSelfProfile: UserProfileSchema.optional(),\n userSelfPreference: UserPreferencesSchema.optional(),\n organizationMembers: z.array(OrganizationMemberSchema).optional(),\n});\nexport type UserContext = z.infer<typeof UserContextSchema>; \n"]}
1
+ {"version":3,"file":"users.shared.schemas.js","sourceRoot":"","sources":["../../../../src/users/users.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User Shared Schemas\n * \n * Shared user schemas for frontend and backend with MongoDB compatibility\n */\n\nimport { z } from 'zod';\n\nimport { AppRolesSchema, CORE_APP_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { UserPrivacySchema } from '../compliance/privacy/privacy.shared.schemas';\nimport { OrganizationMemberSchema } from '../organizations/organization-members.shared.schemas';\nimport { AvailableLanguage, TimezoneSchema, DateFormat, TimeFormat } from '@wildo-ai/presets-components-models';\nimport { EnumEditMode, z_phone, z_file, FileNature, addDataCategories, addImpersonalizeWith } from '@wildo-ai/zod-decorators';\nimport { RedactionType } from '../compliance/privacy/redaction.shared.schemas';\nimport { PersonalDataCategory } from '../compliance/privacy/personal-data-category.shared.schemas';\n\n/**\n * The address written over a user's `email` when the subject is erased and the row retained.\n *\n * `.invalid` is an RFC 2606 reserved TLD: it can never be registered and never resolves, so an\n * erased address cannot be delivered to, cannot be confused with a live account, and cannot become\n * a real identity if a stray code path ever re-mails it.\n *\n * Exported as ONE named source so the erasure orchestrator, tests and any operator query recognize\n * an erased subject without duplicating the literal.\n */\nexport const ERASED_USER_EMAIL = 'erased@erased.invalid';\n\n/**\n * What a REQUIRED name field becomes when the subject is erased.\n *\n * `firstName` and `lastName` are `min(1)`, so REMOVE is not available to them — nulling a required\n * field would leave a row the schema itself rejects on the next read. MASK with a value that is\n * obviously not a name keeps the row parseable while carrying no information about the person.\n *\n * Deliberately the same placeholder as `ERASED_FILE_NAME_PLACEHOLDER`: a reader meeting `[erased]`\n * in an export or an admin view should not have to learn a second vocabulary to recognise it.\n */\nexport const ERASED_USER_NAME = '[erased]';\n\n/**\n * What an erased EXTERNAL identifier becomes — a provider's own id for the person.\n *\n * Distinct from `ERASED_USER_NAME` despite the same literal, because the two answer different\n * questions and will diverge: a name is displayed to a human, an external id is matched against a\n * provider's records. Merging them would make a future change to either silently change the other.\n */\nexport const ERASED_IDENTITY_VALUE = '[erased]';\n\nexport enum UserStatus {\n ACTIVE = 'ACTIVE',\n INACTIVE = 'INACTIVE',\n SUSPENDED = 'SUSPENDED',\n PENDING_VERIFICATION = 'PENDING_VERIFICATION',\n PENDING_INVITATION = 'PENDING_INVITATION',\n DELETED = 'DELETED'\n}\n\nexport enum UserTheme {\n LIGHT = 'LIGHT',\n DARK = 'DARK',\n AUTO = 'AUTO'\n}\n\nexport const UserSchema = z.object({\n _id: z.string().min(1).isPrimaryKey().isSummaryField(),\n /**\n * Email is the STRICT unique identity anchor — there is never more than one\n * `User` per email. `.isUnique()` is the fail-closed DB backstop; every\n * provisioning path (self-registration, org-admin invite, SSO JIT, SCIM,\n * anonymous transposition) MUST find-or-create by this normalized value rather\n * than blind-create, and recover from the duplicate-key `409` on the rare\n * concurrent race (e.g. an invite and an SSO JIT landing at once). `.toLowerCase()`\n * normalizes before both the lookup and the unique check so casing can't fork an\n * identity. `.excludeFromUpdate()` keeps the anchor immutable.\n *\n * **It is also the ONLY personal datum on this row** (the rest is `_id`, status, roles, types and\n * timestamps; names / bio / phone / avatar all live on `USER_PROFILES`). So it is what a subject\n * erasure scrubs — `MASK` to {@link ERASED_USER_EMAIL}, which keeps the row resolvable as an\n * anonymized subject for the retained billing records whose foreign keys point at it.\n *\n * `MASK` with an explicit value rather than `REMOVE`: `REMOVE` writes `null`, which this schema\n * rejects, so it would force `.nullish()` here — widening the identity anchor to\n * `string | null | undefined` for ~20+ consumers (auth registration, password reset, JWT guard,\n * SCIM, SSO provisioning, org invites) AND making it optional at CREATE, to represent a state only\n * the audited see-through reader can ever observe, since a retained row is hidden from every\n * normal read. The default mask constant cannot be used either — it is not a valid email.\n * Every erased user shares this one address; that cannot collide, because the unique index on a\n * retention-governed resource covers only non-retained rows and the scrub flips the row to\n * `RETAINED` in the same write.\n */\n email: addDataCategories(\n addImpersonalizeWith(\n z.email().isDBIndexed().isUnique().toLowerCase().isSummaryField().excludeFromUpdate(),\n RedactionType.MASK,\n { maskValue: ERASED_USER_EMAIL },\n ),\n // Declared because the engine owes its OWN inventory. Without it, every generated application's\n // privacy notice would name `users.email` as an outstanding category gap — the field carries a\n // scrub treatment, which is the application saying it holds personal data, so the missing\n // category would be a provable omission the framework left for each app to fix. CONTACT_DETAILS\n // rather than IDENTITY: it is how the person is reached. That it also serves as the identity\n // anchor is a property of this schema, not of the datum.\n PersonalDataCategory.CONTACT_DETAILS,\n ),\n // The three fields below carry `.isAuditEvidence()`: their VALUES are recorded before-and-after on\n // the `resource_operation_performed` audit event. All three decide what the principal may do, and\n // all three hold closed vocabulary rather than personal data — so recording them is both necessary\n // as authorization evidence and free of personal data whose erasure obligations could reach the\n // immutable ledger.\n //\n // Contrast `email` directly above, which is deliberately NOT marked: it is the identity anchor and\n // is `.impersonalizeWith(MASK)`, i.e. a value the framework must be able to scrub on erasure.\n // Copying it into an unscrubbable audit row would defeat that capability. That is the whole D4\n // boundary in one file — mark what decides authority, never what identifies a person.\n /**\n * Account lifecycle and access posture.\n *\n * `.excludeFromUpdate()` since 2026-08-01. Lifecycle transitions belong to the dedicated verbs —\n * `users | suspend_user` / `unsuspend_user` and `user_self | deactivate_account` /\n * `reactivate_account` — which own the state machine, the reason, the audit event and the\n * administrative-continuity floors. A generic field patch reproduces none of that, so accepting\n * `status` on the ordinary UPDATE contract meant an administrator could retire an account through\n * a door that asked none of those questions. Mirrors `OrganizationMemberSchema.status`, whose\n * JSDoc has described the same rule for the same reason since before these verbs existed.\n *\n * ⚠️ The trusted server-side writers must therefore use `updateAsSystem`, which re-attaches the\n * field past the repository's strict request-DTO re-parse — email verification\n * (`PENDING_VERIFICATION → ACTIVE`), SCIM re-activation, and SCIM/IdP deprovisioning. All four\n * were migrated in the same change, and `USERS` opts into `systemAccessPolicy.update` for exactly\n * them. A NEW trusted writer that reaches for `servicesRegistryHandler.update` here will be\n * SILENTLY stripped — the account simply never changes state, with no error and no signal.\n *\n * assurance-control: WILDO.IDENTITY.LIFECYCLE — a change to whether a principal may authenticate\n * runs through one guarded, evidenced authority.\n */\n status: z.enum(UserStatus).default(UserStatus.ACTIVE).isDBIndexed().isSummaryField().isAuditEvidence().excludeFromUpdate(),\n appRoles: z.array(AppRolesSchema).default([CORE_APP_ROLES.APP_USER]).isDBIndexed().isAuditEvidence(),\n /** User types from config (e.g. 'user', 'admin', 'consumer'). Determines auth policy, registration context. */\n userTypes: z.array(z.string()).default([]).isDBIndexed().isAuditEvidence(),\n /**\n * When an automated sweep must return this account to `ACTIVE`.\n *\n * Written only by `users | suspend_user`, whose contract takes `suspensionDuration` in DAYS. The\n * transition hook resolves that duration to an absolute instant before persisting, because a\n * duration is only meaningful relative to a moment the row does not otherwise record.\n *\n * Voluntary `user_self | deactivate_account` deliberately has no schedule: an INACTIVE account\n * returns only when its subject calls `reactivate_account`. Absent therefore means an indefinite\n * admin suspension or a non-scheduled lifecycle state.\n *\n * Server-owned (`.excludeFromCreate().excludeFromUpdate()`) so the transition verbs are the only\n * writers, and indexed because the reactivation sweep queries exactly \"rows whose scheduled\n * reactivation has passed\". Deliberately NOT `.isAuditEvidence()`: unlike the three fields above\n * it does not decide what the principal may do — it is a scheduling detail, and the transition's\n * own audit event already records the reason and the resulting status.\n *\n * ⚠️ For admin suspension, the value is a PROMISE the reactivation batch keeps. Persisting it without that sweep would\n * be the same defect as a verb answering success while writing nothing: an authored intention\n * that nothing honors.\n */\n scheduledReactivationAt: z.date().optional().isDBIndexed().excludeFromCreate().excludeFromUpdate(),\n createdAt: z.date().default(() => new Date()).isDBIndexed().isSummaryField().excludeFromCreate().excludeFromUpdate(),\n updatedAt: z.date().default(() => new Date()).isDBIndexed().excludeFromCreate().excludeFromUpdate()\n});\nexport type User = z.infer<typeof UserSchema>;\n\nexport const UserLanguagePreferencesSchema = z.object({\n primaryLanguage: z.enum(AvailableLanguage).systemEnum('AvailableLanguage').default(AvailableLanguage.EN).isSummaryField(),\n // Compact multi-select: render as a chips combobox (searchable popover) instead\n // of a full inline checkbox column — `editMode: COMBOBOX` on the array item is the\n // opt-in that `FormFieldArray` reads to render `ComboboxMultiple`. Fits a\n // settings-row layout where the long language list would otherwise overflow.\n fallbackLanguages: z.array(z.enum(AvailableLanguage).systemEnum('AvailableLanguage').enumUI({ edit: { editMode: EnumEditMode.COMBOBOX } })).default([AvailableLanguage.EN]),\n autoDetect: z.boolean().default(true),\n useOrganizationDefault: z.boolean().default(false),\n});\nexport type UserLanguagePreferences = z.infer<typeof UserLanguagePreferencesSchema>;\n\nexport const UserProfileSchema = z.object({\n _id: z.string().min(1).isPrimaryKey().isSummaryField(),\n // `.isUnique()`: one profile per user (1:1 composition). Backstops the eager\n // `onParentCreate` seed + the provisioning paths against a concurrent\n // double-create — the durable idempotency guarantee behind the declarative seed.\n userId: z.string().min(1).isDBIndexed().isUnique().isForeignKey().isSummaryField().excludeFromUpdate(),\n firstName: addImpersonalizeWith(\n z.string().min(1).max(50).isSummaryField().dataCategories(PersonalDataCategory.IDENTITY),\n RedactionType.MASK,\n { maskValue: ERASED_USER_NAME },\n ),\n lastName: addImpersonalizeWith(\n z.string().min(1).max(50).isSummaryField().dataCategories(PersonalDataCategory.IDENTITY),\n RedactionType.MASK,\n { maskValue: ERASED_USER_NAME },\n ),\n displayName: addImpersonalizeWith(\n z.string().max(100).optional().isSummaryField().dataCategories(PersonalDataCategory.IDENTITY),\n RedactionType.REMOVE,\n ),\n /**\n * Profile avatar — a single uploaded square image (≤ 2 MB, ≤ 1024px), stored\n * as the standard file reference `{ fileId, updatedAt }` and rendered as a\n * square avatar. Uses the plain `z_file()` image pipeline (upload / storage /\n * DTO / persistence / metadata population) with no bespoke field type; the\n * `aspectRatio 1:1` constraint enforces the square crop. Upload-only — there\n * is no external-URL branch.\n */\n // REMOVE nulls the stored `{ fileId, updatedAt }` reference, which is what erasure can honestly\n // promise here: the profile stops pointing at the person's face. It does NOT delete the underlying\n // stored object — file bytes are owned by the file resource and its own lifecycle, and claiming\n // otherwise in a schema comment would be the kind of unverified assertion this lane exists to stop.\n avatar: addImpersonalizeWith(\n z_file({\n nature: FileNature.IMAGE,\n allowedMimeTypes: 'Images',\n maxSize: 2 * 1024 * 1024,\n imageConstraints: {\n maxWidth: 1024,\n maxHeight: 1024,\n aspectRatio: { width: 1, height: 1 },\n generateThumbnails: true,\n },\n }).optional().dataCategories(PersonalDataCategory.IDENTITY),\n RedactionType.REMOVE,\n ),\n // Free prose the person wrote about themselves. USER_CONTENT says what the field is FOR, never\n // what it will contain — a bio is a classic surface where a special category (a health condition,\n // a religious observance, a political affiliation) arrives unannounced, and no schema certifies\n // otherwise. Nothing here is a claim that it does NOT contain one.\n bio: addImpersonalizeWith(\n z.string().max(500).optional().dataCategories(PersonalDataCategory.USER_CONTENT),\n RedactionType.REMOVE,\n ),\n /**\n * E.164 phone number (e.g. \"+33123456789\"). `z_phone()` carries the phone\n * metadata that drives the international phone INPUT on edit (country selector +\n * national number) and the formatted international DISPLAY on read — replacing\n * the old raw `z.string().regex(...)` that surfaced the regex to the user.\n * Stored value is still a plain E.164 string, so DTO/persistence are unchanged.\n */\n //\n // `addDataCategories` rather than the fluent form: `z_phone()` returns a ZodPipe, which carries no\n // prototype-installed decorators at all (a decorator-WIDE gap, not specific to this one). A phone\n // number is contact-detail personal data by definition, so the escape hatch is load-bearing here\n // rather than a curiosity.\n phoneNumber: addImpersonalizeWith(\n addDataCategories(z_phone().optional(), PersonalDataCategory.CONTACT_DETAILS),\n RedactionType.REMOVE,\n ),\n title: addImpersonalizeWith(\n z.string().max(100).optional().dataCategories(PersonalDataCategory.PROFESSIONAL),\n RedactionType.REMOVE,\n )\n});\nexport type UserProfile = z.infer<typeof UserProfileSchema>;\n\nexport const UserPreferences_NotificationsSchema = z.object({\n email: z.boolean().default(true),\n push: z.boolean().default(true),\n sms: z.boolean().default(false),\n inApp: z.boolean().default(true)\n});\nexport type UserPreferences_Notifications = z.infer<typeof UserPreferences_NotificationsSchema>;\n\nexport const UserPreferences_UI_ThemeSchema = z.object({\n theme: z.enum(UserTheme).default(UserTheme.AUTO).isSummaryField(),\n});\nexport type UserPreferences_UI_Theme = z.infer<typeof UserPreferences_UI_ThemeSchema>;\n\nexport const UserPreferences_RegionalSchema = z.object({\n timezone: TimezoneSchema.default('UTC').isSummaryField(),\n // LOCALE_DEFAULT (not ISO_8601): \"no expressed preference\" must mean locale-driven\n // rendering. A stored ISO_8601 default materializes at parse and masks the frontend's\n // locale fallback (I18nContext), pinning every preference-less user to `YYYY-MM-DD`.\n dateFormat: z.enum(DateFormat).systemEnum('DateFormat').default(DateFormat.LOCALE_DEFAULT),\n timeFormat: z.enum(TimeFormat).systemEnum('TimeFormat').default(TimeFormat.TWENTY_FOUR_HOUR),\n locale: z.enum(AvailableLanguage).systemEnum('AvailableLanguage').default(AvailableLanguage.EN).isSummaryField()\n});\nexport type UserPreferences_Regional = z.infer<typeof UserPreferences_RegionalSchema>;\n\n/**\n * The preference blocks a caller can address as a unit — the closed vocabulary behind\n * `reset_to_defaults` on USER_SELF_PREFERENCES.\n *\n * **Every value IS the persisted field name on {@link UserPreferencesSchema}.** That is the\n * point of the enum, not a coincidence: it lets the reset patch be DERIVED from the vocabulary\n * instead of routed through a hand-written flag-to-field map. The previous contract was six\n * booleans (`resetNotifications`, `resetUI`, …) that named no schema path, so the whole request\n * was stripped before persistence and the route answered 200 having reset nothing.\n *\n * Adding a preference group to the schema means adding a member here; the mapped type in\n * `user-preferences-reset.shared.utils.ts` then refuses to compile until the group declares how\n * it resets. Renaming a group field without renaming the value fails the same way.\n *\n * Note `LANGUAGE = 'languagePreferences'` — the member reads as the concept, the value is the\n * field. Do not \"tidy\" the value to `language`; it is an address, not a label.\n */\nexport enum UserPreferenceGroup {\n NOTIFICATIONS = 'notifications',\n PRIVACY = 'privacy',\n UI = 'ui',\n REGIONAL = 'regional',\n LANGUAGE = 'languagePreferences',\n}\n\nexport const UserPreferencesSchema = z.object({\n _id: z.string().min(1).isPrimaryKey().isSummaryField(),\n // `.isUnique()` is the idempotency backstop for onParentCreate seeding: the eager\n // seed (and any retry) is deduplicated at the DB layer — a second seed for the same\n // user fails the unique constraint and is swallowed, guaranteeing exactly one\n // preferences row per user. (Prod migration note: dedupe any pre-existing duplicate\n // userId rows before this index builds; preferences was seeded nowhere pre-feature,\n // so duplicates are unexpected.)\n userId: z.string().min(1).isDBIndexed().isUnique().isForeignKey().isSummaryField().excludeFromUpdate(),\n // ── Which preference blocks are data ABOUT the person, and which are rendering state ──\n //\n // Declared at the BLOCK, not on the leaves inside it. The resolver walks TOP-LEVEL fields only —\n // the same limit the subject-export compiler and the impersonalize writer have — so a category on\n // `regional.timezone` would be invisible. That is not a workaround: a notice enumerates KINDS, and\n // \"communication preferences\" is the kind, not \"the sms boolean\".\n //\n // `ui` is deliberately NOT declared. A theme choice is about how the SYSTEM renders for someone,\n // not a fact about them — the same line that keeps job executions, entitlement limits and unread\n // counters out of the inventory. The three below are the other side of it: how the person wants to\n // be CONTACTED, what they decided about their own privacy, and where and in what language they\n // are — each a fact about them that a notice owes an answer on.\n //\n // USAGE rather than a preference-specific category. The vocabulary is deliberately coarse where it\n // is ours: a member per settings screen is a granularity nobody maintains, and it would tell a\n // reader nothing the word \"preferences\" does not.\n notifications: addImpersonalizeWith(\n UserPreferences_NotificationsSchema.default(UserPreferences_NotificationsSchema.parse({}))\n .dataCategories(PersonalDataCategory.USAGE),\n RedactionType.RESET,\n ),\n \n privacy: addImpersonalizeWith(\n UserPrivacySchema.default(UserPrivacySchema.parse({}))\n .dataCategories(PersonalDataCategory.USAGE),\n RedactionType.RESET,\n ),\n \n ui: UserPreferences_UI_ThemeSchema.default(UserPreferences_UI_ThemeSchema.parse({})).isSummaryField(),\n \n // Timezone and locale are the two that most clearly identify something about the person rather\n // than about the session — a timezone narrows where they are, which is why LOCATION rides here.\n // LOCATION as well as USAGE — a timezone and a locale narrow where a person is. RESET returns the\n // application's own defaults, which is what a person who never chose still has.\n regional: addImpersonalizeWith(\n UserPreferences_RegionalSchema.default(UserPreferences_RegionalSchema.parse({})).isSummaryField()\n .dataCategories([PersonalDataCategory.USAGE, PersonalDataCategory.LOCATION]),\n RedactionType.RESET,\n ),\n \n // Enhanced language preferences\n languagePreferences: addImpersonalizeWith(\n UserLanguagePreferencesSchema.default(UserLanguagePreferencesSchema.parse({})).isSummaryField()\n .dataCategories(PersonalDataCategory.USAGE),\n RedactionType.RESET,\n )\n});\nexport type UserPreferences = z.infer<typeof UserPreferencesSchema>;\n\nexport const UserContextSchema = UserSchema.extend({\n // New relationship-based field names (matching auto-generated context)\n userSelfProfile: UserProfileSchema.optional(),\n userSelfPreference: UserPreferencesSchema.optional(),\n organizationMembers: z.array(OrganizationMemberSchema).optional(),\n});\nexport type UserContext = z.infer<typeof UserContextSchema>; \n"]}