@wildo-ai/saas-models 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. package/dist/esm/applications/applications-context.schemas.d.ts +2 -0
  2. package/dist/esm/applications/applications-context.schemas.d.ts.map +1 -1
  3. package/dist/esm/billing/billing-account.shared.resources-config.schemas.d.ts +1 -1
  4. package/dist/esm/billing/billing-account.shared.resources-config.schemas.d.ts.map +1 -1
  5. package/dist/esm/billing/billing-account.shared.resources-config.schemas.js +36 -0
  6. package/dist/esm/billing/billing-account.shared.resources-config.schemas.js.map +1 -1
  7. package/dist/esm/billing/billing-account.shared.schemas.d.ts.map +1 -1
  8. package/dist/esm/billing/billing-account.shared.schemas.js +8 -1
  9. package/dist/esm/billing/billing-account.shared.schemas.js.map +1 -1
  10. package/dist/esm/billing/billing-types.shared.schemas.d.ts +2 -2
  11. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.d.ts +1 -1
  12. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.d.ts.map +1 -1
  13. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.js +39 -0
  14. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.js.map +1 -1
  15. package/dist/esm/billing/credit-pool.shared.schemas.d.ts +6 -6
  16. package/dist/esm/billing/credit-pool.shared.schemas.d.ts.map +1 -1
  17. package/dist/esm/billing/credit-pool.shared.schemas.js +8 -4
  18. package/dist/esm/billing/credit-pool.shared.schemas.js.map +1 -1
  19. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.d.ts +1 -1
  20. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.d.ts.map +1 -1
  21. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.js +35 -0
  22. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.js.map +1 -1
  23. package/dist/esm/billing/invoice-ref.shared.schemas.d.ts.map +1 -1
  24. package/dist/esm/billing/invoice-ref.shared.schemas.js +8 -3
  25. package/dist/esm/billing/invoice-ref.shared.schemas.js.map +1 -1
  26. package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts +1 -1
  27. package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts.map +1 -1
  28. package/dist/esm/billing/subscription.shared.resources-config.schemas.js +39 -0
  29. package/dist/esm/billing/subscription.shared.resources-config.schemas.js.map +1 -1
  30. package/dist/esm/billing/subscription.shared.schemas.d.ts +4 -4
  31. package/dist/esm/billing/subscription.shared.schemas.d.ts.map +1 -1
  32. package/dist/esm/billing/subscription.shared.schemas.js +6 -2
  33. package/dist/esm/billing/subscription.shared.schemas.js.map +1 -1
  34. package/dist/esm/billing/usage-record.shared.resources-config.schemas.d.ts +1 -1
  35. package/dist/esm/billing/usage-record.shared.resources-config.schemas.d.ts.map +1 -1
  36. package/dist/esm/billing/usage-record.shared.resources-config.schemas.js +39 -0
  37. package/dist/esm/billing/usage-record.shared.resources-config.schemas.js.map +1 -1
  38. package/dist/esm/billing/usage-record.shared.schemas.d.ts +4 -4
  39. package/dist/esm/billing/usage-record.shared.schemas.d.ts.map +1 -1
  40. package/dist/esm/billing/usage-record.shared.schemas.js +7 -3
  41. package/dist/esm/billing/usage-record.shared.schemas.js.map +1 -1
  42. package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.d.ts.map +1 -1
  43. package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.js +35 -2
  44. package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.js.map +1 -1
  45. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts +61 -0
  46. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts.map +1 -1
  47. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js +58 -0
  48. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js.map +1 -1
  49. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.d.ts.map +1 -1
  50. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js +14 -0
  51. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js.map +1 -1
  52. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts +49 -0
  53. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts.map +1 -1
  54. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js +124 -1
  55. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js.map +1 -1
  56. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts +11 -3
  57. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts.map +1 -1
  58. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js +11 -3
  59. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js.map +1 -1
  60. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts +93 -0
  61. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts.map +1 -0
  62. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js +116 -0
  63. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js.map +1 -0
  64. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts +67 -12
  65. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts.map +1 -1
  66. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js +95 -8
  67. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js.map +1 -1
  68. package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts +21 -1
  69. package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts.map +1 -1
  70. package/dist/esm/compliance/privacy/redaction.shared.schemas.js +20 -0
  71. package/dist/esm/compliance/privacy/redaction.shared.schemas.js.map +1 -1
  72. package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts +2 -0
  73. package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts.map +1 -1
  74. package/dist/esm/config/app-configuration-shared.shared.schemas.js +29 -0
  75. package/dist/esm/config/app-configuration-shared.shared.schemas.js.map +1 -1
  76. package/dist/esm/config/frontend/navigation.shared.schemas.d.ts +33 -0
  77. package/dist/esm/config/frontend/navigation.shared.schemas.d.ts.map +1 -1
  78. package/dist/esm/config/frontend/navigation.shared.schemas.js +32 -0
  79. package/dist/esm/config/frontend/navigation.shared.schemas.js.map +1 -1
  80. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts +12 -1
  81. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts.map +1 -1
  82. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js +12 -1
  83. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js.map +1 -1
  84. package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts +13 -0
  85. package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts.map +1 -1
  86. package/dist/esm/external-data/external-data-pipeline.shared.schemas.js.map +1 -1
  87. package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts +6 -6
  88. package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts.map +1 -1
  89. package/dist/esm/external-providers/engine-capabilities.shared.schemas.js +26 -6
  90. package/dist/esm/external-providers/engine-capabilities.shared.schemas.js.map +1 -1
  91. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.d.ts.map +1 -1
  92. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js +0 -2
  93. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js.map +1 -1
  94. package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts +1 -0
  95. package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts.map +1 -1
  96. package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts +4 -3
  97. package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts.map +1 -1
  98. package/dist/esm/external-providers/provider-capability.shared.schemas.js +4 -3
  99. package/dist/esm/external-providers/provider-capability.shared.schemas.js.map +1 -1
  100. package/dist/esm/features/user-features.shared.resources-config.schemas.d.ts +1 -1
  101. package/dist/esm/features/user-features.shared.resources-config.schemas.d.ts.map +1 -1
  102. package/dist/esm/features/user-features.shared.resources-config.schemas.js +48 -0
  103. package/dist/esm/features/user-features.shared.resources-config.schemas.js.map +1 -1
  104. package/dist/esm/files/file-upload-grant.shared.schemas.d.ts +144 -0
  105. package/dist/esm/files/file-upload-grant.shared.schemas.d.ts.map +1 -0
  106. package/dist/esm/files/file-upload-grant.shared.schemas.js +136 -0
  107. package/dist/esm/files/file-upload-grant.shared.schemas.js.map +1 -0
  108. package/dist/esm/files/files.shared.schemas.d.ts +45 -4
  109. package/dist/esm/files/files.shared.schemas.d.ts.map +1 -1
  110. package/dist/esm/files/files.shared.schemas.js +48 -4
  111. package/dist/esm/files/files.shared.schemas.js.map +1 -1
  112. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.d.ts +1 -1
  113. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.d.ts.map +1 -1
  114. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.js +33 -0
  115. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.js.map +1 -1
  116. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.d.ts.map +1 -1
  117. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.js +6 -2
  118. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.js.map +1 -1
  119. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.d.ts +1 -1
  120. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.d.ts.map +1 -1
  121. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.js +53 -0
  122. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.js.map +1 -1
  123. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.d.ts +1 -1
  124. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.d.ts.map +1 -1
  125. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.js +43 -0
  126. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.js.map +1 -1
  127. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.d.ts.map +1 -1
  128. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js +8 -3
  129. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js.map +1 -1
  130. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.d.ts +1 -1
  131. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.d.ts.map +1 -1
  132. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.js +41 -0
  133. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.js.map +1 -1
  134. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.d.ts +0 -7
  135. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.d.ts.map +1 -1
  136. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.js +23 -13
  137. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.js.map +1 -1
  138. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.d.ts +1 -1
  139. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.d.ts.map +1 -1
  140. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.js +51 -0
  141. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.js.map +1 -1
  142. package/dist/esm/guidance/guidance-state.shared.schemas.d.ts.map +1 -1
  143. package/dist/esm/guidance/guidance-state.shared.schemas.js +8 -2
  144. package/dist/esm/guidance/guidance-state.shared.schemas.js.map +1 -1
  145. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.d.ts +1 -1
  146. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.d.ts.map +1 -1
  147. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.js +51 -0
  148. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.js.map +1 -1
  149. package/dist/esm/guidance/lifecycle-state.shared.schemas.d.ts.map +1 -1
  150. package/dist/esm/guidance/lifecycle-state.shared.schemas.js +28 -3
  151. package/dist/esm/guidance/lifecycle-state.shared.schemas.js.map +1 -1
  152. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts +1 -1
  153. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts.map +1 -1
  154. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.js +51 -0
  155. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.js.map +1 -1
  156. package/dist/esm/guidance/progression-state.shared.schemas.d.ts.map +1 -1
  157. package/dist/esm/guidance/progression-state.shared.schemas.js +18 -4
  158. package/dist/esm/guidance/progression-state.shared.schemas.js.map +1 -1
  159. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts +37 -3
  160. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts.map +1 -1
  161. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js +29 -3
  162. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js.map +1 -1
  163. package/dist/esm/index.d.ts +6 -0
  164. package/dist/esm/index.d.ts.map +1 -1
  165. package/dist/esm/index.js +6 -0
  166. package/dist/esm/index.js.map +1 -1
  167. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts +70 -0
  168. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts.map +1 -0
  169. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js +71 -0
  170. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js.map +1 -0
  171. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.d.ts +1 -1
  172. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.d.ts.map +1 -1
  173. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.js +36 -0
  174. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.js.map +1 -1
  175. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts +1 -1
  176. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts.map +1 -1
  177. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.js +44 -0
  178. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.js.map +1 -1
  179. package/dist/esm/organizations/organization-members.shared.schemas.d.ts.map +1 -1
  180. package/dist/esm/organizations/organization-members.shared.schemas.js +15 -4
  181. package/dist/esm/organizations/organization-members.shared.schemas.js.map +1 -1
  182. package/dist/esm/organizations/organizations.shared.resources-config.schemas.d.ts.map +1 -1
  183. package/dist/esm/organizations/organizations.shared.resources-config.schemas.js +18 -10
  184. package/dist/esm/organizations/organizations.shared.resources-config.schemas.js.map +1 -1
  185. package/dist/esm/queue/jobs.shared.resources-config.schemas.d.ts.map +1 -1
  186. package/dist/esm/queue/jobs.shared.resources-config.schemas.js +17 -0
  187. package/dist/esm/queue/jobs.shared.resources-config.schemas.js.map +1 -1
  188. package/dist/esm/requests/websocket.shared.schemas.d.ts +59 -0
  189. package/dist/esm/requests/websocket.shared.schemas.d.ts.map +1 -1
  190. package/dist/esm/requests/websocket.shared.schemas.js +103 -0
  191. package/dist/esm/requests/websocket.shared.schemas.js.map +1 -1
  192. package/dist/esm/resources/collection-query-parameters.shared.d.ts +22 -0
  193. package/dist/esm/resources/collection-query-parameters.shared.d.ts.map +1 -0
  194. package/dist/esm/resources/collection-query-parameters.shared.js +22 -0
  195. package/dist/esm/resources/collection-query-parameters.shared.js.map +1 -0
  196. package/dist/esm/resources/resources-config.shared.factory.d.ts.map +1 -1
  197. package/dist/esm/resources/resources-config.shared.factory.js +86 -13
  198. package/dist/esm/resources/resources-config.shared.factory.js.map +1 -1
  199. package/dist/esm/resources/resources-config.shared.schemas.d.ts +162 -41
  200. package/dist/esm/resources/resources-config.shared.schemas.d.ts.map +1 -1
  201. package/dist/esm/resources/resources-config.shared.schemas.js +109 -20
  202. package/dist/esm/resources/resources-config.shared.schemas.js.map +1 -1
  203. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.d.ts.map +1 -1
  204. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js +21 -6
  205. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js.map +1 -1
  206. package/dist/esm/security/authentications/authentication.shared.schemas.d.ts +57 -0
  207. package/dist/esm/security/authentications/authentication.shared.schemas.d.ts.map +1 -1
  208. package/dist/esm/security/authentications/authentication.shared.schemas.js +64 -0
  209. package/dist/esm/security/authentications/authentication.shared.schemas.js.map +1 -1
  210. package/dist/esm/security/authentications/consumable-token.shared.schemas.d.ts +17 -1
  211. package/dist/esm/security/authentications/consumable-token.shared.schemas.d.ts.map +1 -1
  212. package/dist/esm/security/authentications/consumable-token.shared.schemas.js +16 -0
  213. package/dist/esm/security/authentications/consumable-token.shared.schemas.js.map +1 -1
  214. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts +28 -0
  215. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts.map +1 -0
  216. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js +28 -0
  217. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js.map +1 -0
  218. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts +21 -0
  219. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts.map +1 -0
  220. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js +21 -0
  221. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js.map +1 -0
  222. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts +1 -1
  223. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts.map +1 -1
  224. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js +43 -0
  225. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js.map +1 -1
  226. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts +0 -8
  227. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts.map +1 -1
  228. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js +13 -4
  229. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js.map +1 -1
  230. package/dist/esm/security/authorizations/roles.shared.schemas.d.ts +16 -1
  231. package/dist/esm/security/authorizations/roles.shared.schemas.d.ts.map +1 -1
  232. package/dist/esm/security/authorizations/roles.shared.schemas.js +16 -1
  233. package/dist/esm/security/authorizations/roles.shared.schemas.js.map +1 -1
  234. package/dist/esm/security/authorizations/roles.shared.utils.d.ts +54 -0
  235. package/dist/esm/security/authorizations/roles.shared.utils.d.ts.map +1 -1
  236. package/dist/esm/security/authorizations/roles.shared.utils.js +59 -0
  237. package/dist/esm/security/authorizations/roles.shared.utils.js.map +1 -1
  238. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts +61 -0
  239. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts.map +1 -1
  240. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js +13 -1
  241. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js.map +1 -1
  242. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.d.ts +1 -1
  243. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.d.ts.map +1 -1
  244. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.js +35 -0
  245. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.js.map +1 -1
  246. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.d.ts.map +1 -1
  247. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js +7 -1
  248. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js.map +1 -1
  249. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.d.ts +1 -1
  250. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.d.ts.map +1 -1
  251. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.js +34 -0
  252. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.js.map +1 -1
  253. package/dist/esm/users/inbound-contacts.shared.schemas.d.ts.map +1 -1
  254. package/dist/esm/users/inbound-contacts.shared.schemas.js +7 -4
  255. package/dist/esm/users/inbound-contacts.shared.schemas.js.map +1 -1
  256. package/dist/esm/users/user-credentials.shared.resources-config.schemas.d.ts +1 -1
  257. package/dist/esm/users/user-credentials.shared.resources-config.schemas.d.ts.map +1 -1
  258. package/dist/esm/users/user-credentials.shared.resources-config.schemas.js +37 -0
  259. package/dist/esm/users/user-credentials.shared.resources-config.schemas.js.map +1 -1
  260. package/dist/esm/users/user-credentials.shared.schemas.d.ts.map +1 -1
  261. package/dist/esm/users/user-credentials.shared.schemas.js +17 -2
  262. package/dist/esm/users/user-credentials.shared.schemas.js.map +1 -1
  263. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.d.ts +1 -1
  264. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.d.ts.map +1 -1
  265. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.js +36 -0
  266. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.js.map +1 -1
  267. package/dist/esm/users/user-identity-links.shared.schemas.d.ts.map +1 -1
  268. package/dist/esm/users/user-identity-links.shared.schemas.js +15 -5
  269. package/dist/esm/users/user-identity-links.shared.schemas.js.map +1 -1
  270. package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts +1 -1
  271. package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts.map +1 -1
  272. package/dist/esm/users/user-preferences.shared.resources-config.schemas.js +53 -0
  273. package/dist/esm/users/user-preferences.shared.resources-config.schemas.js.map +1 -1
  274. package/dist/esm/users/user-profiles.shared.resources-config.schemas.d.ts +1 -1
  275. package/dist/esm/users/user-profiles.shared.resources-config.schemas.d.ts.map +1 -1
  276. package/dist/esm/users/user-profiles.shared.resources-config.schemas.js +62 -0
  277. package/dist/esm/users/user-profiles.shared.resources-config.schemas.js.map +1 -1
  278. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts +1 -1
  279. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts.map +1 -1
  280. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.js +53 -0
  281. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.js.map +1 -1
  282. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.d.ts +1 -1
  283. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.d.ts.map +1 -1
  284. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.js +62 -0
  285. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.js.map +1 -1
  286. package/dist/esm/users/users.shared.schemas.d.ts +19 -0
  287. package/dist/esm/users/users.shared.schemas.d.ts.map +1 -1
  288. package/dist/esm/users/users.shared.schemas.js +41 -16
  289. package/dist/esm/users/users.shared.schemas.js.map +1 -1
  290. package/dist/tsconfig.build.tsbuildinfo +1 -1
  291. package/package.json +5 -6
  292. package/dist/esm/.builder.pid +0 -9
