@wildo-ai/saas-backend-lib 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 (265) hide show
  1. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts +14 -3
  2. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts.map +1 -1
  3. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js +115 -22
  4. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js.map +1 -1
  5. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts +3 -1
  6. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts.map +1 -1
  7. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js +8 -3
  8. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js.map +1 -1
  9. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.d.ts +11 -0
  10. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.d.ts.map +1 -1
  11. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.js +11 -2
  12. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.js.map +1 -1
  13. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts +1 -0
  14. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts.map +1 -1
  15. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js +6 -1
  16. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js.map +1 -1
  17. package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.d.ts.map +1 -1
  18. package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.js +16 -0
  19. package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.js.map +1 -1
  20. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts +20 -6
  21. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts.map +1 -1
  22. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js +88 -32
  23. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js.map +1 -1
  24. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.d.ts +3 -1
  25. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.d.ts.map +1 -1
  26. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.js +32 -7
  27. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.js.map +1 -1
  28. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.d.ts +8 -5
  29. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.d.ts.map +1 -1
  30. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.js.map +1 -1
  31. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts +31 -0
  32. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts.map +1 -1
  33. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js +127 -5
  34. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js.map +1 -1
  35. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts +71 -1
  36. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts.map +1 -1
  37. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js +62 -2
  38. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js.map +1 -1
  39. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts +21 -0
  40. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts.map +1 -1
  41. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js +126 -4
  42. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js.map +1 -1
  43. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.d.ts +3 -26
  44. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.d.ts.map +1 -1
  45. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.js +3 -68
  46. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.js.map +1 -1
  47. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts.map +1 -1
  48. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js +4 -2
  49. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js.map +1 -1
  50. package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js +6 -6
  51. package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js.map +1 -1
  52. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts +38 -0
  53. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts.map +1 -1
  54. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js +40 -0
  55. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js.map +1 -1
  56. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts +20 -0
  57. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts.map +1 -1
  58. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js +28 -0
  59. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js.map +1 -1
  60. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts +12 -0
  61. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts.map +1 -0
  62. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js +118 -0
  63. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js.map +1 -0
  64. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.d.ts.map +1 -1
  65. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js +8 -5
  66. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js.map +1 -1
  67. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.d.ts.map +1 -1
  68. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js +14 -0
  69. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js.map +1 -1
  70. package/dist/esm/config/custom/application-config-controller.backend.service.d.ts.map +1 -1
  71. package/dist/esm/config/custom/application-config-controller.backend.service.js +7 -1
  72. package/dist/esm/config/custom/application-config-controller.backend.service.js.map +1 -1
  73. package/dist/esm/config/models/app-config.backend.schemas.d.ts +4 -0
  74. package/dist/esm/config/models/app-config.backend.schemas.d.ts.map +1 -1
  75. package/dist/esm/config/services/app-configuration.backend.utils.d.ts +10 -1
  76. package/dist/esm/config/services/app-configuration.backend.utils.d.ts.map +1 -1
  77. package/dist/esm/config/services/app-configuration.backend.utils.js +13 -2
  78. package/dist/esm/config/services/app-configuration.backend.utils.js.map +1 -1
  79. package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.d.ts +2 -2
  80. package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.js +2 -2
  81. package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.js.map +1 -1
  82. package/dist/esm/databases/models/filter.backend.schemas.js +2 -2
  83. package/dist/esm/databases/models/filter.backend.schemas.js.map +1 -1
  84. package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.d.ts.map +1 -1
  85. package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.js +20 -1
  86. package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.js.map +1 -1
  87. package/dist/esm/databases/services/redis.service.d.ts +27 -0
  88. package/dist/esm/databases/services/redis.service.d.ts.map +1 -1
  89. package/dist/esm/databases/services/redis.service.js +29 -0
  90. package/dist/esm/databases/services/redis.service.js.map +1 -1
  91. package/dist/esm/errors/services/error-handler.backend.service.d.ts.map +1 -1
  92. package/dist/esm/errors/services/error-handler.backend.service.js +5 -0
  93. package/dist/esm/errors/services/error-handler.backend.service.js.map +1 -1
  94. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.d.ts +41 -0
  95. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.d.ts.map +1 -0
  96. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.js +40 -0
  97. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.js.map +1 -0
  98. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.d.ts +64 -0
  99. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.d.ts.map +1 -0
  100. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.js +193 -0
  101. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.js.map +1 -0
  102. package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts +13 -2
  103. package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts.map +1 -1
  104. package/dist/esm/external-data/external-data-pipeline-run.backend.service.js +8 -2
  105. package/dist/esm/external-data/external-data-pipeline-run.backend.service.js.map +1 -1
  106. package/dist/esm/external-data/external-data-transform.backend.d.ts.map +1 -1
  107. package/dist/esm/external-data/external-data-transform.backend.js +7 -1
  108. package/dist/esm/external-data/external-data-transform.backend.js.map +1 -1
  109. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.d.ts +2 -0
  110. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.d.ts.map +1 -1
  111. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.js +13 -0
  112. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.js.map +1 -1
  113. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts +14 -0
  114. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts.map +1 -1
  115. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js +6 -0
  116. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js.map +1 -1
  117. package/dist/esm/files/controllers/file.controller.d.ts +24 -1
  118. package/dist/esm/files/controllers/file.controller.d.ts.map +1 -1
  119. package/dist/esm/files/controllers/file.controller.js +66 -2
  120. package/dist/esm/files/controllers/file.controller.js.map +1 -1
  121. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.d.ts +17 -0
  122. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.d.ts.map +1 -0
  123. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.js +1 -0
  124. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.js.map +1 -0
  125. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts +5 -1
  126. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts.map +1 -1
  127. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js +42 -3
  128. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js.map +1 -1
  129. package/dist/esm/files/services/file-operation-handler.backend.service.d.ts +18 -0
  130. package/dist/esm/files/services/file-operation-handler.backend.service.d.ts.map +1 -1
  131. package/dist/esm/files/services/file-operation-handler.backend.service.js +36 -28
  132. package/dist/esm/files/services/file-operation-handler.backend.service.js.map +1 -1
  133. package/dist/esm/files/services/file-upload-grant.backend.service.d.ts +163 -0
  134. package/dist/esm/files/services/file-upload-grant.backend.service.d.ts.map +1 -0
  135. package/dist/esm/files/services/file-upload-grant.backend.service.js +442 -0
  136. package/dist/esm/files/services/file-upload-grant.backend.service.js.map +1 -0
  137. package/dist/esm/files/services/files.backend.service.d.ts +19 -0
  138. package/dist/esm/files/services/files.backend.service.d.ts.map +1 -1
  139. package/dist/esm/files/services/files.backend.service.js +78 -15
  140. package/dist/esm/files/services/files.backend.service.js.map +1 -1
  141. package/dist/esm/files/utils/file-uploader.utils.d.ts.map +1 -1
  142. package/dist/esm/files/utils/file-uploader.utils.js +12 -0
  143. package/dist/esm/files/utils/file-uploader.utils.js.map +1 -1
  144. package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js +5 -5
  145. package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js.map +1 -1
  146. package/dist/esm/flows-actors/services/agents.backend.service.d.ts +79 -0
  147. package/dist/esm/flows-actors/services/agents.backend.service.d.ts.map +1 -1
  148. package/dist/esm/flows-actors/services/agents.backend.service.js +319 -42
  149. package/dist/esm/flows-actors/services/agents.backend.service.js.map +1 -1
  150. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts +151 -41
  151. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts.map +1 -1
  152. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js +300 -139
  153. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js.map +1 -1
  154. package/dist/esm/index.d.ts +4 -1
  155. package/dist/esm/index.d.ts.map +1 -1
  156. package/dist/esm/index.js +14 -1
  157. package/dist/esm/index.js.map +1 -1
  158. package/dist/esm/inject/models/container.d.ts.map +1 -1
  159. package/dist/esm/inject/models/container.js +4 -0
  160. package/dist/esm/inject/models/container.js.map +1 -1
  161. package/dist/esm/inject/models/service-types.d.ts +3 -0
  162. package/dist/esm/inject/models/service-types.d.ts.map +1 -1
  163. package/dist/esm/inject/models/service-types.js +2 -0
  164. package/dist/esm/inject/models/service-types.js.map +1 -1
  165. package/dist/esm/mcp/controllers/mcp.controller.d.ts.map +1 -1
  166. package/dist/esm/mcp/controllers/mcp.controller.js +12 -4
  167. package/dist/esm/mcp/controllers/mcp.controller.js.map +1 -1
  168. package/dist/esm/mcp/models/mcp-tool.backend.schemas.d.ts +34 -0
  169. package/dist/esm/mcp/models/mcp-tool.backend.schemas.d.ts.map +1 -1
  170. package/dist/esm/mcp/models/mcp-tool.backend.schemas.js +42 -0
  171. package/dist/esm/mcp/models/mcp-tool.backend.schemas.js.map +1 -1
  172. package/dist/esm/mcp/services/mcp-server.backend.service.d.ts +29 -1
  173. package/dist/esm/mcp/services/mcp-server.backend.service.d.ts.map +1 -1
  174. package/dist/esm/mcp/services/mcp-server.backend.service.js +131 -3
  175. package/dist/esm/mcp/services/mcp-server.backend.service.js.map +1 -1
  176. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts +64 -2
  177. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts.map +1 -1
  178. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js +130 -6
  179. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js.map +1 -1
  180. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts +9 -0
  181. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts.map +1 -1
  182. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js +11 -36
  183. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js.map +1 -1
  184. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.d.ts.map +1 -1
  185. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js +9 -7
  186. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js.map +1 -1
  187. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.d.ts +5 -5
  188. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.d.ts.map +1 -1
  189. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.js +14 -13
  190. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.js.map +1 -1
  191. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts +2 -1
  192. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts.map +1 -1
  193. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js +2 -2
  194. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js.map +1 -1
  195. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.d.ts.map +1 -1
  196. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js +9 -7
  197. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js.map +1 -1
  198. package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.d.ts.map +1 -1
  199. package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.js +4 -1
  200. package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.js.map +1 -1
  201. package/dist/esm/requests/service/websocket.service.d.ts.map +1 -1
  202. package/dist/esm/requests/service/websocket.service.js +56 -7
  203. package/dist/esm/requests/service/websocket.service.js.map +1 -1
  204. package/dist/esm/resources/models/custom-service-implementations.backend.definition.d.ts.map +1 -1
  205. package/dist/esm/resources/models/custom-service-implementations.backend.definition.js +2 -0
  206. package/dist/esm/resources/models/custom-service-implementations.backend.definition.js.map +1 -1
  207. package/dist/esm/resources/services/resource-id.backend.service.js +3 -3
  208. package/dist/esm/resources/services/resource-id.backend.service.js.map +1 -1
  209. package/dist/esm/resources/services/resources-registry.backend.service.js +1 -1
  210. package/dist/esm/resources/services/resources-registry.backend.service.js.map +1 -1
  211. package/dist/esm/runtime/services/execution-context-creator.backend.service.d.ts.map +1 -1
  212. package/dist/esm/runtime/services/execution-context-creator.backend.service.js +13 -7
  213. package/dist/esm/runtime/services/execution-context-creator.backend.service.js.map +1 -1
  214. package/dist/esm/runtime/services/start-application.backend.service.d.ts +28 -0
  215. package/dist/esm/runtime/services/start-application.backend.service.d.ts.map +1 -1
  216. package/dist/esm/runtime/services/start-application.backend.service.js +82 -0
  217. package/dist/esm/runtime/services/start-application.backend.service.js.map +1 -1
  218. package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts +3 -23
  219. package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts.map +1 -1
  220. package/dist/esm/security/authentications/models/jwt.backend.schemas.js +20 -45
  221. package/dist/esm/security/authentications/models/jwt.backend.schemas.js.map +1 -1
  222. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts +9 -1
  223. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts.map +1 -1
  224. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js +9 -1
  225. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js.map +1 -1
  226. package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.d.ts.map +1 -1
  227. package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.js +5 -3
  228. package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.js.map +1 -1
  229. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts +25 -1
  230. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts.map +1 -1
  231. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js +55 -4
  232. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js.map +1 -1
  233. package/dist/esm/security/authorizations/initiator-organization-confinement.backend.d.ts.map +1 -1
  234. package/dist/esm/security/authorizations/initiator-organization-confinement.backend.js +24 -1
  235. package/dist/esm/security/authorizations/initiator-organization-confinement.backend.js.map +1 -1
  236. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.d.ts +117 -0
  237. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.d.ts.map +1 -0
  238. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.js +104 -0
  239. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.js.map +1 -0
  240. package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts +101 -6
  241. package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts.map +1 -1
  242. package/dist/esm/security/authorizations/services/authorizations.backend.service.js +210 -30
  243. package/dist/esm/security/authorizations/services/authorizations.backend.service.js.map +1 -1
  244. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts +18 -1
  245. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts.map +1 -1
  246. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.js +110 -74
  247. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.js.map +1 -1
  248. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.d.ts +22 -0
  249. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.d.ts.map +1 -0
  250. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.js +22 -0
  251. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.js.map +1 -0
  252. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts +17 -3
  253. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts.map +1 -1
  254. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.js +12 -0
  255. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.js.map +1 -1
  256. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts +20 -0
  257. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts.map +1 -1
  258. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js +58 -5
  259. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js.map +1 -1
  260. package/dist/esm/security/jwt/services/jwt.backend.service.d.ts.map +1 -1
  261. package/dist/esm/security/jwt/services/jwt.backend.service.js +1 -18
  262. package/dist/esm/security/jwt/services/jwt.backend.service.js.map +1 -1
  263. package/dist/tsconfig.build.tsbuildinfo +1 -1
  264. package/package.json +15 -9
  265. package/dist/esm/.builder.pid +0 -9
@@ -1 +1 @@
1
- {"version":3,"file":"repositories-registry-handler.backend.service.js","sourceRoot":"","sources":["../../../../../../src/base-classes/services/repositories/repositories-registry-handler.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\nimport { injectable, inject, Container } from 'inversify';\nimport { Model, Connection } from 'mongoose';\nimport { sql } from 'kysely';\nimport type {\n ResourceConfiguration,\n ResourceConfiguration_OperationRepositoryPath\n} from '@wildo-ai/saas-models';\nimport type { DataSeedRowMetadata } from '~wildo-backend-lib/data-seeding/models/data-seed-row-metadata.shared.schemas';\nimport {\n ResourceType,\n\n CoreResourceOperation,\n ResourcesConfig_OperationPathUtils,\n ErrorType,\n ErrorCustomMessageReference,\n PersistenceAdapter,\n PersistenceAdapterType,\n DEFAULT_PERSISTENCE_ADAPTER,\n Resources_PaginationRequest,\n Resources_PaginatedResult,\n ResourceOperationVariantType,\n} from '@wildo-ai/saas-models';\nimport {\n buildMissingRetentionMarkerFilterFragment,\n buildRetentionMarkerBackfillPatch,\n isRetentionGovernedResource,\n resolveSoleVisibleRetentionStatus,\n withRetentionHideApplied,\n} from '~wildo-backend-lib/compliance/privacy/retention-hide-predicate.backend';\nimport { EnumLikeType } from '@wildo-ai/zod-decorators';\nimport {\n IdOrFilterType,\n IdOrIdsOrFilterType,\n IdsOrFilterType,\n RepositoryOptions,\n} from '~wildo-backend-lib/base-classes/models/repositories.backend.schemas';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport {\n ApplicationRuntimeProfile,\n resolveApplicationRuntimeProfileBootAssertions,\n} from '~wildo-backend-lib/config/bootstrap/application-runtime-profile.backend';\nimport { ExecutionContext } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';\nimport { RepositoryResourceBackendService } from './repository-resource.backend.service';\nimport { ResourceOperationHelperBackendService } from '~wildo-backend-lib/base-classes/services/resource-operations-helper.backend.service';\nimport { ZodToMongooseSchemaConvertorBackendService } from '~wildo-backend-lib/databases/services/zod-to-mongoose-schema-convertor.backend.service';\nimport { resolvePersistenceAdapterForConfiguration } from '~wildo-backend-lib/databases/models/resolve-persistence-adapter.backend.utils';\nimport type { PersistenceAdapterAuthority } from '~wildo-backend-lib/databases/models/resolve-persistence-adapter.backend.utils';\nimport { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport { describeCaughtError, projectCaughtErrorLogFields } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport { z } from 'zod';\nimport { ResourcesRegistryBackendService } from '~wildo-backend-lib/resources/services/resources-registry.backend.service';\nimport { PostgreSQLDatabaseBackendService } from '~wildo-backend-lib/databases/services/postgresql-database.backend.service';\nimport { ZodToSqlHybridSchemaPlannerBackendService } from '~wildo-backend-lib/databases/services/zod-to-sql-hybrid-schema.planner';\nimport { PostgreSQLResourceRepositoryBackendService } from './postgresql-resource-repository.backend.service';\nimport { HttpApiResourceRepositoryBackendService } from './http-api/http-api-resource-repository.backend.service';\nimport { IntrospectionResourceRepositoryBackendService } from './introspection/introspection-resource-repository.backend.service';\nimport type { IntrospectionResourceSourceBackendPort } from './introspection/introspection-resource-source.backend.port';\nimport { createHttpApiSubjectErasureEffect } from './http-api/http-api-subject-erasure-effect.backend';\nimport type {\n HttpApiResourceBinding,\n} from '@wildo-ai/saas-models/external-data';\nimport { ExternalProvidersHttpApiAccessResolver } from './http-api/http-api-provider-access.backend';\nimport { PostgreSQLFilterBackendService } from '~wildo-backend-lib/databases/services/postgresql-filter.backend.service';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n buildPostgresSchemaStatements,\n classifyPostgresColumnJsReadType,\n PostgresColumnJsReadType,\n postgresColumnTypeSatisfiesPlan,\n renderPostgresColumnType,\n normalizePostgresDefaultExpression,\n renderPostgresColumnDefaultClause,\n} from '~wildo-backend-lib/databases/services/postgresql-schema-ddl.backend';\nimport {\n applyPostgresMigrations,\n loadMigrationsFromDirectory,\n} from '~wildo-backend-lib/databases/services/postgresql-migration-runner.backend';\nimport { ResourceIdBackendService } from '~wildo-backend-lib/resources/services/resource-id.backend.service';\nimport type {\n ConditionalArrayReturnType,\n ConditionalNullableReturnType,\n ConditionalReturnType,\n MainSchemaArrayType,\n MainSchemaType,\n PartialMainSchemaType,\n} from '~wildo-backend-lib/base-classes/utils/backend-type-utils';\nimport {\n enumerateFileFieldValueOccurrences,\n setValueAtRuntimePath,\n} from '~wildo-backend-lib/files/utils/file-field-schema-path.backend.utils';\nimport {\n describeGuardedMutationInexpressibility,\n type RepositoryGuardedMutation,\n} from './repository-guarded-mutation.backend.types';\n\n/**\n * Backend repository interface (no nominal private members).\n * Both Mongo and PostgreSQL repositories conform structurally.\n */\nexport interface BackendResourceRepository<\n TCustomOperationEnum extends EnumLikeType | undefined = undefined,\n TCoreOperationEnum extends Partial<CoreResourceOperation> | undefined = undefined,\n TMainSchema extends z.ZodTypeAny = z.ZodTypeAny\n> {\n doByPath<T = any, U = any>(\n operationRepositoryPath: ResourceConfiguration_OperationRepositoryPath,\n executionContext: ExecutionContext<any>,\n id_or_ids_or_filter?: any,\n data?: U,\n options?: RepositoryOptions\n ): Promise<T>;\n\n doByKey<T = any, U = any>(\n operationRepositoryPathKey: string,\n executionContext: ExecutionContext<any>,\n id_or_ids_or_filter?: any,\n data?: U,\n options?: RepositoryOptions\n ): Promise<T>;\n\n doByExecutionContext<T = any>(\n executionContext: ExecutionContext<any>,\n data?: any,\n options?: RepositoryOptions\n ): Promise<T>;\n\n // Core methods used throughout backend-lib (must be shared across adapters)\n create<T = undefined>(\n executionContext: ExecutionContext<any>,\n data: MainSchemaType<TMainSchema>,\n options?: RepositoryOptions\n ): Promise<ConditionalReturnType<T, TMainSchema>>;\n createMany<T = undefined>(\n executionContext: ExecutionContext<any>,\n data: MainSchemaArrayType<TMainSchema>,\n options?: RepositoryOptions\n ): Promise<ConditionalArrayReturnType<T, TMainSchema>>;\n\n read<T = undefined>(\n executionContext: ExecutionContext<any>,\n id_or_filter: IdOrFilterType,\n options?: RepositoryOptions\n ): Promise<ConditionalNullableReturnType<T, TMainSchema>>;\n\n /**\n * ADAPTER-NEUTRAL guarded-write primitives.\n *\n * These are ON THE CONTRACT deliberately. Both were reached through\n * `(repository as any).<name>` plus a `typeof … !== 'function'` runtime check, which is the\n * unenforced-contract shape this workstream exists to remove: a new adapter that simply omits\n * one compiles perfectly and fails at the first guarded write, in a background job or a metering\n * path where the error is most likely to be swallowed. Declaring them makes the omission a\n * compile error instead.\n *\n * Both take a PRE-BUILT filter including guard conditions. Callers reach them through the\n * registry, which applies the retention-hide predicate first — a retained row is immutable — so\n * these are not to be called directly from services.\n *\n * `T` is intentionally caller-chosen rather than schema-derived: these bypass the operation\n * lifecycle's DTO projection, so the row shape they return is the persisted one.\n */\n atomicIncrementField<T = any>(\n filter: Record<string, unknown>,\n field: string,\n delta: number,\n setFields?: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<T | null>;\n\n atomicConditionalSet<T = any>(\n filter: Record<string, unknown>,\n setFields: Record<string, unknown> | undefined,\n clearFields: readonly string[] | undefined,\n options?: RepositoryOptions,\n ): Promise<T | null>;\n\n /**\n * The GENERAL guarded write — set, clear, increment and array-add on the single matching row, in\n * ONE statement. The two primitives above are shorthands over it.\n *\n * On the contract for the same reason they are: an adapter that cannot compile a guarded mutation\n * must fail to build, not fail at the first lifecycle evaluation in a swallowed background path.\n */\n atomicGuardedMutation<T = any>(\n filter: Record<string, unknown>,\n mutation: RepositoryGuardedMutation,\n options?: RepositoryOptions,\n ): Promise<T | null>;\n\n /**\n * The MULTI-row guarded write, below the operation tier.\n *\n * On the contract for the same reason its single-row sibling is: an adapter that cannot compile a\n * guarded mutation must fail to BUILD. Takes an ALREADY-HIDDEN filter; the retention predicate is\n * applied once, by the handler.\n */\n updateManyByRawFilter(\n filter: Record<string, unknown>,\n mutation: RepositoryGuardedMutation,\n options?: RepositoryOptions,\n ): Promise<number>;\n\n /**\n * INSERT one already-built document, below the operation tier.\n *\n * On the contract for the same reason its siblings are: an adapter that cannot honour it must fail\n * to BUILD. Exists for framework-internal writers that own a resource with no API operation for\n * the write they need — consumable tokens are the case that forced it: the token lifecycle mints\n * and consumes credentials in flows that have NO principal (a verification email is a system\n * action; a magic-link click is pre-authentication by definition), so routing them through the\n * resource's declared, role-gated operations would mean fabricating an administrator.\n */\n insertRawDocument<T = any>(\n document: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<T>;\n\n /**\n * READ many rows matching an already-built filter — the multi-row counterpart of\n * `readUnscopedByKey`. Takes an ALREADY-HIDDEN filter; the retention predicate is applied once, by\n * the handler.\n */\n findManyByRawFilter<T = any>(\n filter: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<T[]>;\n\n /**\n * COUNT rows matching an already-built filter, below the operation tier.\n *\n * **On the contract for the same reason `atomicGuardedMutation` is:** an adapter that cannot answer\n * it must fail to BUILD, not fail at the first call in a path nobody watches. This member exists\n * because the handler's `countDocumentsForInfrastructure` used to reach\n * `(repository as any).mongooseModel` instead, which made a generally-named infrastructure\n * capability work on one adapter only — field-uniqueness validation threw \"No underlying database\n * model found\" for every PostgreSQL-backed resource, and nothing in the type system objected.\n *\n * Takes an ALREADY-HIDDEN filter: the retention predicate is applied once, by the handler.\n * Implementations must not re-apply it — see the `retention-gate` notes on both arms.\n */\n countByRawFilter(\n filter: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<number>;\n\n /**\n * A single-row read below BOTH the operation tier and the execution-context tier — the read\n * counterpart of the atomic trio above, and the only read on this contract that takes no context.\n *\n * ## Why it exists, and why it is not a loophole\n *\n * `readForInternalScan` drops the OPERATION but still applies the context's scope filter, so it\n * serves a caller that has a context. Some framework callers structurally cannot have one.\n * `ConsumableTokenBackendService` is the case that forced this: a password-reset or magic-link\n * request arrives with an unguessable secret and NO tenant identity — resolving the token is how\n * identity is established — and the service sits so far below the context tier that\n * `ExecutionContextCreatorBackendService` INJECTS it. A context cannot be built there without a\n * dependency cycle, and fabricating one would either invent a scope or fail closed on every\n * password reset.\n *\n * So the honest expression is a read that says what it does. The dangerous property is in the name:\n * `Unscoped` — no tenant narrowing is applied, and the caller's `filter` is the ONLY confinement.\n * Use it where the filter is itself the credential (an unguessable key), never to \"skip the scope\n * filter\" on a caller that has a scope.\n *\n * Retention hiding IS applied, at the registry dispatch point, exactly as it is for\n * `atomicGuardedMutation` — so an erased-but-retained row stays hidden even here. It carries the\n * same stated residual as that method: public on the contract, so app code holding a repository\n * handle can call it directly and skip the hide. A convention, not a mechanism.\n */\n readUnscopedByKey<T = any>(\n filter: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<T | null>;\n\n /**\n * Framework-internal single-row read independent of an authored/default READ\n * operation. It still applies the execution context's scope/retention filter\n * but bypasses user-facing operation hooks and projections.\n */\n readForInternalScan<T = undefined>(\n executionContext: ExecutionContext<any>,\n id_or_filter: IdOrFilterType,\n options?: RepositoryOptions\n ): Promise<ConditionalNullableReturnType<T, TMainSchema>>;\n\n /**\n * System-level membership projection for scope-required reference search: read\n * THIS (junction) resource's `targetFkField` values for rows matching\n * `{ [scopeFkField]: scopeId }`. Bypasses operation auth + contextual filtering\n * by design — it resolves the in-scope id set for a caller ALREADY authorized\n * for the scope (a membership projection, not a user-facing read). See\n * scope-required reference search (`.claude/plans/fk-filter-reference-search.md`).\n */\n findScopeRelatedTargetIds(scopeFkField: string, scopeId: string, targetFkField: string): Promise<string[]>;\n\n update<T = undefined>(\n executionContext: ExecutionContext<any>,\n id_or_filter: IdOrFilterType,\n data: PartialMainSchemaType<TMainSchema>,\n options?: RepositoryOptions\n ): Promise<ConditionalNullableReturnType<T, TMainSchema>>;\n\n updateMany<T = undefined>(\n executionContext: ExecutionContext<any>,\n data: PartialMainSchemaType<TMainSchema>,\n options?: RepositoryOptions\n ): Promise<ConditionalArrayReturnType<T, TMainSchema>>;\n\n delete(executionContext: ExecutionContext<any>, id_or_ids_or_filter: IdOrIdsOrFilterType, options?: RepositoryOptions): Promise<string>;\n deleteMany(\n executionContext: ExecutionContext<any>,\n ids_or_filter: IdsOrFilterType,\n options?: RepositoryOptions\n ): Promise<string[]>;\n\n list<T = undefined>(\n executionContext: ExecutionContext<any>,\n ids_or_filter: IdsOrFilterType,\n options?: RepositoryOptions\n ): Promise<ConditionalArrayReturnType<T, TMainSchema>>;\n list<T = undefined>(\n executionContext: ExecutionContext<any>,\n ids_or_filter: IdsOrFilterType,\n options: RepositoryOptions & { paginated: true; listOptions?: Partial<Resources_PaginationRequest> }\n ): Promise<Resources_PaginatedResult<ConditionalReturnType<T, TMainSchema>>>;\n\n /**\n * Framework-internal LIST. Unlike {@link list}, it does NOT require the\n * resource to declare a default LIST operation — see the implementation\n * JSDoc on `RepositoryResourceBackendService`. Used by framework\n * machinery that must list regardless of a user-facing LIST surface:\n * the data-seed engines (scan by `__seed.seedKey`) and the controller's\n * context-addressed-singleton authorization (resolve singleton id by\n * parent FK).\n */\n listForInternalScan<T = undefined>(\n executionContext: ExecutionContext<any>,\n ids_or_filter: IdsOrFilterType,\n options?: RepositoryOptions\n ): Promise<ConditionalArrayReturnType<T, TMainSchema>>;\n listForInternalScan<T = undefined>(\n executionContext: ExecutionContext<any>,\n ids_or_filter: IdsOrFilterType,\n options: RepositoryOptions & { paginated: true; listOptions?: Partial<Resources_PaginationRequest> }\n ): Promise<Resources_PaginatedResult<ConditionalReturnType<T, TMainSchema>>>;\n\n search<T = any>(\n executionContext: ExecutionContext<any>,\n searchQuery: string,\n filter?: any,\n searchOptions?: any,\n options?: RepositoryOptions\n ): Promise<Resources_PaginatedResult<T>>;\n\n count(executionContext: ExecutionContext<any>, filter?: any, options?: RepositoryOptions): Promise<{ count: number }>;\n\n supportsOperation(operationIdentifier: string): boolean;\n\n aggregateField(\n executionContext: ExecutionContext<any>,\n filter: any,\n field: string,\n operation: string,\n ): Promise<number>;\n\n // ---------------------------------------------------------------------------\n // Business-key surface (data-seeding subsystem)\n //\n // These three methods are the abstract contract the data-seeding dispatcher\n // depends on. Both Mongo (`RepositoryResourceBackendService`) and PostgreSQL\n // (`PostgreSQLResourceRepositoryBackendService`) implementations expose them\n // structurally; declaring them here lets `DataSeedDispatcherBackendService`\n // type its repository handles as `BackendResourceRepository<...>` instead of\n // narrowing to a concrete adapter (which would silently break the moment a\n // seed targets a PG-backed resource type).\n //\n // The signatures carry the SCHEMA-DERIVED types, not `<T = any>`.\n //\n // This reverses an earlier decision recorded here, and the reason is worth\n // keeping: that decision held the per-adapter refinements (the Mongo\n // `ConditionalReturnType<T, TMainSchema>`) to be \"structurally compatible with\n // `Promise<T>` when the caller does not pin `T`\". They are NOT. A conformance\n // check requires the method to accept ANY `T`, and TypeScript rejects the\n // narrowing outright — 12 members failed the moment `implements` was added.\n // The claim survived only because both repositories were cast through `as any`\n // at construction, so nothing ever checked it.\n //\n // A contract that says `any` is not a contract: it is what let three declared\n // members go unimplemented on PostgreSQL without a single compile error.\n // ---------------------------------------------------------------------------\n\n findByBusinessKey<T = undefined>(\n executionContext: ExecutionContext<any>,\n businessKeyShape: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<ConditionalNullableReturnType<T, TMainSchema>>;\n\n findManyByBusinessKeys<T = undefined>(\n executionContext: ExecutionContext<any>,\n businessKeyShapes: Array<Record<string, unknown>>,\n options?: RepositoryOptions,\n ): Promise<ConditionalArrayReturnType<T, TMainSchema>>;\n\n upsertByBusinessKey<T = undefined>(\n executionContext: ExecutionContext<any>,\n businessKeyShape: Record<string, unknown>,\n payload: Record<string, unknown>,\n seedMetadata: DataSeedRowMetadata,\n options?: RepositoryOptions,\n ): Promise<{ inserted: boolean; row: ConditionalReturnType<T, TMainSchema> }>;\n\n /**\n * Insert-or-update a row by an explicit singleton filter without writing\n * data-seeding metadata.\n *\n * This is the normal resource-write counterpart to `upsertByBusinessKey`.\n * Use it for framework-owned singleton materialization paths where the\n * selector is not represented by `.isBusinessKey()` on `mainSchema` (for\n * example relationship-injected scope FK fields such as `organizationId` or\n * `appId`). Callers must pass a semantically unique filter and keep any\n * fail-closed duplicate checks they need at the service boundary.\n *\n * ⚠️ **ADAPTER-ASYMMETRIC PRECONDITION — `options.excludeContextualFilter: true` is REQUIRED.**\n * The MongoDB arm runs the filter through `buildContextualFilter`, so its update branch is confined\n * to the caller's scope. PostgreSQL cannot do that: `ON CONFLICT` must name a UNIQUE constraint and\n * a scope predicate is not part of one, so arbitration happens on the business key ALONE. A caller\n * that relied on tenant confinement would therefore be confined on one adapter and update another\n * tenant's row on the other. Rather than leave that silent, the PostgreSQL arm REFUSES any caller\n * that has not waived contextual filtering explicitly (an array value is refused too — partial\n * scope filtering is exactly what cannot be expressed). So: pass a filter that already names the\n * scope, or use a scoped read-then-write instead.\n *\n * A multi-column filter additionally requires a DECLARED COMPOSITE unique constraint covering\n * exactly those columns; individually-unique columns do not compose into one.\n *\n * RETENTION is unaffected by that flag and always applied: a retained row is never rewritten and\n * never returned, on either adapter.\n */\n upsertByFilter<T = undefined>(\n executionContext: ExecutionContext<any>,\n filterShape: Record<string, unknown>,\n payload: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<{ inserted: boolean; row: ConditionalReturnType<T, TMainSchema> }>;\n\n /**\n * Privileged write path for the `__seed` row-metadata ledger ONLY.\n *\n * Purpose (R3-1, Phase-4 deep-review hotfix):\n * The data-seeding dispatcher needs to mutate a row's `__seed` ledger\n * (today: stamping `__seed.deprecated` from SYNC's orphan handler;\n * tomorrow: any future LAZY-mode bookkeeping). The standard\n * `update(...)` path runs the patch through the resource's `INTERNAL`\n * UPDATE `requestDto`, which Zod `.strip()`s any field not listed —\n * including `__seed` (no app resource declares it on its own DTO,\n * because `__seed` is a system-managed field added by the framework\n * via `ZodToMongooseSchemaConvertor`). Without this method, the\n * dispatcher's `repo.update(_id, { __seed })` would silently strip\n * `__seed` from the patch, the underlying `findOneAndUpdate` would\n * run with an empty `$set`, the orphan policy's counter would\n * increment, and `__seed.deprecated` would never persist — every\n * subsequent SYNC pass would re-deprecate the same orphans forever.\n *\n * Contract:\n * - Targets a row by `_id` (no business-key indirection — orphan\n * handling already has the row).\n * - Replaces the row's `__seed` ledger atomically. The caller passes\n * the FULL `DataSeedRowMetadata` (the dispatcher always carries\n * `priorMetadata` and merges deprecation/version/source on its\n * side; this method does not merge).\n * - Skips `cleanInputData` and `validateRequestData` (the whole\n * point — `__seed` is a system field the resource DTO never\n * declares).\n * - Still applies `addUserTracking` and `_version_db_doc` increment\n * so subsequent optimistic-locking reads stay consistent.\n * - Still respects `options.transaction` (transaction session\n * propagation — for parity with `upsertByBusinessKey`).\n *\n * Intentionally NOT exposed for general use:\n * - The dispatcher is the only legitimate writer of `__seed`. App\n * code must never call this; if it ever does, that's a layering\n * violation the reviewer should catch.\n *\n * Returns `void` because the caller already holds the row from the\n * preceding orphan-scan list and needs no echo. If a future call\n * site needs the post-write document, add a typed overload then.\n *\n * @throws WildoError_Backend on persistence failure (E11000 etc.,\n * wrapped via the adapter's `handleMongoDBError` / PG equivalent).\n * @throws WildoError_Backend(NOT_FOUND) if `id` does not exist.\n */\n updateSeedMetadata(\n executionContext: ExecutionContext<any>,\n id: string,\n seedMetadata: DataSeedRowMetadata,\n options?: RepositoryOptions,\n ): Promise<void>;\n\n}\n\n/**\n * Repository Registry Handler Backend Service\n *\n * Central registry for managing all repository resources in the application.\n * Provides unified access to repositories via operation paths and manages\n * cross-repository dependencies and relationships.\n *\n * Features:\n * - Repository lifecycle management (create, store, retrieve)\n * - Operation path-based repository access\n * - Cross-repository dependency injection\n * - Automatic repository initialization from resource configurations\n * - ExecutionContext integration for streamlined operations\n * - Resource relationship handling\n * - Unified error handling with ErrorBuilderBackendService\n */\n@injectable()\nexport class RepositoriesRegistryHandlerBackendService {\n\n private readonly repositories: Map<ResourceType, BackendResourceRepository<any, any, any>>;\n private readonly repositoryOperationsMap: Map<string, {\n repository: BackendResourceRepository<any, any, any>;\n operationRepositoryPath: ResourceConfiguration_OperationRepositoryPath;\n }>;\n private isInitialized = false;\n /**\n * Warn once per process, not once per resource: an unavailable index catalog is a property of the\n * DATABASE, so repeating it per PostgreSQL-backed resource would bury the boot log in one fact.\n */\n private hasWarnedPostgreSqlIndexIntrospectionUnavailable = false;\n\n /** Warn-once latch for {@link collectMissingPostgreSqlPrimaryKey}'s catalog read — separate from the\n * unique-index latch so each skipped verification is named truthfully, once. */\n private hasWarnedPostgreSqlPrimaryKeyIntrospectionUnavailable = false;\n protected logDebug: (message: string, context?: Record<string, unknown>) => void;\n\n\n constructor(\n @inject(SAAS_SERVICE_TYPES.ZodToMongooseSchemaConvertorService) private readonly zodToMongooseConverter: ZodToMongooseSchemaConvertorBackendService,\n @inject(SAAS_SERVICE_TYPES.ZodToSqlHybridSchemaPlannerService) private readonly zodToSqlPlanner: ZodToSqlHybridSchemaPlannerBackendService,\n @inject(SAAS_SERVICE_TYPES.Logger) private readonly logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) private readonly errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.ResourceRegistryService) private readonly resourceRegistry: ResourcesRegistryBackendService,\n @inject(SAAS_SERVICE_TYPES.ResourceOperationHelperService) private readonly resourceOperationHelper: ResourceOperationHelperBackendService,\n /**\n * Declared as the ADAPTER AUTHORITY, not as the whole application configuration: this registry\n * reads it for adapter resolution and nothing else (the three references below). The narrower\n * type is what lets a registry built for a DIFFERENT persistence scope than its host process\n * supply its own authority — see {@link PersistenceAdapterAuthority}. `AppConfigurationService`\n * satisfies it, so the container binding and every existing caller are unchanged.\n */\n @inject(SAAS_SERVICE_TYPES.AppConfigService) private readonly configService: PersistenceAdapterAuthority,\n @inject(SAAS_SERVICE_TYPES.PostgreSQLDatabaseService) private readonly postgresqlDb: PostgreSQLDatabaseBackendService,\n @inject(SAAS_SERVICE_TYPES.ResourceIdBackendService) private readonly resourceIdService: ResourceIdBackendService,\n // Appended LAST on purpose — this constructor is resolved positionally by\n // several containers, and inserting a parameter mid-list silently shifts\n // every dependency after it.\n @inject(SAAS_SERVICE_TYPES.Container) private readonly container: Container\n ) {\n\n this.repositories = new Map();\n this.repositoryOperationsMap = new Map();\n\n this.logDebug = this.logger.debugByType('RepositoriesRegistryHandler');\n this.logger.setDebugTypeLogging('RepositoriesRegistryHandler', false);\n\n this.logDebug('Repository registry service created');\n }\n\n// ================================\n// Initialize repositories\n// ================================\n\n public async initializeRepositories(\n resourceConfigurations: Map<ResourceType, ResourceConfiguration<any, any, any>>,\n connection?: Connection\n ): Promise<void> {\n if (this.isInitialized) {\n this.logDebug('Registry already initialized, skipping...');\n return;\n }\n\n this.logDebug('Initializing repositories', {\n resourceCount: resourceConfigurations.size,\n resourceTypes: Array.from(resourceConfigurations.keys())\n });\n\n // First pass: Create all repositories\n for (const [resourceType] of resourceConfigurations) {\n try {\n await this.createRepository(resourceType, connection);\n } catch (error) {\n this.logger.error('Failed to create repository', {\n resourceType,\n ...projectCaughtErrorLogFields(error)\n });\n throw error;\n }\n }\n\n\n this.buildOperationRepositoryPathsMap();\n\n // Boot-time schema maintenance belongs to the runtime ACCOUNTABLE for it —\n // the application backend — not to every runtime that happens to build a\n // repository registry.\n //\n // A minion's Mongo user is collection-scoped to what its `resourceAccess`\n // declared, so running these here means `updateMany` on collections it never\n // asked for: unauthorised, and not its concern. Observed 2026-08-12 as a\n // crash-loop on `not authorized ... update \"users\"` the moment per-principal\n // Mongo users landed. The containment was correct — the minion was doing the\n // backend's job.\n //\n // Gated on the PROFILE rather than on \"did the write fail?\": a maintenance\n // step that silently tolerates its own denial is indistinguishable from one\n // that ran.\n if (resolveApplicationRuntimeProfileBootAssertions(this.resolveRuntimeProfile()).performsBootSchemaMaintenance) {\n // BEFORE the index reconciliation, never after: the backfill stamps legacy rows with the marker\n // that a retention-scoped partial unique index selects on, so an index rebuilt first would be\n // built over rows that are about to become eligible for it.\n await this.reconcileRetentionGovernedMongoCollections();\n\n await this.reconcileDriftedMongoUniqueIndexes();\n\n // AFTER both reconciliations, never before: they drop and recreate indexes whose declared options\n // have drifted, so verifying first would report an index that is about to be fixed.\n //\n // Inside the SAME gate, because this step BUILDS as well as verifies: it\n // awaits Mongoose's `autoIndex` build, and re-attempts it when the memoized\n // one failed, so a declared index gets created here — a write on a\n // collection a confined runtime may not hold. Leaving only\n // the verification outside would also be wrong on its own terms — a minion\n // asserting that 60 indexes exist is asserting something it is not\n // accountable for and cannot repair. The backend proves it for every\n // runtime; a minion that reached this point is running against a database\n // the backend already verified.\n await this.verifyDeclaredMongoUniqueIndexes();\n } else {\n this.logger.debug(\n 'Skipping boot schema maintenance and index verification: this runtime does not own them '\n + '(see ApplicationRuntimeProfileBootAssertions.performsBootSchemaMaintenance). The '\n + 'application backend performs the retention backfill, the index reconciliation AND the '\n + 'declared-unique-index verification for every runtime.',\n );\n }\n\n this.isInitialized = true;\n\n this.logDebug('Repository registry initialization completed', {\n repositoryCount: this.repositories.size,\n operationRepositoryPathsCount: this.repositoryOperationsMap.size\n });\n }\n\n\n /**\n * PLATFORM-MODE default adapter, set explicitly before repository construction (Phase 5.2, D7).\n *\n * ## The ordering problem this solves\n *\n * Platform services (apps-manager, module-registry) build their repositories inside\n * `super.initialize()` while `AppConfigurationService` is deliberately UNHYDRATED — hydration is\n * their own later phase. So the fallback chain below reached \"config not initialized → framework\n * default\" for every platform resource, and no configuration could ever make a platform resource\n * PostgreSQL-backed: the answer was needed before the config that carries it existed.\n *\n * The fix is NOT re-resolution after hydration: repositories are CONSTRUCTED as concrete\n * Mongo/PostgreSQL classes exactly once, and an adapter answer that changes after construction is\n * a split-brain, not a correction. The platform KNOWS its store in its Phase 1 (the bridged\n * platform config, which exists before `super.initialize()`), so the answer is passed EXPLICITLY\n * at construction time.\n *\n * ## Why the override outranks the hydrated config's own default\n *\n * Once set, it stays authoritative even after `configService.isInitialized()` flips true. Both\n * values derive from one platform config, so disagreement is a bug — and if it happens, the\n * construction-time answer is the one the LIVE repositories were actually built with; letting the\n * later value win would make the boot door and schema gate reason about repositories that do not\n * exist. {@link setPlatformModeDefaultPersistenceAdapter} refuses a conflicting re-set for the\n * same reason.\n *\n * `undefined` for every non-platform application — nothing changes outside platform mode, and\n * `StartApplicationBackendService` refuses the parameter without `isPlatformApplication` so it\n * cannot become a side door around the application config contract.\n *\n * The VALUE is stored on `AppConfigurationService` (review R2): three independent resolvers\n * consume it — this registry, the services-tier transaction router, and the\n * resource-id/unit-of-work resolver — and the config service is the one dependency all three\n * share without a cycle. This method remains the ONLY sanctioned writer and owns the conflict\n * guard; the shared derivation lives in `resolveDefaultPersistenceAdapter`.\n */\n public setPlatformModeDefaultPersistenceAdapter(adapter: PersistenceAdapterType): void {\n const current = this.configService.platformModeDefaultPersistenceAdapter;\n if (current !== undefined && current !== adapter) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'platform_persistence_adapter_conflict',\n previous: current,\n attempted: adapter,\n },\n });\n }\n this.configService.adoptPlatformModeDefaultPersistenceAdapter(adapter);\n }\n\n /**\n * The persistence adapter a resource actually runs on. This registry's consumers — repository\n * construction, the migrations boot door, the schema verifier, the retention prerequisites —\n * all route here, and the derivation itself is the shared seam\n * (`resolveDefaultPersistenceAdapter`), so this tier can never disagree with the services-tier\n * or resource-id resolvers. Tolerates an uninitialized config service (unit harnesses\n * construct the registry without one; the seam answers the framework default).\n */\n private getResolvedPersistenceAdapterForResource(resourceType: ResourceType): PersistenceAdapterType {\n const declaredAdapter = this.resourceRegistry.tryGetResourceConfiguration(resourceType)?.persistenceAdapter;\n return resolvePersistenceAdapterForConfiguration(declaredAdapter, this.configService);\n }\n\n private async createRepository(\n resourceType: ResourceType,\n connection?: Connection,\n ): Promise<void> {\n this.logDebug('Creating repository', { resourceType });\n\n // Always use registry as the single source of truth.\n const resourceConfiguration = this.resourceRegistry.getResourceConfiguration(resourceType);\n\n const adapterToUse = this.getResolvedPersistenceAdapterForResource(resourceType);\n\n let repository: BackendResourceRepository<any, any, any>;\n\n // Dispatched as the ENUM type: `PersistenceAdapterType` is the template-literal union, which\n // TypeScript does not narrow to `never` through enum-member case labels — the enum type does,\n // and that narrowing is what makes the `default` arm's exhaustiveness assignment work.\n const adapterForDispatch = adapterToUse as PersistenceAdapter;\n switch (adapterForDispatch) {\n case PersistenceAdapter.POSTGRESQL:\n repository = new PostgreSQLResourceRepositoryBackendService(\n resourceType,\n this.postgresqlDb,\n this.logger,\n this.errorBuilder,\n this.resourceRegistry,\n this.resourceOperationHelper,\n this,\n this.zodToSqlPlanner,\n this.resourceIdService\n );\n break;\n case PersistenceAdapter.MONGODB:\n repository = RepositoryResourceBackendService.createInstance(\n resourceType,\n this.zodToMongooseConverter,\n this.logger,\n this.errorBuilder,\n this.resourceRegistry,\n this.resourceOperationHelper,\n this as any,\n connection,\n this.resourceIdService\n );\n break;\n case PersistenceAdapter.HTTP_API: {\n // ETL Step 3 (`.claude/plans/etl-post-repository.md`): rows are served on demand through\n // the resource's committed `httpApiBinding` — read-only in slice 1, every other contract\n // member an honest refusal (D2/D3). The provider registry resolves credentials (D7); it\n // is fetched LAZILY through the container rather than a new constructor parameter, per\n // the positional-resolution warning on this constructor's last parameter.\n // NO cast, deliberately: the structural assignment below is what keeps D2 true — a future\n // contract member this adapter omits must fail to BUILD here, exactly as it does for the\n // PostgreSQL sibling. (The Mongo sibling's `as any` at `createInstance` is an argument\n // cast, not an assignment cast.)\n const httpApiRepository = new HttpApiResourceRepositoryBackendService(\n resourceType,\n this.logger,\n this.errorBuilder,\n this.resourceRegistry,\n new ExternalProvidersHttpApiAccessResolver(\n this.container.get(SAAS_SERVICE_TYPES.ExternalProvidersRegistryService),\n ),\n undefined,\n // The read-through audit seam (ETL D8/R6), resolved lazily per emission — the\n // authorizations-service precedent: never a hard dependency, so a container without the\n // audit binding still constructs the repository and the reads it serves.\n () => (this.container.isBound(SAAS_SERVICE_TYPES.AuditLogsService)\n ? this.container.get(SAAS_SERVICE_TYPES.AuditLogsService)\n : undefined),\n );\n repository = httpApiRepository;\n this.registerHttpApiSubjectErasureEffect(resourceType, resourceConfiguration, httpApiRepository);\n break;\n }\n case PersistenceAdapter.INTROSPECTION: {\n /*\n * Rows are DERIVED per read by the dev companion; nothing is stored. The source is resolved\n * LAZILY from the container and its absence is not an error — an application running without\n * a companion binds nothing, and the repository refuses per call. Refusing at BOOT instead\n * would need a running companion to repair the companion\n * (`continuity-drift-and-cas-basis.md` Rule 3).\n *\n * No subject-erasure effect is registered, unlike the HTTP_API arm: there is no store, so\n * there are no rows to erase and nothing that could outlive a request. Stated rather than\n * omitted, because a silent absence here reads as an oversight.\n */\n repository = new IntrospectionResourceRepositoryBackendService(\n resourceType,\n this.logger,\n this.errorBuilder,\n () => (this.container.isBound(SAAS_SERVICE_TYPES.IntrospectionResourceSource)\n ? this.container.get<IntrospectionResourceSourceBackendPort>(SAAS_SERVICE_TYPES.IntrospectionResourceSource)\n : undefined),\n ) as unknown as BackendResourceRepository<any, any, any>;\n break;\n }\n default: {\n // Compile-time exhaustiveness: `adapterForDispatch` narrows to `never` only while every enum\n // member has a `case` above, so a new PersistenceAdapter member reddens this assignment\n // at typecheck instead of surfacing as a boot failure. The runtime throw stays for the\n // other failure direction — an unknown string smuggled through erased configuration.\n const unhandledAdapter: never = adapterForDispatch;\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n {\n customMessageReference:\n ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'unsupported_persistence_adapter',\n resourceType,\n persistenceAdapter: unhandledAdapter,\n },\n },\n );\n }\n }\n\n this.repositories.set(resourceType, repository);\n\n this.logDebug('Repository created successfully', { resourceType,});\n }\n\n /**\n * Register the D6 erasure-stance effect for one HTTP_API-bound resource (ETL D6 slices B/C) —\n * one `http-api:<resourceType>` entry per resource in every subject-erasure report whose graph\n * reaches it.\n *\n * Registered HERE, where the adapter is built, for the billing precedent's reason: the erasure\n * orchestrator stays domain-agnostic (\"run whatever declared itself relevant\"), and the\n * effect's lifetime is tied to the repository's — a runtime that never builds this adapter\n * registers nothing. Feature-detected on both service bindings (the effects registry and the\n * audit service): a partial container (minion runtimes, unit harnesses) still constructs the\n * repository. `register` is idempotent per `effectRef`, so a re-created repository re-registers\n * rather than double-running.\n *\n * The subject-link resolution below is DECLARATION-driven (the stance's `subjectLinkLocalField`\n * + the relationship that names its subject type — boot check B4), never inferred from FK\n * shapes: an FK usually names an owner or an actor, not the data subject.\n */\n private registerHttpApiSubjectErasureEffect(\n resourceType: ResourceType,\n resourceConfiguration: { httpApiBinding?: unknown; resourceRelationships?: unknown },\n repository: HttpApiResourceRepositoryBackendService,\n ): void {\n if (!this.container.isBound(SAAS_SERVICE_TYPES.SubjectErasureExternalEffectsService)) return;\n const binding = resourceConfiguration.httpApiBinding as HttpApiResourceBinding | undefined;\n if (!binding) return;\n\n const ownFkRelationships = (): Array<{ resourceType1?: unknown; resourceType2?: unknown; foreignKeyField?: unknown; isDisabled?: unknown }> => {\n const buckets = resourceConfiguration.resourceRelationships as\n | Record<string, Array<Record<string, unknown>>>\n | undefined;\n return [\n ...(buckets?.parentRelationships ?? []),\n ...(buckets?.childRelationships ?? []),\n ...(buckets?.selfRelationships ?? []),\n ].filter((relationship) =>\n relationship.isDisabled !== true && relationship.resourceType2 === resourceType,\n );\n };\n\n const declaredSubjectLinkField = (): string | undefined =>\n (binding.erasure as { subjectLinkLocalField?: string }).subjectLinkLocalField;\n\n const effectsRegistry = this.container.get(\n SAAS_SERVICE_TYPES.SubjectErasureExternalEffectsService,\n ) as { register: (effect: unknown) => void };\n effectsRegistry.register(createHttpApiSubjectErasureEffect({\n resourceType: String(resourceType),\n binding,\n subjectIsLinked: (subjectResourceType) =>\n ownFkRelationships().some((relationship) => relationship.resourceType1 === subjectResourceType),\n resolveSubjectLinkFields: (subjectResourceType) => {\n const linkField = declaredSubjectLinkField();\n if (!linkField) return [];\n const declaresIt = ownFkRelationships().some((relationship) =>\n relationship.resourceType1 === subjectResourceType && relationship.foreignKeyField === linkField,\n );\n return declaresIt ? [linkField] : [];\n },\n eraseLinkedRows: (localFkField, subjectId) =>\n repository.executeDeclaredSubjectLinkErasure(localFkField, subjectId),\n countLinkedRows: (localFkField, subjectId) =>\n repository.countRowsLinkedToSubject(localFkField, subjectId),\n auditLogsResolver: () => (this.container.isBound(SAAS_SERVICE_TYPES.AuditLogsService)\n ? this.container.get(SAAS_SERVICE_TYPES.AuditLogsService)\n : undefined),\n }));\n }\n\n // ================================\n // PostgreSQL startup migrations (the production door)\n // ================================\n\n /**\n * Apply pending PostgreSQL migrations at BOOT — the production door of the migration system\n * (K7: one runner, two doors; this is the one that exists in production, where there is no\n * source tree and no operator CLI).\n *\n * ## Placement and gating\n *\n * Runs from application startup immediately BEFORE {@link verifyPostgreSqlTableSchemas}, so the\n * gate verifies the schema migrations just produced — the runner changes the database, the gate\n * remains the fleet's backstop (K6), and a runner bug cannot silently become a served schema.\n *\n * Safe in every topology by the same construction as the gate:\n * - **No PostgreSQL-backed resource** (every application today, and every platform-mode boot,\n * whose uninitialized config resolves all adapters to the framework default) → returns before\n * touching `getDb()`. It can never force a connection an application does not use.\n * - **No migrations directory** → logged no-op. An application that has not adopted migrations\n * boots exactly as before; the gate still speaks for its schema. The directory is\n * `<cwd>/migrations` by convention (shipped inside the deployable, beside the code that needs\n * it), overridable via `WILDO_MIGRATIONS_DIR` for layouts where cwd is not the service root.\n *\n * ## It THROWS on failure, and that is the design\n *\n * A failed or refused migration fails the BOOT: new code must not serve behind the schema it was\n * built against. This does not violate the \"no boot-deadlock\" rule\n * (`continuity-drift-and-cas-basis.md` rule 3): the remedy — fix the migration draft, restore an\n * edited file, add the destructive acknowledgement — lives in the REPOSITORY, and never routes\n * through the process that just refused to start.\n *\n * Concurrency is the RUNNER's property, not this caller's: N instances booting simultaneously\n * elect one applier via the in-database advisory lock; the others wait, then everyone verifies.\n */\n public async applyStartupPostgresMigrations(): Promise<void> {\n /**\n * ONLY the runtime that owns the application's schema. Same gate as the Mongo boot maintenance\n * in `initializeRepositories`, and it belongs here for the same reason\n * `performsBootSchemaMaintenance`'s own contract already generalises: \"a boot step that WRITES\n * to the application's schema belongs to the runtime that owns the schema, and adding one\n * without asking which runtime owns it is how a confined runtime acquires an authority nobody\n * intended.\"\n *\n * That lesson was recorded on 2026-08-12 after a collection-scoped minion crash-looped TWICE on\n * Mongo boot maintenance — and it was applied to the Mongo steps only. The PostgreSQL pair was\n * gated at its call site on `!isPlatformApplication`, which a MINION also satisfies, so both ran\n * on every confined runtime. Observed 2026-08-21 once the application moved to PostgreSQL: the\n * marketing-scrapper minion crash-looped on `postgresql_table_schema_mismatch` reporting that 90\n * tables \"do not exist (no migration has created it)\" — against a database holding all 94 of\n * them. `information_schema` is PERMISSION-FILTERED, and a table-scoped role held grants on\n * exactly ONE table, so the gate was reading its own confinement as a missing schema.\n *\n * The migration runner is the clearer half: it issues DDL, which a confined role has no rights\n * for and no accountability over. The verifier follows the identical argument its Mongo sibling\n * records — a minion asserting that 90 tables match a plan is asserting something it cannot\n * repair, on a database the application backend already verified for every runtime.\n *\n * It is also a boot-deadlock removal (`continuity-drift-and-cas-basis.md` rule 3): the minion's\n * remedy is a GRANT issued by apps-manager, so a minion that fails closed here can never be the\n * process that fixes it.\n *\n * The gate is HERE rather than at the call site so every caller inherits it — including the\n * platform services that invoke these methods themselves. Those resolve the fail-safe\n * `APPLICATION_BACKEND` default, so their behaviour is unchanged.\n */\n if (!resolveApplicationRuntimeProfileBootAssertions(this.resolveRuntimeProfile()).performsBootSchemaMaintenance) {\n this.logger.debug(\n 'Skipping PostgreSQL startup migrations and physical-schema verification: this runtime does not own '\n + 'the application schema (see ApplicationRuntimeProfileBootAssertions.performsBootSchemaMaintenance). '\n + 'The application backend applies the migrations and proves the physical schema for every runtime.',\n );\n return;\n }\n\n // persistence-adapter binary comparison: N/A — genuine PG-feature gate. \"Does any resource\n // need the PostgreSQL migration door?\" A resource on any other adapter (current or future)\n // correctly does not; misrouting is impossible because every resource already passed the\n // exhaustive `createRepository` dispatch before this runs.\n const hasPostgresResources = Array.from(this.repositories.keys()).some(\n (resourceType) => this.getResolvedPersistenceAdapterForResource(resourceType) === PersistenceAdapter.POSTGRESQL,\n );\n if (!hasPostgresResources) return;\n\n const migrationsDirectory = process.env.WILDO_MIGRATIONS_DIR ?? join(process.cwd(), 'migrations');\n if (!existsSync(migrationsDirectory)) {\n this.logDebug('No migrations directory — startup migrations skipped', { migrationsDirectory });\n return;\n }\n\n const migrations = loadMigrationsFromDirectory(migrationsDirectory);\n if (migrations.length === 0) {\n this.logDebug('Migrations directory is empty — startup migrations skipped', { migrationsDirectory });\n return;\n }\n\n const db = await this.postgresqlDb.getDb();\n const report = await applyPostgresMigrations({ db, migrations });\n if (report.outOfOrder?.length) {\n // Applied, never refused — but the author deserves the pointer: an out-of-order migration was\n // drafted against an older accepted state. The gate right after this verifies the end state.\n this.logger.warn(\n `[Migrations] ${report.outOfOrder.length} migration(s) arrived OUT OF ORDER (older name than an `\n + `already-applied one) and were applied in sorted position: ${report.outOfOrder.join(', ')}. `\n + 'Normal after a branch merge; review them against the newer migrations they sorted before.',\n );\n }\n this.logDebug('Startup PostgreSQL migrations complete', {\n role: report.role,\n applied: report.applied,\n verifiedCount: report.verified.length,\n });\n }\n\n // ================================\n // PostgreSQL physical-schema verification\n // ================================\n\n /**\n * Prove that every PostgreSQL-backed resource's table actually HAS the columns the engine writes,\n * at BOOT, with a diagnosable error — instead of a raw driver failure on the first request.\n *\n * **Why this gate exists.** Mongo materializes a collection's shape from the Zod schema, so a\n * MongoDB-backed resource cannot disagree with its storage. PostgreSQL cannot: DDL is owned outside\n * the engine (`planSqlHybridTable` is explicitly \"planning only — migration execution and DDL\n * application are owned by apps-manager\"), so the table is whatever a migration author or fixture\n * wrote. Nothing checked that against the plan. The failure that motivated this: a framework-owned\n * column (`_version_db_doc`, the optimistic-locking version — a `SYSTEM_MANAGED_FIELDS` entry no app\n * schema declares) was written on every INSERT while the plan declared no such column, so the FIRST\n * create on any PostgreSQL-backed resource died with a bare `column \"_version_db_doc\" does not\n * exist` — a message that names no resource, no plan, and no fix.\n *\n * **Called from application startup, NOT from `initializeRepositories`.** Repositories are built\n * before the PostgreSQL connection is necessarily reachable (`getDb()` is deliberately lazy, and\n * fixtures provision their tables after building the registry), so verifying there would fail for\n * ordering reasons rather than schema reasons. Startup is where live-database probes already belong\n * — it is the same phase as the native-transaction readiness probe.\n *\n * **Zero cost when no resource is PostgreSQL-backed** (today: essentially every application): it\n * returns before touching `getDb()`, so it can never force a connection an app does not use.\n *\n * Scope, deliberately: PRESENCE of columns only. Column TYPES, nullability, indexes and constraints\n * are migration-owned and intentionally not asserted — this gate exists to convert one specific\n * class of opaque runtime failure into a boot-time diagnosis, not to become a schema differ. Extra\n * columns the plan does not know about are ignored for the same reason: the plan is a MINIMUM\n * contract, and a migration may legitimately add more.\n *\n * Every problem across every resource is collected into ONE error. Failing on the first one would\n * make fixing a drifted schema an N-boot loop.\n */\n public async verifyPostgreSqlTableSchemas(): Promise<void> {\n /**\n * ONLY the runtime that owns the application's schema. Same gate as the Mongo boot maintenance\n * in `initializeRepositories`, and it belongs here for the same reason\n * `performsBootSchemaMaintenance`'s own contract already generalises: \"a boot step that WRITES\n * to the application's schema belongs to the runtime that owns the schema, and adding one\n * without asking which runtime owns it is how a confined runtime acquires an authority nobody\n * intended.\"\n *\n * That lesson was recorded on 2026-08-12 after a collection-scoped minion crash-looped TWICE on\n * Mongo boot maintenance — and it was applied to the Mongo steps only. The PostgreSQL pair was\n * gated at its call site on `!isPlatformApplication`, which a MINION also satisfies, so both ran\n * on every confined runtime. Observed 2026-08-21 once the application moved to PostgreSQL: the\n * marketing-scrapper minion crash-looped on `postgresql_table_schema_mismatch` reporting that 90\n * tables \"do not exist (no migration has created it)\" — against a database holding all 94 of\n * them. `information_schema` is PERMISSION-FILTERED, and a table-scoped role held grants on\n * exactly ONE table, so the gate was reading its own confinement as a missing schema.\n *\n * The migration runner is the clearer half: it issues DDL, which a confined role has no rights\n * for and no accountability over. The verifier follows the identical argument its Mongo sibling\n * records — a minion asserting that 90 tables match a plan is asserting something it cannot\n * repair, on a database the application backend already verified for every runtime.\n *\n * It is also a boot-deadlock removal (`continuity-drift-and-cas-basis.md` rule 3): the minion's\n * remedy is a GRANT issued by apps-manager, so a minion that fails closed here can never be the\n * process that fixes it.\n *\n * The gate is HERE rather than at the call site so every caller inherits it — including the\n * platform services that invoke these methods themselves. Those resolve the fail-safe\n * `APPLICATION_BACKEND` default, so their behaviour is unchanged.\n */\n if (!resolveApplicationRuntimeProfileBootAssertions(this.resolveRuntimeProfile()).performsBootSchemaMaintenance) {\n this.logger.debug(\n 'Skipping PostgreSQL startup migrations and physical-schema verification: this runtime does not own '\n + 'the application schema (see ApplicationRuntimeProfileBootAssertions.performsBootSchemaMaintenance). '\n + 'The application backend applies the migrations and proves the physical schema for every runtime.',\n );\n return;\n }\n\n // persistence-adapter binary comparison: N/A — genuine PG-feature gate (which resources does\n // the physical-schema verifier speak for?). Same reasoning as the migrations gate above:\n // `createRepository`'s exhaustive dispatch has already refused any unknown adapter.\n const postgresResourceTypes = Array.from(this.repositories.keys()).filter(\n (resourceType) => this.getResolvedPersistenceAdapterForResource(resourceType) === PersistenceAdapter.POSTGRESQL,\n );\n\n if (postgresResourceTypes.length === 0) {\n return;\n }\n\n this.logDebug('Verifying PostgreSQL physical table schemas', {\n resourceTypes: postgresResourceTypes,\n });\n\n const db = await this.postgresqlDb.getDb();\n const problems: string[] = [];\n\n for (const resourceType of postgresResourceTypes) {\n const resourceConfiguration = this.resourceRegistry.tryGetResourceConfiguration(resourceType);\n if (!resourceConfiguration) continue;\n\n // Alias-aware, matching the repository and the planner: probing `userself` instead of the\n // shared `users` table would report a perfectly provisioned schema as missing.\n const tableName = PostgreSQLFilterBackendService.resolveTableNameForResource(String(resourceType));\n const expectedColumns = this.zodToSqlPlanner.planPhysicalColumnNames(\n resourceConfiguration as any,\n resourceConfiguration.mainSchema as any,\n );\n\n // Unqualified by schema ON PURPOSE: the repository issues unqualified statements too, so both\n // resolve through the same `search_path`. (`to_regclass` would pin the resolution exactly but is\n // unsupported by the in-memory Postgres the integration fixtures run on.)\n const result = await sql<{ column_name: string; data_type: string; column_default: string | null }>`\n select column_name, data_type, column_default from information_schema.columns where table_name = ${tableName}\n `.execute(db);\n const liveColumnTypes = new Map(result.rows.map((row) => [String(row.column_name), String(row.data_type)]));\n const liveColumnDefaults = new Map(\n result.rows.map((row) => [String(row.column_name), row.column_default == null ? null : String(row.column_default)]),\n );\n const actualColumns = new Set(liveColumnTypes.keys());\n\n // A table always has at least one column, so an empty result means the table is not there —\n // no second existence query needed, and portable across real Postgres and the in-memory one.\n if (actualColumns.size === 0) {\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" does not exist (no migration has created it)`,\n );\n continue;\n }\n\n const missingColumns = expectedColumns.filter((column) => !actualColumns.has(column));\n if (missingColumns.length > 0) {\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" is missing column(s) ${missingColumns.map((c) => `\"${c}\"`).join(', ')}`,\n );\n // Uniqueness over a column that is not there cannot be assessed, and reporting it would bury\n // the real defect under a derived one.\n continue;\n }\n\n problems.push(...this.collectPostgreSqlColumnTypeMismatches(resourceType, tableName, resourceConfiguration, liveColumnTypes));\n\n problems.push(...this.collectPostgreSqlColumnDefaultMismatches(resourceType, tableName, resourceConfiguration, liveColumnDefaults));\n\n problems.push(...await this.collectMissingPostgreSqlUniqueConstraints(db, resourceType, tableName, resourceConfiguration));\n\n problems.push(...await this.collectMissingPostgreSqlPrimaryKey(db, resourceType, tableName, resourceConfiguration));\n }\n\n if (problems.length === 0) {\n this.logDebug('PostgreSQL physical table schemas verified', {\n resourceCount: postgresResourceTypes.length,\n });\n return;\n }\n\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'postgresql_table_schema_mismatch',\n message:\n `${problems.length} PostgreSQL-backed resource(s) have a table that does not match the engine's `\n + `schema plan, so their first request would fail with a bare driver error:\\n${problems.join('\\n')}\\n`\n + `The plan (ZodToSqlHybridSchemaPlannerBackendService.planSqlHybridTable) is the contract migrations `\n + `must build these tables from. It includes framework-owned columns no app schema declares — notably `\n + `\"_version_db_doc\", the optimistic-locking version the repository writes on every insert.`,\n problems,\n },\n });\n }\n\n // ================================\n // Retention opt-in prerequisites (MongoDB)\n // ================================\n\n /**\n * MECHANICALLY ENFORCED prerequisites for opting a MongoDB-backed resource into `retentionPolicy`\n * (gate **G-BKEY**, second half). Runs once at boot, and is a no-op for every application whose\n * resources are not retention-governed — which is all of them until the first opt-in.\n *\n * **The `retentionStatus = ACTIVE` backfill**, an obligation no comment in the index builder could\n * enforce. MongoDB rejects `$ne` inside a `partialFilterExpression`, so the retention-scoped unique\n * index is keyed on plain equality (`{ retentionStatus: ACTIVE }`). Every row written BEFORE the\n * resource opted in carries NO marker and therefore falls OUT of the index entirely — uniqueness\n * silently LAPSES for exactly the legacy rows most likely to contain duplicates. (Postgres does not\n * have this problem: its `IS DISTINCT FROM` predicate covers NULL.) The backfill closes the gap; it\n * is idempotent and matches nothing on every subsequent boot.\n *\n * FAIL-CLOSED: a duplicate-key error during the backfill means legacy rows already violate the\n * uniqueness the opt-in is about to assert. Boot fails loudly instead.\n *\n * The second half of the opt-in — rebuilding a unique index whose live `partialFilterExpression`\n * still predates the opt-in — used to live here, scoped to retention-governed resources. It now\n * belongs to {@link reconcileDriftedMongoUniqueIndexes}, which reconciles that axis for EVERY unique\n * index rather than only retention-scoped ones, and which this method must therefore run before: the\n * backfill has to stamp the legacy rows before an index selecting on that marker is rebuilt over\n * them.\n */\n private async reconcileRetentionGovernedMongoCollections(): Promise<void> {\n const retentionGovernedResourceTypes = Array.from(this.repositories.keys()).filter(\n (resourceType) => {\n const resourceConfiguration = this.resourceRegistry.tryGetResourceConfiguration(resourceType);\n if (!isRetentionGovernedResource(resourceConfiguration)) return false;\n // A PostgreSQL-backed resource needs neither obligation, for two DIFFERENT reasons:\n // - no marker backfill, because its retention predicate compiles to `IS DISTINCT FROM`, which\n // already matches the NULL marker a pre-opt-in row carries;\n // - no index rebuild HERE, because although the framework now DOES render its retention-scoped\n // partial unique indexes (`postgresql-schema-ddl.backend.ts`), applying schema changes stays\n // migration-owned. `verifyPostgreSqlTableSchemas` is the gate that speaks for those, and it\n // fails the boot when such an index is missing or not partial.\n // Selected POSITIVELY (`=== MONGODB`): this pass drives Mongoose collection reconciliation,\n // so it may only ever see MongoDB-backed resources. The previous `!== POSTGRESQL` would\n // have swept any future backing kind into the Mongo lane.\n return this.getResolvedPersistenceAdapterForResource(resourceType) === PersistenceAdapter.MONGODB;\n },\n );\n\n if (retentionGovernedResourceTypes.length === 0) {\n return;\n }\n\n this.logDebug('Reconciling retention-governed MongoDB collections', {\n resourceTypes: retentionGovernedResourceTypes,\n });\n\n for (const resourceType of retentionGovernedResourceTypes) {\n const mongooseModel = (this.repositories.get(resourceType) as any)?.mongooseModel as\n | Model<any>\n | undefined;\n if (!mongooseModel) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'retention_governed_resource_without_mongoose_model',\n resourceType,\n },\n });\n }\n\n // Mongoose attaches `model.collection` at COMPILE time, before any connection — so a model\n // without one is not a Mongoose model bound to a database at all (a stub schema converter in a\n // unit/integration harness). There is no collection to backfill or reindex, and such a model\n // cannot serve a query either. Skip loudly rather than failing a boot over a missing double.\n if (typeof mongooseModel.collection?.updateMany !== 'function') {\n this.logger.warn(\n `[Retention] Skipping the opt-in prerequisites for \"${resourceType}\": its model exposes no live `\n + 'MongoDB collection handle. Expected only under a stubbed schema converter — in a real '\n + 'deployment this means the backfill and index reconciliation did NOT run.',\n );\n continue;\n }\n\n await this.backfillRetentionStatusMarkers(resourceType, mongooseModel);\n }\n }\n\n\n /**\n * The runtime profile of this process, defaulting fail-SAFE.\n *\n * Mirrors `SystemAccessBackendService.resolveRuntimeProfile`, including the\n * default: an unresolvable principal cannot be a MINION (minion startup binds\n * and initializes it), so defaulting to `APPLICATION_BACKEND` preserves the\n * pre-existing behaviour for minimal and test containers rather than silently\n * skipping maintenance everywhere.\n */\n private resolveRuntimeProfile(): ApplicationRuntimeProfile {\n try {\n return this.container\n .get<{ describe(): { runtimeProfile: ApplicationRuntimeProfile } }>(SAAS_SERVICE_TYPES.RuntimePrincipalService)\n .describe().runtimeProfile;\n } catch {\n return ApplicationRuntimeProfile.APPLICATION_BACKEND;\n }\n }\n\n /** @see reconcileRetentionGovernedMongoCollections — obligation 1. */\n private async backfillRetentionStatusMarkers(\n resourceType: ResourceType,\n mongooseModel: Model<any>,\n ): Promise<void> {\n // The value written MUST be the value the retention-scoped partial unique index selects on, or the\n // backfill produces rows that STILL fall outside the index it exists to populate. Both derive it\n // from the same authority so they cannot diverge; `undefined` means `RetentionStatus` gained a\n // second visible member, which the index builder also refuses to guess at — fail the boot loudly\n // rather than backfill rows into an index that no longer covers them.\n const visibleStatus = resolveSoleVisibleRetentionStatus();\n if (visibleStatus === undefined) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'retention_status_backfill_target_ambiguous',\n resourceType,\n message:\n 'RetentionStatus now has more than one visible member, so the pre-opt-in backfill can no '\n + 'longer name a single target status. Resolve it together with the unique-index partial '\n + 'filter (both derive from resolveSoleVisibleRetentionStatus) before adding the member.',\n },\n });\n }\n\n try {\n const result = await mongooseModel.collection.updateMany(\n buildMissingRetentionMarkerFilterFragment(),\n { $set: buildRetentionMarkerBackfillPatch(visibleStatus) },\n );\n if (result.modifiedCount > 0) {\n this.logger.warn(\n `[Retention] Backfilled ${result.modifiedCount} pre-opt-in row(s) on \"${resourceType}\" to retentionStatus=${visibleStatus}. `\n + 'Those rows were outside every retention-scoped unique index until now.',\n );\n }\n } catch (error) {\n if (this.isMissingNamespaceError(error)) {\n return; // Fresh deployment: the collection does not exist yet, so there is nothing to backfill.\n }\n // A restart racing the backfill lands here as a driver session-lifecycle error. It is classified\n // rather than described: this branch used to name the race in prose and then report it as a\n // backfill failure anyway, which is the same conflation of \"the probe was interrupted\" with \"the\n // data is wrong\" that the index gates below made. See {@link isDatastoreLifecycleTerminatedError}.\n if (this.isDatastoreLifecycleTerminatedError(error)) {\n this.throwDatastoreLifecycleTerminated('the retention-status backfill', error, resourceType);\n }\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'retention_status_backfill_failed',\n resourceType,\n message:\n `Backfilling retentionStatus=${visibleStatus} failed. ${this.isDuplicateKeyError(error)\n ? 'A duplicate-key error here means legacy rows already violate the uniqueness the '\n + 'retention-scoped index is about to assert — resolve the duplicates before opting '\n + 'this resource into retentionPolicy.'\n : 'This is NOT a duplicate-key error, so it does not indicate colliding legacy rows — '\n + 'read the `error` field below for the actual cause. A connection torn down mid-backfill '\n + 'is classified separately and never reaches here.'}`,\n error: describeCaughtError(error),\n },\n });\n }\n }\n\n /**\n * Rebuild every declared UNIQUE index whose live options have drifted away from the declaration.\n *\n * MongoDB cannot modify an index in place. `createIndex` with a key pattern that already exists but\n * different options fails with `IndexOptionsConflict` REGARDLESS of the index name — creating it\n * under a new name is rejected just the same, so drop-then-create is the only reconciliation MongoDB\n * offers. Mongoose's backgrounded `autoIndex` swallows that conflict into a console error, so before\n * this pass existed the collection silently kept its OLD index: a schema could declare uniqueness\n * that nothing enforced, and the declaration would appear to have shipped while changing nothing.\n *\n * WHY THIS IS NOT SCOPED TO RETENTION-GOVERNED RESOURCES. It used to be, and it only compared\n * `partialFilterExpression`. That covered exactly one way a unique index can drift and left every\n * other one unreconciled — `.isUnique()` added to a field whose plain index already exists, or a\n * business key moving between sparse and non-sparse semantics. Both are ordinary schema evolution,\n * both hit the same `IndexOptionsConflict`, and neither had a migration path: boot failed closed in\n * every environment with no supported way forward. Uniqueness drift is a property of unique indexes,\n * not of retention, so the reconciliation belongs to all of them.\n *\n * THE COMPARED AXES are exactly those MongoDB refuses to change in place: `unique`, `sparse`, and\n * `partialFilterExpression`. Options that are irrelevant or mutable are deliberately NOT compared —\n * notably `background` (Mongoose sets it, modern servers ignore it) and `expireAfterSeconds`\n * (alterable through `collMod`, and never a unique-key concern). Comparing them would drop and\n * recreate healthy indexes on every boot.\n *\n * FAIL-CLOSED. A rebuild that cannot complete — almost always because existing rows already violate\n * the newly-declared key — aborts the boot. A collection whose index topology cannot be reconciled\n * must not serve traffic pretending its business keys are protected.\n *\n * ⚠️ OPERATIONAL NOTE: between the drop and the create, uniqueness is NOT enforced on that key. The\n * window is one round-trip per drifted index and only opens when a declaration actually changed, but\n * on a large collection the rebuild is the cost of the index build itself. Every rebuild is logged at\n * WARN with the before/after options so the event is visible in production logs.\n */\n private async reconcileDriftedMongoUniqueIndexes(): Promise<void> {\n for (const { resourceType, mongooseModel, declaredUniqueIndexes: desiredUniqueIndexes } of this.eachMongoResourceWithDeclaredUniqueIndexes()) {\n // Read the catalog directly, never through anything Mongoose memoized. This pass can only\n // reconcile an index that ALREADY exists, so it needs the live pre-repair state.\n //\n // An earlier version of this comment said the read happened \"BEFORE `Model.init()` runs (the\n // verification pass owns that await)\". Both halves are false and the pair of them cost a\n // failed boot: Mongoose fires `init()` itself at model-compile time, so by the time this pass\n // runs the build has already been attempted — and, when an index has drifted, already FAILED.\n // See {@link awaitIndexBuildAgainstCurrentState} for what that broke and how it is handled.\n let liveIndexes: Array<Record<string, any>>;\n try {\n liveIndexes = await mongooseModel.collection.indexes() as Array<Record<string, any>>;\n } catch (error) {\n if (this.isMissingNamespaceError(error)) {\n continue; // Fresh deployment: autoIndex will build the desired indexes on first write.\n }\n // The catalog read could not reach the datastore, so it observed no drift AND no absence.\n // Reporting `unique_index_inspection_failed` here told a dev-companion operator on 2026-08-15\n // that the `users` index topology was unreadable, when the only fact was that the companion\n // was being stopped mid-startup.\n if (this.isDatastoreLifecycleTerminatedError(error)) {\n this.throwDatastoreLifecycleTerminated('unique-index drift reconciliation', error, resourceType);\n }\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'unique_index_inspection_failed',\n resourceType,\n error: describeCaughtError(error),\n },\n });\n }\n\n for (const [keySpec, rawOptions] of desiredUniqueIndexes) {\n const desiredOptions = rawOptions ?? {};\n\n const liveIndex = liveIndexes.find(\n (candidate) => candidate.name !== '_id_' && this.isSameIndexKeyPattern(candidate.key, keySpec),\n );\n // No live index over this key: nothing has drifted. `mongooseModel.init()` in the verification\n // pass builds it, and that pass reports it if the build fails.\n if (!liveIndex) continue;\n\n const liveDescription = this.describeRebuildRelevantIndexOptions(liveIndex);\n const desiredDescription = this.describeRebuildRelevantIndexOptions(desiredOptions);\n if (liveDescription === desiredDescription) continue;\n\n this.logger.warn(\n `[IndexReconciliation] Unique index \"${liveIndex.name}\" on \"${resourceType}\" has drifted from its `\n + `declaration (${liveDescription} → ${desiredDescription}). MongoDB cannot modify an index in place `\n + '(IndexOptionsConflict), so it is being dropped and recreated. Uniqueness on that key is not '\n + 'enforced until the rebuild completes.',\n );\n\n try {\n await mongooseModel.collection.dropIndex(liveIndex.name);\n await mongooseModel.collection.createIndex(keySpec as any, desiredOptions as any);\n } catch (error) {\n // The ONE site in this file where a torn-down connection is NOT purely indeterminate, and so\n // the only one that must not reuse {@link throwDatastoreLifecycleTerminated}: its message\n // ends \"this is NOT a missing index\", which would be false here. The drop and the create are\n // two round trips with no transaction between them, so a teardown landing in the gap leaves\n // the collection with the old index GONE and the new one never created — uniqueness on that\n // key is genuinely unenforced, and the operator has to know that rather than be reassured.\n const lifecycleTerminated = this.isDatastoreLifecycleTerminatedError(error);\n throw this.errorBuilder.buildError(\n lifecycleTerminated ? ErrorType.INFRASTRUCTURE : ErrorType.INTERNAL,\n undefined,\n {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: lifecycleTerminated ? 'unique_index_rebuild_interrupted' : 'unique_index_rebuild_failed',\n resourceType,\n indexName: liveIndex.name,\n liveOptions: liveDescription,\n desiredOptions: desiredDescription,\n ...(lifecycleTerminated\n ? {\n message:\n `The MongoDB connection was torn down while unique index \"${liveIndex.name}\" on `\n + `\"${resourceType}\" was being rebuilt (drop-then-create). ⚠️ THE INDEX MAY HAVE BEEN `\n + 'DROPPED AND NOT RECREATED — uniqueness on that key may currently be UNENFORCED. '\n + 'The next boot reaching a live database rebuilds it (a missing index is rebuilt by '\n + '`autoIndex` and proven by the verification pass), but any write accepted in the '\n + 'meantime bypassed the constraint. If writes were served against this collection '\n + 'after this error, check that key for duplicates before relying on it.',\n }\n : {}),\n error: describeCaughtError(error),\n },\n },\n );\n }\n }\n }\n }\n\n /**\n * Every Mongo-backed resource that declares at least one UNIQUE index, with that declaration.\n *\n * ONE authority for the walk, because two passes consume it — {@link reconcileDriftedMongoUniqueIndexes}\n * and {@link verifyDeclaredMongoUniqueIndexes} — and they previously carried identical filtering and\n * tolerance rules with comments pointing at each other for justification. Circular provenance is how\n * two copies drift: whichever is edited first stops being what the other claims to mirror.\n *\n * The tolerance itself: a resource with no live collection handle is a stubbed schema converter in a\n * test harness, not a deployment defect — it cannot serve a query either, so neither pass has\n * anything to say about it. A PostgreSQL-backed resource is skipped because its indexes are\n * migration-owned; `verifyPostgreSqlTableSchemas` is the gate that speaks for those.\n */\n private *eachMongoResourceWithDeclaredUniqueIndexes(): Generator<{\n resourceType: ResourceType;\n mongooseModel: Model<any>;\n declaredUniqueIndexes: Array<[Record<string, any>, Record<string, any> | undefined]>;\n }> {\n for (const [resourceType, repository] of this.repositories.entries()) {\n // Positive Mongo selection: this generator reaches into `mongooseModel`, so anything that\n // is not MongoDB-backed is skipped — `=== POSTGRESQL → continue` would have admitted any\n // future backing kind into the Mongoose index walk.\n if (this.getResolvedPersistenceAdapterForResource(resourceType) !== PersistenceAdapter.MONGODB) {\n continue;\n }\n\n const mongooseModel = (repository as any)?.mongooseModel as Model<any> | undefined;\n if (!mongooseModel || typeof mongooseModel.collection?.indexes !== 'function') {\n continue;\n }\n\n const declaredUniqueIndexes = ((mongooseModel.schema?.indexes?.() ?? []) as Array<[Record<string, any>, Record<string, any> | undefined]>)\n .filter(([, options]) => options?.unique === true);\n if (declaredUniqueIndexes.length === 0) {\n continue;\n }\n\n yield { resourceType, mongooseModel, declaredUniqueIndexes };\n }\n }\n\n /**\n * Render the option axes MongoDB refuses to change in place, in a form two sources can be compared\n * on. Absent and `false` collapse to the same value because MongoDB omits defaulted options from\n * `listIndexes` output while Mongoose spells them out.\n *\n * `partialFilterExpression` is canonicalized key-first: it is a QUERY document, so `{a:1,b:2}` and\n * `{b:2,a:1}` select identically, and comparing their raw serializations would report drift that\n * does not exist. That false positive matters far more now that the walk covers every collection —\n * it would drop and recreate healthy unique indexes on every single boot. (Index KEY patterns are\n * order-SENSITIVE and are compared separately by `isSameIndexKeyPattern`.)\n */\n private describeRebuildRelevantIndexOptions(source: Record<string, any> | undefined): string {\n return JSON.stringify(this.canonicalizeIndexOptionValue({\n unique: source?.unique === true,\n sparse: source?.sparse === true,\n partialFilterExpression: source?.partialFilterExpression ?? null,\n }));\n }\n\n /** Recursively sort object keys so that structurally equal documents serialize identically. */\n private canonicalizeIndexOptionValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((entry) => this.canonicalizeIndexOptionValue(entry));\n }\n if (value !== null && typeof value === 'object') {\n return Object.entries(value as Record<string, unknown>)\n .sort(([leftKey], [rightKey]) => (leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0))\n .reduce<Record<string, unknown>>((canonical, [key, entry]) => {\n canonical[key] = this.canonicalizeIndexOptionValue(entry);\n return canonical;\n }, {});\n }\n return value;\n }\n\n /**\n * The declared uniqueness for one PostgreSQL table that the live catalog does NOT carry.\n *\n * **Why uniqueness is verified when column TYPES are not.** The sibling column check states that\n * types, nullability and constraints are migration-owned and deliberately unasserted. That line is\n * kept for types and nullability and broken for uniqueness, on a principle worth naming: this gate\n * exists to convert SILENT failures into boot-time diagnoses. A wrong column type fails loudly on\n * first use, with a driver error naming the column. A missing unique constraint fails silently and\n * permanently — duplicate rows accumulate, and for a creation-time identity such as\n * `ORGANIZATIONS.slug` (`.excludeFromUpdate()`) they can never be repaired through the API. Being\n * migration-OWNED never implied being un-VERIFIED; the column check is migration-owned too.\n *\n * **Matched as a SET, not in order — deliberately different from the MongoDB check.** `UNIQUE(a,b)`\n * and `UNIQUE(b,a)` enforce the identical constraint in PostgreSQL; column order only affects index\n * usability for queries, which is a migration author's call to make. (In MongoDB the order changes\n * index IDENTITY, which is why the sibling check there compares ordered key patterns.) Asserting\n * order here would fail a perfectly correct schema.\n *\n * **Partiality must match in both directions.** `skipRowsMissing` declares that rows missing a\n * member are outside the constraint, which in PostgreSQL is a PARTIAL unique index, never a plain\n * `UNIQUE (...)` — a plain constraint treats NULLs as distinct in most configurations, silently\n * producing the opposite semantics from the declaration and from the MongoDB adapter. The converse\n * matters just as much: a partial index where the schema declared a full one is a WEAKER constraint\n * than promised, so it is reported rather than accepted.\n *\n * **Single-column `isUnique` COVERAGE is checked weakly, on purpose.** The plan records only that a\n * column is unique — `planSqlHybridTable` discards the scope/`compoundWith` params — so a scoped\n * declaration (unique per organization) is indistinguishable in the plan from a global one. Requiring\n * a single-column index would therefore fail a correctly-provisioned scoped constraint. Until the plan\n * can express scope, the check is \"some unique index covers this column\", which cannot false-fail.\n *\n * **Its PARTIALITY is checked strictly when the resource is retention-governed**, because that is a\n * different axis and the plan states it outright rather than discarding it. It is also the one case\n * where a FULL index is not \"stronger than declared\" but broken: the scrub writes one shared value to\n * every retained row, so a full index makes the SECOND erasure of a subject abort. Limitation, stated\n * rather than implied: this asserts the index IS partial, not that its predicate is the retention one\n * — same depth as the composite check above, and for the same reason (gating a boot on a regex over\n * catalog DDL text is more fragile than the drift it would catch).\n *\n * **Introspection may be unavailable, and that is NOT a defect.** The catalog query is rejected\n * outright by the in-memory PostgreSQL the fixtures run on. Treating \"no rows\" as \"no constraints\"\n * there would fail every fixture boot, and special-casing the test double by name would couple a\n * production gate to a harness. Instead the query's own failure IS the signal: introspection is\n * unavailable, the constraint half is skipped with a warning, and the column half still runs.\n */\n /**\n * Columns that EXIST but whose type cannot hold what the plan declared.\n *\n * ## Why this was added, and why the old \"types are migration-owned\" line no longer holds\n *\n * This gate's contract used to say column types were \"migration-owned and intentionally not\n * asserted\". That was correct WHEN IT WAS WRITTEN — nothing rendered DDL, so the engine had no\n * opinion about a column's type to compare against. `postgresql-schema-ddl.backend.ts` is now\n * exactly that opinion, so the comparison became available and the omission became a hole.\n *\n * And it is the ONE drift class that is completely silent. Measured on a real server: `pg` sends\n * parameters in TEXT format, so PostgreSQL casts them to whatever the column already is, and decodes\n * results by that same column. Change a field from `z.string()` to `z.number()` against a live `text`\n * column and the write succeeds, the boot succeeds, and every read comes back a STRING — a value that\n * compares wrongly rather than loudly, all the way into DTOs and guards. Every other drift class this\n * gate knows about announces itself: a missing column fails the boot, a missing unique index fails the\n * boot, an `_id uuid` column rejects the write outright.\n *\n * ## Compared by JS READ TYPE, not by SQL type name\n *\n * Deliberately tolerant of decisions the plan does not express. The plan records\n * `logicalType: 'string' | 'number'` and nothing about width or precision, so a migration author who\n * chose `varchar(64)` made a decision the schema left open and must not fail a boot for it.\n * `postgresColumnTypeSatisfiesPlan` therefore asks whether a row read through the live column arrives\n * as the JavaScript type the application layer expects — which is both looser than name equality and\n * STRICTER than SQL family, because `numeric` and `bigint` decode to strings while `double precision`\n * decodes to a number. Cutting by family would have missed the very defect the renderer already\n * documents.\n *\n * Reports the expected type alongside the actual one, matching what the unique-index half does with\n * its expected DDL: this gate names a schema the framework cannot itself repair, so a refusal that\n * does not carry its remedy just moves the derivation to a human who may get it wrong.\n */\n /**\n * Columns whose live `DEFAULT` disagrees with the plan.\n *\n * Without this the gate is blind to the exact defect that motivated column defaults: a\n * `.default()` on an `.excludeFromCreate()` field is supplied by the STORE and by nothing else, so\n * a table built before the plan carried defaults accepts every write and silently stores NULL.\n * There is no bare driver error to fail on later — just rows missing a value the schema declares,\n * which is how a seeded application ended up with an organization whose only member had a NULL\n * `status` and therefore did not count as an administrator.\n *\n * Reports only a MISSING or DIFFERING default, never an EXTRA one. A column carrying a default the\n * plan does not declare is a superset the repository's writes are unaffected by — always supplying\n * the column — and refusing it would fail boot on hand-tuned operational defaults that harm\n * nothing.\n */\n private collectPostgreSqlColumnDefaultMismatches(\n resourceType: ResourceType,\n tableName: string,\n resourceConfiguration: ResourceConfiguration<any, any, any>,\n liveColumnDefaults: ReadonlyMap<string, string | null>,\n ): string[] {\n const plan = this.zodToSqlPlanner.planSqlHybridTable(\n resourceConfiguration as any,\n resourceConfiguration.mainSchema as any,\n );\n\n const problems: string[] = [];\n for (const field of plan.fields) {\n const expectedClause = renderPostgresColumnDefaultClause(field);\n if (!expectedClause) continue;\n\n const expected = normalizePostgresDefaultExpression(expectedClause.replace(/^ default /, ''));\n const live = liveColumnDefaults.get(field.name);\n\n if (live == null) {\n problems.push(\n `• \"${resourceType}\": column \"${tableName}\".\"${field.name}\" is missing its declared default `\n + `(${expected}) — the schema declares it and the create DTO cannot supply it, so rows store NULL`,\n );\n continue;\n }\n\n const actual = normalizePostgresDefaultExpression(live);\n if (actual !== expected) {\n problems.push(\n `• \"${resourceType}\": column \"${tableName}\".\"${field.name}\" has default ${actual}, plan declares ${expected}`,\n );\n }\n }\n return problems;\n }\n\n private collectPostgreSqlColumnTypeMismatches(\n resourceType: ResourceType,\n tableName: string,\n resourceConfiguration: { mainSchema?: unknown },\n liveColumnTypes: ReadonlyMap<string, string>,\n ): string[] {\n const plan = this.zodToSqlPlanner.planSqlHybridTable(\n resourceConfiguration as any,\n (resourceConfiguration as any).mainSchema,\n );\n\n const problems: string[] = [];\n for (const field of plan.fields) {\n const liveType = liveColumnTypes.get(field.name);\n // Absent columns are the caller's business, and it has already reported them. A variant-only\n // field swept into `variantConfig` is legitimately absent and must not be reported at all —\n // which is why this walks the LIVE map rather than demanding a column per planned field.\n if (liveType === undefined) continue;\n\n const plannedType = renderPostgresColumnType(field);\n if (postgresColumnTypeSatisfiesPlan(plannedType, liveType)) continue;\n\n /**\n * The CONSEQUENCE differs by class, and stating the wrong one is worse than stating none.\n *\n * Every mismatch here is a defect, but `uuid` fails LOUDLY — it rejects the write — while the\n * rest fail silently on the read. Describing a uuid column as \"silently wrong\" would send the\n * reader looking for corrupted data that does not exist, and would undersell a column that has\n * narrowed what the application is permitted to persist at all.\n */\n const consequence = classifyPostgresColumnJsReadType(liveType) === PostgresColumnJsReadType.UUID\n ? 'this column REJECTS any value that is not a UUID (\"invalid input syntax for type uuid\"), so '\n + 'the table has narrowed which identity formats the application may persist. The plan types '\n + 'identity from the schema, which is correct for BOTH ResourceIdFormat members'\n : 'a row read through this column would arrive as the wrong JavaScript type, silently — the '\n + 'driver casts writes to the column\\'s type and decodes reads by it, so nothing throws';\n\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" column \"${field.name}\" is \"${liveType}\" but the plan `\n + `declares \"${plannedType}\" — ${consequence}.\\n ↳ expected DDL: alter table \"${tableName}\" `\n + `alter column \"${field.name}\" type ${plannedType} using \"${field.name}\"::${plannedType}`,\n );\n }\n return problems;\n }\n\n private async collectMissingPostgreSqlUniqueConstraints(\n db: unknown,\n resourceType: ResourceType,\n tableName: string,\n resourceConfiguration: { mainSchema?: unknown },\n ): Promise<string[]> {\n const plan = this.zodToSqlPlanner.planSqlHybridTable(\n resourceConfiguration as any,\n (resourceConfiguration as any).mainSchema,\n );\n /**\n * The FIELDS, not just their names: `uniqueNullsAreDistinct` is a per-field opt-out and the\n * NULL-distinctness check below has to read it.\n *\n * **PRIMARY-KEY fields are excluded, mirroring the DDL renderer**, which states the rule this\n * side has to honour: *\"A primary key already carries a unique index; emitting a second one\n * would duplicate the structure PostgreSQL created implicitly\"*\n * (`postgresql-schema-ddl.backend.ts`). The producer therefore emits NO separate unique index\n * for such a field, and a verifier that still demands one is asking about an index its own\n * generator deliberately never creates.\n *\n * Every check in the loop below is VACUOUS for a primary key, which is why the exclusion is a\n * correction rather than a relaxation:\n *\n * - NULL-distinctness — a PRIMARY KEY implies NOT NULL, so no row can carry a NULL in it and\n * there is nothing for `NULLS NOT DISTINCT` to constrain. PostgreSQL never sets\n * `indnullsnotdistinct` on a `_pkey`, so the question cannot have the answer the gate wants.\n * - coverage — the `_pkey` always covers the column, so it can never fire.\n * - retention partiality — a primary key cannot be partial, and `_id` is never a scrubbed\n * column.\n *\n * FOUND BY THE FIRST LIVE POSTGRESQL BOOT (2026-08-18): INIT completed phases 2.5 → 2.6 → 2.7 →\n * 4 and then this gate refused with 22 findings, every one of them `covering column \"_id\"`. The\n * 22 are the platform resources that declare `_id` as `.isUnique()` IN ADDITION to being the\n * primary key — redundant in Mongo, where `_id` is unique by definition. The other 70 declare it\n * primary-key only and passed, which is why the split looked arbitrary from the outside.\n *\n * The pre-flight could not see it: that lane's \"gate-equivalent\" check compared planner column\n * NAMES against `information_schema`, while this gate reads INDEX SEMANTICS from `pg_index` —\n * a different question, so it answered \"would accept\" truthfully and uninformatively.\n *\n * NOTE this also removes an incidental PK-existence check that only ever applied to those 22\n * resources (via `covering.length === 0`). That asymmetry was an accident of which schemas\n * happen to add a redundant `.isUnique()`, not a designed guarantee. If PK existence should be\n * verified, it belongs in a check applied UNIFORMLY to every resource, not as a side effect here.\n */\n const singleColumnUnique = plan.fields.filter((field) => field.isUnique && !field.isPrimaryKey);\n if (singleColumnUnique.length === 0 && plan.uniqueConstraints.length === 0) {\n return [];\n }\n\n let liveUniqueIndexes: Array<{ columns: string[]; isPartial: boolean; predicate: string | null; name: string; nullsAreDistinct: boolean | null }>;\n try {\n // ONLY the query is guarded. Interpreting its rows happens inside `readPostgreSqlUniqueIndexes`\n // AFTER the await, so a defect in the mapping propagates instead of being swallowed as\n // \"this database has no catalog\" — which would silently downgrade a broken gate into a skipped\n // one, the exact failure class this gate exists to eliminate. (It did: an unparsed `array_agg`\n // result threw here and every case quietly \"passed\".)\n liveUniqueIndexes = await this.readPostgreSqlUniqueIndexes(db, tableName);\n } catch (error) {\n if (!this.isPostgreSqlCatalogUnavailableError(error)) {\n throw error;\n }\n if (!this.hasWarnedPostgreSqlIndexIntrospectionUnavailable) {\n this.hasWarnedPostgreSqlIndexIntrospectionUnavailable = true;\n this.logger.warn(\n '[PostgreSQL] Unique-constraint verification SKIPPED: this database does not expose the index catalog '\n + `(${describeCaughtError(error)}). Expected under the in-memory PostgreSQL used by fixtures. `\n + 'In a real deployment this means declared unique constraints were NOT verified — column presence still was.',\n );\n }\n return [];\n }\n\n const problems: string[] = [];\n\n /**\n * A retention-governed table's unique indexes must EXCLUDE erasure-retained rows.\n *\n * This is the one case where a FULL index is not merely \"stronger than declared\" but actively\n * broken: the scrub writes one shared value to every retained row, so a full index makes the\n * SECOND erasure of a subject violate it and abort. MongoDB carries the same scoping as a\n * `partialFilterExpression`; a table provisioned before the DDL renderer emitted the predicate\n * would silently disagree, which is exactly the shape this gate converts into a boot diagnosis.\n */\n const uniquenessExcludesRetainedRows = plan.uniquenessExcludesErasureRetainedRows === true;\n\n /**\n * The exact statement the framework would emit for a given index — attached to its own problem, so a\n * refusal carries its remedy.\n *\n * This gate names a schema the framework did not provision and CANNOT provision: applying DDL is\n * migration-owned, so every failure here is handed to a human who then has to work out what to write.\n * Since the renderer is a pure function of the same plan this check reads, that answer is already\n * computable — and printing it removes the step where someone re-derives the partial predicate,\n * the `NULLS NOT DISTINCT` clause or the retention scope by hand and gets one of them subtly wrong.\n *\n * Matched on the EXACT column set rather than \"contains these columns\", or a single-column lookup\n * would match a composite index that happens to include it. An unmatched lookup yields no hint\n * rather than a wrong one: the diagnosis must never depend on this succeeding.\n */\n const expectedUniqueIndexStatements = buildPostgresSchemaStatements(plan)\n .filter((statement) => statement.startsWith('create unique index'));\n\n const describeExpectedUniqueIndexDdl = (columns: readonly string[]): string => {\n const wanted = [...columns].sort().join(', ');\n const match = expectedUniqueIndexStatements.find((statement) => {\n const indexed = /\\(([^)]*)\\)/.exec(statement)?.[1];\n if (!indexed) return false;\n return indexed\n .split(',')\n .map((column) => column.trim().replace(/^\"|\"$/g, ''))\n .sort()\n .join(', ') === wanted;\n });\n return match ? `\\n ↳ expected DDL: ${match}` : '';\n };\n\n /**\n * A deployed index that treats NULLs as DISTINCT does not enforce what the schema declared.\n *\n * PostgreSQL's default is nulls-are-distinct, so a unique index simply does not constrain rows\n * whose key contains one — while MongoDB, for the SAME declaration, indexes a missing key as\n * `null` and treats those nulls as equal. The DDL renderer therefore emits `NULLS NOT DISTINCT`\n * (see `postgresql-schema-ddl.backend.ts`), and this is the half that notices when a DEPLOYED\n * table predates that. It is the same shape as the partiality check beside it: the plan states\n * the semantics, the catalog says what was actually provisioned, and disagreeing silently is\n * what the gate exists to stop.\n *\n * Measured on `ORGANIZATION_UNITS`: with the previous DDL, two ROOT units sharing a `code` were\n * both accepted, because `parentUnitId` is NULL for a root and is deliberately not in\n * `skipRowsMissing`. The index existed, was over the right columns, and had the right predicate —\n * every property this gate checked — and enforced nothing for the rows an org chart starts with.\n *\n * `null` (a server older than PostgreSQL 15, which has no such setting) is UNKNOWN and never\n * faults: a gate that cannot ask must not accuse.\n */\n const reportNullsDistinct = (\n live: { name: string; nullsAreDistinct: boolean | null },\n subject: string,\n ): void => {\n if (live.nullsAreDistinct !== true) return;\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" index \"${live.name}\" ${subject} treats NULLs as DISTINCT, so it `\n + 'does NOT constrain rows whose key contains one — two such rows are both accepted. The schema declares '\n + 'the MongoDB semantics (a missing key is one shared value), which PostgreSQL spells NULLS NOT DISTINCT. '\n + 'Re-provision the index from the current plan.',\n );\n };\n\n for (const uniqueField of singleColumnUnique) {\n const column = uniqueField.name;\n const covering = liveUniqueIndexes.filter((index) => index.columns.includes(column));\n if (covering.length === 0) {\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" has no UNIQUE index covering column \"${column}\"`\n + describeExpectedUniqueIndexDdl([column]),\n );\n continue;\n }\n // Only for an index whose columns are EXACTLY this one: coverage above is deliberately weak\n // (an index over a superset counts), and a wider index's NULL rule is that key's business, not\n // this column's. The plan's own opt-out is honoured — see `uniqueNullsAreDistinct`.\n if (uniqueField.uniqueNullsAreDistinct !== true) {\n const exact = covering.find((index) => index.columns.length === 1);\n if (exact) reportNullsDistinct(exact, `covering column \"${column}\"`);\n }\n // Partiality is checked even though COVERAGE is checked weakly — see the header. The weak\n // coverage rule exists because a scoped declaration is indistinguishable from a global one in\n // the plan; that ambiguity does not extend to partiality, which the plan states outright.\n if (uniquenessExcludesRetainedRows && !covering.some((index) => index.isPartial)) {\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" index \"${covering[0]!.name}\" covering column \"${column}\" is a `\n + 'FULL unique index, but this resource is retention-governed — it must be PARTIAL, excluding '\n + 'erasure-retained rows. Every retained row carries the same scrubbed value, so a full index makes '\n + 'the SECOND erasure of a subject violate it and abort.'\n + describeExpectedUniqueIndexDdl([column]),\n );\n }\n }\n\n for (const constraint of plan.uniqueConstraints) {\n /**\n * Why this constraint must be partial, if it must — ONE list, because partiality now has TWO\n * independent sources and the report has to name whichever applies.\n *\n * Built as text rather than branching on `skipRowsMissing` at each message site: that field is\n * `undefined` when partiality comes from retention alone, so the previous `skipRowsMissing!`\n * dereferences would have thrown while formatting the very diagnosis they exist to print.\n */\n const partialityReasons = [\n ...((constraint.skipRowsMissing?.length ?? 0) > 0\n ? [`${constraint.skipRowsMissing!.map((f) => `\"${f}\" IS NOT NULL`).join(' AND ')} (declared skipRowsMissing — a plain UNIQUE treats NULLs as distinct, the opposite of the declared semantics)`]\n : []),\n ...(uniquenessExcludesRetainedRows\n ? ['it must exclude erasure-retained rows (retentionPolicy — every retained row carries the same scrubbed value, so a full index aborts the SECOND erasure of a subject)']\n : []),\n ];\n const expectPartial = partialityReasons.length > 0;\n const sameColumns = liveUniqueIndexes.filter((index) => this.isSameColumnSet(index.columns, constraint.fields));\n\n if (sameColumns.length === 0) {\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" has no UNIQUE index over (${constraint.fields.join(', ')})`\n + (expectPartial ? ` — it must be a PARTIAL index: ${partialityReasons.join('; ')}` : '')\n + describeExpectedUniqueIndexDdl(constraint.fields),\n );\n continue;\n }\n\n // A composite business key never opts out: it mirrors a MongoDB compound unique index, whose\n // NULL semantics are nulls-not-distinct.\n reportNullsDistinct(sameColumns[0]!, `over (${constraint.fields.join(', ')})`);\n\n if (!sameColumns.some((index) => index.isPartial === expectPartial)) {\n const live = sameColumns[0]!;\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" index \"${live.name}\" over (${constraint.fields.join(', ')}) is `\n + `${live.isPartial ? `PARTIAL (${live.predicate}) but the schema declares a full constraint` : 'a FULL constraint but the schema declares it partial'}`\n + `${expectPartial ? ` — ${partialityReasons.join('; ')}` : ''}`\n + describeExpectedUniqueIndexDdl(constraint.fields),\n );\n }\n }\n\n return problems;\n }\n\n /**\n * Prove that every PostgreSQL-backed resource's table actually HAS the PRIMARY KEY its plan\n * declares — the check {@link collectMissingPostgreSqlUniqueConstraints}'s own header asked for:\n * *\"If PK existence should be verified, it belongs in a check applied UNIFORMLY to every resource,\n * not as a side effect here.\"*\n *\n * **The hole this closes.** The unique-constraint gate EXCLUDES primary-key fields by design (the\n * DDL renderer emits no separate unique index for them), so before this check NOTHING verified\n * that the `_pkey` PostgreSQL was trusted to enforce actually exists. It can fail to: three\n * resources (`consumableTokens`, `jobExecutions`, `jobPayloadStorage`) declared `_id` without\n * `.isPrimaryKey()` and their tables were provisioned constraint-less — duplicate `_id` rows\n * representable on this adapter only, silently, while MongoDB enforces `_id` uniqueness on every\n * collection. The planner now flags a declared `_id` unconditionally and a follow-up migration\n * heals old tables; this gate is what notices a table that predates both and never got the ALTER.\n *\n * A refusal carries its remedy (the exact `alter table … add primary key`), same convention as\n * the unique-index gate's expected-DDL hints: every failure here names a schema the framework\n * cannot repair itself — applying DDL is migration-owned — so the message hands the human the\n * statement instead of making them derive it.\n *\n * Comparison is on the column SET ({@link isSameColumnSet}), matching the unique-index gate:\n * PostgreSQL enforces `PRIMARY KEY (a,b)` and `(b,a)` identically.\n */\n private async collectMissingPostgreSqlPrimaryKey(\n db: unknown,\n resourceType: ResourceType,\n tableName: string,\n resourceConfiguration: { mainSchema?: unknown },\n ): Promise<string[]> {\n const plan = this.zodToSqlPlanner.planSqlHybridTable(\n resourceConfiguration as any,\n (resourceConfiguration as any).mainSchema,\n );\n const declaredPkColumns = plan.fields.filter((field) => field.isPrimaryKey).map((field) => field.name);\n if (declaredPkColumns.length === 0) {\n // Unreachable through the current planner — it flags a declared `_id` as primary key\n // unconditionally and injects one when the schema declares none (both pinned in\n // `aggregation-join-target-pk-matches-planner.test.ts`). An empty set would mean the PLANNER\n // contract moved, which is that pin's defect to name, not a table problem this gate can\n // truthfully report against a database.\n return [];\n }\n\n let livePkColumns: string[] | null;\n try {\n // ONLY the query is guarded — same discipline as the unique-index read above: interpreting\n // rows happens after the await, so a mapping defect propagates instead of downgrading the\n // gate into a silent skip.\n livePkColumns = await this.readPostgreSqlPrimaryKeyColumns(db, tableName);\n } catch (error) {\n if (!this.isPostgreSqlCatalogUnavailableError(error)) {\n throw error;\n }\n if (!this.hasWarnedPostgreSqlPrimaryKeyIntrospectionUnavailable) {\n this.hasWarnedPostgreSqlPrimaryKeyIntrospectionUnavailable = true;\n this.logger.warn(\n '[PostgreSQL] Primary-key verification SKIPPED: this database does not expose the index catalog '\n + `(${describeCaughtError(error)}). Expected under the in-memory PostgreSQL used by fixtures. `\n + 'In a real deployment this means the declared primary key was NOT verified — column presence still was.',\n );\n }\n return [];\n }\n\n if (livePkColumns === null) {\n return [\n `• \"${resourceType}\": table \"${tableName}\" has NO PRIMARY KEY constraint — the plan declares one over `\n + `(${declaredPkColumns.join(', ')}), and every repository statement keys on it. Without the constraint, `\n + 'duplicate rows are representable on PostgreSQL that MongoDB structurally refuses.'\n + `\\n ↳ expected DDL: alter table \"${tableName}\" add primary key (${declaredPkColumns.map((column) => `\"${column}\"`).join(', ')});`,\n ];\n }\n\n if (!this.isSameColumnSet(livePkColumns, declaredPkColumns)) {\n return [\n `• \"${resourceType}\": table \"${tableName}\" PRIMARY KEY is over (${livePkColumns.join(', ')}) but the plan `\n + `declares (${declaredPkColumns.join(', ')}) — a constraint over the wrong columns enforces the wrong `\n + 'identity. Re-provision from the current plan; a primary-key move is migration-owned and hand-authored.',\n ];\n }\n\n return [];\n }\n\n /**\n * The live PRIMARY KEY's column set for a table, or `null` when the table has no primary key.\n *\n * Read from `pg_index.indisprimary` rather than `pg_constraint` so the query shares\n * {@link readPostgreSqlUniqueIndexes}'s exact join shape — including the `::text` cast on\n * `attname`, which that method's header records as REQUIRED (a `name[]` arrives from the driver\n * as an unparsed `{a,b,c}` string), and the `unnest … with ordinality` that keeps column order\n * for the report.\n */\n private async readPostgreSqlPrimaryKeyColumns(\n db: unknown,\n tableName: string,\n ): Promise<string[] | null> {\n const result = await sql<{ columns: string[] }>`\n select array_agg(a.attname::text order by k.ord) as columns\n from pg_class t\n join pg_index ix on t.oid = ix.indrelid\n join lateral unnest(ix.indkey) with ordinality as k(attnum, ord) on true\n join pg_attribute a on a.attrelid = t.oid and a.attnum = k.attnum\n where t.relname = ${tableName} and ix.indisprimary\n group by ix.indexrelid\n `.execute(db as any);\n\n if (result.rows.length === 0) {\n return null;\n }\n return this.normalizePostgreSqlArrayColumn(result.rows[0]!.columns);\n }\n\n /**\n * Unique indexes on one table, read from the catalog.\n *\n * `pg_index` rather than `information_schema`: a PARTIAL unique index is not a table CONSTRAINT and\n * is invisible to `information_schema.table_constraints`, so that source would report the framework's\n * presence-scoped keys as missing. `pg_index` reports plain `UNIQUE` constraints and partial unique\n * indexes uniformly, which is what makes one query enough.\n *\n * Structured rather than parsed out of `pg_indexes.indexdef`: the text form is stable but quoting is\n * case-dependent (`\"organizationId\"` vs `code`), and a regex over DDL text is a fragile thing to gate\n * a boot on. `unnest(indkey) with ordinality` preserves column order for the report even though the\n * comparison itself is order-insensitive.\n *\n * `indnullsnotdistinct` is read THROUGH `to_jsonb(ix)` rather than as a column, and that is the\n * whole point of the indirection: the column exists only on PostgreSQL 15+, and naming it directly\n * makes an older server answer `42703`, which\n * {@link isPostgreSqlCatalogUnavailableError} classifies as \"this database cannot answer\" — so a\n * single missing column would silently disable the ENTIRE gate on that server, including the\n * presence and partiality checks that work there perfectly well. Through `to_jsonb` the field is\n * simply `null`, which the comparison treats as unknown and does not fault.\n *\n * The `::text` cast on `attname` is REQUIRED, not cosmetic. `attname` is PostgreSQL's `name` type,\n * and node-postgres only parses an array whose element OID it recognises — a `name[]` arrives as the\n * raw literal STRING `{a,b,c}`, which is not an array and blows up on `.map`. Casting to `text[]`,\n * a type the driver does parse, is what makes the column list a real array. This was a live defect\n * caught only once the query ran against a real PostgreSQL; the hand-run probe that preceded it\n * returned the same string and it was misread as an array.\n */\n private async readPostgreSqlUniqueIndexes(\n db: unknown,\n tableName: string,\n ): Promise<Array<{ columns: string[]; isPartial: boolean; predicate: string | null; name: string; nullsAreDistinct: boolean | null }>> {\n const result = await sql<{ index_name: string; is_partial: boolean; predicate: string | null; columns: string[]; nulls_not_distinct: boolean | null }>`\n select i.relname as index_name,\n ix.indpred is not null as is_partial,\n pg_get_expr(ix.indpred, ix.indrelid) as predicate,\n (to_jsonb(ix) ->> 'indnullsnotdistinct')::boolean as nulls_not_distinct,\n array_agg(a.attname::text order by k.ord) as columns\n from pg_class t\n join pg_index ix on t.oid = ix.indrelid\n join pg_class i on i.oid = ix.indexrelid\n join lateral unnest(ix.indkey) with ordinality as k(attnum, ord) on true\n join pg_attribute a on a.attrelid = t.oid and a.attnum = k.attnum\n where t.relname = ${tableName} and ix.indisunique\n group by i.relname, ix.indpred, ix.indrelid, to_jsonb(ix)\n `.execute(db as any);\n\n return result.rows.map((row) => ({\n name: String(row.index_name),\n isPartial: Boolean(row.is_partial),\n predicate: row.predicate ?? null,\n // `null` means \"this server cannot say\" (PostgreSQL < 15), NOT \"nulls are distinct\". The two\n // must stay distinguishable: the gate faults on the latter and stays silent on the former.\n nullsAreDistinct: row.nulls_not_distinct === null || row.nulls_not_distinct === undefined\n ? null\n : !row.nulls_not_distinct,\n // Defensive on top of the ::text[] cast: a driver that hands back the raw `{a,b,c}` literal\n // would otherwise throw here, and this method is called from a boot gate — degrading a driver\n // quirk into a crash-loop would be a worse outcome than the gap the gate closes.\n columns: this.normalizePostgreSqlArrayColumn(row.columns),\n }));\n }\n\n /** Accept both a parsed array and PostgreSQL's raw `{a,b,c}` array literal. */\n private normalizePostgreSqlArrayColumn(value: unknown): string[] {\n if (Array.isArray(value)) return value.map((entry) => String(entry));\n if (typeof value !== 'string') return [];\n return value\n .replace(/^\\{|\\}$/g, '')\n .split(',')\n .map((entry) => entry.trim().replace(/^\"|\"$/g, ''))\n .filter((entry) => entry.length > 0);\n }\n\n /**\n * Whether a failed catalog read means \"this database cannot answer\" rather than \"this code is wrong\".\n *\n * The distinction is load-bearing. Treating every error as unavailability turns a defect in the\n * gate into a silent skip — which is the same silent-failure class the gate exists to remove, just\n * relocated. Only a missing/unknown relation or column counts: PostgreSQL reports those as\n * `42P01` / `42703`, and the SQL emulator used by fixtures rejects the catalog query with an\n * equivalent \"does not exist\" message.\n */\n private isPostgreSqlCatalogUnavailableError(error: unknown): boolean {\n const code = String((error as { code?: unknown })?.code ?? '');\n if (code === '42P01' || code === '42703') return true;\n return /does not exist/i.test(describeCaughtError(error));\n }\n\n /** Uniqueness is a property of the column SET; PostgreSQL enforces `UNIQUE(a,b)` and `UNIQUE(b,a)` identically. */\n private isSameColumnSet(live: readonly string[], declared: readonly string[]): boolean {\n if (live.length !== declared.length) return false;\n const liveSet = new Set(live);\n return declared.every((column) => liveSet.has(column));\n }\n\n /**\n * Prove that every UNIQUE index the schema declares actually EXISTS on its MongoDB collection.\n *\n * **The hole this closes.** A unique index that fails to build is completely silent. The framework\n * leaves Mongoose's `autoIndex` at its default and never awaits `Model.init()`, so a rejected build\n * surfaces only as a console error: boot succeeds, writes succeed, and the constraint the schema\n * promises does not exist. Two realistic causes — existing rows already violating a newly-declared\n * key, and an option pair MongoDB refuses (`sparse` + `partialFilterExpression` is rejected with\n * `CannotCreateIndex`). Neither is hypothetical: both are documented failure modes in this codebase.\n *\n * **Why {@link reconcileDriftedMongoUniqueIndexes} next door does not cover it.** That pass now walks\n * every collection too, but it answers the opposite question: given an index that IS there, do its\n * options still match the declaration. An index that is ABSENT is precisely what it skips, and\n * deliberately — a missing index is what `autoIndex` is supposed to build, so there is nothing to\n * reconcile and everything to verify. The two are sequential halves of one obligation: reconcile\n * what exists, then prove what should exist does.\n *\n * **Awaiting the index build is the fix, not the check.** `init()` resolves when index building\n * finishes and REJECTS when it fails, so awaiting it is what converts the silent console error into\n * something a boot can act on. The comparison afterwards is the belt-and-braces half: it also\n * catches an index that was never attempted (autoIndex disabled downstream) rather than attempted\n * and failed.\n *\n * It is awaited through {@link awaitIndexBuildAgainstCurrentState} rather than by calling\n * `mongooseModel.init()` here, and that indirection is load-bearing: `init()` memoizes, and\n * Mongoose has already called it once — before this boot's repair passes ran. Awaiting it directly\n * reads a verdict about the PRE-repair catalog.\n *\n * **Fail-closed on a definitive absence; never on an indeterminate probe.** A missing unique index\n * is not a transient state — serving traffic while pretending a business key is protected is how\n * duplicate rows become permanent (`ORGANIZATIONS.slug` is `.excludeFromUpdate()`, so a collision\n * written today could never be repaired through the API). Both sibling gates in this file already\n * make that call unconditionally: the PostgreSQL column check fails the boot, and\n * {@link reconcileDriftedMongoUniqueIndexes} refuses to let a resource \"serve traffic pretending its\n * business keys are protected\". An environment-class split (fail in dev, warn in prod) was REJECTED —\n * no boot gate in this service uses such an axis, and introducing one here would leave two gates\n * disagreeing about the same hazard. A collection that does not exist yet, or a model with no live\n * collection handle, is INDETERMINATE and is skipped rather than reported.\n *\n * Every problem is collected into ONE error, matching the PostgreSQL verifier: fixing a drifted\n * deployment must not be an N-boot loop.\n *\n * assurance-control: WILDO.DATA.INTEGRITY_CONSTRAINTS — a uniqueness control the schema declares is\n * proven to exist in the datastore before the application serves traffic, rather than assumed.\n */\n private async verifyDeclaredMongoUniqueIndexes(): Promise<void> {\n const problems: string[] = [];\n // Counted so SUCCESS carries evidence, not just silence. A fail-closed gate that passes proves\n // nothing on its own: a gate that iterated an EMPTY set — an unpopulated registry, a generator\n // that yielded nothing — exits exactly the same way as one that checked every index and found\n // them all present. Boot then looks identical either way, and \"it booted, therefore the indexes\n // exist\" is an inference the run never actually earned.\n let uniqueIndexesVerifiedPresent = 0;\n let resourcesCarryingUniqueIndexes = 0;\n // Resources the gate could NOT inspect because their collection does not exist yet. Counted and\n // REPORTED rather than passed over: the verified count alone reads as a coverage figure, and a\n // reader has no way to tell \"62 verified\" from \"62 verified, 40 never looked at\". On a fresh or\n // lightly-exercised database the skipped set can be the larger one.\n let skippedMissingCollectionCount = 0;\n let mongoBackedResourceCount = 0;\n for (const resourceType of this.repositories.keys()) {\n // Positive Mongo count: this figure is the evidence line for the MONGO unique-index gate,\n // so only MongoDB-backed resources belong in it — `!== POSTGRESQL` would have inflated it\n // with any future backing kind.\n if (this.getResolvedPersistenceAdapterForResource(resourceType) === PersistenceAdapter.MONGODB) {\n mongoBackedResourceCount += 1;\n }\n }\n\n for (const { resourceType, mongooseModel, declaredUniqueIndexes } of this.eachMongoResourceWithDeclaredUniqueIndexes()) {\n // THE load-bearing line. Production has never awaited this, which is the entire reason a failed\n // build has been invisible. A rejection here names the real cause (duplicate data,\n // `CannotCreateIndex`, …) instead of leaving it in a console nobody reads.\n try {\n await this.awaitIndexBuildAgainstCurrentState(resourceType, mongooseModel);\n } catch (error) {\n // Abort the whole pass, do not collect a per-resource \"problem\". Once the connection is gone\n // every remaining resource fails identically and tells us nothing, so collecting them produces\n // a list that reads like a survey of broken collections and is really one closed socket\n // reported N times. The 2026-08-15 apps-manager boot printed 49 such bullets.\n if (this.isDatastoreLifecycleTerminatedError(error)) {\n this.throwDatastoreLifecycleTerminated('declared-unique-index verification', error, resourceType);\n }\n if (!this.isMissingNamespaceError(error)) {\n problems.push(\n `• \"${resourceType}\": index building FAILED — ${describeCaughtError(error)}`,\n );\n } else {\n skippedMissingCollectionCount += 1;\n }\n continue;\n }\n\n // A SECOND catalog read, and not a redundant one: the reconciliation pass read the collection\n // BEFORE `init()`, and `init()` both builds missing indexes and (on a fresh deployment) creates\n // the collection itself. Reusing that earlier snapshot would report indexes as missing that this\n // pass has just caused to exist.\n let liveIndexes: Array<Record<string, any>>;\n try {\n liveIndexes = await mongooseModel.collection.indexes() as Array<Record<string, any>>;\n } catch (error) {\n // A collection that does not exist yet is a fresh deployment, not a missing constraint.\n if (this.isMissingNamespaceError(error)) {\n skippedMissingCollectionCount += 1;\n continue;\n }\n // Same abort as the index-build half above. This is the exact site that produced the FIRST of\n // the 49 bullets (\"could not read indexes — Operation interrupted because client was closed\"),\n // with the remaining 48 following from the build half once the client was fully closed.\n if (this.isDatastoreLifecycleTerminatedError(error)) {\n this.throwDatastoreLifecycleTerminated('declared-unique-index verification', error, resourceType);\n }\n problems.push(`• \"${resourceType}\": could not read indexes — ${describeCaughtError(error)}`);\n continue;\n }\n\n resourcesCarryingUniqueIndexes += 1;\n\n for (const [keySpec, options] of declaredUniqueIndexes) {\n const isPresent = liveIndexes.some(\n (live) => live.unique === true && this.isSameIndexKeyPattern(live.key, keySpec),\n );\n if (isPresent) uniqueIndexesVerifiedPresent += 1;\n if (!isPresent) {\n const keyDescription = Object.keys(keySpec).join(', ');\n const predicate = options?.partialFilterExpression\n ? ` (partial: ${JSON.stringify(options.partialFilterExpression)})`\n : '';\n problems.push(\n `• \"${resourceType}\": declared UNIQUE index over (${keyDescription})${predicate} is NOT present on the collection`,\n );\n }\n }\n }\n\n if (problems.length === 0) {\n // Deliberately WARN, not debug, when the gate verified nothing. Zero is not a pass — it means\n // the check had no population to check, and the deployment should not read a silent boot as\n // \"every declared uniqueness constraint is enforced\". Any non-zero count is the ordinary case\n // and stays at debug level.\n if (uniqueIndexesVerifiedPresent === 0) {\n this.logger.warn(\n 'Declared-unique-index verification ran but checked NOTHING — no Mongo-backed resource '\n + 'presented a declared unique index. A silent boot therefore proves no uniqueness '\n + 'constraint; confirm the resource registry was populated before this gate ran.',\n { reason: 'mongodb_declared_unique_index_verification_empty' },\n );\n return;\n }\n // INFO, not `logDebug`: this service disables its own debug channel in the constructor\n // (`setDebugTypeLogging('RepositoriesRegistryHandler', false)`), so a debug line here is\n // written to nowhere. That is fine for chatter and wrong for this — the whole point of the\n // counter is that a silent boot can otherwise be read as \"every declared uniqueness\n // constraint is enforced\" when the gate may have checked nothing. One line per boot, stating\n // what a fail-closed control actually verified, is the evidence that claim rests on.\n this.logger.info('Unique-index verification complete (MongoDB)', {\n // NAMED for what they are. `verifiedIndexCount` said neither what was counted nor against\n // what — it read as \"how many indexes exist\", which invited exactly the wrong question.\n uniqueIndexesVerifiedPresent,\n resourcesCarryingUniqueIndexes,\n // The denominators. Without them the first number reads as coverage, and a resource whose\n // collection has never been written is indistinguishable from one that passed.\n resourcesSkippedCollectionMissing: skippedMissingCollectionCount,\n mongoBackedResourceCount,\n // THE discriminator. Every process that boots this registry logs under the same `service`\n // name, so five different registries — app backend, companion, minion, apps-manager,\n // module-registry — emitted five different counts that were indistinguishable in the\n // payload and looked like one number fluctuating. Each registry holds a different resource\n // set, so the count is only meaningful next to the registry it was taken from.\n //\n // It also settles a question this field was added to answer. `platform-apps-manager` logged\n // 65 twenty-eight times and 61 once, which read like a fail-closed control occasionally\n // verifying a subset. It is not: that process holds MORE THAN ONE registry. 65 is its own\n // platform registry (one per restart); the single 61 is a PER-MANAGED-APPLICATION registry,\n // built by `PlatformWildoApplicationRepositoriesManager` right after the app's database\n // connection opens. Two registries, two legitimately different resource sets, one process.\n //\n // Worth stating because the wrong reading was reached twice — first as \"the count varies\n // between boots\" (it does not; it varies between SERVICES), then as \"the gate races registry\n // population\" (it does not; `initializeRepositories` receives its resource set as an argument\n // and the caller has it in hand). Both readings came from comparing counts without knowing\n // which registry produced them, which is exactly the gap this field closes.\n registrySize: this.repositories.size,\n });\n return;\n }\n\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'mongodb_declared_unique_index_missing',\n message:\n `${problems.length} declared UNIQUE index(es) do not exist on their MongoDB collection, so the `\n + `uniqueness those schemas promise is NOT being enforced:\\n${problems.join('\\n')}\\n`\n + `The usual cause is existing rows that already violate a newly-declared key — run `\n + `\"node scripts/check-duplicate-business-keys.mjs\" against the database to find them. The other `\n + `cause is an index whose options MongoDB refuses to build (it rejects \"sparse\" combined with `\n + `\"partialFilterExpression\"). Until the index exists, duplicate writes will be accepted silently.`,\n problems,\n },\n });\n }\n\n /**\n * `Model.init()`, re-attempted once when the CACHED attempt is what failed.\n *\n * ## The defect this closes\n *\n * `Model.init()` is a one-shot: it memoizes its promise on `$init` and every later call returns\n * that same settled promise. Mongoose fires it ITSELF the moment a model is compiled — from\n * `Model.compile`, `Mongoose#model` and `Connection#model`, each as `init().catch(() => {})` —\n * which is long before this registry runs a single boot pass.\n *\n * (Read against mongoose 8.23.0. Cited by FUNCTION rather than by line: a dependency's line numbers\n * rot silently on the next bump, and this comment is the reason the code below looks unusual.)\n *\n * So the await in {@link verifyDeclaredMongoUniqueIndexes} was never the first attempt, and the\n * ordering the boot sequence carefully establishes — repair, THEN verify — could not reach it. The\n * promise it consumes settled before either repair pass began.\n *\n * Measured on the running platform stack, 2026-08-14 (`platform-apps-manager` INIT):\n *\n * 1. models compile → mongoose `ensureIndexes` → `createIndex` hits the still-drifted\n * `platformApplications.name_1` → `IndexKeySpecsConflict`. `$init` is now permanently rejected,\n * and the rejection is swallowed by mongoose's own `.catch`.\n * 2. {@link reconcileDriftedMongoUniqueIndexes} drops and recreates it correctly. It does not\n * throw; the collection genuinely ends up carrying `{unique: true, sparse: true}`.\n * 3. this gate awaits `init()`, receives the step-1 rejection, and fails the boot describing a\n * collection that step 2 had already repaired — quoting the PRE-repair index in the message.\n *\n * Every genuine drift therefore cost exactly one failed boot before self-healing on the next one:\n * precisely the N-boot loop this gate's contract promises to avoid. It failed CLOSED, so nothing\n * unsafe ever shipped — the gate was over-strict, never over-permissive.\n *\n * ## Why a retry, rather than invalidating the cache when a repair happens\n *\n * Two boot passes can change what a build would do — the retention backfill and the unique-index\n * reconciliation — and a third is a plausible future addition. Coupling this gate to \"whichever\n * pass repaired something\" makes the next pass a silent regression. A cached FAILURE is not\n * evidence about the CURRENT catalog under any circumstances, so discarding it needs no knowledge\n * of who repaired what.\n *\n * The converse does not hold and no retry is spent on it: a cached SUCCESS means mongoose built\n * every index the schema declares, which is exactly the condition under which the reconciliation\n * finds no drift and changes nothing. Both passes read their declarations from the same\n * `schema.indexes()`.\n *\n * ## What the retry cannot hide\n *\n * A build that fails for a REAL reason fails identically the second time — duplicate rows are still\n * there, an illegal option pair is still illegal — and that second error is what gets reported. It\n * is also the more useful one: it describes the catalog as it stands after every repair, rather\n * than as it stood before them.\n *\n * `$init` is mongoose-internal, and this is the only production code that touches it — the\n * integration suites reach for it too, to put an already-booted harness back into the state a real\n * first boot starts from, which is how the mechanism was understood at a test site for months\n * while the path that mattered kept consuming a stale verdict. The alternative\n * — `ensureIndexes()`, which is public and uncached — silently drops the `autoCreate` and\n * search-index halves of `init()`, so a retry through it would not re-attempt what actually failed.\n */\n private async awaitIndexBuildAgainstCurrentState(\n resourceType: ResourceType,\n mongooseModel: Model<any>,\n ): Promise<void> {\n try {\n await mongooseModel.init();\n return;\n } catch (cachedFailure) {\n // A collection that does not exist is the FRESH-DEPLOYMENT state, not a stale verdict: no boot\n // pass creates a collection, so nothing between the memoized attempt and here can have changed\n // the answer. Re-attempting would spend a round trip to reach the same rejection, and — if\n // `autoCreate` created the collection on the second pass — would silently move the resource out\n // of the caller's `skippedMissingCollectionCount` and into the verified population. Leave that\n // path exactly as it was and let the caller classify it.\n if (this.isMissingNamespaceError(cachedFailure)) throw cachedFailure;\n\n // Discard the one-shot cache so `init()` re-runs against the repaired catalog. Deliberately\n // NOT swallowing the retry's own rejection: it is the answer this gate exists to produce.\n (mongooseModel as unknown as { $init: Promise<unknown> | null }).$init = null;\n }\n\n await mongooseModel.init();\n\n // Only reachable when the cached attempt failed and a fresh one succeeded — i.e. a boot pass\n // repaired the collection between them. Logged because the reconciliation's own WARN describes\n // the repair, and nothing else would record that the fail-closed gate re-examined it.\n //\n // INFO for the same reason the completion counters below are: measured on the 2026-08-14\n // `platform-apps-manager` INIT log, the environment where this fires emits 264 info, 15 warn and\n // 9 error lines and ZERO debug ones. A debug line here would be written to nowhere, which is\n // precisely the state that let this defect run — a gate that refused a boot with no record of\n // what it had actually examined. It fires only when a repair happened, so it is not per-boot noise.\n this.logger.info(\n `[IndexReconciliation] \"${resourceType}\": the memoized Mongoose index build had failed, but a fresh `\n + 'attempt against the current catalog succeeded — a boot repair pass ran between the two. '\n + 'Verifying against the fresh result.',\n );\n }\n\n /**\n * Index key patterns are ORDER-SENSITIVE in MongoDB — `{a:1,b:1}` and `{b:1,a:1}` are different\n * indexes — so the comparison walks the keys in declaration order rather than sorting them.\n */\n private isSameIndexKeyPattern(\n liveKey: Record<string, any> | undefined,\n desiredKey: Record<string, any>,\n ): boolean {\n if (!liveKey) return false;\n const liveEntries = Object.entries(liveKey);\n const desiredEntries = Object.entries(desiredKey);\n if (liveEntries.length !== desiredEntries.length) return false;\n return liveEntries.every(\n ([field, direction], index) =>\n desiredEntries[index]![0] === field && String(desiredEntries[index]![1]) === String(direction),\n );\n }\n\n /** MongoDB reports an operation against a not-yet-created collection with code 26 / `NamespaceNotFound`. */\n private isMissingNamespaceError(error: unknown): boolean {\n const code = (error as { code?: unknown })?.code;\n const codeName = (error as { codeName?: unknown })?.codeName;\n return code === 26 || codeName === 'NamespaceNotFound';\n }\n\n /**\n * The driver's connection LIFECYCLE has terminated underneath a probe — the client was closed, the\n * topology shut down, the pool closed, or the session ended.\n *\n * ## Why this needed its own classifier\n *\n * Every index gate in this file documents the same contract: *fail-closed on a definitive absence;\n * never on an indeterminate probe* (see {@link verifyDeclaredMongoUniqueIndexes}). Until this\n * existed, {@link isMissingNamespaceError} was the ONLY indeterminacy classifier, so exactly one\n * shape of \"the probe learned nothing\" was recognised and every other shape was reported as a\n * definitive constraint verdict.\n *\n * A torn-down connection is the purest indeterminate probe there is: the gate did not observe an\n * absent index, it failed to observe anything at all. Reporting it as a missing unique index is not\n * a conservative approximation — it is a different claim, about the DATA rather than the CONNECTION,\n * and it is false. It also came with remediation (\"existing rows already violate a newly-declared\n * key — run check-duplicate-business-keys.mjs\") that sends an operator to audit data which is fine.\n *\n * Observed twice in one dev session on 2026-08-15, at two different call sites, from one cause: the\n * dev stack received SIGTERM ~14s into an application initialization. `platform-apps-manager`\n * reported 49 collections whose \"declared UNIQUE index does not exist\"; the companion refused to\n * start with `unique_index_inspection_failed` on `users`. Both databases were entirely healthy.\n *\n * ## Why treating it as indeterminate does NOT weaken the fail-closed control\n *\n * The control exists to stop the application serving traffic while a declared uniqueness constraint\n * is unenforced. That risk requires the application to SERVE traffic — and a process whose Mongo\n * client has closed serves nothing. Registry initialization still fails (the registry genuinely did\n * not initialize); what changes is that it fails as INFRASTRUCTURE with an accurate reason instead\n * of accusing the schema or the data. The next boot that reaches a live datastore re-runs the gate\n * in full, so no window is opened in which unverified indexes back live traffic.\n *\n * ## Scope of the match, and what is deliberately excluded\n *\n * The four `Mongo*Error` names below are the driver's LIFECYCLE-TERMINAL errors, verified against\n * mongodb 6.21.0 (`lib/error.js`, `lib/cmap/errors.js`), each exposing a stable `name` getter.\n * Matched by `name` rather than message — the messages are the driver's, not ours, and it reserves\n * the right to change them.\n *\n * `MongoPoolClearedError` and `MongoWaitQueueTimeoutError` are deliberately NOT matched. A cleared\n * pool or an exhausted wait queue happens under a LIVE client and describes a datastore that is\n * unhealthy rather than one that is going away — failing the boot loudly is the right answer there,\n * and folding them in here would turn a real infrastructure problem into a shrug.\n */\n private isDatastoreLifecycleTerminatedError(error: unknown): boolean {\n const name = (error as { name?: unknown })?.name;\n return (\n name === 'MongoClientClosedError' // client.close() interrupted an in-flight operation\n || name === 'MongoNotConnectedError' // the client was already closed when the probe started\n || name === 'MongoTopologyClosedError' // the topology shut down\n || name === 'MongoPoolClosedError' // the connection pool was closed\n || name === 'MongoExpiredSessionError' // the implicit/explicit session was ended by teardown\n );\n }\n\n /**\n * The ONE refusal path for a probe the datastore lifecycle interrupted.\n *\n * Deliberately a single shared throw rather than the same guard re-derived at each call site: this\n * invariant has four sites in this file (the retention backfill, the drift reconciliation, and both\n * halves of the verification pass), and the defect it closes was itself an invariant applied at one\n * site and missed at the others. A shared thrower makes the fifth site an import rather than a\n * re-derivation. See `.claude/rules/invariant-call-site-enumeration.md`.\n *\n * It THROWS rather than returning a verdict, and that is what stops the wall of noise: once the\n * client is gone every remaining probe in the pass is equally uninformative, so the first one to\n * notice aborts. The 2026-08-15 boot emitted 49 bullet points describing 49 collections it had\n * never successfully inspected.\n *\n * `ErrorType.INFRASTRUCTURE`, not `CONFIGURATION` or `INTERNAL`: nothing is misconfigured and no\n * invariant in this service was violated — a dependency went away mid-probe.\n */\n private throwDatastoreLifecycleTerminated(phase: string, error: unknown, resourceType?: ResourceType): never {\n throw this.errorBuilder.buildError(ErrorType.INFRASTRUCTURE, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'datastore_unavailable_during_index_work',\n phase,\n ...(resourceType ? { resourceType } : {}),\n message:\n `The MongoDB connection was torn down while ${phase} was running, so this pass could not `\n + 'determine anything about the index topology. This is NOT a missing index, NOT a duplicate-key '\n + 'conflict, and NOT a schema problem — do not go looking for colliding rows. The usual cause is '\n + 'the process receiving a shutdown signal mid-initialization (a dev-stack restart, a supervisor '\n + 'respawn, a rolling deploy). If the process was not shutting down, investigate why the '\n + 'datastore connection closed. The gate re-runs in full on the next boot that reaches a live '\n + 'database.',\n error: describeCaughtError(error),\n },\n });\n }\n\n /**\n * MongoDB's duplicate-key error, the ONE cause the retention backfill's operator guidance names.\n *\n * It exists because that guidance used to be unconditional: any backfill failure told the operator\n * that \"legacy rows already violate the uniqueness the retention-scoped index is about to assert\"\n * and to go resolve the duplicates. Observed live on 2026-08-11 against `users`, where the actual\n * error was `Cannot use a session that has ended` — a driver session-lifecycle error from a\n * companion restart racing the backfill, already covered by the entry's `retry` policy. The\n * message sent the reader hunting colliding rows that do not exist, and an operator who believes\n * it reasons from it rather than from the `error` field one line below.\n *\n * ## What this inspects, stated accurately\n *\n * `code` and `codeName` ONLY. An earlier revision of this comment justified the `codeName` check by\n * claiming \"a bulk write path reports `E11000` without a `codeName`\" — that is wrong in a way worth\n * recording, because `E11000` is a token in the driver's MESSAGE, not a value this predicate can\n * ever see. The real reason to check both is simpler: the driver populates `codeName` on some\n * paths and not others, and both spellings mean the same thing.\n *\n * The reachable call site here is `collection.updateMany`, which surfaces `code: 11000`, so this is\n * adequate for the one branch that uses it. If a caller is ever added whose failure carries the\n * duplicate only in its message text, this must grow a message check — do not assume it already has\n * one.\n *\n * Pinned in both directions by `retention-backfill-duplicate-key-classification.test.ts`; an\n * unpinned classifier fails silently, because a misclassified message is still a message.\n */\n private isDuplicateKeyError(error: unknown): boolean {\n const code = (error as { code?: unknown })?.code;\n const codeName = (error as { codeName?: unknown })?.codeName;\n return code === 11000 || code === 11001 || codeName === 'DuplicateKey';\n }\n\n private buildOperationRepositoryPathsMap(): void {\n this.logDebug('Building operation repository paths map');\n\n let totalOperationRepositoryPaths = 0;\n\n this.repositories.forEach((repository, resourceType) => {\n const resourceConfiguration = this.resourceRegistry.getResourceConfiguration(resourceType);\n\n if (!resourceConfiguration.operations) {\n return;\n }\n\n resourceConfiguration.operations.forEach(operation => {\n const operationRepositoryPath = ResourcesConfig_OperationPathUtils.extractOperationRepositoryPath(operation);\n const operationRepositoryPathKey = ResourcesConfig_OperationPathUtils.createOperationRepositoryPathKey(operationRepositoryPath);\n\n this.repositoryOperationsMap.set(operationRepositoryPathKey, {\n repository,\n operationRepositoryPath\n });\n\n totalOperationRepositoryPaths++;\n });\n });\n\n this.logDebug('Operation repository paths map built', {\n totalOperationRepositoryPaths,\n operationRepositoryPathKeys: Array.from(this.repositoryOperationsMap.keys()).slice(0, 5) // Show first 5 as sample\n });\n }\n\n\n // ================================\n // Execute operations\n // ================================\n\n public async doByPath<T = any>(\n operationRepositoryPath: ResourceConfiguration_OperationRepositoryPath,\n executionContext: ExecutionContext<any>,\n id_or_ids_or_filter?: IdOrIdsOrFilterType,\n data?: any,\n options?: RepositoryOptions\n ): Promise<T> {\n const operationRepositoryPathKey = ResourcesConfig_OperationPathUtils.createOperationRepositoryPathKey(operationRepositoryPath);\n\n this.logDebug('Executing operation by repository path', { operationRepositoryPath, operationRepositoryPathKey, id_or_ids_or_filter });\n\n return this.doByKey<T>( operationRepositoryPathKey, executionContext, id_or_ids_or_filter, data, options\n );\n }\n\n /**\n * Execute operation by operation repository path key (string)\n */\n public async doByKey<T = any>(\n operationRepositoryPathKey: string,\n executionContext: ExecutionContext<any>,\n id_or_ids_or_filter?: IdOrIdsOrFilterType,\n data?: any,\n options?: RepositoryOptions\n ): Promise<T> {\n // Validate the key format first\n ResourcesConfig_OperationPathUtils.validateOperationRepositoryPathKey(operationRepositoryPathKey);\n\n const operationInfo = this.repositoryOperationsMap.get(operationRepositoryPathKey);\n\n if (!operationInfo) {\n throw this.errorBuilder.buildError( ErrorType.NOT_FOUND, executionContext,\n { context: { operationRepositoryPathKey }, customMessageReference: ErrorCustomMessageReference.REPOSITORIES_REGISTRY_NOT_FOUND } );\n }\n\n this.logDebug('Executing operation by repository path key', { operationRepositoryPathKey, id_or_ids_or_filter });\n\n return operationInfo.repository.doByPath( operationInfo.operationRepositoryPath, executionContext, id_or_ids_or_filter, data, options);\n }\n\n /**\n * Execute operation by ExecutionContext shortcut\n */\n public async doByExecutionContext<T = any>(\n executionContext: ExecutionContext<any>,\n data?: any,\n options?: RepositoryOptions\n ): Promise<T> {\n const operation = executionContext.operation;\n const resourceType = operation.resourceIdentifier as ResourceType;\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n\n this.logDebug('Executing operation by execution context', { resourceType, operationIdentifier: operation.operationIdentifier });\n\n return repository.doByExecutionContext(executionContext, data, options);\n }\n\n // ================================\n // Getters\n // ================================\n\n public getRepository<\n TCustomOperationEnum extends EnumLikeType | undefined = undefined,\n TCoreOperationEnum extends Partial<CoreResourceOperation> | undefined = undefined,\n TMainSchema extends z.ZodTypeAny = z.ZodTypeAny,\n >(\n resourceType: ResourceType\n ): BackendResourceRepository<TCustomOperationEnum, TCoreOperationEnum, TMainSchema> | undefined {\n const repository = this.repositories.get(resourceType);\n\n if (!repository) {\n this.logDebug('Repository not found', { resourceType });\n return undefined;\n }\n\n return repository as BackendResourceRepository<TCustomOperationEnum, TCoreOperationEnum, TMainSchema>;\n }\n\n\n public getRepositoryOrThrow<\n TCustomOperationEnum extends EnumLikeType | undefined = undefined,\n TCoreOperationEnum extends Partial<CoreResourceOperation> | undefined = undefined,\n TMainSchema extends z.ZodTypeAny = z.ZodTypeAny,\n >(\n resourceType: ResourceType,\n executionContext?: ExecutionContext<any>\n ): BackendResourceRepository<TCustomOperationEnum, TCoreOperationEnum, TMainSchema> {\n const repository = this.getRepository<TCustomOperationEnum, TCoreOperationEnum, TMainSchema>(resourceType);\n\n if (!repository) {\n throw this.errorBuilder.buildError( ErrorType.NOT_FOUND, executionContext,\n { context: { resourceType }, customMessageReference: ErrorCustomMessageReference.REPOSITORIES_REGISTRY_NOT_FOUND } );\n }\n\n return repository;\n }\n\n\n public getRegisteredResourceTypes(): ResourceType[] {\n return Array.from(this.repositories.keys());\n }\n\n public getRepositoryCount(): number {\n return this.repositories.size;\n }\n\n public getAvailableOperationRepositoryPaths(): ResourceConfiguration_OperationRepositoryPath[] {\n return Array.from(this.repositoryOperationsMap.values()).map(info => info.operationRepositoryPath);\n }\n\n public hasRepository(resourceType: ResourceType): boolean {\n return this.repositories.has(resourceType);\n }\n\n\n // ================================\n // Framework-internal infrastructure queries\n // ================================\n\n /**\n * Apply the retention hide (`retentionStatus != RETAINED`) to a RAW infrastructure filter.\n *\n * The methods below reach the underlying database model DIRECTLY, so they never pass through\n * `buildContextualFilter` — the chokepoint where retained (impersonalized-and-retained) rows are\n * hidden and made immutable. Without this, an infrastructure query would still SEE and MUTATE a row\n * that has been erased-but-retained for a legal obligation: an `$inc` could move money on a scrubbed\n * financial record, a bulk update could rewrite it, and a uniqueness count would reveal that a hidden\n * row exists (an existence oracle).\n *\n * FAIL-CLOSED, and ALWAYS — deliberately with no see-through escape:\n * - The predicate is assigned at the TOP LEVEL, OVERWRITING any caller-supplied `retentionStatus`\n * (mirroring the chokepoint). Top-level keys AND-combine and cannot be un-ANDed by a nested\n * `$or`/`$and`, so an injected `retentionStatus: RETAINED` is neutralised rather than honoured.\n * - The audited see-through path is `readRetainedAsSystem` / `listRetainedAsSystem` ONLY. These\n * infrastructure helpers are never that path, so they must not consult the EC's see-through flag;\n * a future privileged disposal job (the retention clock) needs its own explicit primitive rather\n * than a bypass here.\n *\n * No-op for resources that have not opted into `retentionPolicy` (the overwhelming majority), so\n * this costs one registry lookup and changes no existing behaviour.\n *\n * The predicate itself comes from the single retention authority; this method owns only the\n * registry lookup and the no-see-through-escape decision for the raw infrastructure paths.\n */\n public applyRetentionHideToRawFilter(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n ): Record<string, unknown> {\n const resourceConfiguration = this.resourceRegistry.tryGetResourceConfiguration(resourceType);\n\n /**\n * A MISSING configuration is an inconsistency, and it decides the hide by DEFAULT — so it is\n * reported rather than left silent.\n *\n * Every caller has already resolved a repository for this resource type, so the registry holding\n * no configuration for it cannot happen in a coherent runtime. If it ever does, this method reads\n * \"not governed\" and the hide silently does not apply — on a retention-governed resource that is\n * a disclosed-and-mutable erased row.\n *\n * **Why this WARNS instead of failing closed**, which is the opposite of what the rest of this\n * boundary does: failing closed here means \"assume governed and apply the predicate\". On MongoDB\n * that would be free — `$ne` matches documents missing the field, so it is a no-op on an\n * ungoverned collection. But `atomicGuardedMutation` / `atomicIncrementField` became\n * ADAPTER-NEUTRAL, so the filter can now reach PostgreSQL, where a table that never opted in has\n * no `retentionStatus` COLUMN at all and the predicate is a SQL error rather than a no-op. Failing\n * closed would therefore break every ungoverned PostgreSQL resource to protect a state that\n * cannot occur. Visible-instead-of-unbypassable is the weaker guarantee that is actually available.\n */\n if (!resourceConfiguration) {\n this.logger.warn(\n '[Retention] No resource configuration found while applying the retention hide to a raw '\n + 'infrastructure filter — treating the resource as NOT retention-governed. If it IS governed, '\n + 'erased-but-retained rows were readable and mutable on this path.',\n { resourceType },\n );\n return filter;\n }\n\n if (!isRetentionGovernedResource(resourceConfiguration)) {\n return filter;\n }\n return withRetentionHideApplied(filter);\n }\n\n /**\n * Count documents matching a filter for a given resource type.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.COUNT_DOCUMENTS`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * @param resourceType - The resource type to query\n * @param filter - Pre-built filter (caller must have applied scope filtering)\n * @param executionContext - For error context only (NOT used for authorization)\n * @returns Number of documents matching the filter\n */\n public async countDocumentsForInfrastructure(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n executionContext?: ExecutionContext<any>\n ): Promise<number> {\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n\n // Adapter-neutral primitive, and the hide applied HERE and only here. Both arms' `countByRawFilter`\n // document that they take an already-hidden filter, so the predicate lives in one place; WHY each\n // is so is the contract's COUNT_DOCUMENTS row.\n return repository.countByRawFilter(this.applyRetentionHideToRawFilter(resourceType, filter));\n }\n\n\n /**\n * ADAPTER-NEUTRAL atomic counter: add `delta` to one numeric field on the single row matching\n * `filter`, optionally setting other fields in the same statement, returning the row AFTER the\n * write (or `null` when nothing matched).\n *\n * A shorthand over {@link atomicGuardedMutation}, kept because a counter is the commonest guarded\n * write by a wide margin and `atomicIncrementField(filter, 'available', -5)` reads better at those\n * call sites than a descriptor would.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.ATOMIC_INCREMENT_FIELD`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * rag-ingestion-gate: N/A — bounded by the hourly RAG reconciliation sweep; the contract's\n * ATOMIC_INCREMENT_FIELD row states what the sweep reconciles here and why.\n */\n public async atomicIncrementField<T = any>(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n field: string,\n delta: number,\n setFields?: Record<string, unknown>,\n executionContext?: ExecutionContext<any>,\n options?: RepositoryOptions,\n ): Promise<T | null> {\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n\n // No `as any` and no runtime `typeof` probe: the primitive is on `BackendResourceRepository`,\n // so an adapter that omits it fails to compile rather than throwing on first use.\n return repository.atomicIncrementField<T>(\n this.applyRetentionHideToRawFilter(resourceType, filter),\n field,\n delta,\n setFields,\n // Forward the repository options so a caller already inside a transaction enrols this write\n // in it (Mongo session / PG trx). Dropping them here would make both arms' transaction\n // handling dead code reachable only from a direct repository call.\n options,\n );\n }\n\n /**\n * ADAPTER-NEUTRAL guarded set-and-clear: on the single row matching `filter`, write\n * `setFields` and REMOVE `clearFields`, returning the row AFTER the write (or `null` when\n * nothing matched).\n *\n * A shorthand over {@link atomicGuardedMutation}, for the common set-and-clear case.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.ATOMIC_CONDITIONAL_SET`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * rag-ingestion-gate: N/A — bounded by the hourly RAG reconciliation sweep; the contract's\n * ATOMIC_CONDITIONAL_SET row states what the sweep reconciles here and why.\n */\n public async atomicConditionalSet<T = any>(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n changes: {\n readonly set?: Record<string, unknown>;\n readonly clear?: readonly string[];\n },\n executionContext?: ExecutionContext<any>,\n options?: RepositoryOptions,\n ): Promise<T | null> {\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n\n return repository.atomicConditionalSet<T>(\n this.applyRetentionHideToRawFilter(resourceType, filter),\n changes.set,\n changes.clear,\n // Forwarded so a caller already inside a transaction enrols this write in it, matching\n // `atomicIncrementField`. Dropping them would make both arms' transaction handling dead\n // code reachable only from a direct repository call.\n options,\n );\n }\n\n /**\n * ADAPTER-NEUTRAL guarded mutation: apply `mutation` to the single row matching `filter` in ONE\n * statement, returning the row AFTER the write (or `null` when nothing matched).\n *\n * This is the general form that {@link atomicIncrementField} and {@link atomicConditionalSet}\n * are shorthands for, and the only one that can express a counter and an array addition\n * TOGETHER — which the lifecycle evaluator's engagement write needs, because the row it reads\n * back decides whether the scope transitions to ENGAGED (see the descriptor's own JSDoc).\n *\n * Two rules are enforced HERE, at the single dispatch point, rather than in each adapter:\n *\n * - **Retention.** A retained (erased-but-kept) row is immutable and must never be mutated.\n * - **Expressibility.** A descriptor that no adapter-neutral compilation can honour is refused\n * for EVERY adapter, so a combination cannot work on one store and silently degrade on\n * another.\n *\n * @internal Framework-internal infrastructure primitive — NOT part of the operation lifecycle.\n * The caller owns authorization, scope-aware filter construction, and audit logging.\n */\n /**\n * The dispatch point for {@link BackendResourceRepository.readUnscopedByKey} — the ONE place the\n * retention hide is applied to it, exactly as for the guarded mutation below.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.READ_UNSCOPED_BY_KEY`). Do not restate it here: two copies of a\n * rationale are how they drift.\n */\n public async readUnscopedByKey<T = any>(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<T | null> {\n const repository = this.getRepositoryOrThrow(resourceType);\n return repository.readUnscopedByKey<T>(\n this.applyRetentionHideToRawFilter(resourceType, filter),\n options,\n );\n }\n\n /**\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.ATOMIC_GUARDED_MUTATION`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * rag-ingestion-gate: N/A — bounded by the hourly RAG reconciliation sweep; the contract's\n * ATOMIC_GUARDED_MUTATION row states what the sweep reconciles here and why.\n */\n public async atomicGuardedMutation<T = any>(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n mutation: RepositoryGuardedMutation,\n executionContext?: ExecutionContext<any>,\n options?: RepositoryOptions,\n ): Promise<T | null> {\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n\n const inexpressible = describeGuardedMutationInexpressibility(mutation);\n if (inexpressible) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, executionContext, {\n customMessageReference: ErrorCustomMessageReference.SERVICE_RESOURCE_VALIDATION_FAILED,\n context: { resourceType, reason: `Guarded mutation is not adapter-neutral: ${inexpressible}` },\n });\n }\n\n return repository.atomicGuardedMutation<T>(\n this.applyRetentionHideToRawFilter(resourceType, filter),\n mutation,\n // Forwarded so a caller already inside a transaction enrols this write in it, matching the\n // two shorthand primitives.\n options,\n );\n }\n\n /**\n * INSERT one already-built document for a framework-internal writer.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.INSERT_DOCUMENT`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * rag-ingestion-gate: N/A — bounded by the hourly RAG reconciliation sweep; the contract's\n * INSERT_DOCUMENT row states what the sweep reconciles here and why.\n *\n * @param executionContext - For error context only (NOT used for authorization).\n */\n public async insertDocumentForInfrastructure<T = any>(\n resourceType: ResourceType,\n document: Record<string, unknown>,\n executionContext?: ExecutionContext<any>,\n options?: RepositoryOptions,\n ): Promise<T> {\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n return repository.insertRawDocument<T>(document, options);\n }\n\n /**\n * READ many rows matching a pre-built filter for a framework-internal reader.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.FIND_MANY`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * @param executionContext - For error context only (NOT used for authorization).\n */\n public async findManyForInfrastructure<T = any>(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n executionContext?: ExecutionContext<any>,\n options?: RepositoryOptions,\n ): Promise<T[]> {\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n return repository.findManyByRawFilter<T>(\n this.applyRetentionHideToRawFilter(resourceType, filter),\n options,\n );\n }\n\n /**\n * Bulk guarded update of every row matching a pre-built filter, returning the modified count.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.BULK_UPDATE`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * rag-ingestion-gate: N/A — bounded by the hourly RAG reconciliation sweep; the contract's\n * BULK_UPDATE row states what the sweep reconciles here and why.\n */\n public async bulkUpdateForInfrastructure(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n /** An ADAPTER-NEUTRAL descriptor, not a MongoDB update expression — contract, ADAPTER_NEUTRALITY. */\n mutation: RepositoryGuardedMutation,\n executionContext?: ExecutionContext<any>,\n /** Carries the TRANSACTION — contract, TRANSACTION_PARTICIPATION, where its absence is the story. */\n options?: RepositoryOptions,\n ): Promise<number> {\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n\n const inexpressible = describeGuardedMutationInexpressibility(mutation);\n if (inexpressible) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, executionContext, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORIES_REGISTRY_NOT_FOUND,\n context: { resourceType, reason: `Guarded mutation is not adapter-neutral: ${inexpressible}` },\n });\n }\n\n // The hide is applied HERE and only here — both arms take an already-hidden filter. WHY is the\n // contract's BULK_UPDATE / retentionHide row.\n return repository.updateManyByRawFilter(\n this.applyRetentionHideToRawFilter(resourceType, filter),\n mutation,\n options,\n );\n }\n\n\n// ================================\n// Debug methods\n// ================================\n\n public getDebugInfo(): {\n repositoryCount: number;\n operationRepositoryPathsCount: number;\n resourceTypes: ResourceType[];\n isInitialized: boolean;\n } {\n return {\n repositoryCount: this.repositories.size,\n operationRepositoryPathsCount: this.repositoryOperationsMap.size,\n resourceTypes: Array.from(this.repositories.keys()),\n isInitialized: this.isInitialized\n };\n }\n\n public debugDisplayMongooseSchemas(options: {\n showSchemaStructure?: boolean;\n showIndexes?: boolean;\n showVirtuals?: boolean;\n resourceTypeFilter?: string[];\n maxFieldDepth?: number;\n } = {}): void {\n this.logDebug('Displaying Mongoose schemas debug info', {\n repositories: this.repositories.size,\n options\n });\n\n // Collect models from all repositories\n const models: Model<any>[] = [];\n const resourceTypes: string[] = [];\n\n for (const [resourceType, repository] of this.repositories) {\n // Apply resource type filter if specified\n if (options.resourceTypeFilter && options.resourceTypeFilter.length > 0 &&\n !options.resourceTypeFilter.includes(resourceType)) {\n continue;\n }\n\n // Access the mongooseModel from the repository\n const model = (repository as any).mongooseModel;\n if (model) {\n models.push(model);\n resourceTypes.push(resourceType);\n }\n }\n\n this.logDebug('\\n🔍 === REPOSITORY MONGOOSE SCHEMAS DEBUG ===\\n');\n this.logDebug(`Found ${models.length} models from ${this.repositories.size} repositories`);\n\n if (options.resourceTypeFilter && options.resourceTypeFilter.length > 0) {\n this.logDebug(`Filtered for: [${options.resourceTypeFilter.join(', ')}]`);\n }\n\n this.logDebug(`Resource Types: [${resourceTypes.join(', ')}]\\n`);\n\n // Display each model individually using the simplified debug method\n for (const model of models) {\n this.zodToMongooseConverter.debugDisplayModelSchema(model, options.showSchemaStructure !== false);\n }\n\n this.logDebug('================================================\\n');\n }\n\n /**\n * Quick debug function to show schemas summary\n */\n public debugShowSchemasSummary(): void {\n this.logDebug('Displaying schemas summary');\n\n // Collect models from all repositories\n const models: Model<any>[] = [];\n\n for (const [resourceType, repository] of this.repositories) {\n const model = (repository as any).mongooseModel;\n if (model) {\n models.push(model);\n }\n }\n\n this.zodToMongooseConverter.debugShowModelsSummary(models);\n }\n\n /**\n * Validate and filter request data against operation DTO\n * NOTE: This assumes data has already been cleaned by cleanInputData()\n */\n public validateRequestData(\n data: any,\n resourceType: ResourceType,\n operationIdentifier: string,\n options?: Pick<RepositoryOptions, 'frameworkGeneratedPdfFileIdsByField' | 'frameworkGeneratedPdfFileIdsByFieldByRow' | 'preserveServerInjectedFields'>,\n ): any {\n if (!data || typeof data !== 'object') {\n return data;\n }\n\n // Get the resource configuration to find the operation\n const resourceConfiguration = this.resourceRegistry.getResourceConfiguration(resourceType);\n\n if (!resourceConfiguration.operations) {\n // If no operations defined, data is already cleaned so return as-is\n return data;\n }\n\n // Prefer the default non-bulk URL-bearing operation when several concrete\n // variants share the same semantic identifier. Cron/batch/internal variants\n // can carry a requestDto too, but repository validation for normal resource\n // writes must not become dependent on declaration order.\n const matchingOperations = resourceConfiguration.operations.filter(op =>\n op.operationIdentifier === operationIdentifier\n );\n const operation = matchingOperations.find(op =>\n (\n op.variantType === ResourceOperationVariantType.API_CALL\n || op.variantType === ResourceOperationVariantType.API_CALL_WITH_CALLBACK\n )\n && op.isOperationDefault === true\n && op.isBulkOperation !== true\n ) ?? (\n matchingOperations.length === 1 ? matchingOperations[0] : undefined\n ) ?? matchingOperations.find(op =>\n op.variantType === ResourceOperationVariantType.REPOSITORY_ONLY\n || op.variantType === ResourceOperationVariantType.INTERNAL_CALL\n ) ?? matchingOperations.find(op =>\n (op as { variantType?: ResourceOperationVariantType }).variantType === undefined\n && !('isBulkOperation' in op && op.isBulkOperation === true)\n );\n if (matchingOperations.length > 1) {\n this.logDebug('Resolved request validation operation among multiple variants', {\n resourceType,\n operationIdentifier,\n candidateVariants: matchingOperations.map(op => ({\n variantType: op.variantType,\n isOperationDefault: op.isOperationDefault,\n isBulkOperation: 'isBulkOperation' in op ? op.isBulkOperation : undefined,\n variantKey: op.variantKey,\n })),\n selectedVariantType: operation?.variantType,\n });\n }\n\n if (!operation || !operation.requestDto) {\n if (this.hasFrameworkGeneratedPdfAllowlist(options)) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n context: {\n resourceType,\n operationIdentifier,\n message: 'Framework-generated PDF write preservation requires a matching operation requestDto.',\n },\n });\n }\n // If no operation or requestDto found, data is already cleaned so return as-is\n return data;\n }\n\n try {\n // Validate against the operation's requestDto, then re-attach the two\n // trusted internal allowlists the strict parse would otherwise drop:\n // framework-generated PDF files, and fields a custom-impl CREATE prefix\n // injected (`preserveServerInjectedFields`).\n const validatedData = this.preserveServerInjectedFields(\n data,\n this.preserveFrameworkGeneratedPdfFields(\n data,\n operation.requestDto.parse(data),\n options,\n ),\n options,\n );\n this.logDebug('Request data validation successful', {\n resourceType,\n operationIdentifier,\n validatedKeys: typeof validatedData === 'object' ? Object.keys(validatedData) : 'not-object'\n });\n return validatedData;\n } catch (error) {\n this.logDebug('Request data validation failed', {\n resourceType,\n operationIdentifier,\n error: describeCaughtError(error),\n dataKeys: typeof data === 'object' ? Object.keys(data) : 'not-object',\n data: data\n });\n\n if (error instanceof z.ZodError) {\n throw this.errorBuilder.buildError(ErrorType.VALIDATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n stack: error.stack,\n context: {\n resourceType,\n operationIdentifier,\n inputData: data,\n zodIssues: error.issues,\n }\n });\n }\n\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n context: {\n resourceType,\n operationIdentifier,\n inputData: data,\n error: describeCaughtError(error),\n }\n });\n }\n }\n\n /**\n * Validate the payload slice that repositories actually persist.\n *\n * For bulk writes, the service/controller layer validates the full bulk\n * envelope. Repositories only receive the per-row create item or the shared\n * update patch, so repository validation must intentionally target that write\n * slice rather than the bulk transport wrapper.\n */\n public validateRepositoryWriteData(\n data: any,\n resourceType: ResourceType,\n operationIdentifier: string,\n isBulkOperation: boolean = false,\n options?: Pick<RepositoryOptions, 'frameworkGeneratedPdfFileIdsByField' | 'frameworkGeneratedPdfFileIdsByFieldByRow' | 'preserveServerInjectedFields'>,\n ): any {\n if (!data || typeof data !== 'object') {\n return data;\n }\n\n const resourceConfiguration = this.resourceRegistry.getResourceConfiguration(resourceType);\n if (!resourceConfiguration.operations) {\n return data;\n }\n\n const matchingOperations = resourceConfiguration.operations.filter((candidate) => {\n const candidateIsBulkOperation = 'isBulkOperation' in candidate && candidate.isBulkOperation === true;\n\n return candidate.operationIdentifier === operationIdentifier\n && candidateIsBulkOperation === isBulkOperation;\n });\n const defaultMatchingOperations = matchingOperations.filter((candidate) => candidate.isOperationDefault === true);\n const operationCandidates = defaultMatchingOperations.length > 0 ? defaultMatchingOperations : matchingOperations;\n if (operationCandidates.length > 1) {\n const candidateVariants = operationCandidates.map((candidate) => ({\n variantType: candidate.variantType,\n variantKey: candidate.variantKey,\n isOperationDefault: candidate.isOperationDefault,\n }));\n this.logDebug('Ambiguous repository write validation operation candidates', {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n candidateVariants,\n });\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n context: {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n candidateVariants,\n message: 'Repository write validation requires a unique operation identity; pass through a fully resolved operation path before adding duplicate variants for this repository operation.',\n },\n });\n }\n const operation = operationCandidates[0];\n\n if (!operation) {\n if (this.hasFrameworkGeneratedPdfAllowlist(options)) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n context: {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n message: 'Framework-generated PDF write preservation requires a matching repository write operation.',\n },\n });\n }\n return data;\n }\n\n const validationOperation = (() => {\n if (!isBulkOperation || (\n operationIdentifier !== CoreResourceOperation.CREATE\n && operationIdentifier !== CoreResourceOperation.UPDATE\n )) {\n return operation;\n }\n\n const allNonBulkCandidates = resourceConfiguration.operations.filter((candidate) => {\n const candidateIsBulkOperation = 'isBulkOperation' in candidate && candidate.isBulkOperation === true;\n\n return candidate.operationIdentifier === operationIdentifier\n && candidateIsBulkOperation === false;\n });\n const defaultNonBulkCandidates = allNonBulkCandidates.filter((candidate) => candidate.isOperationDefault === true);\n const nonBulkCandidates = defaultNonBulkCandidates.length > 0 ? defaultNonBulkCandidates : allNonBulkCandidates;\n if (nonBulkCandidates.length > 1) {\n const candidateVariants = nonBulkCandidates.map((candidate) => ({\n variantType: candidate.variantType,\n variantKey: candidate.variantKey,\n isOperationDefault: candidate.isOperationDefault,\n }));\n this.logDebug('Ambiguous repository bulk validation base candidates', {\n resourceType,\n operationIdentifier,\n candidateVariants,\n });\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n context: {\n resourceType,\n operationIdentifier,\n candidateVariants,\n message: 'Bulk repository write validation requires a unique non-bulk default validation base.',\n },\n });\n }\n return nonBulkCandidates[0] ?? operation;\n })();\n\n if (!validationOperation.requestDto) {\n if (this.hasFrameworkGeneratedPdfAllowlist(options)) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n context: {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n message: 'Framework-generated PDF write preservation requires a repository write requestDto.',\n },\n });\n }\n return data;\n }\n\n try {\n // Re-attach the two trusted internal allowlists the strict parse drops —\n // framework-generated PDF files AND fields a trusted caller server-injected\n // (`preserveServerInjectedFields`). This MUST mirror the single-write\n // `validateRequestData` path: the bulk write paths (`_doCreateMany` /\n // `_doUpdateMany`) run through THIS method, so omitting the\n // `preserveServerInjectedFields` wrap silently strips the allowlisted keys on\n // every BULK trusted write. Concretely, anon→user ownership transposition's\n // `updateManyAsSystem(resource, ids, { userId, anonymousUserId: null })` derives\n // `preserveServerInjectedFields: ['userId','anonymousUserId']` (context-auto-\n // populated FKs the request DTO strips by name), but without this wrap they were\n // dropped after the parse → an empty `$set` → the rows never moved (silent no-op,\n // audit still emitted). The re-attach is safe here for the same reason it is on\n // the single path: the allowlist is schema-derived by trusted primitives (or the\n // prefix snapshot-diff), never a client payload, so it cannot smuggle a\n // client-forbidden field.\n const validatedData = this.preserveServerInjectedFields(\n data,\n this.preserveFrameworkGeneratedPdfFields(\n data,\n validationOperation.requestDto.parse(data),\n options,\n ),\n options,\n );\n this.logDebug('Repository write payload validation successful', {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n validatedKeys: typeof validatedData === 'object' ? Object.keys(validatedData) : 'not-object'\n });\n return validatedData;\n } catch (error) {\n this.logDebug('Repository write payload validation failed', {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n error: describeCaughtError(error),\n dataKeys: typeof data === 'object' ? Object.keys(data) : 'not-object',\n data,\n });\n\n if (error instanceof z.ZodError) {\n throw this.errorBuilder.buildError(ErrorType.VALIDATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n stack: error.stack,\n context: {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n inputData: data,\n zodIssues: error.issues,\n }\n });\n }\n\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n context: {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n inputData: data,\n error: describeCaughtError(error),\n }\n });\n }\n }\n\n /**\n * Re-attach fields a trusted custom-impl `prefixCoreOperations` hook injected\n * that the strict `requestDto.parse` just stripped.\n *\n * The create/update request DTO omits `.excludeFromCreate()` /\n * `.excludeFromUpdate()` fields, so `requestDto.parse(data)` drops them — even\n * when a server-side prefix legitimately populated them (e.g. an API key's\n * `keyPrefix` / `hashedKey`). The service orchestration diffs the prefix output\n * against the pre-prefix payload and passes ONLY the prefix-added keys in\n * `options.preserveServerInjectedFields`, so a client cannot smuggle a value\n * through this path (its fields were present before the prefix and never make\n * the list). Each allowlisted key is copied straight from the original\n * (service-layer loose-validated) payload back onto the parsed result. Mirrors\n * `preserveFrameworkGeneratedPdfFields` but for arbitrary scalar fields.\n */\n private preserveServerInjectedFields(\n originalData: any,\n validatedData: any,\n options?: Pick<RepositoryOptions, 'preserveServerInjectedFields'>,\n ): any {\n const fields = options?.preserveServerInjectedFields;\n if (!fields || fields.length === 0 || !originalData || typeof originalData !== 'object' || !validatedData || typeof validatedData !== 'object') {\n return validatedData;\n }\n\n for (const fieldName of fields) {\n if (Object.prototype.hasOwnProperty.call(originalData, fieldName)) {\n validatedData[fieldName] = originalData[fieldName];\n }\n }\n\n return validatedData;\n }\n\n private preserveFrameworkGeneratedPdfFields(\n originalData: any,\n validatedData: any,\n options?: Pick<RepositoryOptions, 'frameworkGeneratedPdfFileIdsByField' | 'frameworkGeneratedPdfFileIdsByFieldByRow' | 'preserveServerInjectedFields'>,\n ): any {\n const allowlist = options?.frameworkGeneratedPdfFileIdsByField;\n if (!allowlist || !originalData || typeof originalData !== 'object' || !validatedData || typeof validatedData !== 'object') {\n return validatedData;\n }\n\n for (const [fieldName, allowedFileIds] of Object.entries(allowlist)) {\n const allowed = new Set(allowedFileIds);\n if (Object.prototype.hasOwnProperty.call(originalData, fieldName)) {\n const generatedFileValue = this.normalizeGeneratedFileValue(originalData[fieldName]);\n if (generatedFileValue && allowed.has(generatedFileValue.fileId)) {\n validatedData[fieldName] = generatedFileValue;\n }\n continue;\n }\n\n const occurrences = enumerateFileFieldValueOccurrences(originalData, fieldName);\n for (const occurrence of occurrences) {\n const generatedFileValue = this.normalizeGeneratedFileValue(occurrence.value);\n if (!generatedFileValue || !allowed.has(generatedFileValue.fileId)) {\n continue;\n }\n this.setValueAtRuntimePathCreating(validatedData, occurrence.runtimeFieldPath, generatedFileValue);\n }\n }\n\n return validatedData;\n }\n\n private hasFrameworkGeneratedPdfAllowlist(\n options?: Pick<RepositoryOptions, 'frameworkGeneratedPdfFileIdsByField' | 'frameworkGeneratedPdfFileIdsByFieldByRow' | 'preserveServerInjectedFields'>,\n ): boolean {\n return Boolean(\n options?.frameworkGeneratedPdfFileIdsByField &&\n Object.keys(options.frameworkGeneratedPdfFileIdsByField).length > 0\n || options?.frameworkGeneratedPdfFileIdsByFieldByRow?.some((row) => Object.keys(row).length > 0)\n );\n }\n\n public buildGeneratedPdfRowRepositoryOptions(\n options: RepositoryOptions | undefined,\n rowIndex: number,\n ): RepositoryOptions | undefined {\n if (!options?.frameworkGeneratedPdfFileIdsByFieldByRow) {\n return options;\n }\n\n return {\n ...options,\n frameworkGeneratedPdfFileIdsByField: options.frameworkGeneratedPdfFileIdsByFieldByRow[rowIndex] ?? {},\n };\n }\n\n private normalizeGeneratedFileValue(value: unknown): { fileId: string; updatedAt: unknown } | undefined {\n if (!value || Array.isArray(value) || typeof value !== 'object') {\n return undefined;\n }\n\n const record = value as Record<string, unknown>;\n const fileId = record.fileId;\n if (typeof fileId !== 'string' || fileId.trim().length === 0 || !('updatedAt' in record)) {\n return undefined;\n }\n\n return {\n fileId,\n updatedAt: record.updatedAt,\n };\n }\n\n private setValueAtRuntimePathCreating(\n target: Record<string, unknown> | unknown[],\n runtimePath: string,\n value: unknown,\n ): void {\n const normalizedSegments = runtimePath\n .replace(/\\[(\\d+)\\]/g, '.$1')\n .split('.')\n .filter(Boolean);\n\n if (normalizedSegments.length === 0) {\n return;\n }\n\n let current: any = target;\n for (let index = 0; index < normalizedSegments.length - 1; index += 1) {\n const segment = normalizedSegments[index];\n const nextSegment = normalizedSegments[index + 1];\n\n if (Array.isArray(current)) {\n const arrayIndex = Number(segment);\n if (!current[arrayIndex]) {\n current[arrayIndex] = /^\\d+$/.test(nextSegment) ? [] : {};\n }\n current = current[arrayIndex];\n continue;\n }\n\n if (!current || typeof current !== 'object') {\n return;\n }\n\n if (!(segment in current) || current[segment] === null || current[segment] === undefined) {\n current[segment] = /^\\d+$/.test(nextSegment) ? [] : {};\n }\n current = current[segment];\n }\n\n setValueAtRuntimePath(target, runtimePath, value);\n }\n}\n"]}
1
+ {"version":3,"file":"repositories-registry-handler.backend.service.js","sourceRoot":"","sources":["../../../../../../src/base-classes/services/repositories/repositories-registry-handler.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\nimport { injectable, inject, Container } from 'inversify';\nimport { Model, Connection } from 'mongoose';\nimport { sql } from 'kysely';\nimport type {\n ResourceConfiguration,\n ResourceConfiguration_OperationRepositoryPath\n} from '@wildo-ai/saas-models';\nimport type { DataSeedRowMetadata } from '~wildo-backend-lib/data-seeding/models/data-seed-row-metadata.shared.schemas';\nimport {\n ResourceType,\n\n CoreResourceOperation,\n ResourcesConfig_OperationPathUtils,\n ErrorType,\n ErrorCustomMessageReference,\n PersistenceAdapter,\n PersistenceAdapterType,\n DEFAULT_PERSISTENCE_ADAPTER,\n Resources_PaginationRequest,\n Resources_PaginatedResult,\n ResourceOperationVariantType,\n} from '@wildo-ai/saas-models';\nimport {\n buildMissingRetentionMarkerFilterFragment,\n buildRetentionMarkerBackfillPatch,\n isRetentionGovernedResource,\n resolveSoleVisibleRetentionStatus,\n withRetentionHideApplied,\n} from '~wildo-backend-lib/compliance/privacy/retention-hide-predicate.backend';\nimport { EnumLikeType } from '@wildo-ai/zod-decorators';\nimport {\n IdOrFilterType,\n IdOrIdsOrFilterType,\n IdsOrFilterType,\n RepositoryOptions,\n} from '~wildo-backend-lib/base-classes/models/repositories.backend.schemas';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport {\n ApplicationRuntimeProfile,\n resolveApplicationRuntimeProfileBootAssertions,\n} from '~wildo-backend-lib/config/bootstrap/application-runtime-profile.backend';\nimport { ExecutionContext } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';\nimport { RepositoryResourceBackendService } from './repository-resource.backend.service';\nimport { ResourceOperationHelperBackendService } from '~wildo-backend-lib/base-classes/services/resource-operations-helper.backend.service';\nimport { ZodToMongooseSchemaConvertorBackendService } from '~wildo-backend-lib/databases/services/zod-to-mongoose-schema-convertor.backend.service';\nimport { resolvePersistenceAdapterForConfiguration } from '~wildo-backend-lib/databases/models/resolve-persistence-adapter.backend.utils';\nimport type { PersistenceAdapterAuthority } from '~wildo-backend-lib/databases/models/resolve-persistence-adapter.backend.utils';\nimport { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport { describeCaughtError, projectCaughtErrorLogFields } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport { z } from 'zod';\nimport { ResourcesRegistryBackendService } from '~wildo-backend-lib/resources/services/resources-registry.backend.service';\nimport { PostgreSQLDatabaseBackendService } from '~wildo-backend-lib/databases/services/postgresql-database.backend.service';\nimport { ZodToSqlHybridSchemaPlannerBackendService } from '~wildo-backend-lib/databases/services/zod-to-sql-hybrid-schema.planner';\nimport { PostgreSQLResourceRepositoryBackendService } from './postgresql-resource-repository.backend.service';\nimport { HttpApiResourceRepositoryBackendService } from './http-api/http-api-resource-repository.backend.service';\nimport { IntrospectionResourceRepositoryBackendService } from './introspection/introspection-resource-repository.backend.service';\nimport type { IntrospectionResourceSourceBackendPort } from './introspection/introspection-resource-source.backend.port';\nimport { createHttpApiSubjectErasureEffect } from './http-api/http-api-subject-erasure-effect.backend';\nimport type {\n HttpApiResourceBinding,\n} from '@wildo-ai/saas-models/external-data';\nimport { ExternalProvidersHttpApiAccessResolver } from './http-api/http-api-provider-access.backend';\nimport { PostgreSQLFilterBackendService } from '~wildo-backend-lib/databases/services/postgresql-filter.backend.service';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n buildPostgresSchemaStatements,\n classifyPostgresColumnJsReadType,\n PostgresColumnJsReadType,\n postgresColumnTypeSatisfiesPlan,\n renderPostgresColumnType,\n normalizePostgresDefaultExpression,\n renderPostgresColumnDefaultClause,\n} from '~wildo-backend-lib/databases/services/postgresql-schema-ddl.backend';\nimport {\n applyPostgresMigrations,\n loadMigrationsFromDirectory,\n} from '~wildo-backend-lib/databases/services/postgresql-migration-runner.backend';\nimport { ResourceIdBackendService } from '~wildo-backend-lib/resources/services/resource-id.backend.service';\nimport type {\n ConditionalArrayReturnType,\n ConditionalNullableReturnType,\n ConditionalReturnType,\n MainSchemaArrayType,\n MainSchemaType,\n PartialMainSchemaType,\n} from '~wildo-backend-lib/base-classes/utils/backend-type-utils';\nimport {\n enumerateFileFieldValueOccurrences,\n setValueAtRuntimePath,\n} from '~wildo-backend-lib/files/utils/file-field-schema-path.backend.utils';\nimport {\n describeGuardedMutationInexpressibility,\n type RepositoryGuardedMutation,\n} from './repository-guarded-mutation.backend.types';\n\n/**\n * Backend repository interface (no nominal private members).\n * Both Mongo and PostgreSQL repositories conform structurally.\n */\nexport interface BackendResourceRepository<\n TCustomOperationEnum extends EnumLikeType | undefined = undefined,\n TCoreOperationEnum extends Partial<CoreResourceOperation> | undefined = undefined,\n TMainSchema extends z.ZodTypeAny = z.ZodTypeAny\n> {\n doByPath<T = any, U = any>(\n operationRepositoryPath: ResourceConfiguration_OperationRepositoryPath,\n executionContext: ExecutionContext<any>,\n id_or_ids_or_filter?: any,\n data?: U,\n options?: RepositoryOptions\n ): Promise<T>;\n\n doByKey<T = any, U = any>(\n operationRepositoryPathKey: string,\n executionContext: ExecutionContext<any>,\n id_or_ids_or_filter?: any,\n data?: U,\n options?: RepositoryOptions\n ): Promise<T>;\n\n doByExecutionContext<T = any>(\n executionContext: ExecutionContext<any>,\n data?: any,\n options?: RepositoryOptions\n ): Promise<T>;\n\n // Core methods used throughout backend-lib (must be shared across adapters)\n create<T = undefined>(\n executionContext: ExecutionContext<any>,\n data: MainSchemaType<TMainSchema>,\n options?: RepositoryOptions\n ): Promise<ConditionalReturnType<T, TMainSchema>>;\n createMany<T = undefined>(\n executionContext: ExecutionContext<any>,\n data: MainSchemaArrayType<TMainSchema>,\n options?: RepositoryOptions\n ): Promise<ConditionalArrayReturnType<T, TMainSchema>>;\n\n read<T = undefined>(\n executionContext: ExecutionContext<any>,\n id_or_filter: IdOrFilterType,\n options?: RepositoryOptions\n ): Promise<ConditionalNullableReturnType<T, TMainSchema>>;\n\n /**\n * ADAPTER-NEUTRAL guarded-write primitives.\n *\n * These are ON THE CONTRACT deliberately. Both were reached through\n * `(repository as any).<name>` plus a `typeof … !== 'function'` runtime check, which is the\n * unenforced-contract shape this workstream exists to remove: a new adapter that simply omits\n * one compiles perfectly and fails at the first guarded write, in a background job or a metering\n * path where the error is most likely to be swallowed. Declaring them makes the omission a\n * compile error instead.\n *\n * Both take a PRE-BUILT filter including guard conditions. Callers reach them through the\n * registry, which applies the retention-hide predicate first — a retained row is immutable — so\n * these are not to be called directly from services.\n *\n * `T` is intentionally caller-chosen rather than schema-derived: these bypass the operation\n * lifecycle's DTO projection, so the row shape they return is the persisted one.\n */\n atomicIncrementField<T = any>(\n filter: Record<string, unknown>,\n field: string,\n delta: number,\n setFields?: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<T | null>;\n\n atomicConditionalSet<T = any>(\n filter: Record<string, unknown>,\n setFields: Record<string, unknown> | undefined,\n clearFields: readonly string[] | undefined,\n options?: RepositoryOptions,\n ): Promise<T | null>;\n\n /**\n * The GENERAL guarded write — set, clear, increment and array-add on the single matching row, in\n * ONE statement. The two primitives above are shorthands over it.\n *\n * On the contract for the same reason they are: an adapter that cannot compile a guarded mutation\n * must fail to build, not fail at the first lifecycle evaluation in a swallowed background path.\n */\n atomicGuardedMutation<T = any>(\n filter: Record<string, unknown>,\n mutation: RepositoryGuardedMutation,\n options?: RepositoryOptions,\n ): Promise<T | null>;\n\n /**\n * The MULTI-row guarded write, below the operation tier.\n *\n * On the contract for the same reason its single-row sibling is: an adapter that cannot compile a\n * guarded mutation must fail to BUILD. Takes an ALREADY-HIDDEN filter; the retention predicate is\n * applied once, by the handler.\n */\n updateManyByRawFilter(\n filter: Record<string, unknown>,\n mutation: RepositoryGuardedMutation,\n options?: RepositoryOptions,\n ): Promise<number>;\n\n /**\n * The MULTI-row DELETE, below the operation tier: destroy every row matching an already-built\n * filter and report how many went.\n *\n * ## Why it exists\n *\n * This tier had a bulk UPDATE and no bulk DELETE, so a framework sweep that needed to reap rows\n * had exactly one route: reach past the contract for the native driver. The consumable-tokens\n * cleanup batch took it, and that made the framework's only credential-retention sweep MongoDB-only\n * — invisible for as long as every application also ran a mongod beside PostgreSQL, and a hard\n * failure every six hours on the first one that did not. The sibling `updateManyByRawFilter`\n * records the same shape for bulk updates: \"the dialect used to sit in the SIGNATURE, so every\n * caller wrote MongoDB and a PostgreSQL-backed resource could not be bulk-updated at all\".\n *\n * ## The empty-filter refusal is part of the contract, not an implementation detail\n *\n * Both arms MUST refuse an empty or unusable filter rather than issuing an unfiltered statement.\n * This is stricter than `countByRawFilter` and `findManyByRawFilter`, which legitimately answer a\n * whole-table question because a read has no side effect: an unfiltered DELETE destroys the table.\n * The refusal is declared here so it is a property of the door rather than a habit two arms happen\n * to share — and the handler refuses the CALLER's filter separately, BEFORE the retention hide,\n * because the hide adds a predicate and would otherwise turn `{}` into something an arm-level\n * guard accepts.\n *\n * Takes an ALREADY-HIDDEN filter: the retention predicate is applied once, by the handler, exactly\n * as for every filter-bearing sibling on this tier.\n */\n deleteManyByRawFilter(\n filter: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<number>;\n\n /**\n * INSERT one already-built document, below the operation tier.\n *\n * On the contract for the same reason its siblings are: an adapter that cannot honour it must fail\n * to BUILD. Exists for framework-internal writers that own a resource with no API operation for\n * the write they need — consumable tokens are the case that forced it: the token lifecycle mints\n * and consumes credentials in flows that have NO principal (a verification email is a system\n * action; a magic-link click is pre-authentication by definition), so routing them through the\n * resource's declared, role-gated operations would mean fabricating an administrator.\n */\n insertRawDocument<T = any>(\n document: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<T>;\n\n /**\n * READ many rows matching an already-built filter — the multi-row counterpart of\n * `readUnscopedByKey`. Takes an ALREADY-HIDDEN filter; the retention predicate is applied once, by\n * the handler.\n */\n findManyByRawFilter<T = any>(\n filter: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<T[]>;\n\n /**\n * COUNT rows matching an already-built filter, below the operation tier.\n *\n * **On the contract for the same reason `atomicGuardedMutation` is:** an adapter that cannot answer\n * it must fail to BUILD, not fail at the first call in a path nobody watches. This member exists\n * because the handler's `countDocumentsForInfrastructure` used to reach\n * `(repository as any).mongooseModel` instead, which made a generally-named infrastructure\n * capability work on one adapter only — field-uniqueness validation threw \"No underlying database\n * model found\" for every PostgreSQL-backed resource, and nothing in the type system objected.\n *\n * Takes an ALREADY-HIDDEN filter: the retention predicate is applied once, by the handler.\n * Implementations must not re-apply it — see the `retention-gate` notes on both arms.\n */\n countByRawFilter(\n filter: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<number>;\n\n /**\n * A single-row read below BOTH the operation tier and the execution-context tier — the read\n * counterpart of the atomic trio above, and the only read on this contract that takes no context.\n *\n * ## Why it exists, and why it is not a loophole\n *\n * `readForInternalScan` drops the OPERATION but still applies the context's scope filter, so it\n * serves a caller that has a context. Some framework callers structurally cannot have one.\n * `ConsumableTokenBackendService` is the case that forced this: a password-reset or magic-link\n * request arrives with an unguessable secret and NO tenant identity — resolving the token is how\n * identity is established — and the service sits so far below the context tier that\n * `ExecutionContextCreatorBackendService` INJECTS it. A context cannot be built there without a\n * dependency cycle, and fabricating one would either invent a scope or fail closed on every\n * password reset.\n *\n * So the honest expression is a read that says what it does. The dangerous property is in the name:\n * `Unscoped` — no tenant narrowing is applied, and the caller's `filter` is the ONLY confinement.\n * Use it where the filter is itself the credential (an unguessable key), never to \"skip the scope\n * filter\" on a caller that has a scope.\n *\n * Retention hiding IS applied, at the registry dispatch point, exactly as it is for\n * `atomicGuardedMutation` — so an erased-but-retained row stays hidden even here. It carries the\n * same stated residual as that method: public on the contract, so app code holding a repository\n * handle can call it directly and skip the hide. A convention, not a mechanism.\n */\n readUnscopedByKey<T = any>(\n filter: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<T | null>;\n\n /**\n * Framework-internal single-row read independent of an authored/default READ\n * operation. It still applies the execution context's scope/retention filter\n * but bypasses user-facing operation hooks and projections.\n */\n readForInternalScan<T = undefined>(\n executionContext: ExecutionContext<any>,\n id_or_filter: IdOrFilterType,\n options?: RepositoryOptions\n ): Promise<ConditionalNullableReturnType<T, TMainSchema>>;\n\n /**\n * System-level membership projection for scope-required reference search: read\n * THIS (junction) resource's `targetFkField` values for rows matching\n * `{ [scopeFkField]: scopeId }`. Bypasses operation auth + contextual filtering\n * by design — it resolves the in-scope id set for a caller ALREADY authorized\n * for the scope (a membership projection, not a user-facing read). See\n * scope-required reference search (`.claude/plans/fk-filter-reference-search.md`).\n */\n findScopeRelatedTargetIds(scopeFkField: string, scopeId: string, targetFkField: string): Promise<string[]>;\n\n update<T = undefined>(\n executionContext: ExecutionContext<any>,\n id_or_filter: IdOrFilterType,\n data: PartialMainSchemaType<TMainSchema>,\n options?: RepositoryOptions\n ): Promise<ConditionalNullableReturnType<T, TMainSchema>>;\n\n updateMany<T = undefined>(\n executionContext: ExecutionContext<any>,\n data: PartialMainSchemaType<TMainSchema>,\n options?: RepositoryOptions\n ): Promise<ConditionalArrayReturnType<T, TMainSchema>>;\n\n delete(executionContext: ExecutionContext<any>, id_or_ids_or_filter: IdOrIdsOrFilterType, options?: RepositoryOptions): Promise<string>;\n deleteMany(\n executionContext: ExecutionContext<any>,\n ids_or_filter: IdsOrFilterType,\n options?: RepositoryOptions\n ): Promise<string[]>;\n\n list<T = undefined>(\n executionContext: ExecutionContext<any>,\n ids_or_filter: IdsOrFilterType,\n options?: RepositoryOptions\n ): Promise<ConditionalArrayReturnType<T, TMainSchema>>;\n list<T = undefined>(\n executionContext: ExecutionContext<any>,\n ids_or_filter: IdsOrFilterType,\n options: RepositoryOptions & { paginated: true; listOptions?: Partial<Resources_PaginationRequest> }\n ): Promise<Resources_PaginatedResult<ConditionalReturnType<T, TMainSchema>>>;\n\n /**\n * Framework-internal LIST. Unlike {@link list}, it does NOT require the\n * resource to declare a default LIST operation — see the implementation\n * JSDoc on `RepositoryResourceBackendService`. Used by framework\n * machinery that must list regardless of a user-facing LIST surface:\n * the data-seed engines (scan by `__seed.seedKey`) and the controller's\n * context-addressed-singleton authorization (resolve singleton id by\n * parent FK).\n */\n listForInternalScan<T = undefined>(\n executionContext: ExecutionContext<any>,\n ids_or_filter: IdsOrFilterType,\n options?: RepositoryOptions\n ): Promise<ConditionalArrayReturnType<T, TMainSchema>>;\n listForInternalScan<T = undefined>(\n executionContext: ExecutionContext<any>,\n ids_or_filter: IdsOrFilterType,\n options: RepositoryOptions & { paginated: true; listOptions?: Partial<Resources_PaginationRequest> }\n ): Promise<Resources_PaginatedResult<ConditionalReturnType<T, TMainSchema>>>;\n\n search<T = any>(\n executionContext: ExecutionContext<any>,\n searchQuery: string,\n filter?: any,\n searchOptions?: any,\n options?: RepositoryOptions\n ): Promise<Resources_PaginatedResult<T>>;\n\n count(executionContext: ExecutionContext<any>, filter?: any, options?: RepositoryOptions): Promise<{ count: number }>;\n\n supportsOperation(operationIdentifier: string): boolean;\n\n aggregateField(\n executionContext: ExecutionContext<any>,\n filter: any,\n field: string,\n operation: string,\n ): Promise<number>;\n\n // ---------------------------------------------------------------------------\n // Business-key surface (data-seeding subsystem)\n //\n // These three methods are the abstract contract the data-seeding dispatcher\n // depends on. Both Mongo (`RepositoryResourceBackendService`) and PostgreSQL\n // (`PostgreSQLResourceRepositoryBackendService`) implementations expose them\n // structurally; declaring them here lets `DataSeedDispatcherBackendService`\n // type its repository handles as `BackendResourceRepository<...>` instead of\n // narrowing to a concrete adapter (which would silently break the moment a\n // seed targets a PG-backed resource type).\n //\n // The signatures carry the SCHEMA-DERIVED types, not `<T = any>`.\n //\n // This reverses an earlier decision recorded here, and the reason is worth\n // keeping: that decision held the per-adapter refinements (the Mongo\n // `ConditionalReturnType<T, TMainSchema>`) to be \"structurally compatible with\n // `Promise<T>` when the caller does not pin `T`\". They are NOT. A conformance\n // check requires the method to accept ANY `T`, and TypeScript rejects the\n // narrowing outright — 12 members failed the moment `implements` was added.\n // The claim survived only because both repositories were cast through `as any`\n // at construction, so nothing ever checked it.\n //\n // A contract that says `any` is not a contract: it is what let three declared\n // members go unimplemented on PostgreSQL without a single compile error.\n // ---------------------------------------------------------------------------\n\n findByBusinessKey<T = undefined>(\n executionContext: ExecutionContext<any>,\n businessKeyShape: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<ConditionalNullableReturnType<T, TMainSchema>>;\n\n findManyByBusinessKeys<T = undefined>(\n executionContext: ExecutionContext<any>,\n businessKeyShapes: Array<Record<string, unknown>>,\n options?: RepositoryOptions,\n ): Promise<ConditionalArrayReturnType<T, TMainSchema>>;\n\n upsertByBusinessKey<T = undefined>(\n executionContext: ExecutionContext<any>,\n businessKeyShape: Record<string, unknown>,\n payload: Record<string, unknown>,\n seedMetadata: DataSeedRowMetadata,\n options?: RepositoryOptions,\n ): Promise<{ inserted: boolean; row: ConditionalReturnType<T, TMainSchema> }>;\n\n /**\n * Insert-or-update a row by an explicit singleton filter without writing\n * data-seeding metadata.\n *\n * This is the normal resource-write counterpart to `upsertByBusinessKey`.\n * Use it for framework-owned singleton materialization paths where the\n * selector is not represented by `.isBusinessKey()` on `mainSchema` (for\n * example relationship-injected scope FK fields such as `organizationId` or\n * `appId`). Callers must pass a semantically unique filter and keep any\n * fail-closed duplicate checks they need at the service boundary.\n *\n * ⚠️ **ADAPTER-ASYMMETRIC PRECONDITION — `options.excludeContextualFilter: true` is REQUIRED.**\n * The MongoDB arm runs the filter through `buildContextualFilter`, so its update branch is confined\n * to the caller's scope. PostgreSQL cannot do that: `ON CONFLICT` must name a UNIQUE constraint and\n * a scope predicate is not part of one, so arbitration happens on the business key ALONE. A caller\n * that relied on tenant confinement would therefore be confined on one adapter and update another\n * tenant's row on the other. Rather than leave that silent, the PostgreSQL arm REFUSES any caller\n * that has not waived contextual filtering explicitly (an array value is refused too — partial\n * scope filtering is exactly what cannot be expressed). So: pass a filter that already names the\n * scope, or use a scoped read-then-write instead.\n *\n * A multi-column filter additionally requires a DECLARED COMPOSITE unique constraint covering\n * exactly those columns; individually-unique columns do not compose into one.\n *\n * RETENTION is unaffected by that flag and always applied: a retained row is never rewritten and\n * never returned, on either adapter.\n */\n upsertByFilter<T = undefined>(\n executionContext: ExecutionContext<any>,\n filterShape: Record<string, unknown>,\n payload: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<{ inserted: boolean; row: ConditionalReturnType<T, TMainSchema> }>;\n\n /**\n * Privileged write path for the `__seed` row-metadata ledger ONLY.\n *\n * Purpose (R3-1, Phase-4 deep-review hotfix):\n * The data-seeding dispatcher needs to mutate a row's `__seed` ledger\n * (today: stamping `__seed.deprecated` from SYNC's orphan handler;\n * tomorrow: any future LAZY-mode bookkeeping). The standard\n * `update(...)` path runs the patch through the resource's `INTERNAL`\n * UPDATE `requestDto`, which Zod `.strip()`s any field not listed —\n * including `__seed` (no app resource declares it on its own DTO,\n * because `__seed` is a system-managed field added by the framework\n * via `ZodToMongooseSchemaConvertor`). Without this method, the\n * dispatcher's `repo.update(_id, { __seed })` would silently strip\n * `__seed` from the patch, the underlying `findOneAndUpdate` would\n * run with an empty `$set`, the orphan policy's counter would\n * increment, and `__seed.deprecated` would never persist — every\n * subsequent SYNC pass would re-deprecate the same orphans forever.\n *\n * Contract:\n * - Targets a row by `_id` (no business-key indirection — orphan\n * handling already has the row).\n * - Replaces the row's `__seed` ledger atomically. The caller passes\n * the FULL `DataSeedRowMetadata` (the dispatcher always carries\n * `priorMetadata` and merges deprecation/version/source on its\n * side; this method does not merge).\n * - Skips `cleanInputData` and `validateRequestData` (the whole\n * point — `__seed` is a system field the resource DTO never\n * declares).\n * - Still applies `addUserTracking` and `_version_db_doc` increment\n * so subsequent optimistic-locking reads stay consistent.\n * - Still respects `options.transaction` (transaction session\n * propagation — for parity with `upsertByBusinessKey`).\n *\n * Intentionally NOT exposed for general use:\n * - The dispatcher is the only legitimate writer of `__seed`. App\n * code must never call this; if it ever does, that's a layering\n * violation the reviewer should catch.\n *\n * Returns `void` because the caller already holds the row from the\n * preceding orphan-scan list and needs no echo. If a future call\n * site needs the post-write document, add a typed overload then.\n *\n * @throws WildoError_Backend on persistence failure (E11000 etc.,\n * wrapped via the adapter's `handleMongoDBError` / PG equivalent).\n * @throws WildoError_Backend(NOT_FOUND) if `id` does not exist.\n */\n updateSeedMetadata(\n executionContext: ExecutionContext<any>,\n id: string,\n seedMetadata: DataSeedRowMetadata,\n options?: RepositoryOptions,\n ): Promise<void>;\n\n}\n\n/**\n * Repository Registry Handler Backend Service\n *\n * Central registry for managing all repository resources in the application.\n * Provides unified access to repositories via operation paths and manages\n * cross-repository dependencies and relationships.\n *\n * Features:\n * - Repository lifecycle management (create, store, retrieve)\n * - Operation path-based repository access\n * - Cross-repository dependency injection\n * - Automatic repository initialization from resource configurations\n * - ExecutionContext integration for streamlined operations\n * - Resource relationship handling\n * - Unified error handling with ErrorBuilderBackendService\n */\n@injectable()\nexport class RepositoriesRegistryHandlerBackendService {\n\n private readonly repositories: Map<ResourceType, BackendResourceRepository<any, any, any>>;\n private readonly repositoryOperationsMap: Map<string, {\n repository: BackendResourceRepository<any, any, any>;\n operationRepositoryPath: ResourceConfiguration_OperationRepositoryPath;\n }>;\n private isInitialized = false;\n /**\n * Warn once per process, not once per resource: an unavailable index catalog is a property of the\n * DATABASE, so repeating it per PostgreSQL-backed resource would bury the boot log in one fact.\n */\n private hasWarnedPostgreSqlIndexIntrospectionUnavailable = false;\n\n /** Warn-once latch for {@link collectMissingPostgreSqlPrimaryKey}'s catalog read — separate from the\n * unique-index latch so each skipped verification is named truthfully, once. */\n private hasWarnedPostgreSqlPrimaryKeyIntrospectionUnavailable = false;\n protected logDebug: (message: string, context?: Record<string, unknown>) => void;\n\n\n constructor(\n @inject(SAAS_SERVICE_TYPES.ZodToMongooseSchemaConvertorService) private readonly zodToMongooseConverter: ZodToMongooseSchemaConvertorBackendService,\n @inject(SAAS_SERVICE_TYPES.ZodToSqlHybridSchemaPlannerService) private readonly zodToSqlPlanner: ZodToSqlHybridSchemaPlannerBackendService,\n @inject(SAAS_SERVICE_TYPES.Logger) private readonly logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) private readonly errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.ResourceRegistryService) private readonly resourceRegistry: ResourcesRegistryBackendService,\n @inject(SAAS_SERVICE_TYPES.ResourceOperationHelperService) private readonly resourceOperationHelper: ResourceOperationHelperBackendService,\n /**\n * Declared as the ADAPTER AUTHORITY, not as the whole application configuration: this registry\n * reads it for adapter resolution and nothing else (the three references below). The narrower\n * type is what lets a registry built for a DIFFERENT persistence scope than its host process\n * supply its own authority — see {@link PersistenceAdapterAuthority}. `AppConfigurationService`\n * satisfies it, so the container binding and every existing caller are unchanged.\n */\n @inject(SAAS_SERVICE_TYPES.AppConfigService) private readonly configService: PersistenceAdapterAuthority,\n @inject(SAAS_SERVICE_TYPES.PostgreSQLDatabaseService) private readonly postgresqlDb: PostgreSQLDatabaseBackendService,\n @inject(SAAS_SERVICE_TYPES.ResourceIdBackendService) private readonly resourceIdService: ResourceIdBackendService,\n // Appended LAST on purpose — this constructor is resolved positionally by\n // several containers, and inserting a parameter mid-list silently shifts\n // every dependency after it.\n @inject(SAAS_SERVICE_TYPES.Container) private readonly container: Container\n ) {\n\n this.repositories = new Map();\n this.repositoryOperationsMap = new Map();\n\n this.logDebug = this.logger.debugByType('RepositoriesRegistryHandler');\n this.logger.setDebugTypeLogging('RepositoriesRegistryHandler', false);\n\n this.logDebug('Repository registry service created');\n }\n\n// ================================\n// Initialize repositories\n// ================================\n\n public async initializeRepositories(\n resourceConfigurations: Map<ResourceType, ResourceConfiguration<any, any, any>>,\n connection?: Connection\n ): Promise<void> {\n if (this.isInitialized) {\n this.logDebug('Registry already initialized, skipping...');\n return;\n }\n\n this.logDebug('Initializing repositories', {\n resourceCount: resourceConfigurations.size,\n resourceTypes: Array.from(resourceConfigurations.keys())\n });\n\n // First pass: Create all repositories\n for (const [resourceType] of resourceConfigurations) {\n try {\n await this.createRepository(resourceType, connection);\n } catch (error) {\n this.logger.error('Failed to create repository', {\n resourceType,\n ...projectCaughtErrorLogFields(error)\n });\n throw error;\n }\n }\n\n\n this.buildOperationRepositoryPathsMap();\n\n // Boot-time schema maintenance belongs to the runtime ACCOUNTABLE for it —\n // the application backend — not to every runtime that happens to build a\n // repository registry.\n //\n // A minion's Mongo user is collection-scoped to what its `resourceAccess`\n // declared, so running these here means `updateMany` on collections it never\n // asked for: unauthorised, and not its concern. Observed 2026-08-12 as a\n // crash-loop on `not authorized ... update \"users\"` the moment per-principal\n // Mongo users landed. The containment was correct — the minion was doing the\n // backend's job.\n //\n // Gated on the PROFILE rather than on \"did the write fail?\": a maintenance\n // step that silently tolerates its own denial is indistinguishable from one\n // that ran.\n if (resolveApplicationRuntimeProfileBootAssertions(this.resolveRuntimeProfile()).performsBootSchemaMaintenance) {\n // BEFORE the index reconciliation, never after: the backfill stamps legacy rows with the marker\n // that a retention-scoped partial unique index selects on, so an index rebuilt first would be\n // built over rows that are about to become eligible for it.\n await this.reconcileRetentionGovernedMongoCollections();\n\n await this.reconcileDriftedMongoUniqueIndexes();\n\n // AFTER both reconciliations, never before: they drop and recreate indexes whose declared options\n // have drifted, so verifying first would report an index that is about to be fixed.\n //\n // Inside the SAME gate, because this step BUILDS as well as verifies: it\n // awaits Mongoose's `autoIndex` build, and re-attempts it when the memoized\n // one failed, so a declared index gets created here — a write on a\n // collection a confined runtime may not hold. Leaving only\n // the verification outside would also be wrong on its own terms — a minion\n // asserting that 60 indexes exist is asserting something it is not\n // accountable for and cannot repair. The backend proves it for every\n // runtime; a minion that reached this point is running against a database\n // the backend already verified.\n await this.verifyDeclaredMongoUniqueIndexes();\n } else {\n this.logger.debug(\n 'Skipping boot schema maintenance and index verification: this runtime does not own them '\n + '(see ApplicationRuntimeProfileBootAssertions.performsBootSchemaMaintenance). The '\n + 'application backend performs the retention backfill, the index reconciliation AND the '\n + 'declared-unique-index verification for every runtime.',\n );\n }\n\n this.isInitialized = true;\n\n this.logDebug('Repository registry initialization completed', {\n repositoryCount: this.repositories.size,\n operationRepositoryPathsCount: this.repositoryOperationsMap.size\n });\n }\n\n\n /**\n * PLATFORM-MODE default adapter, set explicitly before repository construction (Phase 5.2, D7).\n *\n * ## The ordering problem this solves\n *\n * Platform services (apps-manager, module-registry) build their repositories inside\n * `super.initialize()` while `AppConfigurationService` is deliberately UNHYDRATED — hydration is\n * their own later phase. So the fallback chain below reached \"config not initialized → framework\n * default\" for every platform resource, and no configuration could ever make a platform resource\n * PostgreSQL-backed: the answer was needed before the config that carries it existed.\n *\n * The fix is NOT re-resolution after hydration: repositories are CONSTRUCTED as concrete\n * Mongo/PostgreSQL classes exactly once, and an adapter answer that changes after construction is\n * a split-brain, not a correction. The platform KNOWS its store in its Phase 1 (the bridged\n * platform config, which exists before `super.initialize()`), so the answer is passed EXPLICITLY\n * at construction time.\n *\n * ## Why the override outranks the hydrated config's own default\n *\n * Once set, it stays authoritative even after `configService.isInitialized()` flips true. Both\n * values derive from one platform config, so disagreement is a bug — and if it happens, the\n * construction-time answer is the one the LIVE repositories were actually built with; letting the\n * later value win would make the boot door and schema gate reason about repositories that do not\n * exist. {@link setPlatformModeDefaultPersistenceAdapter} refuses a conflicting re-set for the\n * same reason.\n *\n * `undefined` for every non-platform application — nothing changes outside platform mode, and\n * `StartApplicationBackendService` refuses the parameter without `isPlatformApplication` so it\n * cannot become a side door around the application config contract.\n *\n * The VALUE is stored on `AppConfigurationService` (review R2): three independent resolvers\n * consume it — this registry, the services-tier transaction router, and the\n * resource-id/unit-of-work resolver — and the config service is the one dependency all three\n * share without a cycle. This method remains the ONLY sanctioned writer and owns the conflict\n * guard; the shared derivation lives in `resolveDefaultPersistenceAdapter`.\n */\n public setPlatformModeDefaultPersistenceAdapter(adapter: PersistenceAdapterType): void {\n const current = this.configService.platformModeDefaultPersistenceAdapter;\n if (current !== undefined && current !== adapter) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'platform_persistence_adapter_conflict',\n previous: current,\n attempted: adapter,\n },\n });\n }\n this.configService.adoptPlatformModeDefaultPersistenceAdapter(adapter);\n }\n\n /**\n * The persistence adapter a resource actually runs on. This registry's consumers — repository\n * construction, the migrations boot door, the schema verifier, the retention prerequisites —\n * all route here, and the derivation itself is the shared seam\n * (`resolveDefaultPersistenceAdapter`), so this tier can never disagree with the services-tier\n * or resource-id resolvers. Tolerates an uninitialized config service (unit harnesses\n * construct the registry without one; the seam answers the framework default).\n */\n private getResolvedPersistenceAdapterForResource(resourceType: ResourceType): PersistenceAdapterType {\n const declaredAdapter = this.resourceRegistry.tryGetResourceConfiguration(resourceType)?.persistenceAdapter;\n return resolvePersistenceAdapterForConfiguration(declaredAdapter, this.configService);\n }\n\n private async createRepository(\n resourceType: ResourceType,\n connection?: Connection,\n ): Promise<void> {\n this.logDebug('Creating repository', { resourceType });\n\n // Always use registry as the single source of truth.\n const resourceConfiguration = this.resourceRegistry.getResourceConfiguration(resourceType);\n\n const adapterToUse = this.getResolvedPersistenceAdapterForResource(resourceType);\n\n let repository: BackendResourceRepository<any, any, any>;\n\n // Dispatched as the ENUM type: `PersistenceAdapterType` is the template-literal union, which\n // TypeScript does not narrow to `never` through enum-member case labels — the enum type does,\n // and that narrowing is what makes the `default` arm's exhaustiveness assignment work.\n const adapterForDispatch = adapterToUse as PersistenceAdapter;\n switch (adapterForDispatch) {\n case PersistenceAdapter.POSTGRESQL:\n repository = new PostgreSQLResourceRepositoryBackendService(\n resourceType,\n this.postgresqlDb,\n this.logger,\n this.errorBuilder,\n this.resourceRegistry,\n this.resourceOperationHelper,\n this,\n this.zodToSqlPlanner,\n this.resourceIdService\n );\n break;\n case PersistenceAdapter.MONGODB:\n repository = RepositoryResourceBackendService.createInstance(\n resourceType,\n this.zodToMongooseConverter,\n this.logger,\n this.errorBuilder,\n this.resourceRegistry,\n this.resourceOperationHelper,\n this as any,\n connection,\n this.resourceIdService\n );\n break;\n case PersistenceAdapter.HTTP_API: {\n // ETL Step 3 (`.claude/plans/etl-post-repository.md`): rows are served on demand through\n // the resource's committed `httpApiBinding` — read-only in slice 1, every other contract\n // member an honest refusal (D2/D3). The provider registry resolves credentials (D7); it\n // is fetched LAZILY through the container rather than a new constructor parameter, per\n // the positional-resolution warning on this constructor's last parameter.\n // NO cast, deliberately: the structural assignment below is what keeps D2 true — a future\n // contract member this adapter omits must fail to BUILD here, exactly as it does for the\n // PostgreSQL sibling. (The Mongo sibling's `as any` at `createInstance` is an argument\n // cast, not an assignment cast.)\n const httpApiRepository = new HttpApiResourceRepositoryBackendService(\n resourceType,\n this.logger,\n this.errorBuilder,\n this.resourceRegistry,\n new ExternalProvidersHttpApiAccessResolver(\n this.container.get(SAAS_SERVICE_TYPES.ExternalProvidersRegistryService),\n ),\n undefined,\n // The read-through audit seam (ETL D8/R6), resolved lazily per emission — the\n // authorizations-service precedent: never a hard dependency, so a container without the\n // audit binding still constructs the repository and the reads it serves.\n () => (this.container.isBound(SAAS_SERVICE_TYPES.AuditLogsService)\n ? this.container.get(SAAS_SERVICE_TYPES.AuditLogsService)\n : undefined),\n );\n repository = httpApiRepository;\n this.registerHttpApiSubjectErasureEffect(resourceType, resourceConfiguration, httpApiRepository);\n break;\n }\n case PersistenceAdapter.INTROSPECTION: {\n /*\n * Rows are DERIVED per read by the dev companion; nothing is stored. The source is resolved\n * LAZILY from the container and its absence is not an error — an application running without\n * a companion binds nothing, and the repository refuses per call. Refusing at BOOT instead\n * would need a running companion to repair the companion\n * (`continuity-drift-and-cas-basis.md` Rule 3).\n *\n * No subject-erasure effect is registered, unlike the HTTP_API arm: there is no store, so\n * there are no rows to erase and nothing that could outlive a request. Stated rather than\n * omitted, because a silent absence here reads as an oversight.\n */\n repository = new IntrospectionResourceRepositoryBackendService(\n resourceType,\n this.logger,\n this.errorBuilder,\n () => (this.container.isBound(SAAS_SERVICE_TYPES.IntrospectionResourceSource)\n ? this.container.get<IntrospectionResourceSourceBackendPort>(SAAS_SERVICE_TYPES.IntrospectionResourceSource)\n : undefined),\n ) as unknown as BackendResourceRepository<any, any, any>;\n break;\n }\n default: {\n // Compile-time exhaustiveness: `adapterForDispatch` narrows to `never` only while every enum\n // member has a `case` above, so a new PersistenceAdapter member reddens this assignment\n // at typecheck instead of surfacing as a boot failure. The runtime throw stays for the\n // other failure direction — an unknown string smuggled through erased configuration.\n const unhandledAdapter: never = adapterForDispatch;\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n {\n customMessageReference:\n ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'unsupported_persistence_adapter',\n resourceType,\n persistenceAdapter: unhandledAdapter,\n },\n },\n );\n }\n }\n\n this.repositories.set(resourceType, repository);\n\n this.logDebug('Repository created successfully', { resourceType,});\n }\n\n /**\n * Register the D6 erasure-stance effect for one HTTP_API-bound resource (ETL D6 slices B/C) —\n * one `http-api:<resourceType>` entry per resource in every subject-erasure report whose graph\n * reaches it.\n *\n * Registered HERE, where the adapter is built, for the billing precedent's reason: the erasure\n * orchestrator stays domain-agnostic (\"run whatever declared itself relevant\"), and the\n * effect's lifetime is tied to the repository's — a runtime that never builds this adapter\n * registers nothing. Feature-detected on both service bindings (the effects registry and the\n * audit service): a partial container (minion runtimes, unit harnesses) still constructs the\n * repository. `register` is idempotent per `effectRef`, so a re-created repository re-registers\n * rather than double-running.\n *\n * The subject-link resolution below is DECLARATION-driven (the stance's `subjectLinkLocalField`\n * + the relationship that names its subject type — boot check B4), never inferred from FK\n * shapes: an FK usually names an owner or an actor, not the data subject.\n */\n private registerHttpApiSubjectErasureEffect(\n resourceType: ResourceType,\n resourceConfiguration: { httpApiBinding?: unknown; resourceRelationships?: unknown },\n repository: HttpApiResourceRepositoryBackendService,\n ): void {\n if (!this.container.isBound(SAAS_SERVICE_TYPES.SubjectErasureExternalEffectsService)) return;\n const binding = resourceConfiguration.httpApiBinding as HttpApiResourceBinding | undefined;\n if (!binding) return;\n\n const ownFkRelationships = (): Array<{ resourceType1?: unknown; resourceType2?: unknown; foreignKeyField?: unknown; isDisabled?: unknown }> => {\n const buckets = resourceConfiguration.resourceRelationships as\n | Record<string, Array<Record<string, unknown>>>\n | undefined;\n return [\n ...(buckets?.parentRelationships ?? []),\n ...(buckets?.childRelationships ?? []),\n ...(buckets?.selfRelationships ?? []),\n ].filter((relationship) =>\n relationship.isDisabled !== true && relationship.resourceType2 === resourceType,\n );\n };\n\n const declaredSubjectLinkField = (): string | undefined =>\n (binding.erasure as { subjectLinkLocalField?: string }).subjectLinkLocalField;\n\n const effectsRegistry = this.container.get(\n SAAS_SERVICE_TYPES.SubjectErasureExternalEffectsService,\n ) as { register: (effect: unknown) => void };\n effectsRegistry.register(createHttpApiSubjectErasureEffect({\n resourceType: String(resourceType),\n binding,\n subjectIsLinked: (subjectResourceType) =>\n ownFkRelationships().some((relationship) => relationship.resourceType1 === subjectResourceType),\n resolveSubjectLinkFields: (subjectResourceType) => {\n const linkField = declaredSubjectLinkField();\n if (!linkField) return [];\n const declaresIt = ownFkRelationships().some((relationship) =>\n relationship.resourceType1 === subjectResourceType && relationship.foreignKeyField === linkField,\n );\n return declaresIt ? [linkField] : [];\n },\n eraseLinkedRows: (localFkField, subjectId) =>\n repository.executeDeclaredSubjectLinkErasure(localFkField, subjectId),\n countLinkedRows: (localFkField, subjectId) =>\n repository.countRowsLinkedToSubject(localFkField, subjectId),\n auditLogsResolver: () => (this.container.isBound(SAAS_SERVICE_TYPES.AuditLogsService)\n ? this.container.get(SAAS_SERVICE_TYPES.AuditLogsService)\n : undefined),\n }));\n }\n\n // ================================\n // PostgreSQL startup migrations (the production door)\n // ================================\n\n /**\n * Apply pending PostgreSQL migrations at BOOT — the production door of the migration system\n * (K7: one runner, two doors; this is the one that exists in production, where there is no\n * source tree and no operator CLI).\n *\n * ## Placement and gating\n *\n * Runs from application startup immediately BEFORE {@link verifyPostgreSqlTableSchemas}, so the\n * gate verifies the schema migrations just produced — the runner changes the database, the gate\n * remains the fleet's backstop (K6), and a runner bug cannot silently become a served schema.\n *\n * Safe in every topology by the same construction as the gate:\n * - **No PostgreSQL-backed resource** (every application today, and every platform-mode boot,\n * whose uninitialized config resolves all adapters to the framework default) → returns before\n * touching `getDb()`. It can never force a connection an application does not use.\n * - **No migrations directory** → logged no-op. An application that has not adopted migrations\n * boots exactly as before; the gate still speaks for its schema. The directory is\n * `<cwd>/migrations` by convention (shipped inside the deployable, beside the code that needs\n * it), overridable via `WILDO_MIGRATIONS_DIR` for layouts where cwd is not the service root.\n *\n * ## It THROWS on failure, and that is the design\n *\n * A failed or refused migration fails the BOOT: new code must not serve behind the schema it was\n * built against. This does not violate the \"no boot-deadlock\" rule\n * (`continuity-drift-and-cas-basis.md` rule 3): the remedy — fix the migration draft, restore an\n * edited file, add the destructive acknowledgement — lives in the REPOSITORY, and never routes\n * through the process that just refused to start.\n *\n * Concurrency is the RUNNER's property, not this caller's: N instances booting simultaneously\n * elect one applier via the in-database advisory lock; the others wait, then everyone verifies.\n */\n public async applyStartupPostgresMigrations(): Promise<void> {\n /**\n * ONLY the runtime that owns the application's schema. Same gate as the Mongo boot maintenance\n * in `initializeRepositories`, and it belongs here for the same reason\n * `performsBootSchemaMaintenance`'s own contract already generalises: \"a boot step that WRITES\n * to the application's schema belongs to the runtime that owns the schema, and adding one\n * without asking which runtime owns it is how a confined runtime acquires an authority nobody\n * intended.\"\n *\n * That lesson was recorded on 2026-08-12 after a collection-scoped minion crash-looped TWICE on\n * Mongo boot maintenance — and it was applied to the Mongo steps only. The PostgreSQL pair was\n * gated at its call site on `!isPlatformApplication`, which a MINION also satisfies, so both ran\n * on every confined runtime. Observed 2026-08-21 once the application moved to PostgreSQL: the\n * marketing-scrapper minion crash-looped on `postgresql_table_schema_mismatch` reporting that 90\n * tables \"do not exist (no migration has created it)\" — against a database holding all 94 of\n * them. `information_schema` is PERMISSION-FILTERED, and a table-scoped role held grants on\n * exactly ONE table, so the gate was reading its own confinement as a missing schema.\n *\n * The migration runner is the clearer half: it issues DDL, which a confined role has no rights\n * for and no accountability over. The verifier follows the identical argument its Mongo sibling\n * records — a minion asserting that 90 tables match a plan is asserting something it cannot\n * repair, on a database the application backend already verified for every runtime.\n *\n * It is also a boot-deadlock removal (`continuity-drift-and-cas-basis.md` rule 3): the minion's\n * remedy is a GRANT issued by apps-manager, so a minion that fails closed here can never be the\n * process that fixes it.\n *\n * The gate is HERE rather than at the call site so every caller inherits it — including the\n * platform services that invoke these methods themselves. Those resolve the fail-safe\n * `APPLICATION_BACKEND` default, so their behaviour is unchanged.\n */\n if (!resolveApplicationRuntimeProfileBootAssertions(this.resolveRuntimeProfile()).performsBootSchemaMaintenance) {\n this.logger.debug(\n 'Skipping PostgreSQL startup migrations and physical-schema verification: this runtime does not own '\n + 'the application schema (see ApplicationRuntimeProfileBootAssertions.performsBootSchemaMaintenance). '\n + 'The application backend applies the migrations and proves the physical schema for every runtime.',\n );\n return;\n }\n\n // persistence-adapter binary comparison: N/A — genuine PG-feature gate. \"Does any resource\n // need the PostgreSQL migration door?\" A resource on any other adapter (current or future)\n // correctly does not; misrouting is impossible because every resource already passed the\n // exhaustive `createRepository` dispatch before this runs.\n const hasPostgresResources = Array.from(this.repositories.keys()).some(\n (resourceType) => this.getResolvedPersistenceAdapterForResource(resourceType) === PersistenceAdapter.POSTGRESQL,\n );\n if (!hasPostgresResources) return;\n\n const migrationsDirectory = process.env.WILDO_MIGRATIONS_DIR ?? join(process.cwd(), 'migrations');\n if (!existsSync(migrationsDirectory)) {\n this.logDebug('No migrations directory — startup migrations skipped', { migrationsDirectory });\n return;\n }\n\n const migrations = loadMigrationsFromDirectory(migrationsDirectory);\n if (migrations.length === 0) {\n this.logDebug('Migrations directory is empty — startup migrations skipped', { migrationsDirectory });\n return;\n }\n\n const db = await this.postgresqlDb.getDb();\n const report = await applyPostgresMigrations({ db, migrations });\n if (report.outOfOrder?.length) {\n // Applied, never refused — but the author deserves the pointer: an out-of-order migration was\n // drafted against an older accepted state. The gate right after this verifies the end state.\n this.logger.warn(\n `[Migrations] ${report.outOfOrder.length} migration(s) arrived OUT OF ORDER (older name than an `\n + `already-applied one) and were applied in sorted position: ${report.outOfOrder.join(', ')}. `\n + 'Normal after a branch merge; review them against the newer migrations they sorted before.',\n );\n }\n this.logDebug('Startup PostgreSQL migrations complete', {\n role: report.role,\n applied: report.applied,\n verifiedCount: report.verified.length,\n });\n }\n\n // ================================\n // PostgreSQL physical-schema verification\n // ================================\n\n /**\n * Prove that every PostgreSQL-backed resource's table actually HAS the columns the engine writes,\n * at BOOT, with a diagnosable error — instead of a raw driver failure on the first request.\n *\n * **Why this gate exists.** Mongo materializes a collection's shape from the Zod schema, so a\n * MongoDB-backed resource cannot disagree with its storage. PostgreSQL cannot: DDL is owned outside\n * the engine (`planSqlHybridTable` is explicitly \"planning only — migration execution and DDL\n * application are owned by apps-manager\"), so the table is whatever a migration author or fixture\n * wrote. Nothing checked that against the plan. The failure that motivated this: a framework-owned\n * column (`_version_db_doc`, the optimistic-locking version — a `SYSTEM_MANAGED_FIELDS` entry no app\n * schema declares) was written on every INSERT while the plan declared no such column, so the FIRST\n * create on any PostgreSQL-backed resource died with a bare `column \"_version_db_doc\" does not\n * exist` — a message that names no resource, no plan, and no fix.\n *\n * **Called from application startup, NOT from `initializeRepositories`.** Repositories are built\n * before the PostgreSQL connection is necessarily reachable (`getDb()` is deliberately lazy, and\n * fixtures provision their tables after building the registry), so verifying there would fail for\n * ordering reasons rather than schema reasons. Startup is where live-database probes already belong\n * — it is the same phase as the native-transaction readiness probe.\n *\n * **Zero cost when no resource is PostgreSQL-backed** (today: essentially every application): it\n * returns before touching `getDb()`, so it can never force a connection an app does not use.\n *\n * Scope, deliberately: PRESENCE of columns only. Column TYPES, nullability, indexes and constraints\n * are migration-owned and intentionally not asserted — this gate exists to convert one specific\n * class of opaque runtime failure into a boot-time diagnosis, not to become a schema differ. Extra\n * columns the plan does not know about are ignored for the same reason: the plan is a MINIMUM\n * contract, and a migration may legitimately add more.\n *\n * Every problem across every resource is collected into ONE error. Failing on the first one would\n * make fixing a drifted schema an N-boot loop.\n */\n public async verifyPostgreSqlTableSchemas(): Promise<void> {\n /**\n * ONLY the runtime that owns the application's schema. Same gate as the Mongo boot maintenance\n * in `initializeRepositories`, and it belongs here for the same reason\n * `performsBootSchemaMaintenance`'s own contract already generalises: \"a boot step that WRITES\n * to the application's schema belongs to the runtime that owns the schema, and adding one\n * without asking which runtime owns it is how a confined runtime acquires an authority nobody\n * intended.\"\n *\n * That lesson was recorded on 2026-08-12 after a collection-scoped minion crash-looped TWICE on\n * Mongo boot maintenance — and it was applied to the Mongo steps only. The PostgreSQL pair was\n * gated at its call site on `!isPlatformApplication`, which a MINION also satisfies, so both ran\n * on every confined runtime. Observed 2026-08-21 once the application moved to PostgreSQL: the\n * marketing-scrapper minion crash-looped on `postgresql_table_schema_mismatch` reporting that 90\n * tables \"do not exist (no migration has created it)\" — against a database holding all 94 of\n * them. `information_schema` is PERMISSION-FILTERED, and a table-scoped role held grants on\n * exactly ONE table, so the gate was reading its own confinement as a missing schema.\n *\n * The migration runner is the clearer half: it issues DDL, which a confined role has no rights\n * for and no accountability over. The verifier follows the identical argument its Mongo sibling\n * records — a minion asserting that 90 tables match a plan is asserting something it cannot\n * repair, on a database the application backend already verified for every runtime.\n *\n * It is also a boot-deadlock removal (`continuity-drift-and-cas-basis.md` rule 3): the minion's\n * remedy is a GRANT issued by apps-manager, so a minion that fails closed here can never be the\n * process that fixes it.\n *\n * The gate is HERE rather than at the call site so every caller inherits it — including the\n * platform services that invoke these methods themselves. Those resolve the fail-safe\n * `APPLICATION_BACKEND` default, so their behaviour is unchanged.\n */\n if (!resolveApplicationRuntimeProfileBootAssertions(this.resolveRuntimeProfile()).performsBootSchemaMaintenance) {\n this.logger.debug(\n 'Skipping PostgreSQL startup migrations and physical-schema verification: this runtime does not own '\n + 'the application schema (see ApplicationRuntimeProfileBootAssertions.performsBootSchemaMaintenance). '\n + 'The application backend applies the migrations and proves the physical schema for every runtime.',\n );\n return;\n }\n\n // persistence-adapter binary comparison: N/A — genuine PG-feature gate (which resources does\n // the physical-schema verifier speak for?). Same reasoning as the migrations gate above:\n // `createRepository`'s exhaustive dispatch has already refused any unknown adapter.\n const postgresResourceTypes = Array.from(this.repositories.keys()).filter(\n (resourceType) => this.getResolvedPersistenceAdapterForResource(resourceType) === PersistenceAdapter.POSTGRESQL,\n );\n\n if (postgresResourceTypes.length === 0) {\n return;\n }\n\n this.logDebug('Verifying PostgreSQL physical table schemas', {\n resourceTypes: postgresResourceTypes,\n });\n\n const db = await this.postgresqlDb.getDb();\n const problems: string[] = [];\n\n for (const resourceType of postgresResourceTypes) {\n const resourceConfiguration = this.resourceRegistry.tryGetResourceConfiguration(resourceType);\n if (!resourceConfiguration) continue;\n\n // Alias-aware, matching the repository and the planner: probing `userself` instead of the\n // shared `users` table would report a perfectly provisioned schema as missing.\n const tableName = PostgreSQLFilterBackendService.resolveTableNameForResource(String(resourceType));\n const expectedColumns = this.zodToSqlPlanner.planPhysicalColumnNames(\n resourceConfiguration as any,\n resourceConfiguration.mainSchema as any,\n );\n\n // Unqualified by schema ON PURPOSE: the repository issues unqualified statements too, so both\n // resolve through the same `search_path`. (`to_regclass` would pin the resolution exactly but is\n // unsupported by the in-memory Postgres the integration fixtures run on.)\n const result = await sql<{ column_name: string; data_type: string; column_default: string | null }>`\n select column_name, data_type, column_default from information_schema.columns where table_name = ${tableName}\n `.execute(db);\n const liveColumnTypes = new Map(result.rows.map((row) => [String(row.column_name), String(row.data_type)]));\n const liveColumnDefaults = new Map(\n result.rows.map((row) => [String(row.column_name), row.column_default == null ? null : String(row.column_default)]),\n );\n const actualColumns = new Set(liveColumnTypes.keys());\n\n // A table always has at least one column, so an empty result means the table is not there —\n // no second existence query needed, and portable across real Postgres and the in-memory one.\n if (actualColumns.size === 0) {\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" does not exist (no migration has created it)`,\n );\n continue;\n }\n\n const missingColumns = expectedColumns.filter((column) => !actualColumns.has(column));\n if (missingColumns.length > 0) {\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" is missing column(s) ${missingColumns.map((c) => `\"${c}\"`).join(', ')}`,\n );\n // Uniqueness over a column that is not there cannot be assessed, and reporting it would bury\n // the real defect under a derived one.\n continue;\n }\n\n problems.push(...this.collectPostgreSqlColumnTypeMismatches(resourceType, tableName, resourceConfiguration, liveColumnTypes));\n\n problems.push(...this.collectPostgreSqlColumnDefaultMismatches(resourceType, tableName, resourceConfiguration, liveColumnDefaults));\n\n problems.push(...await this.collectMissingPostgreSqlUniqueConstraints(db, resourceType, tableName, resourceConfiguration));\n\n problems.push(...await this.collectMissingPostgreSqlPrimaryKey(db, resourceType, tableName, resourceConfiguration));\n }\n\n if (problems.length === 0) {\n this.logDebug('PostgreSQL physical table schemas verified', {\n resourceCount: postgresResourceTypes.length,\n });\n return;\n }\n\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'postgresql_table_schema_mismatch',\n message:\n `${problems.length} PostgreSQL-backed resource(s) have a table that does not match the engine's `\n + `schema plan, so their first request would fail with a bare driver error:\\n${problems.join('\\n')}\\n`\n + `The plan (ZodToSqlHybridSchemaPlannerBackendService.planSqlHybridTable) is the contract migrations `\n + `must build these tables from. It includes framework-owned columns no app schema declares — notably `\n + `\"_version_db_doc\", the optimistic-locking version the repository writes on every insert.`,\n problems,\n },\n });\n }\n\n // ================================\n // Retention opt-in prerequisites (MongoDB)\n // ================================\n\n /**\n * MECHANICALLY ENFORCED prerequisites for opting a MongoDB-backed resource into `retentionPolicy`\n * (gate **G-BKEY**, second half). Runs once at boot, and is a no-op for every application whose\n * resources are not retention-governed — which is all of them until the first opt-in.\n *\n * **The `retentionStatus = ACTIVE` backfill**, an obligation no comment in the index builder could\n * enforce. MongoDB rejects `$ne` inside a `partialFilterExpression`, so the retention-scoped unique\n * index is keyed on plain equality (`{ retentionStatus: ACTIVE }`). Every row written BEFORE the\n * resource opted in carries NO marker and therefore falls OUT of the index entirely — uniqueness\n * silently LAPSES for exactly the legacy rows most likely to contain duplicates. (Postgres does not\n * have this problem: its `IS DISTINCT FROM` predicate covers NULL.) The backfill closes the gap; it\n * is idempotent and matches nothing on every subsequent boot.\n *\n * FAIL-CLOSED: a duplicate-key error during the backfill means legacy rows already violate the\n * uniqueness the opt-in is about to assert. Boot fails loudly instead.\n *\n * The second half of the opt-in — rebuilding a unique index whose live `partialFilterExpression`\n * still predates the opt-in — used to live here, scoped to retention-governed resources. It now\n * belongs to {@link reconcileDriftedMongoUniqueIndexes}, which reconciles that axis for EVERY unique\n * index rather than only retention-scoped ones, and which this method must therefore run before: the\n * backfill has to stamp the legacy rows before an index selecting on that marker is rebuilt over\n * them.\n */\n private async reconcileRetentionGovernedMongoCollections(): Promise<void> {\n const retentionGovernedResourceTypes = Array.from(this.repositories.keys()).filter(\n (resourceType) => {\n const resourceConfiguration = this.resourceRegistry.tryGetResourceConfiguration(resourceType);\n if (!isRetentionGovernedResource(resourceConfiguration)) return false;\n // A PostgreSQL-backed resource needs neither obligation, for two DIFFERENT reasons:\n // - no marker backfill, because its retention predicate compiles to `IS DISTINCT FROM`, which\n // already matches the NULL marker a pre-opt-in row carries;\n // - no index rebuild HERE, because although the framework now DOES render its retention-scoped\n // partial unique indexes (`postgresql-schema-ddl.backend.ts`), applying schema changes stays\n // migration-owned. `verifyPostgreSqlTableSchemas` is the gate that speaks for those, and it\n // fails the boot when such an index is missing or not partial.\n // Selected POSITIVELY (`=== MONGODB`): this pass drives Mongoose collection reconciliation,\n // so it may only ever see MongoDB-backed resources. The previous `!== POSTGRESQL` would\n // have swept any future backing kind into the Mongo lane.\n return this.getResolvedPersistenceAdapterForResource(resourceType) === PersistenceAdapter.MONGODB;\n },\n );\n\n if (retentionGovernedResourceTypes.length === 0) {\n return;\n }\n\n this.logDebug('Reconciling retention-governed MongoDB collections', {\n resourceTypes: retentionGovernedResourceTypes,\n });\n\n for (const resourceType of retentionGovernedResourceTypes) {\n const mongooseModel = (this.repositories.get(resourceType) as any)?.mongooseModel as\n | Model<any>\n | undefined;\n if (!mongooseModel) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'retention_governed_resource_without_mongoose_model',\n resourceType,\n },\n });\n }\n\n // Mongoose attaches `model.collection` at COMPILE time, before any connection — so a model\n // without one is not a Mongoose model bound to a database at all (a stub schema converter in a\n // unit/integration harness). There is no collection to backfill or reindex, and such a model\n // cannot serve a query either. Skip loudly rather than failing a boot over a missing double.\n if (typeof mongooseModel.collection?.updateMany !== 'function') {\n this.logger.warn(\n `[Retention] Skipping the opt-in prerequisites for \"${resourceType}\": its model exposes no live `\n + 'MongoDB collection handle. Expected only under a stubbed schema converter — in a real '\n + 'deployment this means the backfill and index reconciliation did NOT run.',\n );\n continue;\n }\n\n await this.backfillRetentionStatusMarkers(resourceType, mongooseModel);\n }\n }\n\n\n /**\n * The runtime profile of this process, defaulting fail-SAFE.\n *\n * Mirrors `SystemAccessBackendService.resolveRuntimeProfile`, including the\n * default: an unresolvable principal cannot be a MINION (minion startup binds\n * and initializes it), so defaulting to `APPLICATION_BACKEND` preserves the\n * pre-existing behaviour for minimal and test containers rather than silently\n * skipping maintenance everywhere.\n */\n private resolveRuntimeProfile(): ApplicationRuntimeProfile {\n try {\n return this.container\n .get<{ describe(): { runtimeProfile: ApplicationRuntimeProfile } }>(SAAS_SERVICE_TYPES.RuntimePrincipalService)\n .describe().runtimeProfile;\n } catch {\n return ApplicationRuntimeProfile.APPLICATION_BACKEND;\n }\n }\n\n /** @see reconcileRetentionGovernedMongoCollections — obligation 1. */\n private async backfillRetentionStatusMarkers(\n resourceType: ResourceType,\n mongooseModel: Model<any>,\n ): Promise<void> {\n // The value written MUST be the value the retention-scoped partial unique index selects on, or the\n // backfill produces rows that STILL fall outside the index it exists to populate. Both derive it\n // from the same authority so they cannot diverge; `undefined` means `RetentionStatus` gained a\n // second visible member, which the index builder also refuses to guess at — fail the boot loudly\n // rather than backfill rows into an index that no longer covers them.\n const visibleStatus = resolveSoleVisibleRetentionStatus();\n if (visibleStatus === undefined) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'retention_status_backfill_target_ambiguous',\n resourceType,\n message:\n 'RetentionStatus now has more than one visible member, so the pre-opt-in backfill can no '\n + 'longer name a single target status. Resolve it together with the unique-index partial '\n + 'filter (both derive from resolveSoleVisibleRetentionStatus) before adding the member.',\n },\n });\n }\n\n try {\n const result = await mongooseModel.collection.updateMany(\n buildMissingRetentionMarkerFilterFragment(),\n { $set: buildRetentionMarkerBackfillPatch(visibleStatus) },\n );\n if (result.modifiedCount > 0) {\n this.logger.warn(\n `[Retention] Backfilled ${result.modifiedCount} pre-opt-in row(s) on \"${resourceType}\" to retentionStatus=${visibleStatus}. `\n + 'Those rows were outside every retention-scoped unique index until now.',\n );\n }\n } catch (error) {\n if (this.isMissingNamespaceError(error)) {\n return; // Fresh deployment: the collection does not exist yet, so there is nothing to backfill.\n }\n // A restart racing the backfill lands here as a driver session-lifecycle error. It is classified\n // rather than described: this branch used to name the race in prose and then report it as a\n // backfill failure anyway, which is the same conflation of \"the probe was interrupted\" with \"the\n // data is wrong\" that the index gates below made. See {@link isDatastoreLifecycleTerminatedError}.\n if (this.isDatastoreLifecycleTerminatedError(error)) {\n this.throwDatastoreLifecycleTerminated('the retention-status backfill', error, resourceType);\n }\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'retention_status_backfill_failed',\n resourceType,\n message:\n `Backfilling retentionStatus=${visibleStatus} failed. ${this.isDuplicateKeyError(error)\n ? 'A duplicate-key error here means legacy rows already violate the uniqueness the '\n + 'retention-scoped index is about to assert — resolve the duplicates before opting '\n + 'this resource into retentionPolicy.'\n : 'This is NOT a duplicate-key error, so it does not indicate colliding legacy rows — '\n + 'read the `error` field below for the actual cause. A connection torn down mid-backfill '\n + 'is classified separately and never reaches here.'}`,\n error: describeCaughtError(error),\n },\n });\n }\n }\n\n /**\n * Rebuild every declared UNIQUE index whose live options have drifted away from the declaration.\n *\n * MongoDB cannot modify an index in place. `createIndex` with a key pattern that already exists but\n * different options fails with `IndexOptionsConflict` REGARDLESS of the index name — creating it\n * under a new name is rejected just the same, so drop-then-create is the only reconciliation MongoDB\n * offers. Mongoose's backgrounded `autoIndex` swallows that conflict into a console error, so before\n * this pass existed the collection silently kept its OLD index: a schema could declare uniqueness\n * that nothing enforced, and the declaration would appear to have shipped while changing nothing.\n *\n * WHY THIS IS NOT SCOPED TO RETENTION-GOVERNED RESOURCES. It used to be, and it only compared\n * `partialFilterExpression`. That covered exactly one way a unique index can drift and left every\n * other one unreconciled — `.isUnique()` added to a field whose plain index already exists, or a\n * business key moving between sparse and non-sparse semantics. Both are ordinary schema evolution,\n * both hit the same `IndexOptionsConflict`, and neither had a migration path: boot failed closed in\n * every environment with no supported way forward. Uniqueness drift is a property of unique indexes,\n * not of retention, so the reconciliation belongs to all of them.\n *\n * THE COMPARED AXES are exactly those MongoDB refuses to change in place: `unique`, `sparse`, and\n * `partialFilterExpression`. Options that are irrelevant or mutable are deliberately NOT compared —\n * notably `background` (Mongoose sets it, modern servers ignore it) and `expireAfterSeconds`\n * (alterable through `collMod`, and never a unique-key concern). Comparing them would drop and\n * recreate healthy indexes on every boot.\n *\n * FAIL-CLOSED. A rebuild that cannot complete — almost always because existing rows already violate\n * the newly-declared key — aborts the boot. A collection whose index topology cannot be reconciled\n * must not serve traffic pretending its business keys are protected.\n *\n * ⚠️ OPERATIONAL NOTE: between the drop and the create, uniqueness is NOT enforced on that key. The\n * window is one round-trip per drifted index and only opens when a declaration actually changed, but\n * on a large collection the rebuild is the cost of the index build itself. Every rebuild is logged at\n * WARN with the before/after options so the event is visible in production logs.\n */\n private async reconcileDriftedMongoUniqueIndexes(): Promise<void> {\n for (const { resourceType, mongooseModel, declaredUniqueIndexes: desiredUniqueIndexes } of this.eachMongoResourceWithDeclaredUniqueIndexes()) {\n // Read the catalog directly, never through anything Mongoose memoized. This pass can only\n // reconcile an index that ALREADY exists, so it needs the live pre-repair state.\n //\n // An earlier version of this comment said the read happened \"BEFORE `Model.init()` runs (the\n // verification pass owns that await)\". Both halves are false and the pair of them cost a\n // failed boot: Mongoose fires `init()` itself at model-compile time, so by the time this pass\n // runs the build has already been attempted — and, when an index has drifted, already FAILED.\n // See {@link awaitIndexBuildAgainstCurrentState} for what that broke and how it is handled.\n let liveIndexes: Array<Record<string, any>>;\n try {\n liveIndexes = await mongooseModel.collection.indexes() as Array<Record<string, any>>;\n } catch (error) {\n if (this.isMissingNamespaceError(error)) {\n continue; // Fresh deployment: autoIndex will build the desired indexes on first write.\n }\n // The catalog read could not reach the datastore, so it observed no drift AND no absence.\n // Reporting `unique_index_inspection_failed` here told a dev-companion operator on 2026-08-15\n // that the `users` index topology was unreadable, when the only fact was that the companion\n // was being stopped mid-startup.\n if (this.isDatastoreLifecycleTerminatedError(error)) {\n this.throwDatastoreLifecycleTerminated('unique-index drift reconciliation', error, resourceType);\n }\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'unique_index_inspection_failed',\n resourceType,\n error: describeCaughtError(error),\n },\n });\n }\n\n for (const [keySpec, rawOptions] of desiredUniqueIndexes) {\n const desiredOptions = rawOptions ?? {};\n\n const liveIndex = liveIndexes.find(\n (candidate) => candidate.name !== '_id_' && this.isSameIndexKeyPattern(candidate.key, keySpec),\n );\n // No live index over this key: nothing has drifted. `mongooseModel.init()` in the verification\n // pass builds it, and that pass reports it if the build fails.\n if (!liveIndex) continue;\n\n const liveDescription = this.describeRebuildRelevantIndexOptions(liveIndex);\n const desiredDescription = this.describeRebuildRelevantIndexOptions(desiredOptions);\n if (liveDescription === desiredDescription) continue;\n\n this.logger.warn(\n `[IndexReconciliation] Unique index \"${liveIndex.name}\" on \"${resourceType}\" has drifted from its `\n + `declaration (${liveDescription} → ${desiredDescription}). MongoDB cannot modify an index in place `\n + '(IndexOptionsConflict), so it is being dropped and recreated. Uniqueness on that key is not '\n + 'enforced until the rebuild completes.',\n );\n\n try {\n await mongooseModel.collection.dropIndex(liveIndex.name);\n await mongooseModel.collection.createIndex(keySpec as any, desiredOptions as any);\n } catch (error) {\n // The ONE site in this file where a torn-down connection is NOT purely indeterminate, and so\n // the only one that must not reuse {@link throwDatastoreLifecycleTerminated}: its message\n // ends \"this is NOT a missing index\", which would be false here. The drop and the create are\n // two round trips with no transaction between them, so a teardown landing in the gap leaves\n // the collection with the old index GONE and the new one never created — uniqueness on that\n // key is genuinely unenforced, and the operator has to know that rather than be reassured.\n const lifecycleTerminated = this.isDatastoreLifecycleTerminatedError(error);\n throw this.errorBuilder.buildError(\n lifecycleTerminated ? ErrorType.INFRASTRUCTURE : ErrorType.INTERNAL,\n undefined,\n {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: lifecycleTerminated ? 'unique_index_rebuild_interrupted' : 'unique_index_rebuild_failed',\n resourceType,\n indexName: liveIndex.name,\n liveOptions: liveDescription,\n desiredOptions: desiredDescription,\n ...(lifecycleTerminated\n ? {\n message:\n `The MongoDB connection was torn down while unique index \"${liveIndex.name}\" on `\n + `\"${resourceType}\" was being rebuilt (drop-then-create). ⚠️ THE INDEX MAY HAVE BEEN `\n + 'DROPPED AND NOT RECREATED — uniqueness on that key may currently be UNENFORCED. '\n + 'The next boot reaching a live database rebuilds it (a missing index is rebuilt by '\n + '`autoIndex` and proven by the verification pass), but any write accepted in the '\n + 'meantime bypassed the constraint. If writes were served against this collection '\n + 'after this error, check that key for duplicates before relying on it.',\n }\n : {}),\n error: describeCaughtError(error),\n },\n },\n );\n }\n }\n }\n }\n\n /**\n * Every Mongo-backed resource that declares at least one UNIQUE index, with that declaration.\n *\n * ONE authority for the walk, because two passes consume it — {@link reconcileDriftedMongoUniqueIndexes}\n * and {@link verifyDeclaredMongoUniqueIndexes} — and they previously carried identical filtering and\n * tolerance rules with comments pointing at each other for justification. Circular provenance is how\n * two copies drift: whichever is edited first stops being what the other claims to mirror.\n *\n * The tolerance itself: a resource with no live collection handle is a stubbed schema converter in a\n * test harness, not a deployment defect — it cannot serve a query either, so neither pass has\n * anything to say about it. A PostgreSQL-backed resource is skipped because its indexes are\n * migration-owned; `verifyPostgreSqlTableSchemas` is the gate that speaks for those.\n */\n private *eachMongoResourceWithDeclaredUniqueIndexes(): Generator<{\n resourceType: ResourceType;\n mongooseModel: Model<any>;\n declaredUniqueIndexes: Array<[Record<string, any>, Record<string, any> | undefined]>;\n }> {\n for (const [resourceType, repository] of this.repositories.entries()) {\n // Positive Mongo selection: this generator reaches into `mongooseModel`, so anything that\n // is not MongoDB-backed is skipped — `=== POSTGRESQL → continue` would have admitted any\n // future backing kind into the Mongoose index walk.\n if (this.getResolvedPersistenceAdapterForResource(resourceType) !== PersistenceAdapter.MONGODB) {\n continue;\n }\n\n const mongooseModel = (repository as any)?.mongooseModel as Model<any> | undefined;\n if (!mongooseModel || typeof mongooseModel.collection?.indexes !== 'function') {\n continue;\n }\n\n const declaredUniqueIndexes = ((mongooseModel.schema?.indexes?.() ?? []) as Array<[Record<string, any>, Record<string, any> | undefined]>)\n .filter(([, options]) => options?.unique === true);\n if (declaredUniqueIndexes.length === 0) {\n continue;\n }\n\n yield { resourceType, mongooseModel, declaredUniqueIndexes };\n }\n }\n\n /**\n * Render the option axes MongoDB refuses to change in place, in a form two sources can be compared\n * on. Absent and `false` collapse to the same value because MongoDB omits defaulted options from\n * `listIndexes` output while Mongoose spells them out.\n *\n * `partialFilterExpression` is canonicalized key-first: it is a QUERY document, so `{a:1,b:2}` and\n * `{b:2,a:1}` select identically, and comparing their raw serializations would report drift that\n * does not exist. That false positive matters far more now that the walk covers every collection —\n * it would drop and recreate healthy unique indexes on every single boot. (Index KEY patterns are\n * order-SENSITIVE and are compared separately by `isSameIndexKeyPattern`.)\n */\n private describeRebuildRelevantIndexOptions(source: Record<string, any> | undefined): string {\n return JSON.stringify(this.canonicalizeIndexOptionValue({\n unique: source?.unique === true,\n sparse: source?.sparse === true,\n partialFilterExpression: source?.partialFilterExpression ?? null,\n }));\n }\n\n /** Recursively sort object keys so that structurally equal documents serialize identically. */\n private canonicalizeIndexOptionValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((entry) => this.canonicalizeIndexOptionValue(entry));\n }\n if (value !== null && typeof value === 'object') {\n return Object.entries(value as Record<string, unknown>)\n .sort(([leftKey], [rightKey]) => (leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0))\n .reduce<Record<string, unknown>>((canonical, [key, entry]) => {\n canonical[key] = this.canonicalizeIndexOptionValue(entry);\n return canonical;\n }, {});\n }\n return value;\n }\n\n /**\n * The declared uniqueness for one PostgreSQL table that the live catalog does NOT carry.\n *\n * **Why uniqueness is verified when column TYPES are not.** The sibling column check states that\n * types, nullability and constraints are migration-owned and deliberately unasserted. That line is\n * kept for types and nullability and broken for uniqueness, on a principle worth naming: this gate\n * exists to convert SILENT failures into boot-time diagnoses. A wrong column type fails loudly on\n * first use, with a driver error naming the column. A missing unique constraint fails silently and\n * permanently — duplicate rows accumulate, and for a creation-time identity such as\n * `ORGANIZATIONS.slug` (`.excludeFromUpdate()`) they can never be repaired through the API. Being\n * migration-OWNED never implied being un-VERIFIED; the column check is migration-owned too.\n *\n * **Matched as a SET, not in order — deliberately different from the MongoDB check.** `UNIQUE(a,b)`\n * and `UNIQUE(b,a)` enforce the identical constraint in PostgreSQL; column order only affects index\n * usability for queries, which is a migration author's call to make. (In MongoDB the order changes\n * index IDENTITY, which is why the sibling check there compares ordered key patterns.) Asserting\n * order here would fail a perfectly correct schema.\n *\n * **Partiality must match in both directions.** `skipRowsMissing` declares that rows missing a\n * member are outside the constraint, which in PostgreSQL is a PARTIAL unique index, never a plain\n * `UNIQUE (...)` — a plain constraint treats NULLs as distinct in most configurations, silently\n * producing the opposite semantics from the declaration and from the MongoDB adapter. The converse\n * matters just as much: a partial index where the schema declared a full one is a WEAKER constraint\n * than promised, so it is reported rather than accepted.\n *\n * **Single-column `isUnique` COVERAGE is checked weakly, on purpose.** The plan records only that a\n * column is unique — `planSqlHybridTable` discards the scope/`compoundWith` params — so a scoped\n * declaration (unique per organization) is indistinguishable in the plan from a global one. Requiring\n * a single-column index would therefore fail a correctly-provisioned scoped constraint. Until the plan\n * can express scope, the check is \"some unique index covers this column\", which cannot false-fail.\n *\n * **Its PARTIALITY is checked strictly when the resource is retention-governed**, because that is a\n * different axis and the plan states it outright rather than discarding it. It is also the one case\n * where a FULL index is not \"stronger than declared\" but broken: the scrub writes one shared value to\n * every retained row, so a full index makes the SECOND erasure of a subject abort. Limitation, stated\n * rather than implied: this asserts the index IS partial, not that its predicate is the retention one\n * — same depth as the composite check above, and for the same reason (gating a boot on a regex over\n * catalog DDL text is more fragile than the drift it would catch).\n *\n * **Introspection may be unavailable, and that is NOT a defect.** The catalog query is rejected\n * outright by the in-memory PostgreSQL the fixtures run on. Treating \"no rows\" as \"no constraints\"\n * there would fail every fixture boot, and special-casing the test double by name would couple a\n * production gate to a harness. Instead the query's own failure IS the signal: introspection is\n * unavailable, the constraint half is skipped with a warning, and the column half still runs.\n */\n /**\n * Columns that EXIST but whose type cannot hold what the plan declared.\n *\n * ## Why this was added, and why the old \"types are migration-owned\" line no longer holds\n *\n * This gate's contract used to say column types were \"migration-owned and intentionally not\n * asserted\". That was correct WHEN IT WAS WRITTEN — nothing rendered DDL, so the engine had no\n * opinion about a column's type to compare against. `postgresql-schema-ddl.backend.ts` is now\n * exactly that opinion, so the comparison became available and the omission became a hole.\n *\n * And it is the ONE drift class that is completely silent. Measured on a real server: `pg` sends\n * parameters in TEXT format, so PostgreSQL casts them to whatever the column already is, and decodes\n * results by that same column. Change a field from `z.string()` to `z.number()` against a live `text`\n * column and the write succeeds, the boot succeeds, and every read comes back a STRING — a value that\n * compares wrongly rather than loudly, all the way into DTOs and guards. Every other drift class this\n * gate knows about announces itself: a missing column fails the boot, a missing unique index fails the\n * boot, an `_id uuid` column rejects the write outright.\n *\n * ## Compared by JS READ TYPE, not by SQL type name\n *\n * Deliberately tolerant of decisions the plan does not express. The plan records\n * `logicalType: 'string' | 'number'` and nothing about width or precision, so a migration author who\n * chose `varchar(64)` made a decision the schema left open and must not fail a boot for it.\n * `postgresColumnTypeSatisfiesPlan` therefore asks whether a row read through the live column arrives\n * as the JavaScript type the application layer expects — which is both looser than name equality and\n * STRICTER than SQL family, because `numeric` and `bigint` decode to strings while `double precision`\n * decodes to a number. Cutting by family would have missed the very defect the renderer already\n * documents.\n *\n * Reports the expected type alongside the actual one, matching what the unique-index half does with\n * its expected DDL: this gate names a schema the framework cannot itself repair, so a refusal that\n * does not carry its remedy just moves the derivation to a human who may get it wrong.\n */\n /**\n * Columns whose live `DEFAULT` disagrees with the plan.\n *\n * Without this the gate is blind to the exact defect that motivated column defaults: a\n * `.default()` on an `.excludeFromCreate()` field is supplied by the STORE and by nothing else, so\n * a table built before the plan carried defaults accepts every write and silently stores NULL.\n * There is no bare driver error to fail on later — just rows missing a value the schema declares,\n * which is how a seeded application ended up with an organization whose only member had a NULL\n * `status` and therefore did not count as an administrator.\n *\n * Reports only a MISSING or DIFFERING default, never an EXTRA one. A column carrying a default the\n * plan does not declare is a superset the repository's writes are unaffected by — always supplying\n * the column — and refusing it would fail boot on hand-tuned operational defaults that harm\n * nothing.\n */\n private collectPostgreSqlColumnDefaultMismatches(\n resourceType: ResourceType,\n tableName: string,\n resourceConfiguration: ResourceConfiguration<any, any, any>,\n liveColumnDefaults: ReadonlyMap<string, string | null>,\n ): string[] {\n const plan = this.zodToSqlPlanner.planSqlHybridTable(\n resourceConfiguration as any,\n resourceConfiguration.mainSchema as any,\n );\n\n const problems: string[] = [];\n for (const field of plan.fields) {\n const expectedClause = renderPostgresColumnDefaultClause(field);\n if (!expectedClause) continue;\n\n const expected = normalizePostgresDefaultExpression(expectedClause.replace(/^ default /, ''));\n const live = liveColumnDefaults.get(field.name);\n\n if (live == null) {\n problems.push(\n `• \"${resourceType}\": column \"${tableName}\".\"${field.name}\" is missing its declared default `\n + `(${expected}) — the schema declares it and the create DTO cannot supply it, so rows store NULL`,\n );\n continue;\n }\n\n const actual = normalizePostgresDefaultExpression(live);\n if (actual !== expected) {\n problems.push(\n `• \"${resourceType}\": column \"${tableName}\".\"${field.name}\" has default ${actual}, plan declares ${expected}`,\n );\n }\n }\n return problems;\n }\n\n private collectPostgreSqlColumnTypeMismatches(\n resourceType: ResourceType,\n tableName: string,\n resourceConfiguration: { mainSchema?: unknown },\n liveColumnTypes: ReadonlyMap<string, string>,\n ): string[] {\n const plan = this.zodToSqlPlanner.planSqlHybridTable(\n resourceConfiguration as any,\n (resourceConfiguration as any).mainSchema,\n );\n\n const problems: string[] = [];\n for (const field of plan.fields) {\n const liveType = liveColumnTypes.get(field.name);\n // Absent columns are the caller's business, and it has already reported them. A variant-only\n // field swept into `variantConfig` is legitimately absent and must not be reported at all —\n // which is why this walks the LIVE map rather than demanding a column per planned field.\n if (liveType === undefined) continue;\n\n const plannedType = renderPostgresColumnType(field);\n if (postgresColumnTypeSatisfiesPlan(plannedType, liveType)) continue;\n\n /**\n * The CONSEQUENCE differs by class, and stating the wrong one is worse than stating none.\n *\n * Every mismatch here is a defect, but `uuid` fails LOUDLY — it rejects the write — while the\n * rest fail silently on the read. Describing a uuid column as \"silently wrong\" would send the\n * reader looking for corrupted data that does not exist, and would undersell a column that has\n * narrowed what the application is permitted to persist at all.\n */\n const consequence = classifyPostgresColumnJsReadType(liveType) === PostgresColumnJsReadType.UUID\n ? 'this column REJECTS any value that is not a UUID (\"invalid input syntax for type uuid\"), so '\n + 'the table has narrowed which identity formats the application may persist. The plan types '\n + 'identity from the schema, which is correct for BOTH ResourceIdFormat members'\n : 'a row read through this column would arrive as the wrong JavaScript type, silently — the '\n + 'driver casts writes to the column\\'s type and decodes reads by it, so nothing throws';\n\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" column \"${field.name}\" is \"${liveType}\" but the plan `\n + `declares \"${plannedType}\" — ${consequence}.\\n ↳ expected DDL: alter table \"${tableName}\" `\n + `alter column \"${field.name}\" type ${plannedType} using \"${field.name}\"::${plannedType}`,\n );\n }\n return problems;\n }\n\n private async collectMissingPostgreSqlUniqueConstraints(\n db: unknown,\n resourceType: ResourceType,\n tableName: string,\n resourceConfiguration: { mainSchema?: unknown },\n ): Promise<string[]> {\n const plan = this.zodToSqlPlanner.planSqlHybridTable(\n resourceConfiguration as any,\n (resourceConfiguration as any).mainSchema,\n );\n /**\n * The FIELDS, not just their names: `uniqueNullsAreDistinct` is a per-field opt-out and the\n * NULL-distinctness check below has to read it.\n *\n * **PRIMARY-KEY fields are excluded, mirroring the DDL renderer**, which states the rule this\n * side has to honour: *\"A primary key already carries a unique index; emitting a second one\n * would duplicate the structure PostgreSQL created implicitly\"*\n * (`postgresql-schema-ddl.backend.ts`). The producer therefore emits NO separate unique index\n * for such a field, and a verifier that still demands one is asking about an index its own\n * generator deliberately never creates.\n *\n * Every check in the loop below is VACUOUS for a primary key, which is why the exclusion is a\n * correction rather than a relaxation:\n *\n * - NULL-distinctness — a PRIMARY KEY implies NOT NULL, so no row can carry a NULL in it and\n * there is nothing for `NULLS NOT DISTINCT` to constrain. PostgreSQL never sets\n * `indnullsnotdistinct` on a `_pkey`, so the question cannot have the answer the gate wants.\n * - coverage — the `_pkey` always covers the column, so it can never fire.\n * - retention partiality — a primary key cannot be partial, and `_id` is never a scrubbed\n * column.\n *\n * FOUND BY THE FIRST LIVE POSTGRESQL BOOT (2026-08-18): INIT completed phases 2.5 → 2.6 → 2.7 →\n * 4 and then this gate refused with 22 findings, every one of them `covering column \"_id\"`. The\n * 22 are the platform resources that declare `_id` as `.isUnique()` IN ADDITION to being the\n * primary key — redundant in Mongo, where `_id` is unique by definition. The other 70 declare it\n * primary-key only and passed, which is why the split looked arbitrary from the outside.\n *\n * The pre-flight could not see it: that lane's \"gate-equivalent\" check compared planner column\n * NAMES against `information_schema`, while this gate reads INDEX SEMANTICS from `pg_index` —\n * a different question, so it answered \"would accept\" truthfully and uninformatively.\n *\n * NOTE this also removes an incidental PK-existence check that only ever applied to those 22\n * resources (via `covering.length === 0`). That asymmetry was an accident of which schemas\n * happen to add a redundant `.isUnique()`, not a designed guarantee. If PK existence should be\n * verified, it belongs in a check applied UNIFORMLY to every resource, not as a side effect here.\n */\n const singleColumnUnique = plan.fields.filter((field) => field.isUnique && !field.isPrimaryKey);\n if (singleColumnUnique.length === 0 && plan.uniqueConstraints.length === 0) {\n return [];\n }\n\n let liveUniqueIndexes: Array<{ columns: string[]; isPartial: boolean; predicate: string | null; name: string; nullsAreDistinct: boolean | null }>;\n try {\n // ONLY the query is guarded. Interpreting its rows happens inside `readPostgreSqlUniqueIndexes`\n // AFTER the await, so a defect in the mapping propagates instead of being swallowed as\n // \"this database has no catalog\" — which would silently downgrade a broken gate into a skipped\n // one, the exact failure class this gate exists to eliminate. (It did: an unparsed `array_agg`\n // result threw here and every case quietly \"passed\".)\n liveUniqueIndexes = await this.readPostgreSqlUniqueIndexes(db, tableName);\n } catch (error) {\n if (!this.isPostgreSqlCatalogUnavailableError(error)) {\n throw error;\n }\n if (!this.hasWarnedPostgreSqlIndexIntrospectionUnavailable) {\n this.hasWarnedPostgreSqlIndexIntrospectionUnavailable = true;\n this.logger.warn(\n '[PostgreSQL] Unique-constraint verification SKIPPED: this database does not expose the index catalog '\n + `(${describeCaughtError(error)}). Expected under the in-memory PostgreSQL used by fixtures. `\n + 'In a real deployment this means declared unique constraints were NOT verified — column presence still was.',\n );\n }\n return [];\n }\n\n const problems: string[] = [];\n\n /**\n * A retention-governed table's unique indexes must EXCLUDE erasure-retained rows.\n *\n * This is the one case where a FULL index is not merely \"stronger than declared\" but actively\n * broken: the scrub writes one shared value to every retained row, so a full index makes the\n * SECOND erasure of a subject violate it and abort. MongoDB carries the same scoping as a\n * `partialFilterExpression`; a table provisioned before the DDL renderer emitted the predicate\n * would silently disagree, which is exactly the shape this gate converts into a boot diagnosis.\n */\n const uniquenessExcludesRetainedRows = plan.uniquenessExcludesErasureRetainedRows === true;\n\n /**\n * The exact statement the framework would emit for a given index — attached to its own problem, so a\n * refusal carries its remedy.\n *\n * This gate names a schema the framework did not provision and CANNOT provision: applying DDL is\n * migration-owned, so every failure here is handed to a human who then has to work out what to write.\n * Since the renderer is a pure function of the same plan this check reads, that answer is already\n * computable — and printing it removes the step where someone re-derives the partial predicate,\n * the `NULLS NOT DISTINCT` clause or the retention scope by hand and gets one of them subtly wrong.\n *\n * Matched on the EXACT column set rather than \"contains these columns\", or a single-column lookup\n * would match a composite index that happens to include it. An unmatched lookup yields no hint\n * rather than a wrong one: the diagnosis must never depend on this succeeding.\n */\n const expectedUniqueIndexStatements = buildPostgresSchemaStatements(plan)\n .filter((statement) => statement.startsWith('create unique index'));\n\n const describeExpectedUniqueIndexDdl = (columns: readonly string[]): string => {\n const wanted = [...columns].sort().join(', ');\n const match = expectedUniqueIndexStatements.find((statement) => {\n const indexed = /\\(([^)]*)\\)/.exec(statement)?.[1];\n if (!indexed) return false;\n return indexed\n .split(',')\n .map((column) => column.trim().replace(/^\"|\"$/g, ''))\n .sort()\n .join(', ') === wanted;\n });\n return match ? `\\n ↳ expected DDL: ${match}` : '';\n };\n\n /**\n * A deployed index that treats NULLs as DISTINCT does not enforce what the schema declared.\n *\n * PostgreSQL's default is nulls-are-distinct, so a unique index simply does not constrain rows\n * whose key contains one — while MongoDB, for the SAME declaration, indexes a missing key as\n * `null` and treats those nulls as equal. The DDL renderer therefore emits `NULLS NOT DISTINCT`\n * (see `postgresql-schema-ddl.backend.ts`), and this is the half that notices when a DEPLOYED\n * table predates that. It is the same shape as the partiality check beside it: the plan states\n * the semantics, the catalog says what was actually provisioned, and disagreeing silently is\n * what the gate exists to stop.\n *\n * Measured on `ORGANIZATION_UNITS`: with the previous DDL, two ROOT units sharing a `code` were\n * both accepted, because `parentUnitId` is NULL for a root and is deliberately not in\n * `skipRowsMissing`. The index existed, was over the right columns, and had the right predicate —\n * every property this gate checked — and enforced nothing for the rows an org chart starts with.\n *\n * `null` (a server older than PostgreSQL 15, which has no such setting) is UNKNOWN and never\n * faults: a gate that cannot ask must not accuse.\n */\n const reportNullsDistinct = (\n live: { name: string; nullsAreDistinct: boolean | null },\n subject: string,\n ): void => {\n if (live.nullsAreDistinct !== true) return;\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" index \"${live.name}\" ${subject} treats NULLs as DISTINCT, so it `\n + 'does NOT constrain rows whose key contains one — two such rows are both accepted. The schema declares '\n + 'the MongoDB semantics (a missing key is one shared value), which PostgreSQL spells NULLS NOT DISTINCT. '\n + 'Re-provision the index from the current plan.',\n );\n };\n\n for (const uniqueField of singleColumnUnique) {\n const column = uniqueField.name;\n const covering = liveUniqueIndexes.filter((index) => index.columns.includes(column));\n if (covering.length === 0) {\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" has no UNIQUE index covering column \"${column}\"`\n + describeExpectedUniqueIndexDdl([column]),\n );\n continue;\n }\n // Only for an index whose columns are EXACTLY this one: coverage above is deliberately weak\n // (an index over a superset counts), and a wider index's NULL rule is that key's business, not\n // this column's. The plan's own opt-out is honoured — see `uniqueNullsAreDistinct`.\n if (uniqueField.uniqueNullsAreDistinct !== true) {\n const exact = covering.find((index) => index.columns.length === 1);\n if (exact) reportNullsDistinct(exact, `covering column \"${column}\"`);\n }\n // Partiality is checked even though COVERAGE is checked weakly — see the header. The weak\n // coverage rule exists because a scoped declaration is indistinguishable from a global one in\n // the plan; that ambiguity does not extend to partiality, which the plan states outright.\n if (uniquenessExcludesRetainedRows && !covering.some((index) => index.isPartial)) {\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" index \"${covering[0]!.name}\" covering column \"${column}\" is a `\n + 'FULL unique index, but this resource is retention-governed — it must be PARTIAL, excluding '\n + 'erasure-retained rows. Every retained row carries the same scrubbed value, so a full index makes '\n + 'the SECOND erasure of a subject violate it and abort.'\n + describeExpectedUniqueIndexDdl([column]),\n );\n }\n }\n\n for (const constraint of plan.uniqueConstraints) {\n /**\n * Why this constraint must be partial, if it must — ONE list, because partiality now has TWO\n * independent sources and the report has to name whichever applies.\n *\n * Built as text rather than branching on `skipRowsMissing` at each message site: that field is\n * `undefined` when partiality comes from retention alone, so the previous `skipRowsMissing!`\n * dereferences would have thrown while formatting the very diagnosis they exist to print.\n */\n const partialityReasons = [\n ...((constraint.skipRowsMissing?.length ?? 0) > 0\n ? [`${constraint.skipRowsMissing!.map((f) => `\"${f}\" IS NOT NULL`).join(' AND ')} (declared skipRowsMissing — a plain UNIQUE treats NULLs as distinct, the opposite of the declared semantics)`]\n : []),\n ...(uniquenessExcludesRetainedRows\n ? ['it must exclude erasure-retained rows (retentionPolicy — every retained row carries the same scrubbed value, so a full index aborts the SECOND erasure of a subject)']\n : []),\n ];\n const expectPartial = partialityReasons.length > 0;\n const sameColumns = liveUniqueIndexes.filter((index) => this.isSameColumnSet(index.columns, constraint.fields));\n\n if (sameColumns.length === 0) {\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" has no UNIQUE index over (${constraint.fields.join(', ')})`\n + (expectPartial ? ` — it must be a PARTIAL index: ${partialityReasons.join('; ')}` : '')\n + describeExpectedUniqueIndexDdl(constraint.fields),\n );\n continue;\n }\n\n // A composite business key never opts out: it mirrors a MongoDB compound unique index, whose\n // NULL semantics are nulls-not-distinct.\n reportNullsDistinct(sameColumns[0]!, `over (${constraint.fields.join(', ')})`);\n\n if (!sameColumns.some((index) => index.isPartial === expectPartial)) {\n const live = sameColumns[0]!;\n problems.push(\n `• \"${resourceType}\": table \"${tableName}\" index \"${live.name}\" over (${constraint.fields.join(', ')}) is `\n + `${live.isPartial ? `PARTIAL (${live.predicate}) but the schema declares a full constraint` : 'a FULL constraint but the schema declares it partial'}`\n + `${expectPartial ? ` — ${partialityReasons.join('; ')}` : ''}`\n + describeExpectedUniqueIndexDdl(constraint.fields),\n );\n }\n }\n\n return problems;\n }\n\n /**\n * Prove that every PostgreSQL-backed resource's table actually HAS the PRIMARY KEY its plan\n * declares — the check {@link collectMissingPostgreSqlUniqueConstraints}'s own header asked for:\n * *\"If PK existence should be verified, it belongs in a check applied UNIFORMLY to every resource,\n * not as a side effect here.\"*\n *\n * **The hole this closes.** The unique-constraint gate EXCLUDES primary-key fields by design (the\n * DDL renderer emits no separate unique index for them), so before this check NOTHING verified\n * that the `_pkey` PostgreSQL was trusted to enforce actually exists. It can fail to: three\n * resources (`consumableTokens`, `jobExecutions`, `jobPayloadStorage`) declared `_id` without\n * `.isPrimaryKey()` and their tables were provisioned constraint-less — duplicate `_id` rows\n * representable on this adapter only, silently, while MongoDB enforces `_id` uniqueness on every\n * collection. The planner now flags a declared `_id` unconditionally and a follow-up migration\n * heals old tables; this gate is what notices a table that predates both and never got the ALTER.\n *\n * A refusal carries its remedy (the exact `alter table … add primary key`), same convention as\n * the unique-index gate's expected-DDL hints: every failure here names a schema the framework\n * cannot repair itself — applying DDL is migration-owned — so the message hands the human the\n * statement instead of making them derive it.\n *\n * Comparison is on the column SET ({@link isSameColumnSet}), matching the unique-index gate:\n * PostgreSQL enforces `PRIMARY KEY (a,b)` and `(b,a)` identically.\n */\n private async collectMissingPostgreSqlPrimaryKey(\n db: unknown,\n resourceType: ResourceType,\n tableName: string,\n resourceConfiguration: { mainSchema?: unknown },\n ): Promise<string[]> {\n const plan = this.zodToSqlPlanner.planSqlHybridTable(\n resourceConfiguration as any,\n (resourceConfiguration as any).mainSchema,\n );\n const declaredPkColumns = plan.fields.filter((field) => field.isPrimaryKey).map((field) => field.name);\n if (declaredPkColumns.length === 0) {\n // Unreachable through the current planner — it flags a declared `_id` as primary key\n // unconditionally and injects one when the schema declares none (both pinned in\n // `aggregation-join-target-pk-matches-planner.test.ts`). An empty set would mean the PLANNER\n // contract moved, which is that pin's defect to name, not a table problem this gate can\n // truthfully report against a database.\n return [];\n }\n\n let livePkColumns: string[] | null;\n try {\n // ONLY the query is guarded — same discipline as the unique-index read above: interpreting\n // rows happens after the await, so a mapping defect propagates instead of downgrading the\n // gate into a silent skip.\n livePkColumns = await this.readPostgreSqlPrimaryKeyColumns(db, tableName);\n } catch (error) {\n if (!this.isPostgreSqlCatalogUnavailableError(error)) {\n throw error;\n }\n if (!this.hasWarnedPostgreSqlPrimaryKeyIntrospectionUnavailable) {\n this.hasWarnedPostgreSqlPrimaryKeyIntrospectionUnavailable = true;\n this.logger.warn(\n '[PostgreSQL] Primary-key verification SKIPPED: this database does not expose the index catalog '\n + `(${describeCaughtError(error)}). Expected under the in-memory PostgreSQL used by fixtures. `\n + 'In a real deployment this means the declared primary key was NOT verified — column presence still was.',\n );\n }\n return [];\n }\n\n if (livePkColumns === null) {\n return [\n `• \"${resourceType}\": table \"${tableName}\" has NO PRIMARY KEY constraint — the plan declares one over `\n + `(${declaredPkColumns.join(', ')}), and every repository statement keys on it. Without the constraint, `\n + 'duplicate rows are representable on PostgreSQL that MongoDB structurally refuses.'\n + `\\n ↳ expected DDL: alter table \"${tableName}\" add primary key (${declaredPkColumns.map((column) => `\"${column}\"`).join(', ')});`,\n ];\n }\n\n if (!this.isSameColumnSet(livePkColumns, declaredPkColumns)) {\n return [\n `• \"${resourceType}\": table \"${tableName}\" PRIMARY KEY is over (${livePkColumns.join(', ')}) but the plan `\n + `declares (${declaredPkColumns.join(', ')}) — a constraint over the wrong columns enforces the wrong `\n + 'identity. Re-provision from the current plan; a primary-key move is migration-owned and hand-authored.',\n ];\n }\n\n return [];\n }\n\n /**\n * The live PRIMARY KEY's column set for a table, or `null` when the table has no primary key.\n *\n * Read from `pg_index.indisprimary` rather than `pg_constraint` so the query shares\n * {@link readPostgreSqlUniqueIndexes}'s exact join shape — including the `::text` cast on\n * `attname`, which that method's header records as REQUIRED (a `name[]` arrives from the driver\n * as an unparsed `{a,b,c}` string), and the `unnest … with ordinality` that keeps column order\n * for the report.\n */\n private async readPostgreSqlPrimaryKeyColumns(\n db: unknown,\n tableName: string,\n ): Promise<string[] | null> {\n const result = await sql<{ columns: string[] }>`\n select array_agg(a.attname::text order by k.ord) as columns\n from pg_class t\n join pg_index ix on t.oid = ix.indrelid\n join lateral unnest(ix.indkey) with ordinality as k(attnum, ord) on true\n join pg_attribute a on a.attrelid = t.oid and a.attnum = k.attnum\n where t.relname = ${tableName} and ix.indisprimary\n group by ix.indexrelid\n `.execute(db as any);\n\n if (result.rows.length === 0) {\n return null;\n }\n return this.normalizePostgreSqlArrayColumn(result.rows[0]!.columns);\n }\n\n /**\n * Unique indexes on one table, read from the catalog.\n *\n * `pg_index` rather than `information_schema`: a PARTIAL unique index is not a table CONSTRAINT and\n * is invisible to `information_schema.table_constraints`, so that source would report the framework's\n * presence-scoped keys as missing. `pg_index` reports plain `UNIQUE` constraints and partial unique\n * indexes uniformly, which is what makes one query enough.\n *\n * Structured rather than parsed out of `pg_indexes.indexdef`: the text form is stable but quoting is\n * case-dependent (`\"organizationId\"` vs `code`), and a regex over DDL text is a fragile thing to gate\n * a boot on. `unnest(indkey) with ordinality` preserves column order for the report even though the\n * comparison itself is order-insensitive.\n *\n * `indnullsnotdistinct` is read THROUGH `to_jsonb(ix)` rather than as a column, and that is the\n * whole point of the indirection: the column exists only on PostgreSQL 15+, and naming it directly\n * makes an older server answer `42703`, which\n * {@link isPostgreSqlCatalogUnavailableError} classifies as \"this database cannot answer\" — so a\n * single missing column would silently disable the ENTIRE gate on that server, including the\n * presence and partiality checks that work there perfectly well. Through `to_jsonb` the field is\n * simply `null`, which the comparison treats as unknown and does not fault.\n *\n * The `::text` cast on `attname` is REQUIRED, not cosmetic. `attname` is PostgreSQL's `name` type,\n * and node-postgres only parses an array whose element OID it recognises — a `name[]` arrives as the\n * raw literal STRING `{a,b,c}`, which is not an array and blows up on `.map`. Casting to `text[]`,\n * a type the driver does parse, is what makes the column list a real array. This was a live defect\n * caught only once the query ran against a real PostgreSQL; the hand-run probe that preceded it\n * returned the same string and it was misread as an array.\n */\n private async readPostgreSqlUniqueIndexes(\n db: unknown,\n tableName: string,\n ): Promise<Array<{ columns: string[]; isPartial: boolean; predicate: string | null; name: string; nullsAreDistinct: boolean | null }>> {\n const result = await sql<{ index_name: string; is_partial: boolean; predicate: string | null; columns: string[]; nulls_not_distinct: boolean | null }>`\n select i.relname as index_name,\n ix.indpred is not null as is_partial,\n pg_get_expr(ix.indpred, ix.indrelid) as predicate,\n (to_jsonb(ix) ->> 'indnullsnotdistinct')::boolean as nulls_not_distinct,\n array_agg(a.attname::text order by k.ord) as columns\n from pg_class t\n join pg_index ix on t.oid = ix.indrelid\n join pg_class i on i.oid = ix.indexrelid\n join lateral unnest(ix.indkey) with ordinality as k(attnum, ord) on true\n join pg_attribute a on a.attrelid = t.oid and a.attnum = k.attnum\n where t.relname = ${tableName} and ix.indisunique\n group by i.relname, ix.indpred, ix.indrelid, to_jsonb(ix)\n `.execute(db as any);\n\n return result.rows.map((row) => ({\n name: String(row.index_name),\n isPartial: Boolean(row.is_partial),\n predicate: row.predicate ?? null,\n // `null` means \"this server cannot say\" (PostgreSQL < 15), NOT \"nulls are distinct\". The two\n // must stay distinguishable: the gate faults on the latter and stays silent on the former.\n nullsAreDistinct: row.nulls_not_distinct === null || row.nulls_not_distinct === undefined\n ? null\n : !row.nulls_not_distinct,\n // Defensive on top of the ::text[] cast: a driver that hands back the raw `{a,b,c}` literal\n // would otherwise throw here, and this method is called from a boot gate — degrading a driver\n // quirk into a crash-loop would be a worse outcome than the gap the gate closes.\n columns: this.normalizePostgreSqlArrayColumn(row.columns),\n }));\n }\n\n /** Accept both a parsed array and PostgreSQL's raw `{a,b,c}` array literal. */\n private normalizePostgreSqlArrayColumn(value: unknown): string[] {\n if (Array.isArray(value)) return value.map((entry) => String(entry));\n if (typeof value !== 'string') return [];\n return value\n .replace(/^\\{|\\}$/g, '')\n .split(',')\n .map((entry) => entry.trim().replace(/^\"|\"$/g, ''))\n .filter((entry) => entry.length > 0);\n }\n\n /**\n * Whether a failed catalog read means \"this database cannot answer\" rather than \"this code is wrong\".\n *\n * The distinction is load-bearing. Treating every error as unavailability turns a defect in the\n * gate into a silent skip — which is the same silent-failure class the gate exists to remove, just\n * relocated. Only a missing/unknown relation or column counts: PostgreSQL reports those as\n * `42P01` / `42703`, and the SQL emulator used by fixtures rejects the catalog query with an\n * equivalent \"does not exist\" message.\n */\n private isPostgreSqlCatalogUnavailableError(error: unknown): boolean {\n const code = String((error as { code?: unknown })?.code ?? '');\n if (code === '42P01' || code === '42703') return true;\n return /does not exist/i.test(describeCaughtError(error));\n }\n\n /** Uniqueness is a property of the column SET; PostgreSQL enforces `UNIQUE(a,b)` and `UNIQUE(b,a)` identically. */\n private isSameColumnSet(live: readonly string[], declared: readonly string[]): boolean {\n if (live.length !== declared.length) return false;\n const liveSet = new Set(live);\n return declared.every((column) => liveSet.has(column));\n }\n\n /**\n * Prove that every UNIQUE index the schema declares actually EXISTS on its MongoDB collection.\n *\n * **The hole this closes.** A unique index that fails to build is completely silent. The framework\n * leaves Mongoose's `autoIndex` at its default and never awaits `Model.init()`, so a rejected build\n * surfaces only as a console error: boot succeeds, writes succeed, and the constraint the schema\n * promises does not exist. Two realistic causes — existing rows already violating a newly-declared\n * key, and an option pair MongoDB refuses (`sparse` + `partialFilterExpression` is rejected with\n * `CannotCreateIndex`). Neither is hypothetical: both are documented failure modes in this codebase.\n *\n * **Why {@link reconcileDriftedMongoUniqueIndexes} next door does not cover it.** That pass now walks\n * every collection too, but it answers the opposite question: given an index that IS there, do its\n * options still match the declaration. An index that is ABSENT is precisely what it skips, and\n * deliberately — a missing index is what `autoIndex` is supposed to build, so there is nothing to\n * reconcile and everything to verify. The two are sequential halves of one obligation: reconcile\n * what exists, then prove what should exist does.\n *\n * **Awaiting the index build is the fix, not the check.** `init()` resolves when index building\n * finishes and REJECTS when it fails, so awaiting it is what converts the silent console error into\n * something a boot can act on. The comparison afterwards is the belt-and-braces half: it also\n * catches an index that was never attempted (autoIndex disabled downstream) rather than attempted\n * and failed.\n *\n * It is awaited through {@link awaitIndexBuildAgainstCurrentState} rather than by calling\n * `mongooseModel.init()` here, and that indirection is load-bearing: `init()` memoizes, and\n * Mongoose has already called it once — before this boot's repair passes ran. Awaiting it directly\n * reads a verdict about the PRE-repair catalog.\n *\n * **Fail-closed on a definitive absence; never on an indeterminate probe.** A missing unique index\n * is not a transient state — serving traffic while pretending a business key is protected is how\n * duplicate rows become permanent (`ORGANIZATIONS.slug` is `.excludeFromUpdate()`, so a collision\n * written today could never be repaired through the API). Both sibling gates in this file already\n * make that call unconditionally: the PostgreSQL column check fails the boot, and\n * {@link reconcileDriftedMongoUniqueIndexes} refuses to let a resource \"serve traffic pretending its\n * business keys are protected\". An environment-class split (fail in dev, warn in prod) was REJECTED —\n * no boot gate in this service uses such an axis, and introducing one here would leave two gates\n * disagreeing about the same hazard. A collection that does not exist yet, or a model with no live\n * collection handle, is INDETERMINATE and is skipped rather than reported.\n *\n * Every problem is collected into ONE error, matching the PostgreSQL verifier: fixing a drifted\n * deployment must not be an N-boot loop.\n *\n * assurance-control: WILDO.DATA.INTEGRITY_CONSTRAINTS — a uniqueness control the schema declares is\n * proven to exist in the datastore before the application serves traffic, rather than assumed.\n */\n private async verifyDeclaredMongoUniqueIndexes(): Promise<void> {\n const problems: string[] = [];\n // Counted so SUCCESS carries evidence, not just silence. A fail-closed gate that passes proves\n // nothing on its own: a gate that iterated an EMPTY set — an unpopulated registry, a generator\n // that yielded nothing — exits exactly the same way as one that checked every index and found\n // them all present. Boot then looks identical either way, and \"it booted, therefore the indexes\n // exist\" is an inference the run never actually earned.\n let uniqueIndexesVerifiedPresent = 0;\n let resourcesCarryingUniqueIndexes = 0;\n // Resources the gate could NOT inspect because their collection does not exist yet. Counted and\n // REPORTED rather than passed over: the verified count alone reads as a coverage figure, and a\n // reader has no way to tell \"62 verified\" from \"62 verified, 40 never looked at\". On a fresh or\n // lightly-exercised database the skipped set can be the larger one.\n let skippedMissingCollectionCount = 0;\n let mongoBackedResourceCount = 0;\n for (const resourceType of this.repositories.keys()) {\n // Positive Mongo count: this figure is the evidence line for the MONGO unique-index gate,\n // so only MongoDB-backed resources belong in it — `!== POSTGRESQL` would have inflated it\n // with any future backing kind.\n if (this.getResolvedPersistenceAdapterForResource(resourceType) === PersistenceAdapter.MONGODB) {\n mongoBackedResourceCount += 1;\n }\n }\n\n for (const { resourceType, mongooseModel, declaredUniqueIndexes } of this.eachMongoResourceWithDeclaredUniqueIndexes()) {\n // THE load-bearing line. Production has never awaited this, which is the entire reason a failed\n // build has been invisible. A rejection here names the real cause (duplicate data,\n // `CannotCreateIndex`, …) instead of leaving it in a console nobody reads.\n try {\n await this.awaitIndexBuildAgainstCurrentState(resourceType, mongooseModel);\n } catch (error) {\n // Abort the whole pass, do not collect a per-resource \"problem\". Once the connection is gone\n // every remaining resource fails identically and tells us nothing, so collecting them produces\n // a list that reads like a survey of broken collections and is really one closed socket\n // reported N times. The 2026-08-15 apps-manager boot printed 49 such bullets.\n if (this.isDatastoreLifecycleTerminatedError(error)) {\n this.throwDatastoreLifecycleTerminated('declared-unique-index verification', error, resourceType);\n }\n if (!this.isMissingNamespaceError(error)) {\n problems.push(\n `• \"${resourceType}\": index building FAILED — ${describeCaughtError(error)}`,\n );\n } else {\n skippedMissingCollectionCount += 1;\n }\n continue;\n }\n\n // A SECOND catalog read, and not a redundant one: the reconciliation pass read the collection\n // BEFORE `init()`, and `init()` both builds missing indexes and (on a fresh deployment) creates\n // the collection itself. Reusing that earlier snapshot would report indexes as missing that this\n // pass has just caused to exist.\n let liveIndexes: Array<Record<string, any>>;\n try {\n liveIndexes = await mongooseModel.collection.indexes() as Array<Record<string, any>>;\n } catch (error) {\n // A collection that does not exist yet is a fresh deployment, not a missing constraint.\n if (this.isMissingNamespaceError(error)) {\n skippedMissingCollectionCount += 1;\n continue;\n }\n // Same abort as the index-build half above. This is the exact site that produced the FIRST of\n // the 49 bullets (\"could not read indexes — Operation interrupted because client was closed\"),\n // with the remaining 48 following from the build half once the client was fully closed.\n if (this.isDatastoreLifecycleTerminatedError(error)) {\n this.throwDatastoreLifecycleTerminated('declared-unique-index verification', error, resourceType);\n }\n problems.push(`• \"${resourceType}\": could not read indexes — ${describeCaughtError(error)}`);\n continue;\n }\n\n resourcesCarryingUniqueIndexes += 1;\n\n for (const [keySpec, options] of declaredUniqueIndexes) {\n const isPresent = liveIndexes.some(\n (live) => live.unique === true && this.isSameIndexKeyPattern(live.key, keySpec),\n );\n if (isPresent) uniqueIndexesVerifiedPresent += 1;\n if (!isPresent) {\n const keyDescription = Object.keys(keySpec).join(', ');\n const predicate = options?.partialFilterExpression\n ? ` (partial: ${JSON.stringify(options.partialFilterExpression)})`\n : '';\n problems.push(\n `• \"${resourceType}\": declared UNIQUE index over (${keyDescription})${predicate} is NOT present on the collection`,\n );\n }\n }\n }\n\n if (problems.length === 0) {\n // Deliberately WARN, not debug, when the gate verified nothing. Zero is not a pass — it means\n // the check had no population to check, and the deployment should not read a silent boot as\n // \"every declared uniqueness constraint is enforced\". Any non-zero count is the ordinary case\n // and stays at debug level.\n if (uniqueIndexesVerifiedPresent === 0) {\n this.logger.warn(\n 'Declared-unique-index verification ran but checked NOTHING — no Mongo-backed resource '\n + 'presented a declared unique index. A silent boot therefore proves no uniqueness '\n + 'constraint; confirm the resource registry was populated before this gate ran.',\n { reason: 'mongodb_declared_unique_index_verification_empty' },\n );\n return;\n }\n // INFO, not `logDebug`: this service disables its own debug channel in the constructor\n // (`setDebugTypeLogging('RepositoriesRegistryHandler', false)`), so a debug line here is\n // written to nowhere. That is fine for chatter and wrong for this — the whole point of the\n // counter is that a silent boot can otherwise be read as \"every declared uniqueness\n // constraint is enforced\" when the gate may have checked nothing. One line per boot, stating\n // what a fail-closed control actually verified, is the evidence that claim rests on.\n this.logger.info('Unique-index verification complete (MongoDB)', {\n // NAMED for what they are. `verifiedIndexCount` said neither what was counted nor against\n // what — it read as \"how many indexes exist\", which invited exactly the wrong question.\n uniqueIndexesVerifiedPresent,\n resourcesCarryingUniqueIndexes,\n // The denominators. Without them the first number reads as coverage, and a resource whose\n // collection has never been written is indistinguishable from one that passed.\n resourcesSkippedCollectionMissing: skippedMissingCollectionCount,\n mongoBackedResourceCount,\n // THE discriminator. Every process that boots this registry logs under the same `service`\n // name, so five different registries — app backend, companion, minion, apps-manager,\n // module-registry — emitted five different counts that were indistinguishable in the\n // payload and looked like one number fluctuating. Each registry holds a different resource\n // set, so the count is only meaningful next to the registry it was taken from.\n //\n // It also settles a question this field was added to answer. `platform-apps-manager` logged\n // 65 twenty-eight times and 61 once, which read like a fail-closed control occasionally\n // verifying a subset. It is not: that process holds MORE THAN ONE registry. 65 is its own\n // platform registry (one per restart); the single 61 is a PER-MANAGED-APPLICATION registry,\n // built by `PlatformWildoApplicationRepositoriesManager` right after the app's database\n // connection opens. Two registries, two legitimately different resource sets, one process.\n //\n // Worth stating because the wrong reading was reached twice — first as \"the count varies\n // between boots\" (it does not; it varies between SERVICES), then as \"the gate races registry\n // population\" (it does not; `initializeRepositories` receives its resource set as an argument\n // and the caller has it in hand). Both readings came from comparing counts without knowing\n // which registry produced them, which is exactly the gap this field closes.\n registrySize: this.repositories.size,\n });\n return;\n }\n\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'mongodb_declared_unique_index_missing',\n message:\n `${problems.length} declared UNIQUE index(es) do not exist on their MongoDB collection, so the `\n + `uniqueness those schemas promise is NOT being enforced:\\n${problems.join('\\n')}\\n`\n + `The usual cause is existing rows that already violate a newly-declared key — run `\n + `\"node scripts/check-duplicate-business-keys.mjs\" against the database to find them. The other `\n + `cause is an index whose options MongoDB refuses to build (it rejects \"sparse\" combined with `\n + `\"partialFilterExpression\"). Until the index exists, duplicate writes will be accepted silently.`,\n problems,\n },\n });\n }\n\n /**\n * `Model.init()`, re-attempted once when the CACHED attempt is what failed.\n *\n * ## The defect this closes\n *\n * `Model.init()` is a one-shot: it memoizes its promise on `$init` and every later call returns\n * that same settled promise. Mongoose fires it ITSELF the moment a model is compiled — from\n * `Model.compile`, `Mongoose#model` and `Connection#model`, each as `init().catch(() => {})` —\n * which is long before this registry runs a single boot pass.\n *\n * (Read against mongoose 8.23.0. Cited by FUNCTION rather than by line: a dependency's line numbers\n * rot silently on the next bump, and this comment is the reason the code below looks unusual.)\n *\n * So the await in {@link verifyDeclaredMongoUniqueIndexes} was never the first attempt, and the\n * ordering the boot sequence carefully establishes — repair, THEN verify — could not reach it. The\n * promise it consumes settled before either repair pass began.\n *\n * Measured on the running platform stack, 2026-08-14 (`platform-apps-manager` INIT):\n *\n * 1. models compile → mongoose `ensureIndexes` → `createIndex` hits the still-drifted\n * `platformApplications.name_1` → `IndexKeySpecsConflict`. `$init` is now permanently rejected,\n * and the rejection is swallowed by mongoose's own `.catch`.\n * 2. {@link reconcileDriftedMongoUniqueIndexes} drops and recreates it correctly. It does not\n * throw; the collection genuinely ends up carrying `{unique: true, sparse: true}`.\n * 3. this gate awaits `init()`, receives the step-1 rejection, and fails the boot describing a\n * collection that step 2 had already repaired — quoting the PRE-repair index in the message.\n *\n * Every genuine drift therefore cost exactly one failed boot before self-healing on the next one:\n * precisely the N-boot loop this gate's contract promises to avoid. It failed CLOSED, so nothing\n * unsafe ever shipped — the gate was over-strict, never over-permissive.\n *\n * ## Why a retry, rather than invalidating the cache when a repair happens\n *\n * Two boot passes can change what a build would do — the retention backfill and the unique-index\n * reconciliation — and a third is a plausible future addition. Coupling this gate to \"whichever\n * pass repaired something\" makes the next pass a silent regression. A cached FAILURE is not\n * evidence about the CURRENT catalog under any circumstances, so discarding it needs no knowledge\n * of who repaired what.\n *\n * The converse does not hold and no retry is spent on it: a cached SUCCESS means mongoose built\n * every index the schema declares, which is exactly the condition under which the reconciliation\n * finds no drift and changes nothing. Both passes read their declarations from the same\n * `schema.indexes()`.\n *\n * ## What the retry cannot hide\n *\n * A build that fails for a REAL reason fails identically the second time — duplicate rows are still\n * there, an illegal option pair is still illegal — and that second error is what gets reported. It\n * is also the more useful one: it describes the catalog as it stands after every repair, rather\n * than as it stood before them.\n *\n * `$init` is mongoose-internal, and this is the only production code that touches it — the\n * integration suites reach for it too, to put an already-booted harness back into the state a real\n * first boot starts from, which is how the mechanism was understood at a test site for months\n * while the path that mattered kept consuming a stale verdict. The alternative\n * — `ensureIndexes()`, which is public and uncached — silently drops the `autoCreate` and\n * search-index halves of `init()`, so a retry through it would not re-attempt what actually failed.\n */\n private async awaitIndexBuildAgainstCurrentState(\n resourceType: ResourceType,\n mongooseModel: Model<any>,\n ): Promise<void> {\n try {\n await mongooseModel.init();\n return;\n } catch (cachedFailure) {\n // A collection that does not exist is the FRESH-DEPLOYMENT state, not a stale verdict: no boot\n // pass creates a collection, so nothing between the memoized attempt and here can have changed\n // the answer. Re-attempting would spend a round trip to reach the same rejection, and — if\n // `autoCreate` created the collection on the second pass — would silently move the resource out\n // of the caller's `skippedMissingCollectionCount` and into the verified population. Leave that\n // path exactly as it was and let the caller classify it.\n if (this.isMissingNamespaceError(cachedFailure)) throw cachedFailure;\n\n // Discard the one-shot cache so `init()` re-runs against the repaired catalog. Deliberately\n // NOT swallowing the retry's own rejection: it is the answer this gate exists to produce.\n (mongooseModel as unknown as { $init: Promise<unknown> | null }).$init = null;\n }\n\n await mongooseModel.init();\n\n // Only reachable when the cached attempt failed and a fresh one succeeded — i.e. a boot pass\n // repaired the collection between them. Logged because the reconciliation's own WARN describes\n // the repair, and nothing else would record that the fail-closed gate re-examined it.\n //\n // INFO for the same reason the completion counters below are: measured on the 2026-08-14\n // `platform-apps-manager` INIT log, the environment where this fires emits 264 info, 15 warn and\n // 9 error lines and ZERO debug ones. A debug line here would be written to nowhere, which is\n // precisely the state that let this defect run — a gate that refused a boot with no record of\n // what it had actually examined. It fires only when a repair happened, so it is not per-boot noise.\n this.logger.info(\n `[IndexReconciliation] \"${resourceType}\": the memoized Mongoose index build had failed, but a fresh `\n + 'attempt against the current catalog succeeded — a boot repair pass ran between the two. '\n + 'Verifying against the fresh result.',\n );\n }\n\n /**\n * Index key patterns are ORDER-SENSITIVE in MongoDB — `{a:1,b:1}` and `{b:1,a:1}` are different\n * indexes — so the comparison walks the keys in declaration order rather than sorting them.\n */\n private isSameIndexKeyPattern(\n liveKey: Record<string, any> | undefined,\n desiredKey: Record<string, any>,\n ): boolean {\n if (!liveKey) return false;\n const liveEntries = Object.entries(liveKey);\n const desiredEntries = Object.entries(desiredKey);\n if (liveEntries.length !== desiredEntries.length) return false;\n return liveEntries.every(\n ([field, direction], index) =>\n desiredEntries[index]![0] === field && String(desiredEntries[index]![1]) === String(direction),\n );\n }\n\n /** MongoDB reports an operation against a not-yet-created collection with code 26 / `NamespaceNotFound`. */\n private isMissingNamespaceError(error: unknown): boolean {\n const code = (error as { code?: unknown })?.code;\n const codeName = (error as { codeName?: unknown })?.codeName;\n return code === 26 || codeName === 'NamespaceNotFound';\n }\n\n /**\n * The driver's connection LIFECYCLE has terminated underneath a probe — the client was closed, the\n * topology shut down, the pool closed, or the session ended.\n *\n * ## Why this needed its own classifier\n *\n * Every index gate in this file documents the same contract: *fail-closed on a definitive absence;\n * never on an indeterminate probe* (see {@link verifyDeclaredMongoUniqueIndexes}). Until this\n * existed, {@link isMissingNamespaceError} was the ONLY indeterminacy classifier, so exactly one\n * shape of \"the probe learned nothing\" was recognised and every other shape was reported as a\n * definitive constraint verdict.\n *\n * A torn-down connection is the purest indeterminate probe there is: the gate did not observe an\n * absent index, it failed to observe anything at all. Reporting it as a missing unique index is not\n * a conservative approximation — it is a different claim, about the DATA rather than the CONNECTION,\n * and it is false. It also came with remediation (\"existing rows already violate a newly-declared\n * key — run check-duplicate-business-keys.mjs\") that sends an operator to audit data which is fine.\n *\n * Observed twice in one dev session on 2026-08-15, at two different call sites, from one cause: the\n * dev stack received SIGTERM ~14s into an application initialization. `platform-apps-manager`\n * reported 49 collections whose \"declared UNIQUE index does not exist\"; the companion refused to\n * start with `unique_index_inspection_failed` on `users`. Both databases were entirely healthy.\n *\n * ## Why treating it as indeterminate does NOT weaken the fail-closed control\n *\n * The control exists to stop the application serving traffic while a declared uniqueness constraint\n * is unenforced. That risk requires the application to SERVE traffic — and a process whose Mongo\n * client has closed serves nothing. Registry initialization still fails (the registry genuinely did\n * not initialize); what changes is that it fails as INFRASTRUCTURE with an accurate reason instead\n * of accusing the schema or the data. The next boot that reaches a live datastore re-runs the gate\n * in full, so no window is opened in which unverified indexes back live traffic.\n *\n * ## Scope of the match, and what is deliberately excluded\n *\n * The four `Mongo*Error` names below are the driver's LIFECYCLE-TERMINAL errors, verified against\n * mongodb 6.21.0 (`lib/error.js`, `lib/cmap/errors.js`), each exposing a stable `name` getter.\n * Matched by `name` rather than message — the messages are the driver's, not ours, and it reserves\n * the right to change them.\n *\n * `MongoPoolClearedError` and `MongoWaitQueueTimeoutError` are deliberately NOT matched. A cleared\n * pool or an exhausted wait queue happens under a LIVE client and describes a datastore that is\n * unhealthy rather than one that is going away — failing the boot loudly is the right answer there,\n * and folding them in here would turn a real infrastructure problem into a shrug.\n */\n private isDatastoreLifecycleTerminatedError(error: unknown): boolean {\n const name = (error as { name?: unknown })?.name;\n return (\n name === 'MongoClientClosedError' // client.close() interrupted an in-flight operation\n || name === 'MongoNotConnectedError' // the client was already closed when the probe started\n || name === 'MongoTopologyClosedError' // the topology shut down\n || name === 'MongoPoolClosedError' // the connection pool was closed\n || name === 'MongoExpiredSessionError' // the implicit/explicit session was ended by teardown\n );\n }\n\n /**\n * The ONE refusal path for a probe the datastore lifecycle interrupted.\n *\n * Deliberately a single shared throw rather than the same guard re-derived at each call site: this\n * invariant has four sites in this file (the retention backfill, the drift reconciliation, and both\n * halves of the verification pass), and the defect it closes was itself an invariant applied at one\n * site and missed at the others. A shared thrower makes the fifth site an import rather than a\n * re-derivation. See `.claude/rules/invariant-call-site-enumeration.md`.\n *\n * It THROWS rather than returning a verdict, and that is what stops the wall of noise: once the\n * client is gone every remaining probe in the pass is equally uninformative, so the first one to\n * notice aborts. The 2026-08-15 boot emitted 49 bullet points describing 49 collections it had\n * never successfully inspected.\n *\n * `ErrorType.INFRASTRUCTURE`, not `CONFIGURATION` or `INTERNAL`: nothing is misconfigured and no\n * invariant in this service was violated — a dependency went away mid-probe.\n */\n private throwDatastoreLifecycleTerminated(phase: string, error: unknown, resourceType?: ResourceType): never {\n throw this.errorBuilder.buildError(ErrorType.INFRASTRUCTURE, undefined, {\n customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_INITIALIZATION_FAILED,\n context: {\n reason: 'datastore_unavailable_during_index_work',\n phase,\n ...(resourceType ? { resourceType } : {}),\n message:\n `The MongoDB connection was torn down while ${phase} was running, so this pass could not `\n + 'determine anything about the index topology. This is NOT a missing index, NOT a duplicate-key '\n + 'conflict, and NOT a schema problem — do not go looking for colliding rows. The usual cause is '\n + 'the process receiving a shutdown signal mid-initialization (a dev-stack restart, a supervisor '\n + 'respawn, a rolling deploy). If the process was not shutting down, investigate why the '\n + 'datastore connection closed. The gate re-runs in full on the next boot that reaches a live '\n + 'database.',\n error: describeCaughtError(error),\n },\n });\n }\n\n /**\n * MongoDB's duplicate-key error, the ONE cause the retention backfill's operator guidance names.\n *\n * It exists because that guidance used to be unconditional: any backfill failure told the operator\n * that \"legacy rows already violate the uniqueness the retention-scoped index is about to assert\"\n * and to go resolve the duplicates. Observed live on 2026-08-11 against `users`, where the actual\n * error was `Cannot use a session that has ended` — a driver session-lifecycle error from a\n * companion restart racing the backfill, already covered by the entry's `retry` policy. The\n * message sent the reader hunting colliding rows that do not exist, and an operator who believes\n * it reasons from it rather than from the `error` field one line below.\n *\n * ## What this inspects, stated accurately\n *\n * `code` and `codeName` ONLY. An earlier revision of this comment justified the `codeName` check by\n * claiming \"a bulk write path reports `E11000` without a `codeName`\" — that is wrong in a way worth\n * recording, because `E11000` is a token in the driver's MESSAGE, not a value this predicate can\n * ever see. The real reason to check both is simpler: the driver populates `codeName` on some\n * paths and not others, and both spellings mean the same thing.\n *\n * The reachable call site here is `collection.updateMany`, which surfaces `code: 11000`, so this is\n * adequate for the one branch that uses it. If a caller is ever added whose failure carries the\n * duplicate only in its message text, this must grow a message check — do not assume it already has\n * one.\n *\n * Pinned in both directions by `retention-backfill-duplicate-key-classification.test.ts`; an\n * unpinned classifier fails silently, because a misclassified message is still a message.\n */\n private isDuplicateKeyError(error: unknown): boolean {\n const code = (error as { code?: unknown })?.code;\n const codeName = (error as { codeName?: unknown })?.codeName;\n return code === 11000 || code === 11001 || codeName === 'DuplicateKey';\n }\n\n private buildOperationRepositoryPathsMap(): void {\n this.logDebug('Building operation repository paths map');\n\n let totalOperationRepositoryPaths = 0;\n\n this.repositories.forEach((repository, resourceType) => {\n const resourceConfiguration = this.resourceRegistry.getResourceConfiguration(resourceType);\n\n if (!resourceConfiguration.operations) {\n return;\n }\n\n resourceConfiguration.operations.forEach(operation => {\n const operationRepositoryPath = ResourcesConfig_OperationPathUtils.extractOperationRepositoryPath(operation);\n const operationRepositoryPathKey = ResourcesConfig_OperationPathUtils.createOperationRepositoryPathKey(operationRepositoryPath);\n\n this.repositoryOperationsMap.set(operationRepositoryPathKey, {\n repository,\n operationRepositoryPath\n });\n\n totalOperationRepositoryPaths++;\n });\n });\n\n this.logDebug('Operation repository paths map built', {\n totalOperationRepositoryPaths,\n operationRepositoryPathKeys: Array.from(this.repositoryOperationsMap.keys()).slice(0, 5) // Show first 5 as sample\n });\n }\n\n\n // ================================\n // Execute operations\n // ================================\n\n public async doByPath<T = any>(\n operationRepositoryPath: ResourceConfiguration_OperationRepositoryPath,\n executionContext: ExecutionContext<any>,\n id_or_ids_or_filter?: IdOrIdsOrFilterType,\n data?: any,\n options?: RepositoryOptions\n ): Promise<T> {\n const operationRepositoryPathKey = ResourcesConfig_OperationPathUtils.createOperationRepositoryPathKey(operationRepositoryPath);\n\n this.logDebug('Executing operation by repository path', { operationRepositoryPath, operationRepositoryPathKey, id_or_ids_or_filter });\n\n return this.doByKey<T>( operationRepositoryPathKey, executionContext, id_or_ids_or_filter, data, options\n );\n }\n\n /**\n * Execute operation by operation repository path key (string)\n */\n public async doByKey<T = any>(\n operationRepositoryPathKey: string,\n executionContext: ExecutionContext<any>,\n id_or_ids_or_filter?: IdOrIdsOrFilterType,\n data?: any,\n options?: RepositoryOptions\n ): Promise<T> {\n // Validate the key format first\n ResourcesConfig_OperationPathUtils.validateOperationRepositoryPathKey(operationRepositoryPathKey);\n\n const operationInfo = this.repositoryOperationsMap.get(operationRepositoryPathKey);\n\n if (!operationInfo) {\n throw this.errorBuilder.buildError( ErrorType.NOT_FOUND, executionContext,\n { context: { operationRepositoryPathKey }, customMessageReference: ErrorCustomMessageReference.REPOSITORIES_REGISTRY_NOT_FOUND } );\n }\n\n this.logDebug('Executing operation by repository path key', { operationRepositoryPathKey, id_or_ids_or_filter });\n\n return operationInfo.repository.doByPath( operationInfo.operationRepositoryPath, executionContext, id_or_ids_or_filter, data, options);\n }\n\n /**\n * Execute operation by ExecutionContext shortcut\n */\n public async doByExecutionContext<T = any>(\n executionContext: ExecutionContext<any>,\n data?: any,\n options?: RepositoryOptions\n ): Promise<T> {\n const operation = executionContext.operation;\n const resourceType = operation.resourceIdentifier as ResourceType;\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n\n this.logDebug('Executing operation by execution context', { resourceType, operationIdentifier: operation.operationIdentifier });\n\n return repository.doByExecutionContext(executionContext, data, options);\n }\n\n // ================================\n // Getters\n // ================================\n\n public getRepository<\n TCustomOperationEnum extends EnumLikeType | undefined = undefined,\n TCoreOperationEnum extends Partial<CoreResourceOperation> | undefined = undefined,\n TMainSchema extends z.ZodTypeAny = z.ZodTypeAny,\n >(\n resourceType: ResourceType\n ): BackendResourceRepository<TCustomOperationEnum, TCoreOperationEnum, TMainSchema> | undefined {\n const repository = this.repositories.get(resourceType);\n\n if (!repository) {\n this.logDebug('Repository not found', { resourceType });\n return undefined;\n }\n\n return repository as BackendResourceRepository<TCustomOperationEnum, TCoreOperationEnum, TMainSchema>;\n }\n\n\n public getRepositoryOrThrow<\n TCustomOperationEnum extends EnumLikeType | undefined = undefined,\n TCoreOperationEnum extends Partial<CoreResourceOperation> | undefined = undefined,\n TMainSchema extends z.ZodTypeAny = z.ZodTypeAny,\n >(\n resourceType: ResourceType,\n executionContext?: ExecutionContext<any>\n ): BackendResourceRepository<TCustomOperationEnum, TCoreOperationEnum, TMainSchema> {\n const repository = this.getRepository<TCustomOperationEnum, TCoreOperationEnum, TMainSchema>(resourceType);\n\n if (!repository) {\n throw this.errorBuilder.buildError( ErrorType.NOT_FOUND, executionContext,\n { context: { resourceType }, customMessageReference: ErrorCustomMessageReference.REPOSITORIES_REGISTRY_NOT_FOUND } );\n }\n\n return repository;\n }\n\n\n public getRegisteredResourceTypes(): ResourceType[] {\n return Array.from(this.repositories.keys());\n }\n\n public getRepositoryCount(): number {\n return this.repositories.size;\n }\n\n public getAvailableOperationRepositoryPaths(): ResourceConfiguration_OperationRepositoryPath[] {\n return Array.from(this.repositoryOperationsMap.values()).map(info => info.operationRepositoryPath);\n }\n\n public hasRepository(resourceType: ResourceType): boolean {\n return this.repositories.has(resourceType);\n }\n\n\n // ================================\n // Framework-internal infrastructure queries\n // ================================\n\n /**\n * Apply the retention hide (`retentionStatus != RETAINED`) to a RAW infrastructure filter.\n *\n * The methods below reach the underlying database model DIRECTLY, so they never pass through\n * `buildContextualFilter` — the chokepoint where retained (impersonalized-and-retained) rows are\n * hidden and made immutable. Without this, an infrastructure query would still SEE and MUTATE a row\n * that has been erased-but-retained for a legal obligation: an `$inc` could move money on a scrubbed\n * financial record, a bulk update could rewrite it, and a uniqueness count would reveal that a hidden\n * row exists (an existence oracle).\n *\n * FAIL-CLOSED, and ALWAYS — deliberately with no see-through escape:\n * - The predicate is assigned at the TOP LEVEL, OVERWRITING any caller-supplied `retentionStatus`\n * (mirroring the chokepoint). Top-level keys AND-combine and cannot be un-ANDed by a nested\n * `$or`/`$and`, so an injected `retentionStatus: RETAINED` is neutralised rather than honoured.\n * - The audited see-through path is `readRetainedAsSystem` / `listRetainedAsSystem` ONLY. These\n * infrastructure helpers are never that path, so they must not consult the EC's see-through flag;\n * a future privileged disposal job (the retention clock) needs its own explicit primitive rather\n * than a bypass here.\n *\n * No-op for resources that have not opted into `retentionPolicy` (the overwhelming majority), so\n * this costs one registry lookup and changes no existing behaviour.\n *\n * The predicate itself comes from the single retention authority; this method owns only the\n * registry lookup and the no-see-through-escape decision for the raw infrastructure paths.\n */\n public applyRetentionHideToRawFilter(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n ): Record<string, unknown> {\n const resourceConfiguration = this.resourceRegistry.tryGetResourceConfiguration(resourceType);\n\n /**\n * A MISSING configuration is an inconsistency, and it decides the hide by DEFAULT — so it is\n * reported rather than left silent.\n *\n * Every caller has already resolved a repository for this resource type, so the registry holding\n * no configuration for it cannot happen in a coherent runtime. If it ever does, this method reads\n * \"not governed\" and the hide silently does not apply — on a retention-governed resource that is\n * a disclosed-and-mutable erased row.\n *\n * **Why this WARNS instead of failing closed**, which is the opposite of what the rest of this\n * boundary does: failing closed here means \"assume governed and apply the predicate\". On MongoDB\n * that would be free — `$ne` matches documents missing the field, so it is a no-op on an\n * ungoverned collection. But `atomicGuardedMutation` / `atomicIncrementField` became\n * ADAPTER-NEUTRAL, so the filter can now reach PostgreSQL, where a table that never opted in has\n * no `retentionStatus` COLUMN at all and the predicate is a SQL error rather than a no-op. Failing\n * closed would therefore break every ungoverned PostgreSQL resource to protect a state that\n * cannot occur. Visible-instead-of-unbypassable is the weaker guarantee that is actually available.\n */\n if (!resourceConfiguration) {\n this.logger.warn(\n '[Retention] No resource configuration found while applying the retention hide to a raw '\n + 'infrastructure filter — treating the resource as NOT retention-governed. If it IS governed, '\n + 'erased-but-retained rows were readable and mutable on this path.',\n { resourceType },\n );\n return filter;\n }\n\n if (!isRetentionGovernedResource(resourceConfiguration)) {\n return filter;\n }\n return withRetentionHideApplied(filter);\n }\n\n /**\n * Count documents matching a filter for a given resource type.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.COUNT_DOCUMENTS`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * @param resourceType - The resource type to query\n * @param filter - Pre-built filter (caller must have applied scope filtering)\n * @param executionContext - For error context only (NOT used for authorization)\n * @param options - Carries the TRANSACTION, so a caller inside one counts INSIDE it.\n * @returns Number of documents matching the filter\n */\n public async countDocumentsForInfrastructure(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n executionContext?: ExecutionContext<any>,\n /**\n * Accepted and forwarded so this door can join a caller's transaction, matching all seven of its\n * siblings.\n *\n * It was the ONE door in the tier that took no options at all, so a caller inside a transaction\n * counted OUTSIDE it and could not see its own uncommitted rows. `countByRawFilter` accepts and\n * honours options on both arms and the repository CONTRACT declares it; only this door dropped\n * them — the identical shape `bulkUpdateForInfrastructure` records as a silent correctness hole,\n * at the door nobody enumerated until the tier's contract gave every door a row to fill in.\n *\n * No caller passes one today (field-uniqueness validation is a standalone route with no\n * transaction), so this is latent hardening rather than a fixed defect. The forward is pinned\n * because an unexercised parameter is exactly the shape that rots.\n */\n options?: RepositoryOptions,\n ): Promise<number> {\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n\n // Adapter-neutral primitive, and the hide applied HERE and only here. Both arms' `countByRawFilter`\n // document that they take an already-hidden filter, so the predicate lives in one place; WHY each\n // is so is the contract's COUNT_DOCUMENTS row.\n return repository.countByRawFilter(this.applyRetentionHideToRawFilter(resourceType, filter), options);\n }\n\n\n /**\n * ADAPTER-NEUTRAL atomic counter: add `delta` to one numeric field on the single row matching\n * `filter`, optionally setting other fields in the same statement, returning the row AFTER the\n * write (or `null` when nothing matched).\n *\n * A shorthand over {@link atomicGuardedMutation}, kept because a counter is the commonest guarded\n * write by a wide margin and `atomicIncrementField(filter, 'available', -5)` reads better at those\n * call sites than a descriptor would.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.ATOMIC_INCREMENT_FIELD`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * rag-ingestion-gate: N/A — bounded by the hourly RAG reconciliation sweep; the contract's\n * ATOMIC_INCREMENT_FIELD row states what the sweep reconciles here and why.\n */\n public async atomicIncrementField<T = any>(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n field: string,\n delta: number,\n setFields?: Record<string, unknown>,\n executionContext?: ExecutionContext<any>,\n options?: RepositoryOptions,\n ): Promise<T | null> {\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n\n // No `as any` and no runtime `typeof` probe: the primitive is on `BackendResourceRepository`,\n // so an adapter that omits it fails to compile rather than throwing on first use.\n return repository.atomicIncrementField<T>(\n this.applyRetentionHideToRawFilter(resourceType, filter),\n field,\n delta,\n setFields,\n // Forward the repository options so a caller already inside a transaction enrols this write\n // in it (Mongo session / PG trx). Dropping them here would make both arms' transaction\n // handling dead code reachable only from a direct repository call.\n options,\n );\n }\n\n /**\n * ADAPTER-NEUTRAL guarded set-and-clear: on the single row matching `filter`, write\n * `setFields` and REMOVE `clearFields`, returning the row AFTER the write (or `null` when\n * nothing matched).\n *\n * A shorthand over {@link atomicGuardedMutation}, for the common set-and-clear case.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.ATOMIC_CONDITIONAL_SET`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * rag-ingestion-gate: N/A — bounded by the hourly RAG reconciliation sweep; the contract's\n * ATOMIC_CONDITIONAL_SET row states what the sweep reconciles here and why.\n */\n public async atomicConditionalSet<T = any>(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n changes: {\n readonly set?: Record<string, unknown>;\n readonly clear?: readonly string[];\n },\n executionContext?: ExecutionContext<any>,\n options?: RepositoryOptions,\n ): Promise<T | null> {\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n\n return repository.atomicConditionalSet<T>(\n this.applyRetentionHideToRawFilter(resourceType, filter),\n changes.set,\n changes.clear,\n // Forwarded so a caller already inside a transaction enrols this write in it, matching\n // `atomicIncrementField`. Dropping them would make both arms' transaction handling dead\n // code reachable only from a direct repository call.\n options,\n );\n }\n\n /**\n * ADAPTER-NEUTRAL guarded mutation: apply `mutation` to the single row matching `filter` in ONE\n * statement, returning the row AFTER the write (or `null` when nothing matched).\n *\n * This is the general form that {@link atomicIncrementField} and {@link atomicConditionalSet}\n * are shorthands for, and the only one that can express a counter and an array addition\n * TOGETHER — which the lifecycle evaluator's engagement write needs, because the row it reads\n * back decides whether the scope transitions to ENGAGED (see the descriptor's own JSDoc).\n *\n * Two rules are enforced HERE, at the single dispatch point, rather than in each adapter:\n *\n * - **Retention.** A retained (erased-but-kept) row is immutable and must never be mutated.\n * - **Expressibility.** A descriptor that no adapter-neutral compilation can honour is refused\n * for EVERY adapter, so a combination cannot work on one store and silently degrade on\n * another.\n *\n * @internal Framework-internal infrastructure primitive — NOT part of the operation lifecycle.\n * The caller owns authorization, scope-aware filter construction, and audit logging.\n */\n /**\n * The dispatch point for {@link BackendResourceRepository.readUnscopedByKey} — the ONE place the\n * retention hide is applied to it, exactly as for the guarded mutation below.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.READ_UNSCOPED_BY_KEY`). Do not restate it here: two copies of a\n * rationale are how they drift.\n */\n public async readUnscopedByKey<T = any>(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n options?: RepositoryOptions,\n ): Promise<T | null> {\n const repository = this.getRepositoryOrThrow(resourceType);\n return repository.readUnscopedByKey<T>(\n this.applyRetentionHideToRawFilter(resourceType, filter),\n options,\n );\n }\n\n /**\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.ATOMIC_GUARDED_MUTATION`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * rag-ingestion-gate: N/A — bounded by the hourly RAG reconciliation sweep; the contract's\n * ATOMIC_GUARDED_MUTATION row states what the sweep reconciles here and why.\n */\n public async atomicGuardedMutation<T = any>(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n mutation: RepositoryGuardedMutation,\n executionContext?: ExecutionContext<any>,\n options?: RepositoryOptions,\n ): Promise<T | null> {\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n\n const inexpressible = describeGuardedMutationInexpressibility(mutation);\n if (inexpressible) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, executionContext, {\n customMessageReference: ErrorCustomMessageReference.SERVICE_RESOURCE_VALIDATION_FAILED,\n context: { resourceType, reason: `Guarded mutation is not adapter-neutral: ${inexpressible}` },\n });\n }\n\n return repository.atomicGuardedMutation<T>(\n this.applyRetentionHideToRawFilter(resourceType, filter),\n mutation,\n // Forwarded so a caller already inside a transaction enrols this write in it, matching the\n // two shorthand primitives.\n options,\n );\n }\n\n /**\n * INSERT one already-built document for a framework-internal writer.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.INSERT_DOCUMENT`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * rag-ingestion-gate: N/A — bounded by the hourly RAG reconciliation sweep; the contract's\n * INSERT_DOCUMENT row states what the sweep reconciles here and why.\n *\n * @param executionContext - For error context only (NOT used for authorization).\n */\n public async insertDocumentForInfrastructure<T = any>(\n resourceType: ResourceType,\n document: Record<string, unknown>,\n executionContext?: ExecutionContext<any>,\n options?: RepositoryOptions,\n ): Promise<T> {\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n return repository.insertRawDocument<T>(document, options);\n }\n\n /**\n * READ many rows matching a pre-built filter for a framework-internal reader.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.FIND_MANY`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * @param executionContext - For error context only (NOT used for authorization).\n */\n public async findManyForInfrastructure<T = any>(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n executionContext?: ExecutionContext<any>,\n options?: RepositoryOptions,\n ): Promise<T[]> {\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n return repository.findManyByRawFilter<T>(\n this.applyRetentionHideToRawFilter(resourceType, filter),\n options,\n );\n }\n\n /**\n * Bulk guarded update of every row matching a pre-built filter, returning the modified count.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.BULK_UPDATE`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * rag-ingestion-gate: N/A — bounded by the hourly RAG reconciliation sweep; the contract's\n * BULK_UPDATE row states what the sweep reconciles here and why.\n */\n public async bulkUpdateForInfrastructure(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n /** An ADAPTER-NEUTRAL descriptor, not a MongoDB update expression — contract, ADAPTER_NEUTRALITY. */\n mutation: RepositoryGuardedMutation,\n executionContext?: ExecutionContext<any>,\n /** Carries the TRANSACTION — contract, TRANSACTION_PARTICIPATION, where its absence is the story. */\n options?: RepositoryOptions,\n ): Promise<number> {\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n\n const inexpressible = describeGuardedMutationInexpressibility(mutation);\n if (inexpressible) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, executionContext, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORIES_REGISTRY_NOT_FOUND,\n context: { resourceType, reason: `Guarded mutation is not adapter-neutral: ${inexpressible}` },\n });\n }\n\n // The hide is applied HERE and only here — both arms take an already-hidden filter. WHY is the\n // contract's BULK_UPDATE / retentionHide row.\n return repository.updateManyByRawFilter(\n this.applyRetentionHideToRawFilter(resourceType, filter),\n mutation,\n options,\n );\n }\n\n /**\n * Bulk DELETE of every row matching a pre-built filter, returning the deleted count.\n *\n * INFRASTRUCTURE TIER. The posture this door takes on every cross-cutting invariant —\n * authorization, tenant scoping, schema validation, the retention hide, the RAG ingestion\n * gate, the audit trail, transaction participation, adapter neutrality — is declared once, with\n * its reasoning, in `infrastructure-tier-contract.backend.ts`\n * (`InfrastructureDoor.DELETE_MANY`). Do not restate it here: two copies of a\n * rationale are how they drift.\n *\n * rag-ingestion-gate: N/A — a DELETE materializes no `.ragSource()` value, so there is nothing to\n * re-derive. What a deleted row's chunks need is REMOVAL, and that is bounded by the hourly RAG\n * reconciliation sweep's orphan reconciliation, which is where the removal-seam guard declares\n * every raw repository door to sit.\n *\n * **The empty-filter refusal happens HERE, on the CALLER's filter, before the hide.** Both arms\n * refuse an empty filter too, and that backstop is not sufficient on its own: the retention hide\n * ADDS a predicate, so `{}` reaches the arm as a non-empty filter and passes a guard that was\n * meant to catch exactly this. Asking the question before the hide is what makes \"the caller\n * supplied no predicate\" a distinct, refusable event.\n *\n * @param executionContext - For error context only (NOT used for authorization).\n */\n public async deleteManyForInfrastructure(\n resourceType: ResourceType,\n filter: Record<string, unknown>,\n executionContext?: ExecutionContext<any>,\n /** Carries the TRANSACTION — contract, TRANSACTION_PARTICIPATION. */\n options?: RepositoryOptions,\n ): Promise<number> {\n // `Array.isArray` is not belt-and-braces: an array's `Object.keys` are its INDICES, so a\n // non-empty array passes a keys-length check and is then handed to a filter compiler that has no\n // meaning for it. The signature says `Record<string, unknown>`, but this door's whole job is to\n // be the place a malformed predicate stops.\n if (!filter || typeof filter !== 'object' || Array.isArray(filter) || Object.keys(filter).length === 0) {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, executionContext, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORIES_REGISTRY_NOT_FOUND,\n context: {\n resourceType,\n reason: 'deleteManyForInfrastructure requires a non-empty filter — refusing an unfiltered DELETE',\n },\n });\n }\n\n const repository = this.getRepositoryOrThrow(resourceType, executionContext);\n\n // The hide is applied HERE and only here — both arms take an already-hidden filter. WHY is the\n // contract's DELETE_MANY / retentionHide row.\n return repository.deleteManyByRawFilter(\n this.applyRetentionHideToRawFilter(resourceType, filter),\n options,\n );\n }\n\n\n// ================================\n// Debug methods\n// ================================\n\n public getDebugInfo(): {\n repositoryCount: number;\n operationRepositoryPathsCount: number;\n resourceTypes: ResourceType[];\n isInitialized: boolean;\n } {\n return {\n repositoryCount: this.repositories.size,\n operationRepositoryPathsCount: this.repositoryOperationsMap.size,\n resourceTypes: Array.from(this.repositories.keys()),\n isInitialized: this.isInitialized\n };\n }\n\n public debugDisplayMongooseSchemas(options: {\n showSchemaStructure?: boolean;\n showIndexes?: boolean;\n showVirtuals?: boolean;\n resourceTypeFilter?: string[];\n maxFieldDepth?: number;\n } = {}): void {\n this.logDebug('Displaying Mongoose schemas debug info', {\n repositories: this.repositories.size,\n options\n });\n\n // Collect models from all repositories\n const models: Model<any>[] = [];\n const resourceTypes: string[] = [];\n\n for (const [resourceType, repository] of this.repositories) {\n // Apply resource type filter if specified\n if (options.resourceTypeFilter && options.resourceTypeFilter.length > 0 &&\n !options.resourceTypeFilter.includes(resourceType)) {\n continue;\n }\n\n // Access the mongooseModel from the repository\n const model = (repository as any).mongooseModel;\n if (model) {\n models.push(model);\n resourceTypes.push(resourceType);\n }\n }\n\n this.logDebug('\\n🔍 === REPOSITORY MONGOOSE SCHEMAS DEBUG ===\\n');\n this.logDebug(`Found ${models.length} models from ${this.repositories.size} repositories`);\n\n if (options.resourceTypeFilter && options.resourceTypeFilter.length > 0) {\n this.logDebug(`Filtered for: [${options.resourceTypeFilter.join(', ')}]`);\n }\n\n this.logDebug(`Resource Types: [${resourceTypes.join(', ')}]\\n`);\n\n // Display each model individually using the simplified debug method\n for (const model of models) {\n this.zodToMongooseConverter.debugDisplayModelSchema(model, options.showSchemaStructure !== false);\n }\n\n this.logDebug('================================================\\n');\n }\n\n /**\n * Quick debug function to show schemas summary\n */\n public debugShowSchemasSummary(): void {\n this.logDebug('Displaying schemas summary');\n\n // Collect models from all repositories\n const models: Model<any>[] = [];\n\n for (const [resourceType, repository] of this.repositories) {\n const model = (repository as any).mongooseModel;\n if (model) {\n models.push(model);\n }\n }\n\n this.zodToMongooseConverter.debugShowModelsSummary(models);\n }\n\n /**\n * Validate and filter request data against operation DTO\n * NOTE: This assumes data has already been cleaned by cleanInputData()\n */\n public validateRequestData(\n data: any,\n resourceType: ResourceType,\n operationIdentifier: string,\n options?: Pick<RepositoryOptions, 'frameworkGeneratedPdfFileIdsByField' | 'frameworkGeneratedPdfFileIdsByFieldByRow' | 'preserveServerInjectedFields'>,\n ): any {\n if (!data || typeof data !== 'object') {\n return data;\n }\n\n // Get the resource configuration to find the operation\n const resourceConfiguration = this.resourceRegistry.getResourceConfiguration(resourceType);\n\n if (!resourceConfiguration.operations) {\n // If no operations defined, data is already cleaned so return as-is\n return data;\n }\n\n // Prefer the default non-bulk URL-bearing operation when several concrete\n // variants share the same semantic identifier. Cron/batch/internal variants\n // can carry a requestDto too, but repository validation for normal resource\n // writes must not become dependent on declaration order.\n const matchingOperations = resourceConfiguration.operations.filter(op =>\n op.operationIdentifier === operationIdentifier\n );\n const operation = matchingOperations.find(op =>\n (\n op.variantType === ResourceOperationVariantType.API_CALL\n || op.variantType === ResourceOperationVariantType.API_CALL_WITH_CALLBACK\n )\n && op.isOperationDefault === true\n && op.isBulkOperation !== true\n ) ?? (\n matchingOperations.length === 1 ? matchingOperations[0] : undefined\n ) ?? matchingOperations.find(op =>\n op.variantType === ResourceOperationVariantType.REPOSITORY_ONLY\n || op.variantType === ResourceOperationVariantType.INTERNAL_CALL\n ) ?? matchingOperations.find(op =>\n (op as { variantType?: ResourceOperationVariantType }).variantType === undefined\n && !('isBulkOperation' in op && op.isBulkOperation === true)\n );\n if (matchingOperations.length > 1) {\n this.logDebug('Resolved request validation operation among multiple variants', {\n resourceType,\n operationIdentifier,\n candidateVariants: matchingOperations.map(op => ({\n variantType: op.variantType,\n isOperationDefault: op.isOperationDefault,\n isBulkOperation: 'isBulkOperation' in op ? op.isBulkOperation : undefined,\n variantKey: op.variantKey,\n })),\n selectedVariantType: operation?.variantType,\n });\n }\n\n if (!operation || !operation.requestDto) {\n if (this.hasFrameworkGeneratedPdfAllowlist(options)) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n context: {\n resourceType,\n operationIdentifier,\n message: 'Framework-generated PDF write preservation requires a matching operation requestDto.',\n },\n });\n }\n // If no operation or requestDto found, data is already cleaned so return as-is\n return data;\n }\n\n try {\n // Validate against the operation's requestDto, then re-attach the two\n // trusted internal allowlists the strict parse would otherwise drop:\n // framework-generated PDF files, and fields a custom-impl CREATE prefix\n // injected (`preserveServerInjectedFields`).\n const validatedData = this.preserveServerInjectedFields(\n data,\n this.preserveFrameworkGeneratedPdfFields(\n data,\n operation.requestDto.parse(data),\n options,\n ),\n options,\n );\n this.logDebug('Request data validation successful', {\n resourceType,\n operationIdentifier,\n validatedKeys: typeof validatedData === 'object' ? Object.keys(validatedData) : 'not-object'\n });\n return validatedData;\n } catch (error) {\n this.logDebug('Request data validation failed', {\n resourceType,\n operationIdentifier,\n error: describeCaughtError(error),\n dataKeys: typeof data === 'object' ? Object.keys(data) : 'not-object',\n data: data\n });\n\n if (error instanceof z.ZodError) {\n throw this.errorBuilder.buildError(ErrorType.VALIDATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n stack: error.stack,\n context: {\n resourceType,\n operationIdentifier,\n inputData: data,\n zodIssues: error.issues,\n }\n });\n }\n\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n context: {\n resourceType,\n operationIdentifier,\n inputData: data,\n error: describeCaughtError(error),\n }\n });\n }\n }\n\n /**\n * Validate the payload slice that repositories actually persist.\n *\n * For bulk writes, the service/controller layer validates the full bulk\n * envelope. Repositories only receive the per-row create item or the shared\n * update patch, so repository validation must intentionally target that write\n * slice rather than the bulk transport wrapper.\n */\n public validateRepositoryWriteData(\n data: any,\n resourceType: ResourceType,\n operationIdentifier: string,\n isBulkOperation: boolean = false,\n options?: Pick<RepositoryOptions, 'frameworkGeneratedPdfFileIdsByField' | 'frameworkGeneratedPdfFileIdsByFieldByRow' | 'preserveServerInjectedFields'>,\n ): any {\n if (!data || typeof data !== 'object') {\n return data;\n }\n\n const resourceConfiguration = this.resourceRegistry.getResourceConfiguration(resourceType);\n if (!resourceConfiguration.operations) {\n return data;\n }\n\n const matchingOperations = resourceConfiguration.operations.filter((candidate) => {\n const candidateIsBulkOperation = 'isBulkOperation' in candidate && candidate.isBulkOperation === true;\n\n return candidate.operationIdentifier === operationIdentifier\n && candidateIsBulkOperation === isBulkOperation;\n });\n const defaultMatchingOperations = matchingOperations.filter((candidate) => candidate.isOperationDefault === true);\n const operationCandidates = defaultMatchingOperations.length > 0 ? defaultMatchingOperations : matchingOperations;\n if (operationCandidates.length > 1) {\n const candidateVariants = operationCandidates.map((candidate) => ({\n variantType: candidate.variantType,\n variantKey: candidate.variantKey,\n isOperationDefault: candidate.isOperationDefault,\n }));\n this.logDebug('Ambiguous repository write validation operation candidates', {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n candidateVariants,\n });\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n context: {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n candidateVariants,\n message: 'Repository write validation requires a unique operation identity; pass through a fully resolved operation path before adding duplicate variants for this repository operation.',\n },\n });\n }\n const operation = operationCandidates[0];\n\n if (!operation) {\n if (this.hasFrameworkGeneratedPdfAllowlist(options)) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n context: {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n message: 'Framework-generated PDF write preservation requires a matching repository write operation.',\n },\n });\n }\n return data;\n }\n\n const validationOperation = (() => {\n if (!isBulkOperation || (\n operationIdentifier !== CoreResourceOperation.CREATE\n && operationIdentifier !== CoreResourceOperation.UPDATE\n )) {\n return operation;\n }\n\n const allNonBulkCandidates = resourceConfiguration.operations.filter((candidate) => {\n const candidateIsBulkOperation = 'isBulkOperation' in candidate && candidate.isBulkOperation === true;\n\n return candidate.operationIdentifier === operationIdentifier\n && candidateIsBulkOperation === false;\n });\n const defaultNonBulkCandidates = allNonBulkCandidates.filter((candidate) => candidate.isOperationDefault === true);\n const nonBulkCandidates = defaultNonBulkCandidates.length > 0 ? defaultNonBulkCandidates : allNonBulkCandidates;\n if (nonBulkCandidates.length > 1) {\n const candidateVariants = nonBulkCandidates.map((candidate) => ({\n variantType: candidate.variantType,\n variantKey: candidate.variantKey,\n isOperationDefault: candidate.isOperationDefault,\n }));\n this.logDebug('Ambiguous repository bulk validation base candidates', {\n resourceType,\n operationIdentifier,\n candidateVariants,\n });\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n context: {\n resourceType,\n operationIdentifier,\n candidateVariants,\n message: 'Bulk repository write validation requires a unique non-bulk default validation base.',\n },\n });\n }\n return nonBulkCandidates[0] ?? operation;\n })();\n\n if (!validationOperation.requestDto) {\n if (this.hasFrameworkGeneratedPdfAllowlist(options)) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n context: {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n message: 'Framework-generated PDF write preservation requires a repository write requestDto.',\n },\n });\n }\n return data;\n }\n\n try {\n // Re-attach the two trusted internal allowlists the strict parse drops —\n // framework-generated PDF files AND fields a trusted caller server-injected\n // (`preserveServerInjectedFields`). This MUST mirror the single-write\n // `validateRequestData` path: the bulk write paths (`_doCreateMany` /\n // `_doUpdateMany`) run through THIS method, so omitting the\n // `preserveServerInjectedFields` wrap silently strips the allowlisted keys on\n // every BULK trusted write. Concretely, anon→user ownership transposition's\n // `updateManyAsSystem(resource, ids, { userId, anonymousUserId: null })` derives\n // `preserveServerInjectedFields: ['userId','anonymousUserId']` (context-auto-\n // populated FKs the request DTO strips by name), but without this wrap they were\n // dropped after the parse → an empty `$set` → the rows never moved (silent no-op,\n // audit still emitted). The re-attach is safe here for the same reason it is on\n // the single path: the allowlist is schema-derived by trusted primitives (or the\n // prefix snapshot-diff), never a client payload, so it cannot smuggle a\n // client-forbidden field.\n const validatedData = this.preserveServerInjectedFields(\n data,\n this.preserveFrameworkGeneratedPdfFields(\n data,\n validationOperation.requestDto.parse(data),\n options,\n ),\n options,\n );\n this.logDebug('Repository write payload validation successful', {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n validatedKeys: typeof validatedData === 'object' ? Object.keys(validatedData) : 'not-object'\n });\n return validatedData;\n } catch (error) {\n this.logDebug('Repository write payload validation failed', {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n error: describeCaughtError(error),\n dataKeys: typeof data === 'object' ? Object.keys(data) : 'not-object',\n data,\n });\n\n if (error instanceof z.ZodError) {\n throw this.errorBuilder.buildError(ErrorType.VALIDATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n stack: error.stack,\n context: {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n inputData: data,\n zodIssues: error.issues,\n }\n });\n }\n\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, undefined, {\n customMessageReference: ErrorCustomMessageReference.REPOSITORY_RESOURCE_OPERATION_FAILED,\n context: {\n resourceType,\n operationIdentifier,\n isBulkOperation,\n inputData: data,\n error: describeCaughtError(error),\n }\n });\n }\n }\n\n /**\n * Re-attach fields a trusted custom-impl `prefixCoreOperations` hook injected\n * that the strict `requestDto.parse` just stripped.\n *\n * The create/update request DTO omits `.excludeFromCreate()` /\n * `.excludeFromUpdate()` fields, so `requestDto.parse(data)` drops them — even\n * when a server-side prefix legitimately populated them (e.g. an API key's\n * `keyPrefix` / `hashedKey`). The service orchestration diffs the prefix output\n * against the pre-prefix payload and passes ONLY the prefix-added keys in\n * `options.preserveServerInjectedFields`, so a client cannot smuggle a value\n * through this path (its fields were present before the prefix and never make\n * the list). Each allowlisted key is copied straight from the original\n * (service-layer loose-validated) payload back onto the parsed result. Mirrors\n * `preserveFrameworkGeneratedPdfFields` but for arbitrary scalar fields.\n */\n private preserveServerInjectedFields(\n originalData: any,\n validatedData: any,\n options?: Pick<RepositoryOptions, 'preserveServerInjectedFields'>,\n ): any {\n const fields = options?.preserveServerInjectedFields;\n if (!fields || fields.length === 0 || !originalData || typeof originalData !== 'object' || !validatedData || typeof validatedData !== 'object') {\n return validatedData;\n }\n\n for (const fieldName of fields) {\n if (Object.prototype.hasOwnProperty.call(originalData, fieldName)) {\n validatedData[fieldName] = originalData[fieldName];\n }\n }\n\n return validatedData;\n }\n\n private preserveFrameworkGeneratedPdfFields(\n originalData: any,\n validatedData: any,\n options?: Pick<RepositoryOptions, 'frameworkGeneratedPdfFileIdsByField' | 'frameworkGeneratedPdfFileIdsByFieldByRow' | 'preserveServerInjectedFields'>,\n ): any {\n const allowlist = options?.frameworkGeneratedPdfFileIdsByField;\n if (!allowlist || !originalData || typeof originalData !== 'object' || !validatedData || typeof validatedData !== 'object') {\n return validatedData;\n }\n\n for (const [fieldName, allowedFileIds] of Object.entries(allowlist)) {\n const allowed = new Set(allowedFileIds);\n if (Object.prototype.hasOwnProperty.call(originalData, fieldName)) {\n const generatedFileValue = this.normalizeGeneratedFileValue(originalData[fieldName]);\n if (generatedFileValue && allowed.has(generatedFileValue.fileId)) {\n validatedData[fieldName] = generatedFileValue;\n }\n continue;\n }\n\n const occurrences = enumerateFileFieldValueOccurrences(originalData, fieldName);\n for (const occurrence of occurrences) {\n const generatedFileValue = this.normalizeGeneratedFileValue(occurrence.value);\n if (!generatedFileValue || !allowed.has(generatedFileValue.fileId)) {\n continue;\n }\n this.setValueAtRuntimePathCreating(validatedData, occurrence.runtimeFieldPath, generatedFileValue);\n }\n }\n\n return validatedData;\n }\n\n private hasFrameworkGeneratedPdfAllowlist(\n options?: Pick<RepositoryOptions, 'frameworkGeneratedPdfFileIdsByField' | 'frameworkGeneratedPdfFileIdsByFieldByRow' | 'preserveServerInjectedFields'>,\n ): boolean {\n return Boolean(\n options?.frameworkGeneratedPdfFileIdsByField &&\n Object.keys(options.frameworkGeneratedPdfFileIdsByField).length > 0\n || options?.frameworkGeneratedPdfFileIdsByFieldByRow?.some((row) => Object.keys(row).length > 0)\n );\n }\n\n public buildGeneratedPdfRowRepositoryOptions(\n options: RepositoryOptions | undefined,\n rowIndex: number,\n ): RepositoryOptions | undefined {\n if (!options?.frameworkGeneratedPdfFileIdsByFieldByRow) {\n return options;\n }\n\n return {\n ...options,\n frameworkGeneratedPdfFileIdsByField: options.frameworkGeneratedPdfFileIdsByFieldByRow[rowIndex] ?? {},\n };\n }\n\n private normalizeGeneratedFileValue(value: unknown): { fileId: string; updatedAt: unknown } | undefined {\n if (!value || Array.isArray(value) || typeof value !== 'object') {\n return undefined;\n }\n\n const record = value as Record<string, unknown>;\n const fileId = record.fileId;\n if (typeof fileId !== 'string' || fileId.trim().length === 0 || !('updatedAt' in record)) {\n return undefined;\n }\n\n return {\n fileId,\n updatedAt: record.updatedAt,\n };\n }\n\n private setValueAtRuntimePathCreating(\n target: Record<string, unknown> | unknown[],\n runtimePath: string,\n value: unknown,\n ): void {\n const normalizedSegments = runtimePath\n .replace(/\\[(\\d+)\\]/g, '.$1')\n .split('.')\n .filter(Boolean);\n\n if (normalizedSegments.length === 0) {\n return;\n }\n\n let current: any = target;\n for (let index = 0; index < normalizedSegments.length - 1; index += 1) {\n const segment = normalizedSegments[index];\n const nextSegment = normalizedSegments[index + 1];\n\n if (Array.isArray(current)) {\n const arrayIndex = Number(segment);\n if (!current[arrayIndex]) {\n current[arrayIndex] = /^\\d+$/.test(nextSegment) ? [] : {};\n }\n current = current[arrayIndex];\n continue;\n }\n\n if (!current || typeof current !== 'object') {\n return;\n }\n\n if (!(segment in current) || current[segment] === null || current[segment] === undefined) {\n current[segment] = /^\\d+$/.test(nextSegment) ? [] : {};\n }\n current = current[segment];\n }\n\n setValueAtRuntimePath(target, runtimePath, value);\n }\n}\n"]}