@@ -15,6 +15,7 @@ import { createResourceConfiguration_Initialization } from '../resources/resourc
15
15
  import { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas.js';
16
16
  import { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas.js';
17
17
  import { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas.js';
18
+ import { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas.js';
18
19
  export const userProgressionStateResourceConfiguration_InitializationFactory = (resourcesRelationships) => createResourceConfiguration_Initialization({
19
20
  mainSchema: UserProgressionStateSchema,
20
21
  resourceIdentifier: CoreResourceType.USER_PROGRESSION_STATE,
@@ -27,6 +28,28 @@ export const userProgressionStateResourceConfiguration_InitializationFactory = (
27
28
  exportSubject: ResourceSystemAccessMode.ALLOWED, create: ResourceSystemAccessMode.ALLOWED
28
29
  },
29
30
  portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.DERIVED },
31
+ /**
32
+ * Subject erasure RETAINS this row and RESETS the achievement records, operation counters and points total to the schema's own defaults.
33
+ *
34
+ * The USAGE categories on this resource are accurate — these are observations the product made about a
35
+ * named person — so `RETAIN_ONLY` would be a false assertion and the factory refuses it. Until
36
+ * `RedactionType.RESET` existed no treatment could reach these fields at all: they are non-nullable WITH
37
+ * a `.default()`, so REMOVE (needs clearable) and MASK (needs a string) both refuse. RESET returns each
38
+ * to what it is when nobody has set it, which for a behavioural record is exactly what erasure should
39
+ * leave behind.
40
+ *
41
+ * The primary scope FK is preserved — severing it is refused outright, because it would leave the
42
+ * retained row with no tenant anchor, unreachable even to the audited see-through read.
43
+ */
44
+ retentionPolicy: {
45
+ mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,
46
+ },
47
+ /**
48
+ * Erasing one of these rows revokes NO session. The row is state ABOUT a person rather than the person,
49
+ * and its primary scope FK anchors it — the enum prescribes `NO_PRINCIPAL` for that shape. The subject's
50
+ * own session ends through the `USERS` row.
51
+ */
52
+ dataSubjectPolicy: { kind: ResourceDataSubjectKind.NO_PRINCIPAL },
30
53
  coreOperations: [
31
54
  CoreResourceOperation.READ,
32
55
  CoreResourceOperation.SEARCH,
@@ -37,9 +60,37 @@ export const userProgressionStateResourceConfiguration_InitializationFactory = (
37
60
  // when its owning scope is deleted. Without it the cascade throws
38
61
  // ErrorType.CONFIGURATION on any scope that has a materialized row.
39
62
  CoreResourceOperation.DELETE,
63
+ // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY (READ is above).
64
+ CoreResourceOperation.LIST,
65
+ CoreResourceOperation.UPDATE_MANY,
40
66
  ],
41
67
  customOperation: {},
42
68
  operationsConfiguration: {
69
+ /*
70
+
71
+ * Route-less retention plumbing — INTERNAL_CALL registers no route and must not be REPOSITORY_ONLY:
72
+
73
+ * the retention primitives resolve through `getServiceOperationPathDefault`, which matches only
74
+
75
+ * INTERNAL_CALL / API_CALL. UPDATE_MANY is the verb the impersonalize writer uses.
76
+
77
+ */
78
+ [CoreResourceOperation.LIST]: {
79
+ variants: [{
80
+ variantType: ResourceOperationVariantType.INTERNAL_CALL,
81
+ isDefault: true,
82
+ roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
83
+ riskLevel: ResourceOperationRiskLevel.LOW,
84
+ }],
85
+ },
86
+ [CoreResourceOperation.UPDATE_MANY]: {
87
+ variants: [{
88
+ variantType: ResourceOperationVariantType.INTERNAL_CALL,
89
+ isDefault: true,
90
+ roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
91
+ riskLevel: ResourceOperationRiskLevel.CRITICAL,
92
+ }],
93
+ },
43
94
  [CoreResourceOperation.READ]: {
44
95
  variants: [
45
96
  {
@@ -1 +1 @@
1
- {"version":3,"file":"progression-state.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/guidance/progression-state.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Progression State Shared Resource Configurations\n *\n * Resource configurations for dual-scope progression state management (USER / ORGANIZATION).\n * Each scope stores milestone achievement progress, operation counts, and category progress.\n * The shared payload schema stays scope-agnostic, while the schema file also owns\n * the scope-aware persisted variants used by these resource configurations.\n */\n\nimport {\n ProgressionStateSchema,\n UserProgressionStateSchema,\n OrganizationProgressionStateSchema,\n} from './progression-state.shared.schemas';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } from '../resources/resources.shared.schemas';\nimport { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationVariantType } from '../resources/resources.shared.schemas';\nimport { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\nimport { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\n\n// ─── USER PROGRESSION STATE ─────────────────────────────────────────────────────\n\ntype UserProgressionStateCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE;\n\nexport const userProgressionStateResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n UserProgressionStateCoreOperations,\n typeof UserProgressionStateSchema\n>({\n mainSchema: UserProgressionStateSchema,\n resourceIdentifier: CoreResourceType.USER_PROGRESSION_STATE,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_PROGRESSION_STATE],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n // onParentCreate eager-seeding writes through createAsSystem → opt into the\n // fail-closed system-write policy (composition-oncreate-lifecycle plan).\n systemAccessPolicy: {\n exportSubject: ResourceSystemAccessMode.ALLOWED, create: ResourceSystemAccessMode.ALLOWED },\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.DERIVED },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): powers the composition\n // onParentDelete cascade so the self-healing state row is physically removed\n // when its owning scope is deleted. Without it the cascade throws\n // ErrorType.CONFIGURATION on any scope that has a materialized row.\n CoreResourceOperation.DELETE,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: false,\n searchableFields: [],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: [],\n maxPaginatedResultPerPageLimit: 50,\n }],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n // INTERNAL_CALL (not REPOSITORY_ONLY): the onParentCreate seed's\n // `createAsSystem` resolves the CREATE op via the service tier, which\n // rejects REPOSITORY_ONLY → OPERATION_PATH_NOT_FOUND, silent no-seed. See\n // the org-preferences config + composition-oncreate plan for the rationale.\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n // Internal-only (REPOSITORY_ONLY, no HTTP route): powers the composition\n // onParentDelete cascade so this self-healing state row is physically removed\n // when its owning user is deleted. Without a DELETE op the cascade\n // (deleteChildrenImmediate) throws ErrorType.CONFIGURATION on any user that\n // has a materialized row — these rows self-heal on first READ, so most active\n // users have one. Super-admin/HIGH: a privileged teardown, not the APP_USER\n // self-write. See composition-oncreate-lifecycle plan (systemic DELETE gap).\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n },\n});\n\n// ─── ORGANIZATION PROGRESSION STATE ─────────────────────────────────────────────\n\ntype OrganizationProgressionStateCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE;\n\nexport const organizationProgressionStateResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n OrganizationProgressionStateCoreOperations,\n typeof OrganizationProgressionStateSchema\n>({\n mainSchema: OrganizationProgressionStateSchema,\n resourceIdentifier: CoreResourceType.ORGANIZATION_PROGRESSION_STATE,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.ORGANIZATION_PROGRESSION_STATE],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n // onParentCreate eager-seeding writes through createAsSystem → opt into the\n // fail-closed system-write policy (composition-oncreate-lifecycle plan).\n systemAccessPolicy: { create: ResourceSystemAccessMode.ALLOWED },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): powers the composition\n // onParentDelete cascade so the self-healing state row is physically removed\n // when its owning scope is deleted. Without it the cascade throws\n // ErrorType.CONFIGURATION on any scope that has a materialized row.\n CoreResourceOperation.DELETE,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: false,\n searchableFields: [],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: [],\n maxPaginatedResultPerPageLimit: 50,\n }],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n // INTERNAL_CALL (not REPOSITORY_ONLY): the onParentCreate seed's\n // `createAsSystem` resolves the CREATE op via the service tier, which\n // rejects REPOSITORY_ONLY → OPERATION_PATH_NOT_FOUND, silent no-seed. See\n // the org-preferences config + composition-oncreate plan for the rationale.\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n // Internal-only (REPOSITORY_ONLY, no HTTP route): powers the composition\n // onParentDelete cascade so this self-healing state row is physically removed\n // when its owning organization is deleted. Without a DELETE op the cascade\n // (deleteChildrenImmediate) throws ErrorType.CONFIGURATION on any org that has\n // a materialized row — these rows self-heal on first READ, so most active orgs\n // have one. ORG_ADMIN/HIGH: the org-scope admin tier for a privileged teardown\n // (org progression writes are ORG_MEMBER, but teardown is admin-gated).\n // See composition-oncreate-lifecycle plan (systemic DELETE gap).\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n },\n});\n"]}
1
+ {"version":3,"file":"progression-state.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/guidance/progression-state.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Progression State Shared Resource Configurations\n *\n * Resource configurations for dual-scope progression state management (USER / ORGANIZATION).\n * Each scope stores milestone achievement progress, operation counts, and category progress.\n * The shared payload schema stays scope-agnostic, while the schema file also owns\n * the scope-aware persisted variants used by these resource configurations.\n */\n\nimport {\n ProgressionStateSchema,\n UserProgressionStateSchema,\n OrganizationProgressionStateSchema,\n} from './progression-state.shared.schemas';\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } from '../resources/resources.shared.schemas';\nimport { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationVariantType } from '../resources/resources.shared.schemas';\nimport { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\nimport { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\nimport { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas';\n\n// ─── USER PROGRESSION STATE ─────────────────────────────────────────────────────\n\ntype UserProgressionStateCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE\n // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY.\n | CoreResourceOperation.LIST\n | CoreResourceOperation.UPDATE_MANY;\n\nexport const userProgressionStateResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n UserProgressionStateCoreOperations,\n typeof UserProgressionStateSchema\n>({\n mainSchema: UserProgressionStateSchema,\n resourceIdentifier: CoreResourceType.USER_PROGRESSION_STATE,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_PROGRESSION_STATE],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n // onParentCreate eager-seeding writes through createAsSystem → opt into the\n // fail-closed system-write policy (composition-oncreate-lifecycle plan).\n systemAccessPolicy: {\n exportSubject: ResourceSystemAccessMode.ALLOWED, create: ResourceSystemAccessMode.ALLOWED },\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.DERIVED },\n\n /**\n * Subject erasure RETAINS this row and RESETS the achievement records, operation counters and points total to the schema's own defaults.\n *\n * The USAGE categories on this resource are accurate — these are observations the product made about a\n * named person — so `RETAIN_ONLY` would be a false assertion and the factory refuses it. Until\n * `RedactionType.RESET` existed no treatment could reach these fields at all: they are non-nullable WITH\n * a `.default()`, so REMOVE (needs clearable) and MASK (needs a string) both refuse. RESET returns each\n * to what it is when nobody has set it, which for a behavioural record is exactly what erasure should\n * leave behind.\n *\n * The primary scope FK is preserved — severing it is refused outright, because it would leave the\n * retained row with no tenant anchor, unreachable even to the audited see-through read.\n */\n retentionPolicy: {\n mode: ErasureRetentionMode.RETAIN_AND_IMPERSONALIZE,\n },\n\n /**\n * Erasing one of these rows revokes NO session. The row is state ABOUT a person rather than the person,\n * and its primary scope FK anchors it — the enum prescribes `NO_PRINCIPAL` for that shape. The subject's\n * own session ends through the `USERS` row.\n */\n dataSubjectPolicy: { kind: ResourceDataSubjectKind.NO_PRINCIPAL },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): powers the composition\n // onParentDelete cascade so the self-healing state row is physically removed\n // when its owning scope is deleted. Without it the cascade throws\n // ErrorType.CONFIGURATION on any scope that has a materialized row.\n CoreResourceOperation.DELETE,\n // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY (READ is above).\n CoreResourceOperation.LIST,\n CoreResourceOperation.UPDATE_MANY,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n\n /*\n\n * Route-less retention plumbing — INTERNAL_CALL registers no route and must not be REPOSITORY_ONLY:\n\n * the retention primitives resolve through `getServiceOperationPathDefault`, which matches only\n\n * INTERNAL_CALL / API_CALL. UPDATE_MANY is the verb the impersonalize writer uses.\n\n */\n\n [CoreResourceOperation.LIST]: {\n\n variants: [{\n\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n\n isDefault: true,\n\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n\n riskLevel: ResourceOperationRiskLevel.LOW,\n\n }],\n\n },\n\n [CoreResourceOperation.UPDATE_MANY]: {\n\n variants: [{\n\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n\n isDefault: true,\n\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n\n }],\n\n },\n\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: false,\n searchableFields: [],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: [],\n maxPaginatedResultPerPageLimit: 50,\n }],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n // INTERNAL_CALL (not REPOSITORY_ONLY): the onParentCreate seed's\n // `createAsSystem` resolves the CREATE op via the service tier, which\n // rejects REPOSITORY_ONLY → OPERATION_PATH_NOT_FOUND, silent no-seed. See\n // the org-preferences config + composition-oncreate plan for the rationale.\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_USER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n // Internal-only (REPOSITORY_ONLY, no HTTP route): powers the composition\n // onParentDelete cascade so this self-healing state row is physically removed\n // when its owning user is deleted. Without a DELETE op the cascade\n // (deleteChildrenImmediate) throws ErrorType.CONFIGURATION on any user that\n // has a materialized row — these rows self-heal on first READ, so most active\n // users have one. Super-admin/HIGH: a privileged teardown, not the APP_USER\n // self-write. See composition-oncreate-lifecycle plan (systemic DELETE gap).\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n },\n});\n\n// ─── ORGANIZATION PROGRESSION STATE ─────────────────────────────────────────────\n\ntype OrganizationProgressionStateCoreOperations =\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.DELETE;\n\nexport const organizationProgressionStateResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n OrganizationProgressionStateCoreOperations,\n typeof OrganizationProgressionStateSchema\n>({\n mainSchema: OrganizationProgressionStateSchema,\n resourceIdentifier: CoreResourceType.ORGANIZATION_PROGRESSION_STATE,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.ORGANIZATION_PROGRESSION_STATE],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n // onParentCreate eager-seeding writes through createAsSystem → opt into the\n // fail-closed system-write policy (composition-oncreate-lifecycle plan).\n systemAccessPolicy: { create: ResourceSystemAccessMode.ALLOWED },\n\n coreOperations: [\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n CoreResourceOperation.CREATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): powers the composition\n // onParentDelete cascade so the self-healing state row is physically removed\n // when its owning scope is deleted. Without it the cascade throws\n // ErrorType.CONFIGURATION on any scope that has a materialized row.\n CoreResourceOperation.DELETE,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: false,\n searchableFields: [],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: [],\n maxPaginatedResultPerPageLimit: 50,\n }],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n // INTERNAL_CALL (not REPOSITORY_ONLY): the onParentCreate seed's\n // `createAsSystem` resolves the CREATE op via the service tier, which\n // rejects REPOSITORY_ONLY → OPERATION_PATH_NOT_FOUND, silent no-seed. See\n // the org-preferences config + composition-oncreate plan for the rationale.\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ],\n },\n\n // Internal-only (REPOSITORY_ONLY, no HTTP route): powers the composition\n // onParentDelete cascade so this self-healing state row is physically removed\n // when its owning organization is deleted. Without a DELETE op the cascade\n // (deleteChildrenImmediate) throws ErrorType.CONFIGURATION on any org that has\n // a materialized row — these rows self-heal on first READ, so most active orgs\n // have one. ORG_ADMIN/HIGH: the org-scope admin tier for a privileged teardown\n // (org progression writes are ORG_MEMBER, but teardown is admin-gated).\n // See composition-oncreate-lifecycle plan (systemic DELETE gap).\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"progression-state.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/guidance/progression-state.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;oEAEoE;AAEpE,+CAA+C;AAC/C,eAAO,MAAM,kCAAkC;;;iBAK7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAE9F;;oEAEoE;AAEpE,uCAAuC;AACvC,eAAO,MAAM,iCAAiC;;;iBAK5C,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAE5F;;oEAEoE;AAEpE;;wDAEwD;AACxD,eAAO,MAAM,sBAAsB;;;;;;;;;;;iBAYjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,0BAA0B;;;;;;;;;;;;iBAErC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,kCAAkC;;;;;;;;;;;;iBAE7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAE9F,MAAM,MAAM,yBAAyB,GAAG,oBAAoB,GAAG,4BAA4B,CAAC"}
1
+ {"version":3,"file":"progression-state.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/guidance/progression-state.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB;;oEAEoE;AAEpE,+CAA+C;AAC/C,eAAO,MAAM,kCAAkC;;;iBAK7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAE9F;;oEAEoE;AAEpE,uCAAuC;AACvC,eAAO,MAAM,iCAAiC;;;iBAK5C,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAE5F;;oEAEoE;AAEpE;;wDAEwD;AACxD,eAAO,MAAM,sBAAsB;;;;;;;;;;;iBAiCjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,0BAA0B;;;;;;;;;;;;iBAErC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,kCAAkC;;;;;;;;;;;;iBAE7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAE9F,MAAM,MAAM,yBAAyB,GAAG,oBAAoB,GAAG,4BAA4B,CAAC"}
@@ -1,5 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { PersonalDataCategory } from '../compliance/privacy/personal-data-category.shared.schemas.js';
3
+ import { RedactionType } from '../compliance/privacy/redaction.shared.schemas.js';
4
+ import { addImpersonalizeWith } from '@wildo-ai/zod-decorators';
3
5
  /** ──────────────────────────────────────────────────────────────
4
6
  * Progression State — Milestone Achievement Record
5
7
  * ────────────────────────────────────────────────────────────── */
@@ -29,13 +31,25 @@ export const ProgressionCategoryProgressSchema = z.object({
29
31
  export const ProgressionStateSchema = z.object({
30
32
  /** Map of milestoneRef → achievement record. Populated when a milestone is achieved. */
31
33
  // USAGE — a per-person record of what they accomplished and how often they acted.
32
- milestonesAchieved: z.record(z.string(), ProgressionMilestoneAchievedSchema).default({})
33
- .dataCategories(PersonalDataCategory.USAGE),
34
+ // RESET on erasure — returns this field to its schema default. It holds what this person achieved and when,
35
+ // which the category above correctly declares as personal data. RESET rather than REMOVE or MASK
36
+ // because the field is non-nullable WITH a `.default()`: REMOVE needs a clearable field and MASK
37
+ // needs a string. The value comes from the schema, so there is no second copy to drift.
38
+ milestonesAchieved: addImpersonalizeWith(z.record(z.string(), ProgressionMilestoneAchievedSchema).default({})
39
+ .dataCategories(PersonalDataCategory.USAGE), RedactionType.RESET),
34
40
  /** Map of `${resourceType}:${operation}` → count. Incremented on every matching operation.
35
41
  * This is the raw data used by COUNT_THRESHOLD conditions. */
36
- operationCounts: z.record(z.string(), z.number().int()).default({}).dataCategories(PersonalDataCategory.USAGE),
42
+ // RESET on erasure — returns this field to its schema default. It holds how often they performed each operation,
43
+ // which the category above correctly declares as personal data. RESET rather than REMOVE or MASK
44
+ // because the field is non-nullable WITH a `.default()`: REMOVE needs a clearable field and MASK
45
+ // needs a string. The value comes from the schema, so there is no second copy to drift.
46
+ operationCounts: addImpersonalizeWith(z.record(z.string(), z.number().int()).default({}).dataCategories(PersonalDataCategory.USAGE), RedactionType.RESET),
37
47
  /** Total points across all achieved milestones. Updated atomically with achievements. */
38
- totalPoints: z.number().int().default(0).isSummaryField().dataCategories(PersonalDataCategory.USAGE),
48
+ // RESET on erasure — returns this field to its schema default. It holds their points total,
49
+ // which the category above correctly declares as personal data. RESET rather than REMOVE or MASK
50
+ // because the field is non-nullable WITH a `.default()`: REMOVE needs a clearable field and MASK
51
+ // needs a string. The value comes from the schema, so there is no second copy to drift.
52
+ totalPoints: addImpersonalizeWith(z.number().int().default(0).isSummaryField().dataCategories(PersonalDataCategory.USAGE), RedactionType.RESET),
39
53
  /** Per-category progress. Pre-aggregated for frontend display efficiency. */
40
54
  categoriesProgress: z.record(z.string(), ProgressionCategoryProgressSchema).default({}),
41
55
  });
@@ -1 +1 @@
1
- {"version":3,"file":"progression-state.shared.schemas.js","sourceRoot":"","sources":["../../../../src/guidance/progression-state.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,6DAA6D,CAAC;AAEnG;;oEAEoE;AAEpE,+CAA+C;AAC/C,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,CAAC,MAAM,CAAC;IACzD,sCAAsC;IACtC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE;IAC3B,qFAAqF;IACrF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;CACnC,CAAC,CAAC;AAGH;;oEAEoE;AAEpE,uCAAuC;AACvC,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC,CAAC,MAAM,CAAC;IACxD,sDAAsD;IACtD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3C,2CAA2C;IAC3C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;CACzC,CAAC,CAAC;AAGH;;oEAEoE;AAEpE;;wDAEwD;AACxD,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,wFAAwF;IACxF,kFAAkF;IAClF,kBAAkB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,kCAAkC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;SACrF,cAAc,CAAC,oBAAoB,CAAC,KAAK,CAAC;IAC7C;mEAC+D;IAC/D,eAAe,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,oBAAoB,CAAC,KAAK,CAAC;IAC9G,yFAAyF;IACzF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,cAAc,CAAC,oBAAoB,CAAC,KAAK,CAAC;IACpG,6EAA6E;IAC7E,kBAAkB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,iCAAiC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACxF,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,0BAA0B,GAAG,sBAAsB,CAAC,MAAM,CAAC;IACtE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,YAAY,EAAE,CAAC,cAAc,EAAE,CAAC,iBAAiB,EAAE;CAC5F,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,kCAAkC,GAAG,sBAAsB,CAAC,MAAM,CAAC;IAC9E,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,YAAY,EAAE,CAAC,cAAc,EAAE,CAAC,iBAAiB,EAAE;CACpG,CAAC,CAAC","sourcesContent":["import { z } from 'zod';\nimport { PersonalDataCategory } from '../compliance/privacy/personal-data-category.shared.schemas';\n\n/** ──────────────────────────────────────────────────────────────\n * Progression State — Milestone Achievement Record\n * ────────────────────────────────────────────────────────────── */\n\n/** Record of a single milestone achievement */\nexport const ProgressionMilestoneAchievedSchema = z.object({\n /** When the milestone was achieved */\n achievedAt: z.coerce.date(),\n /** How many times the triggering operation occurred (for COUNT_THRESHOLD context) */\n count: z.number().int().default(0),\n});\nexport type ProgressionMilestoneAchieved = z.infer<typeof ProgressionMilestoneAchievedSchema>;\n\n/** ──────────────────────────────────────────────────────────────\n * Progression State — Per-Category Aggregated Progress\n * ────────────────────────────────────────────────────────────── */\n\n/** Per-category aggregated progress */\nexport const ProgressionCategoryProgressSchema = z.object({\n /** Number of milestones completed in this category */\n completedCount: z.number().int().default(0),\n /** Total points earned in this category */\n totalPoints: z.number().int().default(0),\n});\nexport type ProgressionCategoryProgress = z.infer<typeof ProgressionCategoryProgressSchema>;\n\n/** ──────────────────────────────────────────────────────────────\n * Progression State — Top-Level Document\n * ────────────────────────────────────────────────────────────── */\n\n/** Shared progression state payload body.\n * Scope-specific state resources extend this schema with their owning FK\n * (`userId` / `organizationId`) before persistence. */\nexport const ProgressionStateSchema = z.object({\n /** Map of milestoneRef → achievement record. Populated when a milestone is achieved. */\n // USAGE — a per-person record of what they accomplished and how often they acted.\n milestonesAchieved: z.record(z.string(), ProgressionMilestoneAchievedSchema).default({})\n .dataCategories(PersonalDataCategory.USAGE),\n /** Map of `${resourceType}:${operation}` → count. Incremented on every matching operation.\n * This is the raw data used by COUNT_THRESHOLD conditions. */\n operationCounts: z.record(z.string(), z.number().int()).default({}).dataCategories(PersonalDataCategory.USAGE),\n /** Total points across all achieved milestones. Updated atomically with achievements. */\n totalPoints: z.number().int().default(0).isSummaryField().dataCategories(PersonalDataCategory.USAGE),\n /** Per-category progress. Pre-aggregated for frontend display efficiency. */\n categoriesProgress: z.record(z.string(), ProgressionCategoryProgressSchema).default({}),\n});\nexport type ProgressionState = z.infer<typeof ProgressionStateSchema>;\n\nexport const UserProgressionStateSchema = ProgressionStateSchema.extend({\n userId: z.string().min(1).isDBIndexed().isForeignKey().isSummaryField().excludeFromUpdate(),\n});\nexport type UserProgressionState = z.infer<typeof UserProgressionStateSchema>;\n\nexport const OrganizationProgressionStateSchema = ProgressionStateSchema.extend({\n organizationId: z.string().min(1).isDBIndexed().isForeignKey().isSummaryField().excludeFromUpdate(),\n});\nexport type OrganizationProgressionState = z.infer<typeof OrganizationProgressionStateSchema>;\n\nexport type PersistedProgressionState = UserProgressionState | OrganizationProgressionState;\n"]}
1
+ {"version":3,"file":"progression-state.shared.schemas.js","sourceRoot":"","sources":["../../../../src/guidance/progression-state.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport { PersonalDataCategory } from '../compliance/privacy/personal-data-category.shared.schemas';\nimport { RedactionType } from '../compliance/privacy/redaction.shared.schemas';\nimport { addImpersonalizeWith } from '@wildo-ai/zod-decorators';\n\n/** ──────────────────────────────────────────────────────────────\n * Progression State — Milestone Achievement Record\n * ────────────────────────────────────────────────────────────── */\n\n/** Record of a single milestone achievement */\nexport const ProgressionMilestoneAchievedSchema = z.object({\n /** When the milestone was achieved */\n achievedAt: z.coerce.date(),\n /** How many times the triggering operation occurred (for COUNT_THRESHOLD context) */\n count: z.number().int().default(0),\n});\nexport type ProgressionMilestoneAchieved = z.infer<typeof ProgressionMilestoneAchievedSchema>;\n\n/** ──────────────────────────────────────────────────────────────\n * Progression State — Per-Category Aggregated Progress\n * ────────────────────────────────────────────────────────────── */\n\n/** Per-category aggregated progress */\nexport const ProgressionCategoryProgressSchema = z.object({\n /** Number of milestones completed in this category */\n completedCount: z.number().int().default(0),\n /** Total points earned in this category */\n totalPoints: z.number().int().default(0),\n});\nexport type ProgressionCategoryProgress = z.infer<typeof ProgressionCategoryProgressSchema>;\n\n/** ──────────────────────────────────────────────────────────────\n * Progression State — Top-Level Document\n * ────────────────────────────────────────────────────────────── */\n\n/** Shared progression state payload body.\n * Scope-specific state resources extend this schema with their owning FK\n * (`userId` / `organizationId`) before persistence. */\nexport const ProgressionStateSchema = z.object({\n /** Map of milestoneRef → achievement record. Populated when a milestone is achieved. */\n // USAGE — a per-person record of what they accomplished and how often they acted.\n // RESET on erasure — returns this field to its schema default. It holds what this person achieved and when,\n // which the category above correctly declares as personal data. RESET rather than REMOVE or MASK\n // because the field is non-nullable WITH a `.default()`: REMOVE needs a clearable field and MASK\n // needs a string. The value comes from the schema, so there is no second copy to drift.\n milestonesAchieved: addImpersonalizeWith(\n z.record(z.string(), ProgressionMilestoneAchievedSchema).default({})\n .dataCategories(PersonalDataCategory.USAGE),\n RedactionType.RESET,\n ),\n /** Map of `${resourceType}:${operation}` → count. Incremented on every matching operation.\n * This is the raw data used by COUNT_THRESHOLD conditions. */\n // RESET on erasure — returns this field to its schema default. It holds how often they performed each operation,\n // which the category above correctly declares as personal data. RESET rather than REMOVE or MASK\n // because the field is non-nullable WITH a `.default()`: REMOVE needs a clearable field and MASK\n // needs a string. The value comes from the schema, so there is no second copy to drift.\n operationCounts: addImpersonalizeWith(\n z.record(z.string(), z.number().int()).default({}).dataCategories(PersonalDataCategory.USAGE),\n RedactionType.RESET,\n ),\n /** Total points across all achieved milestones. Updated atomically with achievements. */\n // RESET on erasure — returns this field to its schema default. It holds their points total,\n // which the category above correctly declares as personal data. RESET rather than REMOVE or MASK\n // because the field is non-nullable WITH a `.default()`: REMOVE needs a clearable field and MASK\n // needs a string. The value comes from the schema, so there is no second copy to drift.\n totalPoints: addImpersonalizeWith(\n z.number().int().default(0).isSummaryField().dataCategories(PersonalDataCategory.USAGE),\n RedactionType.RESET,\n ),\n /** Per-category progress. Pre-aggregated for frontend display efficiency. */\n categoriesProgress: z.record(z.string(), ProgressionCategoryProgressSchema).default({}),\n});\nexport type ProgressionState = z.infer<typeof ProgressionStateSchema>;\n\nexport const UserProgressionStateSchema = ProgressionStateSchema.extend({\n userId: z.string().min(1).isDBIndexed().isForeignKey().isSummaryField().excludeFromUpdate(),\n});\nexport type UserProgressionState = z.infer<typeof UserProgressionStateSchema>;\n\nexport const OrganizationProgressionStateSchema = ProgressionStateSchema.extend({\n organizationId: z.string().min(1).isDBIndexed().isForeignKey().isSummaryField().excludeFromUpdate(),\n});\nexport type OrganizationProgressionState = z.infer<typeof OrganizationProgressionStateSchema>;\n\nexport type PersistedProgressionState = UserProgressionState | OrganizationProgressionState;\n"]}
@@ -30,9 +30,35 @@ import { z } from 'zod';
30
30
  /** @wildo_source:part:start saas.models.http-api-binding facet:layer:shared facet:audience:app-developer */
31
31
  export declare enum HttpApiTransportDialect {
32
32
  /**
33
- * OData v4 (SAP S/4HANA, Microsoft Dataverse/Dynamics 365): one generic client mechanical
34
- * pushdown of `$filter`/`$select`/`$top`/`$skip`/`$orderby`/`$count`, with a `$metadata`
35
- * boot-time verification probe of the committed declaration.
33
+ * OData **v4** one generic client: mechanical pushdown of
34
+ * `$filter`/`$select`/`$top`/`$skip`/`$orderby`/`$count`, with a `$metadata` boot-time
35
+ * verification probe of the committed declaration.
36
+ *
37
+ * ⚠ **This member is v4 ONLY, and that excludes SAP's most-used API.** An earlier revision of
38
+ * this comment named "SAP S/4HANA, Microsoft Dataverse/Dynamics 365" here, which is half right
39
+ * and was load-bearing — it is why nobody looked:
40
+ *
41
+ * | Target | Version | Consumable today |
42
+ * |---|---|---|
43
+ * | Microsoft Dataverse / Dynamics 365 Web API (`/api/data/v9.2/`) | v4 | ✅ |
44
+ * | SAP S/4HANA OData **v4** services (`/sap/opu/odata4/…`) | v4 | ✅ |
45
+ * | SAP `API_BUSINESS_PARTNER` (`/sap/opu/odata/sap/API_BUSINESS_PARTNER`) | **v2** | ❌ |
46
+ *
47
+ * v2 is not a v4 variant with a different header. Its collection envelope is
48
+ * `{ "d": { "results": [...], "__next": …, "__count": … } }` rather than
49
+ * `{ "value": [...], "@odata.nextLink": … }`; `Edm.DateTime` serializes as `"/Date(<ticks>)/"`
50
+ * rather than ISO 8601; `Edm.Decimal` and `Edm.Int64` serialize as JSON STRINGS rather than
51
+ * numbers; and JSON must be requested (`$format=json`) because v2 defaults to Atom/XML. So it
52
+ * changes the envelope, the paging property, the count property AND the value encoding — a
53
+ * reader written for one cannot read the other, and the mapping layer needs coercions the way
54
+ * Odoo needs `ODOO_FALSE_AS_NULL`.
55
+ * spec-cite: OData Version 2.0 JSON Format
56
+ * (https://www.odata.org/documentation/odata-version-2-0/json-format/) — the `d`/`results`/
57
+ * `__next`/`__count` envelope, the `/Date(<ticks>)/` DateTime literal, and Edm.Decimal /
58
+ * Edm.Int64 "formatted as a JSON string".
59
+ *
60
+ * Supporting v2 is an OPEN decision, not an oversight. Until it lands, point an ODATA binding at
61
+ * a v4 service: for SAP that means the OData v4 edition of the API where one is published.
36
62
  */
37
63
  ODATA = "odata",
38
64
  /**
@@ -555,6 +581,14 @@ export declare const HttpApiResourceBindingSchema: z.ZodDiscriminatedUnion<[z.Zo
555
581
  export declare function assertHttpApiBindingDialectCoherence(binding: HttpApiResourceBinding): void;
556
582
  /** @wildo_source:part:end saas.models.http-api-binding */
557
583
  export type HttpApiResourceBinding = z.infer<typeof HttpApiResourceBindingSchema>;
584
+ /**
585
+ * What an APPLICATION AUTHOR writes — the INPUT shape, so defaulted fields (`verifyMetadataAtBoot`,
586
+ * `identityMode`, the remote-call semantics) are optional to type. Consumers read the parsed shape
587
+ * above. Same split, and same reason, as `ExternalDataPipelineDeclarationAuthored`: a config field
588
+ * typed with the PARSED shape makes every default mandatory for the one person the default exists
589
+ * to serve.
590
+ */
591
+ export type HttpApiResourceBindingAuthored = z.input<typeof HttpApiResourceBindingSchema>;
558
592
  /**
559
593
  * Whether this binding's synthesized `_id` is the single key value VERBATIM (legible ids for
560
594
  * Dataverse GUIDs / Odoo integers) versus the encoded composite form. A STATIC property of the
@@ -1 +1 @@
1
- {"version":3,"file":"http-api-binding.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/http-api-binding/http-api-binding.shared.schemas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http-api-binding.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/http-api-binding/http-api-binding.shared.schemas.ts"],"names":[],"mappings":"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"}
@@ -34,9 +34,35 @@ import { z } from 'zod';
34
34
  export var HttpApiTransportDialect;
35
35
  (function (HttpApiTransportDialect) {
36
36
  /**
37
- * OData v4 (SAP S/4HANA, Microsoft Dataverse/Dynamics 365): one generic client mechanical
38
- * pushdown of `$filter`/`$select`/`$top`/`$skip`/`$orderby`/`$count`, with a `$metadata`
39
- * boot-time verification probe of the committed declaration.
37
+ * OData **v4** one generic client: mechanical pushdown of
38
+ * `$filter`/`$select`/`$top`/`$skip`/`$orderby`/`$count`, with a `$metadata` boot-time
39
+ * verification probe of the committed declaration.
40
+ *
41
+ * ⚠ **This member is v4 ONLY, and that excludes SAP's most-used API.** An earlier revision of
42
+ * this comment named "SAP S/4HANA, Microsoft Dataverse/Dynamics 365" here, which is half right
43
+ * and was load-bearing — it is why nobody looked:
44
+ *
45
+ * | Target | Version | Consumable today |
46
+ * |---|---|---|
47
+ * | Microsoft Dataverse / Dynamics 365 Web API (`/api/data/v9.2/`) | v4 | ✅ |
48
+ * | SAP S/4HANA OData **v4** services (`/sap/opu/odata4/…`) | v4 | ✅ |
49
+ * | SAP `API_BUSINESS_PARTNER` (`/sap/opu/odata/sap/API_BUSINESS_PARTNER`) | **v2** | ❌ |
50
+ *
51
+ * v2 is not a v4 variant with a different header. Its collection envelope is
52
+ * `{ "d": { "results": [...], "__next": …, "__count": … } }` rather than
53
+ * `{ "value": [...], "@odata.nextLink": … }`; `Edm.DateTime` serializes as `"/Date(<ticks>)/"`
54
+ * rather than ISO 8601; `Edm.Decimal` and `Edm.Int64` serialize as JSON STRINGS rather than
55
+ * numbers; and JSON must be requested (`$format=json`) because v2 defaults to Atom/XML. So it
56
+ * changes the envelope, the paging property, the count property AND the value encoding — a
57
+ * reader written for one cannot read the other, and the mapping layer needs coercions the way
58
+ * Odoo needs `ODOO_FALSE_AS_NULL`.
59
+ * spec-cite: OData Version 2.0 JSON Format
60
+ * (https://www.odata.org/documentation/odata-version-2-0/json-format/) — the `d`/`results`/
61
+ * `__next`/`__count` envelope, the `/Date(<ticks>)/` DateTime literal, and Edm.Decimal /
62
+ * Edm.Int64 "formatted as a JSON string".
63
+ *
64
+ * Supporting v2 is an OPEN decision, not an oversight. Until it lands, point an ODATA binding at
65
+ * a v4 service: for SAP that means the OData v4 edition of the API where one is published.
40
66
  */
41
67
  HttpApiTransportDialect["ODATA"] = "odata";
42
68
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"http-api-binding.shared.schemas.js","sourceRoot":"","sources":["../../../../src/http-api-binding/http-api-binding.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * HTTP-API persistence binding — the declaration model for resources whose rows live in a system\n * reached over an authenticated HTTP API (`PersistenceAdapter.HTTP_API`) rather than in a\n * platform-provisioned database.\n *\n * Design source of truth: `.claude/plans/etl-post-repository.md` (decisions D0/D1/D6/D9/D10,\n * requirements R7/R12/R15/R16) plus the two companion papers\n * `.claude/plans/etl-composite-key-synthesis.md` (key declaration + id codec) and\n * `.claude/plans/etl-filter-dialect-scope-down.md` (declared filter/sort/search surface).\n *\n * The binding is a REQUIRED companion declaration on any resource configuration that selects\n * `PersistenceAdapter.HTTP_API`. It answers, statically and per resource:\n * - WHERE the rows live (provider + entity), and in which transport dialect they are queried;\n * - HOW a row is identified (ordered key components → the synthesized engine-facing `_id`);\n * - WHOSE identity reaches the target system (service principal vs per-user delegation);\n * - HOW tenancy confinement is expressed remotely — or the explicit single-tenant stance;\n * - WHAT the erasure story is (all three stances are first-class; none is silently defaulted);\n * - WHICH remote-call semantics apply (timeout, retry, rate budget, id-set bound).\n *\n * Credentials are NEVER declared here. They resolve at runtime through\n * `ExternalProvidersRegistryBackendService` against the `providerRef`, exactly as email, SMS and\n * billing providers do — the binding carries only the reference (plan decision D7).\n */\n\nimport { z } from 'zod';\n\n// --------------------------------\n// Transport dialect\n// --------------------------------\n\n/**\n * The query dialect the adapter speaks toward the target system. Closed vocabulary (slice 1);\n * SOAP is a possible later member over the same HTTP transport, and a direct-database kind would\n * be a NEW `PersistenceAdapter` member, never a dialect here.\n */\n/** @wildo_source:part:start saas.models.http-api-binding facet:layer:shared facet:audience:app-developer */\nexport enum HttpApiTransportDialect {\n /**\n * OData v4 (SAP S/4HANA, Microsoft Dataverse/Dynamics 365): one generic client — mechanical\n * pushdown of `$filter`/`$select`/`$top`/`$skip`/`$orderby`/`$count`, with a `$metadata`\n * boot-time verification probe of the committed declaration.\n */\n ODATA = 'odata',\n\n /**\n * Declared per-binding REST/JSON operation mapping (bespoke enterprise APIs). Unlike ODATA\n * there is no generic client: each binding declares how read/list/count/search map onto\n * concrete HTTP operations.\n */\n REST_JSON = 'rest-json',\n\n /**\n * Odoo's external API (`/jsonrpc` + `execute_kw`). Promoted to its OWN dialect 2026-08-27 —\n * D0's original \"JSON-RPC is a thin envelope variant of REST_JSON\" was corrected by measuring\n * the protocol: it is generic like ODATA (no per-binding operation declarations — the model\n * name IS `entityRef`, and read/list/count map onto `read`/`search_read`/`search_count`\n * mechanically), but it speaks POSITIONAL arguments, its own domain filter language\n * (`[['field','=',value], …]` with polish-notation `'|'` disjunction), and authenticates\n * INSIDE the RPC args (`execute_kw(db, uid, api_key, …)`) rather than via HTTP headers.\n * Forcing that through REST_JSON's declared-parameter model would have been the\n * merge-distinct-concepts failure `design-philosophy.md` forbids.\n *\n * Structural constraint (schema-enforced): exactly ONE key field with the `INTEGER` codec —\n * Odoo row ids are integers, always.\n */\n ODOO_JSONRPC = 'odoo-jsonrpc',\n}\n\n// --------------------------------\n// Identity mode (whose identity reaches the target)\n// --------------------------------\n\n/**\n * Whose identity the adapter presents to the target system. In BOTH modes audit rows carry the\n * REAL initiating user — the shared-principal attribution failure documented for Power Platform\n * (\"credential-sharing as a service\") must not be reproduced (requirement R12).\n *\n * D9 ruling (Paul, 2026-08-27 — re-scoping the original \"both executable in slice 1\"):\n * **SERVICE_PRINCIPAL-first.** `USER_DELEGATED` stays DECLARED and representable so bindings\n * need no reshape when it arrives, but resolving it REFUSES naming the missing substrate: the\n * engine has no outbound per-user token store (measured — `OAuth2_CredentialSchema` is a model\n * with no resource, persistence or service behind it). Building that store is its own workstream.\n */\nexport enum HttpApiIdentityMode {\n /**\n * One service account per binding (never shared across applications — blast-radius doctrine).\n * Wildo's own roles/operations gate who may trigger calls. The default, and the only option\n * when the target has no per-user OAuth surface.\n */\n SERVICE_PRINCIPAL = 'service-principal',\n\n /**\n * Per-user OAuth 2.0 tokens against the target — encrypted, session-bound (the Retool model;\n * on-behalf-of where the IdP is shared, e.g. Entra ID for Dynamics). Use when the TARGET's own\n * authorization must decide per user: the tool can then never show a user more than the target\n * would.\n */\n USER_DELEGATED = 'user-delegated',\n}\n\n// --------------------------------\n// Erasure stance (GDPR Art. 17 on rows we do not own)\n// --------------------------------\n\n/**\n * The declared erasure stance of an HTTP_API-backed resource. All three stances are first-class\n * from slice 1 (decision D6, 2026-08-26); a binding MUST declare one — an undeclared stance is a\n * registration refusal, because `exportSubject` is a fail-closed obligation on every resource and\n * \"we cannot delete rows we do not own\" is not an answer the framework may imply silently.\n */\nexport enum HttpApiErasureStance {\n /**\n * (6a) The resource declares it holds NO personal/subject data. Registration verifies the\n * declaration is coherent (e.g. `exportSubject` posture) and erasure is structurally N/A for\n * the remote rows.\n */\n NO_SUBJECT_DATA = 'no-subject-data',\n\n /**\n * (6b) The binding declares HOW erasure reaches the foreign system: one named API operation the\n * engine invokes on a subject-erasure request. This is a single declared write and does NOT\n * require general write support (slice 1 stays read-only otherwise).\n */\n EXTERNAL_ERASURE_OPERATION = 'external-erasure-operation',\n\n /**\n * (6c) Erasure REFUSES by default; an explicit, per-request, audited controller acknowledgement\n * lets it proceed and records the un-erased remote rows at high severity. Mirrors the existing\n * administrative-floor acknowledgement shape (`administrative-continuity-floors.md`): the record\n * is the control. NEVER a standing default — the acknowledgement is per erasure request.\n */\n CONTROLLER_ACKNOWLEDGED_NON_ERASURE = 'controller-acknowledged-non-erasure',\n}\n\n// --------------------------------\n// Tenancy stance\n// --------------------------------\n\n/**\n * How tenant confinement is enforced against the remote system (requirements R4/R16).\n */\nexport enum HttpApiTenancyStance {\n /**\n * The engine's contextual scope predicate is pushed down into every remote query against a\n * declared remote field. Registration REFUSES a binding whose declared surface cannot express\n * the scope predicate — a query-time refusal would be a data leak one missed branch away.\n */\n SCOPE_FILTER_PUSHDOWN = 'scope-filter-pushdown',\n\n /**\n * The binding declares the target system serves exactly ONE tenant (the normal case for an\n * internal tool on one enterprise's IS). Scope pushdown is then N/A by declaration — an\n * explicit, audited stance, never an inferred one (R16).\n */\n SINGLE_TENANT_BINDING = 'single-tenant-binding',\n}\n\n// --------------------------------\n// Key declaration + component codecs (paper A)\n// --------------------------------\n\n/**\n * Per-component value normalization for key synthesis. The codec is what makes the synthesized\n * `_id` STABLE: every component must round-trip byte-identically between the remote\n * representation and the encoded id, or the same remote row would answer to different ids.\n *\n * `INTEGER` and `GUID` are the two codecs whose entire value space is URL-unreserved-safe, which\n * is what qualifies a single-key binding for the VERBATIM id form (see\n * `httpApiBindingUsesVerbatimKey`).\n */\nexport enum HttpApiKeyComponentCodec {\n /** Arbitrary remote string. NOT charset-safe → always participates via the encoded id form. */\n STRING = 'string',\n\n /** Integer key (Odoo `id`, SAP numeric keys). Digits only → verbatim-eligible. */\n INTEGER = 'integer',\n\n /** GUID/UUID key (Dataverse row ids). Hex + dashes → verbatim-eligible. */\n GUID = 'guid',\n\n /**\n * Date/time key component, normalized to the RFC 3339 / ISO 8601 UTC string form before\n * encoding. NOT verbatim-eligible (`:` is forbidden in ids — websocket room names are\n * colon-parsed).\n */\n DATETIME_ISO = 'datetime-iso',\n}\n/** @wildo_source:part:end saas.models.http-api-binding */\n\n/**\n * One ordered component of the remote entity's key. `keyFields` order is the ENCODING order —\n * declared, committed, and boot-verified against `$metadata` where the dialect provides one;\n * never inferred at runtime (a silently adopted key change would orphan every stored FK value\n * and bookmark).\n */\nexport const HttpApiKeyFieldSchema = z.object({\n /** The field name on the Wildo resource schema that carries this component. */\n localField: z.string().min(1),\n\n /** The remote entity's property name for this component. */\n remoteField: z.string().min(1),\n\n /** Value normalization for stable synthesis. */\n codec: z.enum(HttpApiKeyComponentCodec),\n});\n\nexport type HttpApiKeyField = z.infer<typeof HttpApiKeyFieldSchema>;\n\n// --------------------------------\n// Field mapping\n// --------------------------------\n\n/**\n * Local-to-remote field name mapping for fields whose names differ. Fields not listed map by\n * identity (same name both sides). Key components are declared in `keyFields`, not here.\n */\nexport const HttpApiFieldMappingSchema = z.object({\n localField: z.string().min(1),\n remoteField: z.string().min(1),\n});\n\nexport type HttpApiFieldMapping = z.infer<typeof HttpApiFieldMappingSchema>;\n\n// --------------------------------\n// Remote-call semantics (decision D10 / requirement R15)\n// --------------------------------\n\n/**\n * Declared remote-call semantics. An enterprise API is 100ms–2s, rate-limited, and sometimes\n * down; these are DECISIONS, not inherited pipeline defaults. Defaults are conservative on\n * purpose — a binding that needs more declares more.\n */\nexport const HttpApiRemoteCallSemanticsSchema = z.object({\n /** Per-call timeout. */\n timeoutMs: z.number().int().positive().max(120_000).default(10_000),\n\n /**\n * Retry policy for idempotent READ-family calls only. Writes (when D4 lands) never retry\n * implicitly.\n */\n retry: z\n .object({\n maxAttempts: z.number().int().min(1).max(5).default(2),\n backoffMs: z.number().int().positive().max(30_000).default(500),\n })\n .default({ maxAttempts: 2, backoffMs: 500 }),\n\n /**\n * Rate budget toward the target, per process. `undefined` = no local throttle (the target's own\n * limits still apply and surface as refusals).\n */\n maxRequestsPerMinute: z.number().int().positive().optional(),\n\n /**\n * Upper bound for translated id-set predicates (`_id ∈ {…}` → key-predicate disjunction /\n * `in`). Above the bound the adapter REFUSES rather than emitting an unbounded URL\n * (scope-down paper, shape T2).\n */\n maxIdSetSize: z.number().int().positive().max(500).default(50),\n});\n\nexport type HttpApiRemoteCallSemantics = z.infer<typeof HttpApiRemoteCallSemanticsSchema>;\n\n// --------------------------------\n// Dialect-specific declarations\n// --------------------------------\n\n/**\n * HTTP methods a declared read-family operation may use. Deliberately NOT the full HTTP verb set\n * (`API_HttpMethod` in `@wildo-ai/external-connectors-models` describes provider-protocol\n * operations): slice 1 is read-only, so the closed vocabulary is the read-safe verb plus POST —\n * because JSON-RPC (Odoo) and many enterprise search endpoints are POST-shaped even for reads.\n * Write verbs (PUT/PATCH/DELETE) enter only with the D4 write story, as their own decision.\n */\nexport enum HttpApiRestOperationMethod {\n GET = 'GET',\n POST = 'POST',\n}\n\n/**\n * REST_JSON per-operation declaration: how one read-family member maps onto a concrete HTTP\n * operation. Deliberately minimal in slice 1 — pagination/filter parameter NAMES are declared,\n * their VALUES are supplied by the adapter from the translated query.\n *\n * Related but distinct: `REST_API_OperationSpecSchema` in `@wildo-ai/external-connectors-models`\n * describes provider-protocol operations for capability transformers. This schema describes a\n * RESOURCE read surface; if the two converge later that is a recorded decision, not an implicit\n * merge of distinct concepts.\n */\nexport const HttpApiRestOperationSpecSchema = z.object({\n /** HTTP method for this read-family operation. */\n method: z.enum(HttpApiRestOperationMethod),\n\n /**\n * Path template relative to the provider's base URL. `{key}` interpolates the synthesized\n * key's remote addressing form; other `{param}` tokens must be declared parameter names.\n */\n pathTemplate: z.string().min(1),\n\n /** Query/body parameter names for pagination, when the operation supports it. */\n pagingParams: z\n .object({\n limitParam: z.string().min(1),\n offsetParam: z.string().min(1),\n })\n .optional(),\n\n /**\n * Declared filter parameter name per LOCAL field. Only fields listed here are translatable for\n * this operation (scope-down paper, shape T3); everything else is refused at the adapter\n * boundary.\n */\n filterParams: z.record(z.string().min(1), z.string().min(1)).optional(),\n\n /**\n * The parameter that receives the SEARCH text (T4), for a `search` operation. Absent =\n * search is refused for this binding even when the operation exists.\n */\n searchParam: z.string().min(1).optional(),\n\n /**\n * Dot-path to the payload inside the response body — the rows array (list/search), the entity\n * object (read), or the number (count). Absent = the body IS the payload. Declared, never\n * sniffed: response shapes vary per target (`items`, `result`, `value`, raw array) and a wrong\n * guess would silently read zero rows.\n */\n resultPath: z.string().min(1).optional(),\n\n /** Wrap request/response in a JSON-RPC 2.0 envelope (the Odoo variant). */\n jsonRpcEnvelope: z\n .object({\n rpcMethod: z.string().min(1),\n })\n .optional(),\n});\n\nexport type HttpApiRestOperationSpec = z.infer<typeof HttpApiRestOperationSpecSchema>;\n\n/** The REST_JSON read-surface mapping: which lifecycle members exist remotely, and how. */\nexport const HttpApiRestOperationsSchema = z.object({\n read: HttpApiRestOperationSpecSchema,\n list: HttpApiRestOperationSpecSchema,\n /** Absent = COUNT is refused for this binding (honest refusal, never an emulated scan). */\n count: HttpApiRestOperationSpecSchema.optional(),\n /** Absent = SEARCH is refused for this binding. */\n search: HttpApiRestOperationSpecSchema.optional(),\n});\n\nexport type HttpApiRestOperations = z.infer<typeof HttpApiRestOperationsSchema>;\n\n// --------------------------------\n// Stance sub-declarations\n// --------------------------------\n\n/** Tenancy declaration — discriminated so each stance carries exactly its own obligations. */\nexport const HttpApiTenancyDeclarationSchema = z.discriminatedUnion('stance', [\n z.object({\n stance: z.literal(HttpApiTenancyStance.SCOPE_FILTER_PUSHDOWN),\n /** The remote field the engine's tenant-scope predicate is pushed down against. */\n remoteScopeField: z.string().min(1),\n }),\n z.object({\n stance: z.literal(HttpApiTenancyStance.SINGLE_TENANT_BINDING),\n /** Why this binding is single-tenant — recorded, audited justification (R16). */\n justification: z.string().min(1),\n }),\n]);\n\nexport type HttpApiTenancyDeclaration = z.infer<typeof HttpApiTenancyDeclarationSchema>;\n\n/**\n * HTTP methods a declared EXPLICIT erasure operation (stance 6b, REST_JSON) may use.\n *\n * A separate vocabulary from {@link HttpApiRestOperationMethod} on purpose: that enum describes\n * READ-family operations (GET/POST), and reusing it here would let an erasure declare `GET` — a\n * read spelled as a deletion. Deletion is expressed as the resource-oriented `DELETE` or an\n * RPC-style `POST`; nothing else is a deletion on the wire.\n */\nexport enum HttpApiErasureOperationMethod {\n POST = 'POST',\n DELETE = 'DELETE',\n}\n\n/**\n * The EXPLICIT erasure call a REST_JSON binding declares for stance 6b. Deliberately narrower\n * than {@link HttpApiRestOperationSpecSchema}: an erasure addresses ONE row by key — it has no\n * pagination, no filter params, no search, no result path to project.\n */\nexport const HttpApiErasureOperationSpecSchema = z.object({\n method: z.enum(HttpApiErasureOperationMethod),\n\n /**\n * Path template relative to the provider base URL. `{key}` interpolates the row's remote key\n * addressing form, exactly as in the read-family `pathTemplate`.\n */\n pathTemplate: z.string().min(1),\n\n /**\n * JSON-RPC envelope for RPC-style targets (pairs with `method: POST`), mirroring the\n * read-family declaration.\n */\n jsonRpcEnvelope: z.object({ rpcMethod: z.string().min(1) }).optional(),\n});\n\nexport type HttpApiErasureOperationSpec = z.infer<typeof HttpApiErasureOperationSpecSchema>;\n\n/** Erasure declaration — discriminated; stance 6b names the operation it invokes. */\nexport const HttpApiErasureDeclarationSchema = z.discriminatedUnion('stance', [\n z.object({\n stance: z.literal(HttpApiErasureStance.NO_SUBJECT_DATA),\n }),\n z.object({\n stance: z.literal(HttpApiErasureStance.EXTERNAL_ERASURE_OPERATION),\n /**\n * The declared erasure call. ODATA and ODOO_JSONRPC bindings rely on their CANONICAL delete\n * (`DELETE /EntitySet(key)` / `execute_kw('unlink', [[ids]])`) by declaring\n * `useCanonicalDelete`; REST_JSON bindings declare the operation explicitly. The pairing is\n * enforced by {@link assertHttpApiBindingDialectCoherence}.\n */\n operation: z.union([\n z.object({ useCanonicalDelete: z.literal(true) }),\n HttpApiErasureOperationSpecSchema,\n ]),\n /**\n * The LOCAL field naming the DATA SUBJECT whose erasure deletes a remote row — the rows the\n * declared operation applies to are exactly `{ [subjectLinkLocalField]: <erased subject id> }`.\n *\n * DECLARED, never inferred, for the same reason `dataSubjectPolicy` exists on retention: a\n * foreign key usually names an OWNER or an ACTOR, not the subject — inferring from \"any FK to\n * the erased user\" would delete a purchase-order row because the erased user merely CREATED\n * it, destroying a business record no erasure asked for. One field, mirroring\n * `sessionPrincipalField`'s \"one field names the person\". Registration verifies a declared\n * relationship carries this field as its FK (so the subject type it links is known).\n */\n subjectLinkLocalField: z.string().trim().min(1),\n }),\n z.object({\n stance: z.literal(HttpApiErasureStance.CONTROLLER_ACKNOWLEDGED_NON_ERASURE),\n /**\n * Optional evidence link: the LOCAL field naming the data subject, used ONLY to COUNT the\n * remaining remote rows for the acknowledgement's CRITICAL audit record (`remainingRowCount`).\n * Optional because 6c legitimately covers linkage no FK expresses (an email inside remote\n * rows) — absent, the record carries no count rather than a fabricated zero. Never used to\n * delete anything.\n */\n subjectLinkLocalField: z.string().trim().min(1).optional(),\n }),\n]);\n\nexport type HttpApiErasureDeclaration = z.infer<typeof HttpApiErasureDeclarationSchema>;\n\n// --------------------------------\n// The binding declaration\n// --------------------------------\n\nconst httpApiResourceBindingBaseShape = {\n /**\n * The external provider whose declared protocol configuration carries the base URL and whose\n * credentials resolve through `ExternalProvidersRegistryBackendService` (decision D7 — no new\n * secret store, no connection string on the resource config).\n */\n providerRef: z.string().min(1),\n\n /**\n * The remote entity addressed by this binding — an OData entity-set name, or a logical name for\n * a REST_JSON surface. One binding, one remote entity set.\n */\n entityRef: z.string().min(1),\n\n /** Whose identity reaches the target (D9). */\n identityMode: z.enum(HttpApiIdentityMode).default(HttpApiIdentityMode.SERVICE_PRINCIPAL),\n\n /** Ordered key declaration — the source of the synthesized engine-facing `_id` (paper A). */\n keyFields: z.array(HttpApiKeyFieldSchema).min(1),\n\n /** Non-key field name mappings; unlisted fields map by identity. */\n fieldMappings: z.array(HttpApiFieldMappingSchema).default([]),\n\n /** Tenancy stance (R4/R16). */\n tenancy: HttpApiTenancyDeclarationSchema,\n\n /** Erasure stance (D6) — required; no silent default. */\n erasure: HttpApiErasureDeclarationSchema,\n\n /** Remote-call semantics (D10/R15). */\n remoteCallSemantics: HttpApiRemoteCallSemanticsSchema.default({\n timeoutMs: 10_000,\n retry: { maxAttempts: 2, backoffMs: 500 },\n maxIdSetSize: 50,\n }),\n};\n\n/**\n * The HTTP_API resource binding — discriminated on the transport dialect so each dialect carries\n * exactly its own obligations: ODATA is generic (plus an optional `$metadata` probe opt-out for\n * targets that do not serve one); REST_JSON must declare its whole read surface.\n */\n/** @wildo_source:part:start saas.models.http-api-binding facet:layer:shared facet:audience:app-developer */\nexport const HttpApiResourceBindingSchema = z.discriminatedUnion('dialect', [\n z.object({\n dialect: z.literal(HttpApiTransportDialect.ODATA),\n ...httpApiResourceBindingBaseShape,\n /**\n * Verify the committed declaration against the live `$metadata` at boot (decision D5 —\n * drift is detected at boot and the fix is re-authoring, never silent adaptation). Opt out\n * only for targets that genuinely do not serve `$metadata`.\n */\n verifyMetadataAtBoot: z.boolean().default(true),\n }),\n z.object({\n dialect: z.literal(HttpApiTransportDialect.REST_JSON),\n ...httpApiResourceBindingBaseShape,\n /** The declared read surface — absent members are refused, never emulated. */\n operations: HttpApiRestOperationsSchema,\n }),\n z.object({\n dialect: z.literal(HttpApiTransportDialect.ODOO_JSONRPC),\n ...httpApiResourceBindingBaseShape,\n // Generic like ODATA — no per-binding operation declarations: `entityRef` is the Odoo model\n // (e.g. 'res.partner'); read/list/count map onto read/search_read/search_count mechanically.\n // The single-INTEGER-key constraint is enforced by `assertHttpApiBindingDialectCoherence`\n // (called by the resource-configuration factory) — a refine here would wrap the union member\n // in effects, which discriminated unions do not admit.\n }),\n]);\n\n/**\n * Dialect-specific structural constraints that a discriminated union cannot express member-side.\n * Called by the resource-configuration factory AFTER the schema parse; throws with the offending\n * path named.\n */\nexport function assertHttpApiBindingDialectCoherence(binding: HttpApiResourceBinding): void {\n if (binding.dialect === HttpApiTransportDialect.ODOO_JSONRPC) {\n // Odoo row ids are INTEGERS, always — one key field, INTEGER codec, or the synthesized id\n // could never address a row.\n if (\n binding.keyFields.length !== 1\n || binding.keyFields[0].codec !== HttpApiKeyComponentCodec.INTEGER\n ) {\n throw new Error(\n \"keyFields: an ODOO_JSONRPC binding must declare exactly one key field with the INTEGER codec — Odoo row ids are integers ('id').\",\n );\n }\n }\n\n // D6 stance 6b — the declared erasure operation's FORM is dialect-specific. The union schema\n // admits both forms; only the pairing below is executable, so an incoherent pairing must refuse\n // at authoring rather than on the first subject-erasure request:\n // - ODATA → `useCanonicalDelete` only (the canonical `DELETE /EntitySet(key)`);\n // - ODOO_JSONRPC → `useCanonicalDelete` only (compiles to `execute_kw('unlink', [[ids]])`,\n // Odoo's own canonical delete);\n // - REST_JSON → an explicit operation spec only (there IS no canonical delete to rely on —\n // the binding declares the exact call, like every other REST_JSON operation).\n if (binding.erasure.stance === HttpApiErasureStance.EXTERNAL_ERASURE_OPERATION) {\n const usesCanonicalDelete = 'useCanonicalDelete' in binding.erasure.operation;\n if (binding.dialect === HttpApiTransportDialect.REST_JSON && usesCanonicalDelete) {\n throw new Error(\n 'erasure.operation: a REST_JSON binding has no canonical delete — declare the explicit erasure operation spec (method/path), like its other declared operations.',\n );\n }\n if (binding.dialect !== HttpApiTransportDialect.REST_JSON && !usesCanonicalDelete) {\n throw new Error(\n `erasure.operation: a ${binding.dialect} binding executes erasure through its CANONICAL delete (declare { useCanonicalDelete: true }) — an explicit REST operation spec has no translation on this dialect.`,\n );\n }\n }\n}\n\n/** @wildo_source:part:end saas.models.http-api-binding */\nexport type HttpApiResourceBinding = z.infer<typeof HttpApiResourceBindingSchema>;\n\n// --------------------------------\n// Static binding properties\n// --------------------------------\n\n/**\n * Codecs whose ENTIRE value space stays within the synthesized-id charset law\n * (`^[A-Za-z0-9._~-]+$`, see `http-api-binding-id.shared.utils.ts`). Membership here is what\n * qualifies a single-key binding for the verbatim id form.\n */\nconst VERBATIM_ELIGIBLE_CODECS: readonly HttpApiKeyComponentCodec[] = [\n HttpApiKeyComponentCodec.INTEGER,\n HttpApiKeyComponentCodec.GUID,\n];\n\n/**\n * Whether this binding's synthesized `_id` is the single key value VERBATIM (legible ids for\n * Dataverse GUIDs / Odoo integers) versus the encoded composite form. A STATIC property of the\n * declaration — never sniffed per row — which is what keeps decode unambiguous (paper A).\n */\nexport function httpApiBindingUsesVerbatimKey(\n binding: { keyFields: readonly HttpApiKeyField[] },\n): boolean {\n return (\n binding.keyFields.length === 1\n && VERBATIM_ELIGIBLE_CODECS.includes(binding.keyFields[0].codec)\n );\n}\n"]}
1
+ {"version":3,"file":"http-api-binding.shared.schemas.js","sourceRoot":"","sources":["../../../../src/http-api-binding/http-api-binding.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * HTTP-API persistence binding — the declaration model for resources whose rows live in a system\n * reached over an authenticated HTTP API (`PersistenceAdapter.HTTP_API`) rather than in a\n * platform-provisioned database.\n *\n * Design source of truth: `.claude/plans/etl-post-repository.md` (decisions D0/D1/D6/D9/D10,\n * requirements R7/R12/R15/R16) plus the two companion papers\n * `.claude/plans/etl-composite-key-synthesis.md` (key declaration + id codec) and\n * `.claude/plans/etl-filter-dialect-scope-down.md` (declared filter/sort/search surface).\n *\n * The binding is a REQUIRED companion declaration on any resource configuration that selects\n * `PersistenceAdapter.HTTP_API`. It answers, statically and per resource:\n * - WHERE the rows live (provider + entity), and in which transport dialect they are queried;\n * - HOW a row is identified (ordered key components → the synthesized engine-facing `_id`);\n * - WHOSE identity reaches the target system (service principal vs per-user delegation);\n * - HOW tenancy confinement is expressed remotely — or the explicit single-tenant stance;\n * - WHAT the erasure story is (all three stances are first-class; none is silently defaulted);\n * - WHICH remote-call semantics apply (timeout, retry, rate budget, id-set bound).\n *\n * Credentials are NEVER declared here. They resolve at runtime through\n * `ExternalProvidersRegistryBackendService` against the `providerRef`, exactly as email, SMS and\n * billing providers do — the binding carries only the reference (plan decision D7).\n */\n\nimport { z } from 'zod';\n\n// --------------------------------\n// Transport dialect\n// --------------------------------\n\n/**\n * The query dialect the adapter speaks toward the target system. Closed vocabulary (slice 1);\n * SOAP is a possible later member over the same HTTP transport, and a direct-database kind would\n * be a NEW `PersistenceAdapter` member, never a dialect here.\n */\n/** @wildo_source:part:start saas.models.http-api-binding facet:layer:shared facet:audience:app-developer */\nexport enum HttpApiTransportDialect {\n /**\n * OData **v4** — one generic client: mechanical pushdown of\n * `$filter`/`$select`/`$top`/`$skip`/`$orderby`/`$count`, with a `$metadata` boot-time\n * verification probe of the committed declaration.\n *\n * ⚠ **This member is v4 ONLY, and that excludes SAP's most-used API.** An earlier revision of\n * this comment named \"SAP S/4HANA, Microsoft Dataverse/Dynamics 365\" here, which is half right\n * and was load-bearing — it is why nobody looked:\n *\n * | Target | Version | Consumable today |\n * |---|---|---|\n * | Microsoft Dataverse / Dynamics 365 Web API (`/api/data/v9.2/`) | v4 | ✅ |\n * | SAP S/4HANA OData **v4** services (`/sap/opu/odata4/…`) | v4 | ✅ |\n * | SAP `API_BUSINESS_PARTNER` (`/sap/opu/odata/sap/API_BUSINESS_PARTNER`) | **v2** | ❌ |\n *\n * v2 is not a v4 variant with a different header. Its collection envelope is\n * `{ \"d\": { \"results\": [...], \"__next\": …, \"__count\": … } }` rather than\n * `{ \"value\": [...], \"@odata.nextLink\": … }`; `Edm.DateTime` serializes as `\"/Date(<ticks>)/\"`\n * rather than ISO 8601; `Edm.Decimal` and `Edm.Int64` serialize as JSON STRINGS rather than\n * numbers; and JSON must be requested (`$format=json`) because v2 defaults to Atom/XML. So it\n * changes the envelope, the paging property, the count property AND the value encoding — a\n * reader written for one cannot read the other, and the mapping layer needs coercions the way\n * Odoo needs `ODOO_FALSE_AS_NULL`.\n * spec-cite: OData Version 2.0 JSON Format\n * (https://www.odata.org/documentation/odata-version-2-0/json-format/) — the `d`/`results`/\n * `__next`/`__count` envelope, the `/Date(<ticks>)/` DateTime literal, and Edm.Decimal /\n * Edm.Int64 \"formatted as a JSON string\".\n *\n * Supporting v2 is an OPEN decision, not an oversight. Until it lands, point an ODATA binding at\n * a v4 service: for SAP that means the OData v4 edition of the API where one is published.\n */\n ODATA = 'odata',\n\n /**\n * Declared per-binding REST/JSON operation mapping (bespoke enterprise APIs). Unlike ODATA\n * there is no generic client: each binding declares how read/list/count/search map onto\n * concrete HTTP operations.\n */\n REST_JSON = 'rest-json',\n\n /**\n * Odoo's external API (`/jsonrpc` + `execute_kw`). Promoted to its OWN dialect 2026-08-27 —\n * D0's original \"JSON-RPC is a thin envelope variant of REST_JSON\" was corrected by measuring\n * the protocol: it is generic like ODATA (no per-binding operation declarations — the model\n * name IS `entityRef`, and read/list/count map onto `read`/`search_read`/`search_count`\n * mechanically), but it speaks POSITIONAL arguments, its own domain filter language\n * (`[['field','=',value], …]` with polish-notation `'|'` disjunction), and authenticates\n * INSIDE the RPC args (`execute_kw(db, uid, api_key, …)`) rather than via HTTP headers.\n * Forcing that through REST_JSON's declared-parameter model would have been the\n * merge-distinct-concepts failure `design-philosophy.md` forbids.\n *\n * Structural constraint (schema-enforced): exactly ONE key field with the `INTEGER` codec —\n * Odoo row ids are integers, always.\n */\n ODOO_JSONRPC = 'odoo-jsonrpc',\n}\n\n// --------------------------------\n// Identity mode (whose identity reaches the target)\n// --------------------------------\n\n/**\n * Whose identity the adapter presents to the target system. In BOTH modes audit rows carry the\n * REAL initiating user — the shared-principal attribution failure documented for Power Platform\n * (\"credential-sharing as a service\") must not be reproduced (requirement R12).\n *\n * D9 ruling (Paul, 2026-08-27 — re-scoping the original \"both executable in slice 1\"):\n * **SERVICE_PRINCIPAL-first.** `USER_DELEGATED` stays DECLARED and representable so bindings\n * need no reshape when it arrives, but resolving it REFUSES naming the missing substrate: the\n * engine has no outbound per-user token store (measured — `OAuth2_CredentialSchema` is a model\n * with no resource, persistence or service behind it). Building that store is its own workstream.\n */\nexport enum HttpApiIdentityMode {\n /**\n * One service account per binding (never shared across applications — blast-radius doctrine).\n * Wildo's own roles/operations gate who may trigger calls. The default, and the only option\n * when the target has no per-user OAuth surface.\n */\n SERVICE_PRINCIPAL = 'service-principal',\n\n /**\n * Per-user OAuth 2.0 tokens against the target — encrypted, session-bound (the Retool model;\n * on-behalf-of where the IdP is shared, e.g. Entra ID for Dynamics). Use when the TARGET's own\n * authorization must decide per user: the tool can then never show a user more than the target\n * would.\n */\n USER_DELEGATED = 'user-delegated',\n}\n\n// --------------------------------\n// Erasure stance (GDPR Art. 17 on rows we do not own)\n// --------------------------------\n\n/**\n * The declared erasure stance of an HTTP_API-backed resource. All three stances are first-class\n * from slice 1 (decision D6, 2026-08-26); a binding MUST declare one — an undeclared stance is a\n * registration refusal, because `exportSubject` is a fail-closed obligation on every resource and\n * \"we cannot delete rows we do not own\" is not an answer the framework may imply silently.\n */\nexport enum HttpApiErasureStance {\n /**\n * (6a) The resource declares it holds NO personal/subject data. Registration verifies the\n * declaration is coherent (e.g. `exportSubject` posture) and erasure is structurally N/A for\n * the remote rows.\n */\n NO_SUBJECT_DATA = 'no-subject-data',\n\n /**\n * (6b) The binding declares HOW erasure reaches the foreign system: one named API operation the\n * engine invokes on a subject-erasure request. This is a single declared write and does NOT\n * require general write support (slice 1 stays read-only otherwise).\n */\n EXTERNAL_ERASURE_OPERATION = 'external-erasure-operation',\n\n /**\n * (6c) Erasure REFUSES by default; an explicit, per-request, audited controller acknowledgement\n * lets it proceed and records the un-erased remote rows at high severity. Mirrors the existing\n * administrative-floor acknowledgement shape (`administrative-continuity-floors.md`): the record\n * is the control. NEVER a standing default — the acknowledgement is per erasure request.\n */\n CONTROLLER_ACKNOWLEDGED_NON_ERASURE = 'controller-acknowledged-non-erasure',\n}\n\n// --------------------------------\n// Tenancy stance\n// --------------------------------\n\n/**\n * How tenant confinement is enforced against the remote system (requirements R4/R16).\n */\nexport enum HttpApiTenancyStance {\n /**\n * The engine's contextual scope predicate is pushed down into every remote query against a\n * declared remote field. Registration REFUSES a binding whose declared surface cannot express\n * the scope predicate — a query-time refusal would be a data leak one missed branch away.\n */\n SCOPE_FILTER_PUSHDOWN = 'scope-filter-pushdown',\n\n /**\n * The binding declares the target system serves exactly ONE tenant (the normal case for an\n * internal tool on one enterprise's IS). Scope pushdown is then N/A by declaration — an\n * explicit, audited stance, never an inferred one (R16).\n */\n SINGLE_TENANT_BINDING = 'single-tenant-binding',\n}\n\n// --------------------------------\n// Key declaration + component codecs (paper A)\n// --------------------------------\n\n/**\n * Per-component value normalization for key synthesis. The codec is what makes the synthesized\n * `_id` STABLE: every component must round-trip byte-identically between the remote\n * representation and the encoded id, or the same remote row would answer to different ids.\n *\n * `INTEGER` and `GUID` are the two codecs whose entire value space is URL-unreserved-safe, which\n * is what qualifies a single-key binding for the VERBATIM id form (see\n * `httpApiBindingUsesVerbatimKey`).\n */\nexport enum HttpApiKeyComponentCodec {\n /** Arbitrary remote string. NOT charset-safe → always participates via the encoded id form. */\n STRING = 'string',\n\n /** Integer key (Odoo `id`, SAP numeric keys). Digits only → verbatim-eligible. */\n INTEGER = 'integer',\n\n /** GUID/UUID key (Dataverse row ids). Hex + dashes → verbatim-eligible. */\n GUID = 'guid',\n\n /**\n * Date/time key component, normalized to the RFC 3339 / ISO 8601 UTC string form before\n * encoding. NOT verbatim-eligible (`:` is forbidden in ids — websocket room names are\n * colon-parsed).\n */\n DATETIME_ISO = 'datetime-iso',\n}\n/** @wildo_source:part:end saas.models.http-api-binding */\n\n/**\n * One ordered component of the remote entity's key. `keyFields` order is the ENCODING order —\n * declared, committed, and boot-verified against `$metadata` where the dialect provides one;\n * never inferred at runtime (a silently adopted key change would orphan every stored FK value\n * and bookmark).\n */\nexport const HttpApiKeyFieldSchema = z.object({\n /** The field name on the Wildo resource schema that carries this component. */\n localField: z.string().min(1),\n\n /** The remote entity's property name for this component. */\n remoteField: z.string().min(1),\n\n /** Value normalization for stable synthesis. */\n codec: z.enum(HttpApiKeyComponentCodec),\n});\n\nexport type HttpApiKeyField = z.infer<typeof HttpApiKeyFieldSchema>;\n\n// --------------------------------\n// Field mapping\n// --------------------------------\n\n/**\n * Local-to-remote field name mapping for fields whose names differ. Fields not listed map by\n * identity (same name both sides). Key components are declared in `keyFields`, not here.\n */\nexport const HttpApiFieldMappingSchema = z.object({\n localField: z.string().min(1),\n remoteField: z.string().min(1),\n});\n\nexport type HttpApiFieldMapping = z.infer<typeof HttpApiFieldMappingSchema>;\n\n// --------------------------------\n// Remote-call semantics (decision D10 / requirement R15)\n// --------------------------------\n\n/**\n * Declared remote-call semantics. An enterprise API is 100ms–2s, rate-limited, and sometimes\n * down; these are DECISIONS, not inherited pipeline defaults. Defaults are conservative on\n * purpose — a binding that needs more declares more.\n */\nexport const HttpApiRemoteCallSemanticsSchema = z.object({\n /** Per-call timeout. */\n timeoutMs: z.number().int().positive().max(120_000).default(10_000),\n\n /**\n * Retry policy for idempotent READ-family calls only. Writes (when D4 lands) never retry\n * implicitly.\n */\n retry: z\n .object({\n maxAttempts: z.number().int().min(1).max(5).default(2),\n backoffMs: z.number().int().positive().max(30_000).default(500),\n })\n .default({ maxAttempts: 2, backoffMs: 500 }),\n\n /**\n * Rate budget toward the target, per process. `undefined` = no local throttle (the target's own\n * limits still apply and surface as refusals).\n */\n maxRequestsPerMinute: z.number().int().positive().optional(),\n\n /**\n * Upper bound for translated id-set predicates (`_id ∈ {…}` → key-predicate disjunction /\n * `in`). Above the bound the adapter REFUSES rather than emitting an unbounded URL\n * (scope-down paper, shape T2).\n */\n maxIdSetSize: z.number().int().positive().max(500).default(50),\n});\n\nexport type HttpApiRemoteCallSemantics = z.infer<typeof HttpApiRemoteCallSemanticsSchema>;\n\n// --------------------------------\n// Dialect-specific declarations\n// --------------------------------\n\n/**\n * HTTP methods a declared read-family operation may use. Deliberately NOT the full HTTP verb set\n * (`API_HttpMethod` in `@wildo-ai/external-connectors-models` describes provider-protocol\n * operations): slice 1 is read-only, so the closed vocabulary is the read-safe verb plus POST —\n * because JSON-RPC (Odoo) and many enterprise search endpoints are POST-shaped even for reads.\n * Write verbs (PUT/PATCH/DELETE) enter only with the D4 write story, as their own decision.\n */\nexport enum HttpApiRestOperationMethod {\n GET = 'GET',\n POST = 'POST',\n}\n\n/**\n * REST_JSON per-operation declaration: how one read-family member maps onto a concrete HTTP\n * operation. Deliberately minimal in slice 1 — pagination/filter parameter NAMES are declared,\n * their VALUES are supplied by the adapter from the translated query.\n *\n * Related but distinct: `REST_API_OperationSpecSchema` in `@wildo-ai/external-connectors-models`\n * describes provider-protocol operations for capability transformers. This schema describes a\n * RESOURCE read surface; if the two converge later that is a recorded decision, not an implicit\n * merge of distinct concepts.\n */\nexport const HttpApiRestOperationSpecSchema = z.object({\n /** HTTP method for this read-family operation. */\n method: z.enum(HttpApiRestOperationMethod),\n\n /**\n * Path template relative to the provider's base URL. `{key}` interpolates the synthesized\n * key's remote addressing form; other `{param}` tokens must be declared parameter names.\n */\n pathTemplate: z.string().min(1),\n\n /** Query/body parameter names for pagination, when the operation supports it. */\n pagingParams: z\n .object({\n limitParam: z.string().min(1),\n offsetParam: z.string().min(1),\n })\n .optional(),\n\n /**\n * Declared filter parameter name per LOCAL field. Only fields listed here are translatable for\n * this operation (scope-down paper, shape T3); everything else is refused at the adapter\n * boundary.\n */\n filterParams: z.record(z.string().min(1), z.string().min(1)).optional(),\n\n /**\n * The parameter that receives the SEARCH text (T4), for a `search` operation. Absent =\n * search is refused for this binding even when the operation exists.\n */\n searchParam: z.string().min(1).optional(),\n\n /**\n * Dot-path to the payload inside the response body — the rows array (list/search), the entity\n * object (read), or the number (count). Absent = the body IS the payload. Declared, never\n * sniffed: response shapes vary per target (`items`, `result`, `value`, raw array) and a wrong\n * guess would silently read zero rows.\n */\n resultPath: z.string().min(1).optional(),\n\n /** Wrap request/response in a JSON-RPC 2.0 envelope (the Odoo variant). */\n jsonRpcEnvelope: z\n .object({\n rpcMethod: z.string().min(1),\n })\n .optional(),\n});\n\nexport type HttpApiRestOperationSpec = z.infer<typeof HttpApiRestOperationSpecSchema>;\n\n/** The REST_JSON read-surface mapping: which lifecycle members exist remotely, and how. */\nexport const HttpApiRestOperationsSchema = z.object({\n read: HttpApiRestOperationSpecSchema,\n list: HttpApiRestOperationSpecSchema,\n /** Absent = COUNT is refused for this binding (honest refusal, never an emulated scan). */\n count: HttpApiRestOperationSpecSchema.optional(),\n /** Absent = SEARCH is refused for this binding. */\n search: HttpApiRestOperationSpecSchema.optional(),\n});\n\nexport type HttpApiRestOperations = z.infer<typeof HttpApiRestOperationsSchema>;\n\n// --------------------------------\n// Stance sub-declarations\n// --------------------------------\n\n/** Tenancy declaration — discriminated so each stance carries exactly its own obligations. */\nexport const HttpApiTenancyDeclarationSchema = z.discriminatedUnion('stance', [\n z.object({\n stance: z.literal(HttpApiTenancyStance.SCOPE_FILTER_PUSHDOWN),\n /** The remote field the engine's tenant-scope predicate is pushed down against. */\n remoteScopeField: z.string().min(1),\n }),\n z.object({\n stance: z.literal(HttpApiTenancyStance.SINGLE_TENANT_BINDING),\n /** Why this binding is single-tenant — recorded, audited justification (R16). */\n justification: z.string().min(1),\n }),\n]);\n\nexport type HttpApiTenancyDeclaration = z.infer<typeof HttpApiTenancyDeclarationSchema>;\n\n/**\n * HTTP methods a declared EXPLICIT erasure operation (stance 6b, REST_JSON) may use.\n *\n * A separate vocabulary from {@link HttpApiRestOperationMethod} on purpose: that enum describes\n * READ-family operations (GET/POST), and reusing it here would let an erasure declare `GET` — a\n * read spelled as a deletion. Deletion is expressed as the resource-oriented `DELETE` or an\n * RPC-style `POST`; nothing else is a deletion on the wire.\n */\nexport enum HttpApiErasureOperationMethod {\n POST = 'POST',\n DELETE = 'DELETE',\n}\n\n/**\n * The EXPLICIT erasure call a REST_JSON binding declares for stance 6b. Deliberately narrower\n * than {@link HttpApiRestOperationSpecSchema}: an erasure addresses ONE row by key — it has no\n * pagination, no filter params, no search, no result path to project.\n */\nexport const HttpApiErasureOperationSpecSchema = z.object({\n method: z.enum(HttpApiErasureOperationMethod),\n\n /**\n * Path template relative to the provider base URL. `{key}` interpolates the row's remote key\n * addressing form, exactly as in the read-family `pathTemplate`.\n */\n pathTemplate: z.string().min(1),\n\n /**\n * JSON-RPC envelope for RPC-style targets (pairs with `method: POST`), mirroring the\n * read-family declaration.\n */\n jsonRpcEnvelope: z.object({ rpcMethod: z.string().min(1) }).optional(),\n});\n\nexport type HttpApiErasureOperationSpec = z.infer<typeof HttpApiErasureOperationSpecSchema>;\n\n/** Erasure declaration — discriminated; stance 6b names the operation it invokes. */\nexport const HttpApiErasureDeclarationSchema = z.discriminatedUnion('stance', [\n z.object({\n stance: z.literal(HttpApiErasureStance.NO_SUBJECT_DATA),\n }),\n z.object({\n stance: z.literal(HttpApiErasureStance.EXTERNAL_ERASURE_OPERATION),\n /**\n * The declared erasure call. ODATA and ODOO_JSONRPC bindings rely on their CANONICAL delete\n * (`DELETE /EntitySet(key)` / `execute_kw('unlink', [[ids]])`) by declaring\n * `useCanonicalDelete`; REST_JSON bindings declare the operation explicitly. The pairing is\n * enforced by {@link assertHttpApiBindingDialectCoherence}.\n */\n operation: z.union([\n z.object({ useCanonicalDelete: z.literal(true) }),\n HttpApiErasureOperationSpecSchema,\n ]),\n /**\n * The LOCAL field naming the DATA SUBJECT whose erasure deletes a remote row — the rows the\n * declared operation applies to are exactly `{ [subjectLinkLocalField]: <erased subject id> }`.\n *\n * DECLARED, never inferred, for the same reason `dataSubjectPolicy` exists on retention: a\n * foreign key usually names an OWNER or an ACTOR, not the subject — inferring from \"any FK to\n * the erased user\" would delete a purchase-order row because the erased user merely CREATED\n * it, destroying a business record no erasure asked for. One field, mirroring\n * `sessionPrincipalField`'s \"one field names the person\". Registration verifies a declared\n * relationship carries this field as its FK (so the subject type it links is known).\n */\n subjectLinkLocalField: z.string().trim().min(1),\n }),\n z.object({\n stance: z.literal(HttpApiErasureStance.CONTROLLER_ACKNOWLEDGED_NON_ERASURE),\n /**\n * Optional evidence link: the LOCAL field naming the data subject, used ONLY to COUNT the\n * remaining remote rows for the acknowledgement's CRITICAL audit record (`remainingRowCount`).\n * Optional because 6c legitimately covers linkage no FK expresses (an email inside remote\n * rows) — absent, the record carries no count rather than a fabricated zero. Never used to\n * delete anything.\n */\n subjectLinkLocalField: z.string().trim().min(1).optional(),\n }),\n]);\n\nexport type HttpApiErasureDeclaration = z.infer<typeof HttpApiErasureDeclarationSchema>;\n\n// --------------------------------\n// The binding declaration\n// --------------------------------\n\nconst httpApiResourceBindingBaseShape = {\n /**\n * The external provider whose declared protocol configuration carries the base URL and whose\n * credentials resolve through `ExternalProvidersRegistryBackendService` (decision D7 — no new\n * secret store, no connection string on the resource config).\n */\n providerRef: z.string().min(1),\n\n /**\n * The remote entity addressed by this binding — an OData entity-set name, or a logical name for\n * a REST_JSON surface. One binding, one remote entity set.\n */\n entityRef: z.string().min(1),\n\n /** Whose identity reaches the target (D9). */\n identityMode: z.enum(HttpApiIdentityMode).default(HttpApiIdentityMode.SERVICE_PRINCIPAL),\n\n /** Ordered key declaration — the source of the synthesized engine-facing `_id` (paper A). */\n keyFields: z.array(HttpApiKeyFieldSchema).min(1),\n\n /** Non-key field name mappings; unlisted fields map by identity. */\n fieldMappings: z.array(HttpApiFieldMappingSchema).default([]),\n\n /** Tenancy stance (R4/R16). */\n tenancy: HttpApiTenancyDeclarationSchema,\n\n /** Erasure stance (D6) — required; no silent default. */\n erasure: HttpApiErasureDeclarationSchema,\n\n /** Remote-call semantics (D10/R15). */\n remoteCallSemantics: HttpApiRemoteCallSemanticsSchema.default({\n timeoutMs: 10_000,\n retry: { maxAttempts: 2, backoffMs: 500 },\n maxIdSetSize: 50,\n }),\n};\n\n/**\n * The HTTP_API resource binding — discriminated on the transport dialect so each dialect carries\n * exactly its own obligations: ODATA is generic (plus an optional `$metadata` probe opt-out for\n * targets that do not serve one); REST_JSON must declare its whole read surface.\n */\n/** @wildo_source:part:start saas.models.http-api-binding facet:layer:shared facet:audience:app-developer */\nexport const HttpApiResourceBindingSchema = z.discriminatedUnion('dialect', [\n z.object({\n dialect: z.literal(HttpApiTransportDialect.ODATA),\n ...httpApiResourceBindingBaseShape,\n /**\n * Verify the committed declaration against the live `$metadata` at boot (decision D5 —\n * drift is detected at boot and the fix is re-authoring, never silent adaptation). Opt out\n * only for targets that genuinely do not serve `$metadata`.\n */\n verifyMetadataAtBoot: z.boolean().default(true),\n }),\n z.object({\n dialect: z.literal(HttpApiTransportDialect.REST_JSON),\n ...httpApiResourceBindingBaseShape,\n /** The declared read surface — absent members are refused, never emulated. */\n operations: HttpApiRestOperationsSchema,\n }),\n z.object({\n dialect: z.literal(HttpApiTransportDialect.ODOO_JSONRPC),\n ...httpApiResourceBindingBaseShape,\n // Generic like ODATA — no per-binding operation declarations: `entityRef` is the Odoo model\n // (e.g. 'res.partner'); read/list/count map onto read/search_read/search_count mechanically.\n // The single-INTEGER-key constraint is enforced by `assertHttpApiBindingDialectCoherence`\n // (called by the resource-configuration factory) — a refine here would wrap the union member\n // in effects, which discriminated unions do not admit.\n }),\n]);\n\n/**\n * Dialect-specific structural constraints that a discriminated union cannot express member-side.\n * Called by the resource-configuration factory AFTER the schema parse; throws with the offending\n * path named.\n */\nexport function assertHttpApiBindingDialectCoherence(binding: HttpApiResourceBinding): void {\n if (binding.dialect === HttpApiTransportDialect.ODOO_JSONRPC) {\n // Odoo row ids are INTEGERS, always — one key field, INTEGER codec, or the synthesized id\n // could never address a row.\n if (\n binding.keyFields.length !== 1\n || binding.keyFields[0].codec !== HttpApiKeyComponentCodec.INTEGER\n ) {\n throw new Error(\n \"keyFields: an ODOO_JSONRPC binding must declare exactly one key field with the INTEGER codec — Odoo row ids are integers ('id').\",\n );\n }\n }\n\n // D6 stance 6b — the declared erasure operation's FORM is dialect-specific. The union schema\n // admits both forms; only the pairing below is executable, so an incoherent pairing must refuse\n // at authoring rather than on the first subject-erasure request:\n // - ODATA → `useCanonicalDelete` only (the canonical `DELETE /EntitySet(key)`);\n // - ODOO_JSONRPC → `useCanonicalDelete` only (compiles to `execute_kw('unlink', [[ids]])`,\n // Odoo's own canonical delete);\n // - REST_JSON → an explicit operation spec only (there IS no canonical delete to rely on —\n // the binding declares the exact call, like every other REST_JSON operation).\n if (binding.erasure.stance === HttpApiErasureStance.EXTERNAL_ERASURE_OPERATION) {\n const usesCanonicalDelete = 'useCanonicalDelete' in binding.erasure.operation;\n if (binding.dialect === HttpApiTransportDialect.REST_JSON && usesCanonicalDelete) {\n throw new Error(\n 'erasure.operation: a REST_JSON binding has no canonical delete — declare the explicit erasure operation spec (method/path), like its other declared operations.',\n );\n }\n if (binding.dialect !== HttpApiTransportDialect.REST_JSON && !usesCanonicalDelete) {\n throw new Error(\n `erasure.operation: a ${binding.dialect} binding executes erasure through its CANONICAL delete (declare { useCanonicalDelete: true }) — an explicit REST operation spec has no translation on this dialect.`,\n );\n }\n }\n}\n\n/** @wildo_source:part:end saas.models.http-api-binding */\nexport type HttpApiResourceBinding = z.infer<typeof HttpApiResourceBindingSchema>;\n\n/**\n * What an APPLICATION AUTHOR writes — the INPUT shape, so defaulted fields (`verifyMetadataAtBoot`,\n * `identityMode`, the remote-call semantics) are optional to type. Consumers read the parsed shape\n * above. Same split, and same reason, as `ExternalDataPipelineDeclarationAuthored`: a config field\n * typed with the PARSED shape makes every default mandatory for the one person the default exists\n * to serve.\n */\nexport type HttpApiResourceBindingAuthored = z.input<typeof HttpApiResourceBindingSchema>;\n\n// --------------------------------\n// Static binding properties\n// --------------------------------\n\n/**\n * Codecs whose ENTIRE value space stays within the synthesized-id charset law\n * (`^[A-Za-z0-9._~-]+$`, see `http-api-binding-id.shared.utils.ts`). Membership here is what\n * qualifies a single-key binding for the verbatim id form.\n */\nconst VERBATIM_ELIGIBLE_CODECS: readonly HttpApiKeyComponentCodec[] = [\n HttpApiKeyComponentCodec.INTEGER,\n HttpApiKeyComponentCodec.GUID,\n];\n\n/**\n * Whether this binding's synthesized `_id` is the single key value VERBATIM (legible ids for\n * Dataverse GUIDs / Odoo integers) versus the encoded composite form. A STATIC property of the\n * declaration — never sniffed per row — which is what keeps decode unambiguous (paper A).\n */\nexport function httpApiBindingUsesVerbatimKey(\n binding: { keyFields: readonly HttpApiKeyField[] },\n): boolean {\n return (\n binding.keyFields.length === 1\n && VERBATIM_ELIGIBLE_CODECS.includes(binding.keyFields[0].codec)\n );\n}\n"]}
@@ -45,11 +45,13 @@ export * from './errors/zod-issue-formatting.shared.utils';
45
45
  export * from './files/files.shared.schemas';
46
46
  export * from './files/files.shared.utils';
47
47
  export * from './files/files.shared.resources-config.schemas';
48
+ export * from './files/file-upload-grant.shared.schemas';
48
49
  export * from './notifications/notification-badges.core.definitions';
49
50
  export * from './notifications/notification-badges.schemas';
50
51
  export * from './notifications/notification-badges.shared.resources-config.schemas';
51
52
  export * from './notifications/notifications.shared.schemas';
52
53
  export * from './notifications/m2m/webhook-config.shared.schemas';
54
+ export * from './notifications/m2m/m2m-webhook-delivery-contract.shared';
53
55
  export * from './notifications/m2m/webhook-config.shared.resources-config.schemas';
54
56
  export * from './notifications/m2m/m2m-webhook-delivery-log.shared.schemas';
55
57
  export * from './notifications/m2m/m2m-webhook-delivery-log.shared.resources-config.schemas';
@@ -68,6 +70,7 @@ export * from './resources/relationship-display.shared.schemas';
68
70
  export * from './resources/resources.shared.utils';
69
71
  export * from './resources/resources-config.shared.factory';
70
72
  export * from './resources/resources-config.shared.schemas';
73
+ export * from './resources/collection-query-parameters.shared';
71
74
  export * from './resources/resources-relationships.shared.factory';
72
75
  export * from './resources/resources-serialization.shared.schemas';
73
76
  export * from './resources/utils/persistence-adapter-discrimination.shared.utils';
@@ -141,6 +144,7 @@ export * from './compliance/privacy/ai-use-posture.shared.schemas';
141
144
  export * from './compliance/privacy/client-storage.shared.schemas';
142
145
  export * from './compliance/privacy/personal-data-category.shared.schemas';
143
146
  export * from './compliance/privacy/personal-data-declaration.shared.utils';
147
+ export * from './compliance/privacy/operating-jurisdictions.shared.schemas';
144
148
  export * from './compliance/privacy/operator-compliance-identity.shared.schemas';
145
149
  export * from './external-providers/provider-compliance-profile.shared.schemas';
146
150
  export * from './compliance/privacy/impersonalization.shared.schemas';
@@ -221,6 +225,8 @@ export * from './security/oauth-clients/oauth-consent-grants.shared.schemas';
221
225
  export * from './security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas';
222
226
  export * from './security/authentications/authentication.shared.dto.schemas';
223
227
  export * from './security/authentications/authentication.shared.schemas';
228
+ export * from './security/authentications/mfa-backup-code-contract.shared';
229
+ export * from './security/authentications/siem/siem-delivery-reliability-contract.shared';
224
230
  export * from './security/authentications/authentication.shared.utils';
225
231
  export * from './security/authentications/consumable-token.shared.schemas';
226
232
  export * from './security/authentications/anonymous-session/anonymous-session.shared.contract';