@hed-hog/core 0.0.398 → 0.0.400

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 (664) hide show
  1. package/dist/ai/ai-agent.sort.d.ts +6 -0
  2. package/dist/ai/ai-agent.sort.d.ts.map +1 -0
  3. package/dist/ai/ai-agent.sort.js +21 -0
  4. package/dist/ai/ai-agent.sort.js.map +1 -0
  5. package/dist/ai/ai.controller.d.ts +4 -4
  6. package/dist/ai/ai.service.d.ts +35 -4
  7. package/dist/ai/ai.service.d.ts.map +1 -1
  8. package/dist/ai/ai.service.js +51 -137
  9. package/dist/ai/ai.service.js.map +1 -1
  10. package/dist/ai-instruction/ai-instruction.service.d.ts.map +1 -1
  11. package/dist/ai-instruction/ai-instruction.service.js +26 -23
  12. package/dist/ai-instruction/ai-instruction.service.js.map +1 -1
  13. package/dist/ai-instruction/ai-instruction.sort.d.ts +16 -0
  14. package/dist/ai-instruction/ai-instruction.sort.d.ts.map +1 -0
  15. package/dist/ai-instruction/ai-instruction.sort.js +32 -0
  16. package/dist/ai-instruction/ai-instruction.sort.js.map +1 -0
  17. package/dist/auth/auth.controller.d.ts +24 -8
  18. package/dist/auth/auth.controller.d.ts.map +1 -1
  19. package/dist/auth/auth.module.d.ts.map +1 -1
  20. package/dist/auth/auth.module.js +8 -1
  21. package/dist/auth/auth.module.js.map +1 -1
  22. package/dist/auth/auth.service.d.ts +72 -25
  23. package/dist/auth/auth.service.d.ts.map +1 -1
  24. package/dist/auth/auth.service.js +41 -4
  25. package/dist/auth/auth.service.js.map +1 -1
  26. package/dist/auth/guards/auth.guard.d.ts +3 -1
  27. package/dist/auth/guards/auth.guard.d.ts.map +1 -1
  28. package/dist/auth/guards/auth.guard.js +12 -3
  29. package/dist/auth/guards/auth.guard.js.map +1 -1
  30. package/dist/authorize/authorize.controller.d.ts +30 -6
  31. package/dist/authorize/authorize.controller.d.ts.map +1 -1
  32. package/dist/authorize/authorize.controller.js +120 -13
  33. package/dist/authorize/authorize.controller.js.map +1 -1
  34. package/dist/authorize/authorize.errors.d.ts +34 -0
  35. package/dist/authorize/authorize.errors.d.ts.map +1 -0
  36. package/dist/authorize/authorize.errors.js +37 -0
  37. package/dist/authorize/authorize.errors.js.map +1 -0
  38. package/dist/authorize/authorize.module.d.ts.map +1 -1
  39. package/dist/authorize/authorize.module.js +6 -1
  40. package/dist/authorize/authorize.module.js.map +1 -1
  41. package/dist/authorize/authorize.service.d.ts +78 -4
  42. package/dist/authorize/authorize.service.d.ts.map +1 -1
  43. package/dist/authorize/authorize.service.js +212 -21
  44. package/dist/authorize/authorize.service.js.map +1 -1
  45. package/dist/authorize/dto/authorize-info.dto.d.ts +10 -1
  46. package/dist/authorize/dto/authorize-info.dto.d.ts.map +1 -1
  47. package/dist/authorize/dto/authorize-info.dto.js +16 -1
  48. package/dist/authorize/dto/authorize-info.dto.js.map +1 -1
  49. package/dist/authorize/dto/consent.dto.d.ts +10 -1
  50. package/dist/authorize/dto/consent.dto.d.ts.map +1 -1
  51. package/dist/authorize/dto/consent.dto.js +16 -1
  52. package/dist/authorize/dto/consent.dto.js.map +1 -1
  53. package/dist/authorize/dto/token.dto.d.ts +12 -0
  54. package/dist/authorize/dto/token.dto.d.ts.map +1 -1
  55. package/dist/authorize/dto/token.dto.js +21 -1
  56. package/dist/authorize/dto/token.dto.js.map +1 -1
  57. package/dist/authorize/oauth-exception.filter.d.ts +17 -0
  58. package/dist/authorize/oauth-exception.filter.d.ts.map +1 -0
  59. package/dist/authorize/oauth-exception.filter.js +54 -0
  60. package/dist/authorize/oauth-exception.filter.js.map +1 -0
  61. package/dist/authorize/oauth-metadata.service.d.ts +39 -0
  62. package/dist/authorize/oauth-metadata.service.d.ts.map +1 -0
  63. package/dist/authorize/oauth-metadata.service.js +81 -0
  64. package/dist/authorize/oauth-metadata.service.js.map +1 -0
  65. package/dist/authorize/well-known.controller.d.ts +67 -0
  66. package/dist/authorize/well-known.controller.d.ts.map +1 -0
  67. package/dist/authorize/well-known.controller.js +126 -0
  68. package/dist/authorize/well-known.controller.js.map +1 -0
  69. package/dist/captcha/captcha.service.d.ts +32 -2
  70. package/dist/captcha/captcha.service.d.ts.map +1 -1
  71. package/dist/captcha/captcha.service.js +85 -12
  72. package/dist/captcha/captcha.service.js.map +1 -1
  73. package/dist/challenge/challenge.service.d.ts +2 -2
  74. package/dist/core.module.d.ts.map +1 -1
  75. package/dist/core.module.js +6 -0
  76. package/dist/core.module.js.map +1 -1
  77. package/dist/dashboard/dashboard/dashboard.controller.d.ts +9 -9
  78. package/dist/dashboard/dashboard/dashboard.service.d.ts +9 -9
  79. package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts +3 -3
  80. package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts +3 -3
  81. package/dist/dashboard/dashboard-component-role/dashboard-component-role.controller.d.ts +3 -3
  82. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.d.ts +3 -3
  83. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.d.ts.map +1 -1
  84. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.js +2 -4
  85. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.js.map +1 -1
  86. package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.d.ts +8 -0
  87. package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.d.ts.map +1 -0
  88. package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.js +18 -0
  89. package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.js.map +1 -0
  90. package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts.map +1 -1
  91. package/dist/dashboard/dashboard-item/dashboard-item.service.js +2 -4
  92. package/dist/dashboard/dashboard-item/dashboard-item.service.js.map +1 -1
  93. package/dist/dashboard/dashboard-item/dashboard-item.sort.d.ts +9 -0
  94. package/dist/dashboard/dashboard-item/dashboard-item.sort.d.ts.map +1 -0
  95. package/dist/dashboard/dashboard-item/dashboard-item.sort.js +19 -0
  96. package/dist/dashboard/dashboard-item/dashboard-item.sort.js.map +1 -0
  97. package/dist/dashboard/dashboard-role/dashboard-role.controller.d.ts +3 -3
  98. package/dist/dashboard/dashboard-role/dashboard-role.service.d.ts +3 -3
  99. package/dist/dashboard/dashboard-role/dashboard-role.service.d.ts.map +1 -1
  100. package/dist/dashboard/dashboard-role/dashboard-role.service.js +2 -4
  101. package/dist/dashboard/dashboard-role/dashboard-role.service.js.map +1 -1
  102. package/dist/dashboard/dashboard-role/dashboard-role.sort.d.ts +8 -0
  103. package/dist/dashboard/dashboard-role/dashboard-role.sort.d.ts.map +1 -0
  104. package/dist/dashboard/dashboard-role/dashboard-role.sort.js +16 -0
  105. package/dist/dashboard/dashboard-role/dashboard-role.sort.js.map +1 -0
  106. package/dist/file/file-upload-ticket.service.d.ts +160 -0
  107. package/dist/file/file-upload-ticket.service.d.ts.map +1 -0
  108. package/dist/file/file-upload-ticket.service.js +382 -0
  109. package/dist/file/file-upload-ticket.service.js.map +1 -0
  110. package/dist/file/file.controller.d.ts +24 -1
  111. package/dist/file/file.controller.d.ts.map +1 -1
  112. package/dist/file/file.controller.js +63 -2
  113. package/dist/file/file.controller.js.map +1 -1
  114. package/dist/file/file.module.d.ts.map +1 -1
  115. package/dist/file/file.module.js +14 -2
  116. package/dist/file/file.module.js.map +1 -1
  117. package/dist/file/file.service.d.ts +182 -6
  118. package/dist/file/file.service.d.ts.map +1 -1
  119. package/dist/file/file.service.js +385 -36
  120. package/dist/file/file.service.js.map +1 -1
  121. package/dist/file/filename-encoding.util.d.ts +24 -0
  122. package/dist/file/filename-encoding.util.d.ts.map +1 -0
  123. package/dist/file/filename-encoding.util.js +63 -0
  124. package/dist/file/filename-encoding.util.js.map +1 -0
  125. package/dist/file/image-optimization.service.d.ts +27 -0
  126. package/dist/file/image-optimization.service.d.ts.map +1 -1
  127. package/dist/file/image-optimization.service.js +63 -14
  128. package/dist/file/image-optimization.service.js.map +1 -1
  129. package/dist/file/mcp-file-source.schema.d.ts +33 -0
  130. package/dist/file/mcp-file-source.schema.d.ts.map +1 -0
  131. package/dist/file/mcp-file-source.schema.js +75 -0
  132. package/dist/file/mcp-file-source.schema.js.map +1 -0
  133. package/dist/file/mcp-file-source.service.d.ts +124 -0
  134. package/dist/file/mcp-file-source.service.d.ts.map +1 -0
  135. package/dist/file/mcp-file-source.service.js +262 -0
  136. package/dist/file/mcp-file-source.service.js.map +1 -0
  137. package/dist/file/mimetype-sniff.util.d.ts +62 -0
  138. package/dist/file/mimetype-sniff.util.d.ts.map +1 -0
  139. package/dist/file/mimetype-sniff.util.js +226 -0
  140. package/dist/file/mimetype-sniff.util.js.map +1 -0
  141. package/dist/file/remote-fetch.util.d.ts +35 -0
  142. package/dist/file/remote-fetch.util.d.ts.map +1 -0
  143. package/dist/file/remote-fetch.util.js +236 -0
  144. package/dist/file/remote-fetch.util.js.map +1 -0
  145. package/dist/impersonation/dto/start-impersonation.dto.d.ts +4 -1
  146. package/dist/impersonation/dto/start-impersonation.dto.d.ts.map +1 -1
  147. package/dist/impersonation/dto/start-impersonation.dto.js +1 -1
  148. package/dist/impersonation/dto/start-impersonation.dto.js.map +1 -1
  149. package/dist/impersonation/impersonation.service.d.ts +8 -3
  150. package/dist/impersonation/impersonation.service.d.ts.map +1 -1
  151. package/dist/impersonation/impersonation.service.js +14 -4
  152. package/dist/impersonation/impersonation.service.js.map +1 -1
  153. package/dist/incident/incident.controller.d.ts +2 -1
  154. package/dist/incident/incident.controller.d.ts.map +1 -1
  155. package/dist/incident/incident.controller.js +10 -6
  156. package/dist/incident/incident.controller.js.map +1 -1
  157. package/dist/incident/incident.service.d.ts +2 -0
  158. package/dist/incident/incident.service.d.ts.map +1 -1
  159. package/dist/incident/incident.service.js +4 -0
  160. package/dist/incident/incident.service.js.map +1 -1
  161. package/dist/index.d.ts +17 -0
  162. package/dist/index.d.ts.map +1 -1
  163. package/dist/index.js +17 -0
  164. package/dist/index.js.map +1 -1
  165. package/dist/integration-profile/integration-profile.secrets.d.ts.map +1 -1
  166. package/dist/integration-profile/integration-profile.secrets.js +7 -0
  167. package/dist/integration-profile/integration-profile.secrets.js.map +1 -1
  168. package/dist/integration-profile/integration-profile.service.d.ts +0 -13
  169. package/dist/integration-profile/integration-profile.service.d.ts.map +1 -1
  170. package/dist/integration-profile/integration-profile.service.js +5 -40
  171. package/dist/integration-profile/integration-profile.service.js.map +1 -1
  172. package/dist/integration-profile/integration-profile.utils.js +5 -5
  173. package/dist/integration-profile/integration-profile.utils.js.map +1 -1
  174. package/dist/integration-profile/testers/index.d.ts.map +1 -1
  175. package/dist/integration-profile/testers/index.js +2 -0
  176. package/dist/integration-profile/testers/index.js.map +1 -1
  177. package/dist/integration-profile/testers/shipping.testers.d.ts +3 -0
  178. package/dist/integration-profile/testers/shipping.testers.d.ts.map +1 -0
  179. package/dist/integration-profile/testers/shipping.testers.js +71 -0
  180. package/dist/integration-profile/testers/shipping.testers.js.map +1 -0
  181. package/dist/locale/locale.controller.d.ts +1 -1
  182. package/dist/locale/locale.service.d.ts +1 -1
  183. package/dist/mail/dto/send.dto.d.ts +6 -1
  184. package/dist/mail/dto/send.dto.d.ts.map +1 -1
  185. package/dist/mail/dto/send.dto.js.map +1 -1
  186. package/dist/mail/mail.service.d.ts +9 -0
  187. package/dist/mail/mail.service.d.ts.map +1 -1
  188. package/dist/mail/mail.service.js +34 -14
  189. package/dist/mail/mail.service.js.map +1 -1
  190. package/dist/mail-sent/mail-sent.controller.d.ts +1 -1
  191. package/dist/mail-sent/mail-sent.service.d.ts +1 -1
  192. package/dist/mail-sent/mail-sent.service.d.ts.map +1 -1
  193. package/dist/mail-sent/mail-sent.service.js +2 -1
  194. package/dist/mail-sent/mail-sent.service.js.map +1 -1
  195. package/dist/mail-sent/mail-sent.sort.d.ts +9 -0
  196. package/dist/mail-sent/mail-sent.sort.d.ts.map +1 -0
  197. package/dist/mail-sent/mail-sent.sort.js +19 -0
  198. package/dist/mail-sent/mail-sent.sort.js.map +1 -0
  199. package/dist/mcp/filters/mcp-challenge.filter.d.ts +20 -0
  200. package/dist/mcp/filters/mcp-challenge.filter.d.ts.map +1 -0
  201. package/dist/mcp/filters/mcp-challenge.filter.js +69 -0
  202. package/dist/mcp/filters/mcp-challenge.filter.js.map +1 -0
  203. package/dist/mcp/guards/mcp-auth.guard.d.ts +4 -1
  204. package/dist/mcp/guards/mcp-auth.guard.d.ts.map +1 -1
  205. package/dist/mcp/guards/mcp-auth.guard.js +19 -5
  206. package/dist/mcp/guards/mcp-auth.guard.js.map +1 -1
  207. package/dist/mcp/guards/mcp-permission.guard.d.ts +25 -3
  208. package/dist/mcp/guards/mcp-permission.guard.d.ts.map +1 -1
  209. package/dist/mcp/guards/mcp-permission.guard.js +46 -26
  210. package/dist/mcp/guards/mcp-permission.guard.js.map +1 -1
  211. package/dist/mcp/mcp-audit.service.d.ts +17 -0
  212. package/dist/mcp/mcp-audit.service.d.ts.map +1 -1
  213. package/dist/mcp/mcp-audit.service.js +32 -3
  214. package/dist/mcp/mcp-audit.service.js.map +1 -1
  215. package/dist/mcp/mcp-permission.service.d.ts +64 -0
  216. package/dist/mcp/mcp-permission.service.d.ts.map +1 -0
  217. package/dist/mcp/mcp-permission.service.js +178 -0
  218. package/dist/mcp/mcp-permission.service.js.map +1 -0
  219. package/dist/mcp/mcp-server.service.d.ts +3 -1
  220. package/dist/mcp/mcp-server.service.d.ts.map +1 -1
  221. package/dist/mcp/mcp-server.service.js +36 -15
  222. package/dist/mcp/mcp-server.service.js.map +1 -1
  223. package/dist/mcp/mcp.controller.d.ts.map +1 -1
  224. package/dist/mcp/mcp.controller.js +10 -2
  225. package/dist/mcp/mcp.controller.js.map +1 -1
  226. package/dist/mcp/mcp.module.d.ts.map +1 -1
  227. package/dist/mcp/mcp.module.js +5 -1
  228. package/dist/mcp/mcp.module.js.map +1 -1
  229. package/dist/mcp/tools/core-ai.mcp-tools.js +2 -9
  230. package/dist/mcp/tools/core-ai.mcp-tools.js.map +1 -1
  231. package/dist/mcp/tools/core-dashboard-items.mcp-tools.js +1 -1
  232. package/dist/mcp/tools/core-dashboard-items.mcp-tools.js.map +1 -1
  233. package/dist/mcp/tools/core-dashboard.mcp-tools.js +2 -9
  234. package/dist/mcp/tools/core-dashboard.mcp-tools.js.map +1 -1
  235. package/dist/mcp/tools/core-event-webhooks.mcp-tools.d.ts.map +1 -1
  236. package/dist/mcp/tools/core-event-webhooks.mcp-tools.js +2 -10
  237. package/dist/mcp/tools/core-event-webhooks.mcp-tools.js.map +1 -1
  238. package/dist/mcp/tools/core-files.mcp-tools.d.ts +17 -5
  239. package/dist/mcp/tools/core-files.mcp-tools.d.ts.map +1 -1
  240. package/dist/mcp/tools/core-files.mcp-tools.js +186 -24
  241. package/dist/mcp/tools/core-files.mcp-tools.js.map +1 -1
  242. package/dist/mcp/tools/core-integration-events.mcp-tools.js +2 -9
  243. package/dist/mcp/tools/core-integration-events.mcp-tools.js.map +1 -1
  244. package/dist/mcp/tools/core-mail-sent.mcp-tools.js +2 -14
  245. package/dist/mcp/tools/core-mail-sent.mcp-tools.js.map +1 -1
  246. package/dist/mcp/tools/core-mail.mcp-tools.js +2 -9
  247. package/dist/mcp/tools/core-mail.mcp-tools.js.map +1 -1
  248. package/dist/mcp/tools/core-menus.mcp-tools.d.ts.map +1 -1
  249. package/dist/mcp/tools/core-menus.mcp-tools.js +2 -10
  250. package/dist/mcp/tools/core-menus.mcp-tools.js.map +1 -1
  251. package/dist/mcp/tools/core-notifications.mcp-tools.d.ts.map +1 -1
  252. package/dist/mcp/tools/core-notifications.mcp-tools.js +0 -1
  253. package/dist/mcp/tools/core-notifications.mcp-tools.js.map +1 -1
  254. package/dist/mcp/tools/core-roles.mcp-tools.d.ts.map +1 -1
  255. package/dist/mcp/tools/core-roles.mcp-tools.js +2 -13
  256. package/dist/mcp/tools/core-roles.mcp-tools.js.map +1 -1
  257. package/dist/mcp/tools/core-routes.mcp-tools.d.ts.map +1 -1
  258. package/dist/mcp/tools/core-routes.mcp-tools.js +2 -11
  259. package/dist/mcp/tools/core-routes.mcp-tools.js.map +1 -1
  260. package/dist/mcp/tools/core-screens.mcp-tools.d.ts.map +1 -1
  261. package/dist/mcp/tools/core-screens.mcp-tools.js +2 -11
  262. package/dist/mcp/tools/core-screens.mcp-tools.js.map +1 -1
  263. package/dist/mcp/tools/core-sessions.mcp-tools.d.ts.map +1 -1
  264. package/dist/mcp/tools/core-sessions.mcp-tools.js +0 -2
  265. package/dist/mcp/tools/core-sessions.mcp-tools.js.map +1 -1
  266. package/dist/mcp/tools/core-settings.mcp-tools.d.ts.map +1 -1
  267. package/dist/mcp/tools/core-settings.mcp-tools.js +2 -10
  268. package/dist/mcp/tools/core-settings.mcp-tools.js.map +1 -1
  269. package/dist/mcp/tools/core-users.mcp-tools.js +2 -9
  270. package/dist/mcp/tools/core-users.mcp-tools.js.map +1 -1
  271. package/dist/mcp/tools/core-webhooks.mcp-tools.d.ts.map +1 -1
  272. package/dist/mcp/tools/core-webhooks.mcp-tools.js +2 -10
  273. package/dist/mcp/tools/core-webhooks.mcp-tools.js.map +1 -1
  274. package/dist/mcp/types/mcp-context.type.d.ts +9 -0
  275. package/dist/mcp/types/mcp-context.type.d.ts.map +1 -1
  276. package/dist/mcp-chat/mcp-chat.service.d.ts.map +1 -1
  277. package/dist/mcp-chat/mcp-chat.service.js +8 -0
  278. package/dist/mcp-chat/mcp-chat.service.js.map +1 -1
  279. package/dist/meeting/meeting-provider.registry.d.ts +115 -0
  280. package/dist/meeting/meeting-provider.registry.d.ts.map +1 -1
  281. package/dist/meeting/meeting-provider.registry.js.map +1 -1
  282. package/dist/meeting/meeting.constants.d.ts +70 -0
  283. package/dist/meeting/meeting.constants.d.ts.map +1 -1
  284. package/dist/meeting/meeting.constants.js +9 -1
  285. package/dist/meeting/meeting.constants.js.map +1 -1
  286. package/dist/menu/menu.service.d.ts.map +1 -1
  287. package/dist/menu/menu.service.js +29 -9
  288. package/dist/menu/menu.service.js.map +1 -1
  289. package/dist/message-template/dto/update-message-template.dto.d.ts +18 -0
  290. package/dist/message-template/dto/update-message-template.dto.d.ts.map +1 -0
  291. package/dist/message-template/dto/update-message-template.dto.js +38 -0
  292. package/dist/message-template/dto/update-message-template.dto.js.map +1 -0
  293. package/dist/message-template/message-template-admin.service.d.ts +70 -0
  294. package/dist/message-template/message-template-admin.service.d.ts.map +1 -0
  295. package/dist/message-template/message-template-admin.service.js +226 -0
  296. package/dist/message-template/message-template-admin.service.js.map +1 -0
  297. package/dist/message-template/message-template.controller.d.ts +29 -0
  298. package/dist/message-template/message-template.controller.d.ts.map +1 -0
  299. package/dist/message-template/message-template.controller.js +101 -0
  300. package/dist/message-template/message-template.controller.js.map +1 -0
  301. package/dist/message-template/message-template.module.d.ts +10 -0
  302. package/dist/message-template/message-template.module.d.ts.map +1 -0
  303. package/dist/message-template/message-template.module.js +33 -0
  304. package/dist/message-template/message-template.module.js.map +1 -0
  305. package/dist/message-template/message-template.registry.d.ts +55 -0
  306. package/dist/message-template/message-template.registry.d.ts.map +1 -0
  307. package/dist/message-template/message-template.registry.js +64 -0
  308. package/dist/message-template/message-template.registry.js.map +1 -0
  309. package/dist/message-template/message-template.service.d.ts +59 -0
  310. package/dist/message-template/message-template.service.d.ts.map +1 -0
  311. package/dist/message-template/message-template.service.js +166 -0
  312. package/dist/message-template/message-template.service.js.map +1 -0
  313. package/dist/notification/notification.constants.d.ts +11 -0
  314. package/dist/notification/notification.constants.d.ts.map +1 -0
  315. package/dist/notification/notification.constants.js +14 -0
  316. package/dist/notification/notification.constants.js.map +1 -0
  317. package/dist/notification/notification.controller.d.ts +20 -20
  318. package/dist/notification/notification.module.d.ts.map +1 -1
  319. package/dist/notification/notification.module.js +3 -0
  320. package/dist/notification/notification.module.js.map +1 -1
  321. package/dist/notification/notification.service.d.ts +33 -21
  322. package/dist/notification/notification.service.d.ts.map +1 -1
  323. package/dist/notification/notification.service.js +36 -2
  324. package/dist/notification/notification.service.js.map +1 -1
  325. package/dist/oauth/oauth.controller.d.ts +4 -6
  326. package/dist/oauth/oauth.controller.d.ts.map +1 -1
  327. package/dist/oauth/oauth.controller.js +0 -1
  328. package/dist/oauth/oauth.controller.js.map +1 -1
  329. package/dist/oauth/oauth.errors.d.ts +15 -1
  330. package/dist/oauth/oauth.errors.d.ts.map +1 -1
  331. package/dist/oauth/oauth.errors.js +9 -1
  332. package/dist/oauth/oauth.errors.js.map +1 -1
  333. package/dist/oauth/oauth.module.d.ts.map +1 -1
  334. package/dist/oauth/oauth.module.js +6 -1
  335. package/dist/oauth/oauth.module.js.map +1 -1
  336. package/dist/oauth/oauth.service.d.ts +25 -5
  337. package/dist/oauth/oauth.service.d.ts.map +1 -1
  338. package/dist/oauth/oauth.service.js +63 -27
  339. package/dist/oauth/oauth.service.js.map +1 -1
  340. package/dist/oauth/providers/abstract.provider.d.ts +10 -0
  341. package/dist/oauth/providers/abstract.provider.d.ts.map +1 -1
  342. package/dist/oauth/providers/abstract.provider.js +39 -12
  343. package/dist/oauth/providers/abstract.provider.js.map +1 -1
  344. package/dist/oauth/providers/github.provider.d.ts +1 -1
  345. package/dist/oauth/providers/github.provider.d.ts.map +1 -1
  346. package/dist/oauth/providers/github.provider.js +48 -22
  347. package/dist/oauth/providers/github.provider.js.map +1 -1
  348. package/dist/oauth/providers/microsoft-entra-id.provider.d.ts.map +1 -1
  349. package/dist/oauth/providers/microsoft-entra-id.provider.js +6 -0
  350. package/dist/oauth/providers/microsoft-entra-id.provider.js.map +1 -1
  351. package/dist/observability/monitored-cron.d.ts +29 -12
  352. package/dist/observability/monitored-cron.d.ts.map +1 -1
  353. package/dist/observability/monitored-cron.js +131 -46
  354. package/dist/observability/monitored-cron.js.map +1 -1
  355. package/dist/pairing/pairing.controller.d.ts +9 -9
  356. package/dist/pairing/pairing.service.d.ts +15 -11
  357. package/dist/pairing/pairing.service.d.ts.map +1 -1
  358. package/dist/profile/dto/change-password.dto.d.ts.map +1 -1
  359. package/dist/profile/dto/change-password.dto.js +4 -6
  360. package/dist/profile/dto/change-password.dto.js.map +1 -1
  361. package/dist/profile/profile.controller.d.ts +1 -1
  362. package/dist/profile/profile.service.d.ts +1 -1
  363. package/dist/profile/profile.service.d.ts.map +1 -1
  364. package/dist/profile/profile.service.js +9 -3
  365. package/dist/profile/profile.service.js.map +1 -1
  366. package/dist/realtime/realtime-tick.coalescer.d.ts +34 -0
  367. package/dist/realtime/realtime-tick.coalescer.d.ts.map +1 -0
  368. package/dist/realtime/realtime-tick.coalescer.js +60 -0
  369. package/dist/realtime/realtime-tick.coalescer.js.map +1 -0
  370. package/dist/realtime/realtime.service.d.ts +2 -0
  371. package/dist/realtime/realtime.service.d.ts.map +1 -1
  372. package/dist/realtime/realtime.service.js +22 -2
  373. package/dist/realtime/realtime.service.js.map +1 -1
  374. package/dist/redis/redis-kv.service.d.ts +90 -0
  375. package/dist/redis/redis-kv.service.d.ts.map +1 -0
  376. package/dist/redis/redis-kv.service.js +247 -0
  377. package/dist/redis/redis-kv.service.js.map +1 -0
  378. package/dist/redis/redis-master.d.ts +29 -0
  379. package/dist/redis/redis-master.d.ts.map +1 -0
  380. package/dist/redis/redis-master.js +81 -0
  381. package/dist/redis/redis-master.js.map +1 -0
  382. package/dist/redis/redis-pubsub.d.ts +12 -0
  383. package/dist/redis/redis-pubsub.d.ts.map +1 -1
  384. package/dist/redis/redis-pubsub.js +25 -2
  385. package/dist/redis/redis-pubsub.js.map +1 -1
  386. package/dist/redis/redis.module.d.ts +11 -0
  387. package/dist/redis/redis.module.d.ts.map +1 -0
  388. package/dist/redis/redis.module.js +30 -0
  389. package/dist/redis/redis.module.js.map +1 -0
  390. package/dist/session/session.controller.d.ts +6 -2
  391. package/dist/session/session.controller.d.ts.map +1 -1
  392. package/dist/session/session.service.d.ts +118 -15
  393. package/dist/session/session.service.d.ts.map +1 -1
  394. package/dist/session/session.service.js +251 -77
  395. package/dist/session/session.service.js.map +1 -1
  396. package/dist/setting/setting.controller.d.ts +5 -0
  397. package/dist/setting/setting.controller.d.ts.map +1 -1
  398. package/dist/setting/setting.service.d.ts +7 -0
  399. package/dist/setting/setting.service.d.ts.map +1 -1
  400. package/dist/setting/setting.service.js +38 -3
  401. package/dist/setting/setting.service.js.map +1 -1
  402. package/dist/task/task.service.d.ts +17 -0
  403. package/dist/task/task.service.d.ts.map +1 -1
  404. package/dist/task/task.service.js +48 -13
  405. package/dist/task/task.service.js.map +1 -1
  406. package/dist/token/token.service.d.ts +19 -1
  407. package/dist/token/token.service.d.ts.map +1 -1
  408. package/dist/token/token.service.js +39 -2
  409. package/dist/token/token.service.js.map +1 -1
  410. package/dist/user/user-credential.util.d.ts +10 -0
  411. package/dist/user/user-credential.util.d.ts.map +1 -1
  412. package/dist/user/user-credential.util.js +14 -1
  413. package/dist/user/user-credential.util.js.map +1 -1
  414. package/dist/user/user.service.d.ts +12 -4
  415. package/dist/user/user.service.d.ts.map +1 -1
  416. package/dist/user/user.service.js +2 -11
  417. package/dist/user/user.service.js.map +1 -1
  418. package/dist/user/user.sort.d.ts +16 -0
  419. package/dist/user/user.sort.d.ts.map +1 -0
  420. package/dist/user/user.sort.js +25 -0
  421. package/dist/user/user.sort.js.map +1 -0
  422. package/dist/utils/abbreviate-name.d.ts +13 -0
  423. package/dist/utils/abbreviate-name.d.ts.map +1 -0
  424. package/dist/utils/abbreviate-name.js +42 -0
  425. package/dist/utils/abbreviate-name.js.map +1 -0
  426. package/dist/utils/date-range-query.dto.d.ts +11 -0
  427. package/dist/utils/date-range-query.dto.d.ts.map +1 -0
  428. package/dist/utils/date-range-query.dto.js +63 -0
  429. package/dist/utils/date-range-query.dto.js.map +1 -0
  430. package/dist/utils/date-range.d.ts +96 -0
  431. package/dist/utils/date-range.d.ts.map +1 -0
  432. package/dist/utils/date-range.js +172 -0
  433. package/dist/utils/date-range.js.map +1 -0
  434. package/dist/webhook-integration/webhook-utils.d.ts.map +1 -1
  435. package/dist/webhook-integration/webhook-utils.js +24 -0
  436. package/dist/webhook-integration/webhook-utils.js.map +1 -1
  437. package/dist/whatsapp-sender/whatsapp-recipients.d.ts +49 -0
  438. package/dist/whatsapp-sender/whatsapp-recipients.d.ts.map +1 -0
  439. package/dist/whatsapp-sender/whatsapp-recipients.js +66 -0
  440. package/dist/whatsapp-sender/whatsapp-recipients.js.map +1 -0
  441. package/dist/whatsapp-sender/whatsapp-sender.service.d.ts +25 -0
  442. package/dist/whatsapp-sender/whatsapp-sender.service.d.ts.map +1 -1
  443. package/dist/whatsapp-sender/whatsapp-sender.service.js +46 -5
  444. package/dist/whatsapp-sender/whatsapp-sender.service.js.map +1 -1
  445. package/hedhog/data/integration_provider.yaml +9 -0
  446. package/hedhog/data/integration_type.yaml +6 -0
  447. package/hedhog/data/locale.yaml +0 -1
  448. package/hedhog/data/mail.yaml +2 -2
  449. package/hedhog/data/mail_layout.yaml +6 -3
  450. package/hedhog/data/menu.yaml +25 -5
  451. package/hedhog/data/route.yaml +140 -0
  452. package/hedhog/data/setting_group.yaml +137 -3
  453. package/hedhog/frontend/app/access-log/page.tsx.ejs +47 -53
  454. package/hedhog/frontend/app/account/components/active-sessions.tsx.ejs +33 -8
  455. package/hedhog/frontend/app/account/components/mcp-tokens.tsx.ejs +54 -13
  456. package/hedhog/frontend/app/account/components/mfa-method-card.tsx.ejs +7 -1
  457. package/hedhog/frontend/app/account/components/recovery-codes-dialog.tsx.ejs +1 -0
  458. package/hedhog/frontend/app/account/components/tokens.tsx.ejs +47 -17
  459. package/hedhog/frontend/app/ai_agent/page.tsx.ejs +46 -5
  460. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-form.tsx.ejs +101 -30
  461. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-versions.tsx.ejs +24 -8
  462. package/hedhog/frontend/app/ai_instruction/page.tsx.ejs +80 -15
  463. package/hedhog/frontend/app/configurations/[slug]/components/image-optimization-action.tsx.ejs +166 -0
  464. package/hedhog/frontend/app/configurations/[slug]/components/setting-field.test.tsx.ejs +145 -45
  465. package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +99 -219
  466. package/hedhog/frontend/app/configurations/[slug]/page.tsx.ejs +19 -1
  467. package/hedhog/frontend/app/configurations/layout.tsx.ejs +19 -5
  468. package/hedhog/frontend/app/dashboard/[slug]/widget-renderer.tsx.ejs +2 -8
  469. package/hedhog/frontend/app/dashboard/components/dynamic-widget.tsx.ejs +3 -0
  470. package/hedhog/frontend/app/dashboard/components/widget-wrapper.tsx.ejs +4 -0
  471. package/hedhog/frontend/app/dashboard/dashboard-home-tabs.tsx.ejs +43 -44
  472. package/hedhog/frontend/app/dashboard/management/tabs/component-roles-tab.tsx.ejs +41 -3
  473. package/hedhog/frontend/app/dashboard/management/tabs/components-tab.tsx.ejs +42 -2
  474. package/hedhog/frontend/app/dashboard/management/tabs/dashboard-roles-tab.tsx.ejs +41 -3
  475. package/hedhog/frontend/app/dashboard/management/tabs/dashboards-tab.tsx.ejs +39 -4
  476. package/hedhog/frontend/app/dashboard/management/tabs/items-tab.tsx.ejs +42 -3
  477. package/hedhog/frontend/app/incidents/page.tsx.ejs +60 -31
  478. package/hedhog/frontend/app/integration/profiles/page.tsx.ejs +45 -5
  479. package/hedhog/frontend/app/integrations-webhooks/page.tsx.ejs +92 -15
  480. package/hedhog/frontend/app/mail/log/page.tsx.ejs +109 -61
  481. package/hedhog/frontend/app/mail/template/page.tsx.ejs +125 -23
  482. package/hedhog/frontend/app/mcp_chat/chat-components.tsx.ejs +13 -15
  483. package/hedhog/frontend/app/mcp_chat/page.tsx.ejs +116 -110
  484. package/hedhog/frontend/app/message-templates/_components/message-template-sheet.tsx.ejs +245 -0
  485. package/hedhog/frontend/app/message-templates/_lib/types.ts.ejs +24 -0
  486. package/hedhog/frontend/app/message-templates/page.tsx.ejs +182 -0
  487. package/hedhog/frontend/app/pages/_components/page-wizard-sheet.tsx.ejs +1 -0
  488. package/hedhog/frontend/app/pages/page.tsx.ejs +94 -9
  489. package/hedhog/frontend/app/roles/menus.tsx.ejs +4 -4
  490. package/hedhog/frontend/app/roles/routes.tsx.ejs +4 -4
  491. package/hedhog/frontend/app/roles/users.tsx.ejs +4 -4
  492. package/hedhog/frontend/app/setting-list/page.tsx.ejs +71 -9
  493. package/hedhog/frontend/app/users/page.tsx.ejs +77 -67
  494. package/hedhog/frontend/messages/en.json +183 -36
  495. package/hedhog/frontend/messages/pt.json +183 -36
  496. package/hedhog/table/cron_lock.yaml +17 -0
  497. package/hedhog/table/file.yaml +13 -1
  498. package/hedhog/table/file_upload_chunk.yaml +23 -0
  499. package/hedhog/table/file_upload_ticket.yaml +67 -0
  500. package/hedhog/table/mcp_tool_call_log.yaml +30 -22
  501. package/hedhog/table/message_template.yaml +33 -0
  502. package/hedhog/table/setting.yaml +8 -0
  503. package/hedhog/table/user_session.yaml +36 -1
  504. package/package.json +8 -6
  505. package/src/ai/ai-agent.sort.ts +21 -0
  506. package/src/ai/ai.service.spec.ts +173 -1
  507. package/src/ai/ai.service.ts +64 -193
  508. package/src/ai-instruction/ai-instruction.service.ts +32 -28
  509. package/src/ai-instruction/ai-instruction.sort.ts +32 -0
  510. package/src/auth/auth.module.ts +8 -1
  511. package/src/auth/auth.service.spec.ts +108 -1
  512. package/src/auth/auth.service.ts +59 -5
  513. package/src/auth/guards/auth.guard.ts +9 -1
  514. package/src/authorize/authorize.controller.ts +126 -11
  515. package/src/authorize/authorize.errors.ts +55 -0
  516. package/src/authorize/authorize.module.ts +6 -1
  517. package/src/authorize/authorize.service.spec.ts +379 -7
  518. package/src/authorize/authorize.service.ts +309 -23
  519. package/src/authorize/dto/authorize-info.dto.ts +21 -3
  520. package/src/authorize/dto/consent.dto.ts +21 -3
  521. package/src/authorize/dto/token.dto.ts +24 -2
  522. package/src/authorize/oauth-exception.filter.ts +58 -0
  523. package/src/authorize/oauth-metadata.service.ts +67 -0
  524. package/src/authorize/well-known.controller.spec.ts +84 -0
  525. package/src/authorize/well-known.controller.ts +96 -0
  526. package/src/captcha/captcha.service.spec.ts +211 -4
  527. package/src/captcha/captcha.service.ts +127 -10
  528. package/src/core.module.ts +6 -0
  529. package/src/dashboard/dashboard-component-role/dashboard-component-role.service.ts +2 -3
  530. package/src/dashboard/dashboard-component-role/dashboard-component-role.sort.ts +18 -0
  531. package/src/dashboard/dashboard-item/dashboard-item.service.ts +2 -3
  532. package/src/dashboard/dashboard-item/dashboard-item.sort.ts +19 -0
  533. package/src/dashboard/dashboard-role/dashboard-role.service.ts +2 -3
  534. package/src/dashboard/dashboard-role/dashboard-role.sort.ts +16 -0
  535. package/src/file/file-upload-ticket.service.spec.ts +422 -0
  536. package/src/file/file-upload-ticket.service.ts +513 -0
  537. package/src/file/file.controller.ts +65 -0
  538. package/src/file/file.module.ts +14 -2
  539. package/src/file/file.service.spec.ts +94 -0
  540. package/src/file/file.service.ts +432 -30
  541. package/src/file/filename-encoding.util.spec.ts +54 -0
  542. package/src/file/filename-encoding.util.ts +67 -0
  543. package/src/file/image-optimization.service.spec.ts +156 -19
  544. package/src/file/image-optimization.service.ts +106 -21
  545. package/src/file/mcp-file-source.schema.ts +83 -0
  546. package/src/file/mcp-file-source.service.spec.ts +473 -0
  547. package/src/file/mcp-file-source.service.ts +445 -0
  548. package/src/file/mimetype-sniff.util.spec.ts +126 -0
  549. package/src/file/mimetype-sniff.util.ts +265 -0
  550. package/src/file/remote-fetch.util.spec.ts +117 -0
  551. package/src/file/remote-fetch.util.ts +330 -0
  552. package/src/impersonation/dto/start-impersonation.dto.ts +5 -2
  553. package/src/impersonation/impersonation.service.spec.ts +24 -1
  554. package/src/impersonation/impersonation.service.ts +14 -4
  555. package/src/incident/incident.controller.ts +9 -1
  556. package/src/incident/incident.service.ts +7 -0
  557. package/src/index.ts +17 -0
  558. package/src/integration-profile/integration-profile.secrets.ts +7 -0
  559. package/src/integration-profile/integration-profile.service.ts +7 -64
  560. package/src/integration-profile/integration-profile.utils.spec.ts +9 -0
  561. package/src/integration-profile/integration-profile.utils.ts +5 -5
  562. package/src/integration-profile/testers/index.ts +2 -0
  563. package/src/integration-profile/testers/remaining.testers.spec.ts +79 -0
  564. package/src/integration-profile/testers/shipping.testers.ts +94 -0
  565. package/src/mail/dto/send.dto.ts +6 -1
  566. package/src/mail/mail-template.spec.ts +58 -1
  567. package/src/mail/mail.service.spec.ts +112 -0
  568. package/src/mail/mail.service.ts +42 -4
  569. package/src/mail-sent/mail-sent.service.ts +3 -0
  570. package/src/mail-sent/mail-sent.sort.ts +19 -0
  571. package/src/mcp/filters/mcp-challenge.filter.spec.ts +76 -0
  572. package/src/mcp/filters/mcp-challenge.filter.ts +70 -0
  573. package/src/mcp/guards/mcp-auth.guard.spec.ts +51 -2
  574. package/src/mcp/guards/mcp-auth.guard.ts +24 -1
  575. package/src/mcp/guards/mcp-permission.guard.spec.ts +109 -15
  576. package/src/mcp/guards/mcp-permission.guard.ts +76 -51
  577. package/src/mcp/mcp-audit.service.spec.ts +107 -0
  578. package/src/mcp/mcp-audit.service.ts +37 -1
  579. package/src/mcp/mcp-permission.service.spec.ts +197 -0
  580. package/src/mcp/mcp-permission.service.ts +184 -0
  581. package/src/mcp/mcp-server.service.spec.ts +84 -2
  582. package/src/mcp/mcp-server.service.ts +111 -87
  583. package/src/mcp/mcp.controller.ts +8 -1
  584. package/src/mcp/mcp.module.ts +5 -1
  585. package/src/mcp/tools/core-ai.mcp-tools.ts +1 -1
  586. package/src/mcp/tools/core-dashboard-items.mcp-tools.ts +1 -1
  587. package/src/mcp/tools/core-dashboard.mcp-tools.ts +1 -1
  588. package/src/mcp/tools/core-event-webhooks.mcp-tools.ts +1 -2
  589. package/src/mcp/tools/core-files.mcp-tools.ts +202 -22
  590. package/src/mcp/tools/core-integration-events.mcp-tools.ts +1 -1
  591. package/src/mcp/tools/core-mail-sent.mcp-tools.ts +1 -1
  592. package/src/mcp/tools/core-mail.mcp-tools.ts +1 -1
  593. package/src/mcp/tools/core-menus.mcp-tools.ts +1 -2
  594. package/src/mcp/tools/core-notifications.mcp-tools.ts +0 -1
  595. package/src/mcp/tools/core-roles.mcp-tools.ts +1 -5
  596. package/src/mcp/tools/core-routes.mcp-tools.ts +1 -3
  597. package/src/mcp/tools/core-screens.mcp-tools.ts +1 -3
  598. package/src/mcp/tools/core-sessions.mcp-tools.ts +0 -2
  599. package/src/mcp/tools/core-settings.mcp-tools.ts +1 -2
  600. package/src/mcp/tools/core-users.mcp-tools.ts +1 -1
  601. package/src/mcp/tools/core-webhooks.mcp-tools.ts +1 -2
  602. package/src/mcp/types/mcp-context.type.ts +15 -6
  603. package/src/mcp-chat/mcp-chat.service.ts +8 -0
  604. package/src/meeting/meeting-provider.registry.ts +121 -0
  605. package/src/meeting/meeting.constants.ts +74 -0
  606. package/src/menu/menu.service.spec.ts +89 -0
  607. package/src/menu/menu.service.ts +29 -11
  608. package/src/message-template/dto/update-message-template.dto.ts +22 -0
  609. package/src/message-template/message-template-admin.service.spec.ts +163 -0
  610. package/src/message-template/message-template-admin.service.ts +239 -0
  611. package/src/message-template/message-template.controller.ts +52 -0
  612. package/src/message-template/message-template.module.ts +21 -0
  613. package/src/message-template/message-template.registry.spec.ts +62 -0
  614. package/src/message-template/message-template.registry.ts +125 -0
  615. package/src/message-template/message-template.service.spec.ts +149 -0
  616. package/src/message-template/message-template.service.ts +149 -0
  617. package/src/notification/notification.constants.ts +10 -0
  618. package/src/notification/notification.module.ts +3 -0
  619. package/src/notification/notification.service.spec.ts +75 -1
  620. package/src/notification/notification.service.ts +39 -1
  621. package/src/oauth/oauth.controller.ts +0 -1
  622. package/src/oauth/oauth.errors.ts +7 -0
  623. package/src/oauth/oauth.module.ts +6 -1
  624. package/src/oauth/oauth.service.spec.ts +58 -7
  625. package/src/oauth/oauth.service.ts +71 -32
  626. package/src/oauth/providers/abstract.provider.spec.ts +192 -0
  627. package/src/oauth/providers/abstract.provider.ts +46 -14
  628. package/src/oauth/providers/github.provider.ts +57 -34
  629. package/src/oauth/providers/microsoft-entra-id.provider.ts +8 -1
  630. package/src/observability/monitored-cron.spec.ts +164 -31
  631. package/src/observability/monitored-cron.ts +154 -62
  632. package/src/profile/dto/change-password.dto.ts +25 -7
  633. package/src/profile/profile.service.spec.ts +97 -0
  634. package/src/profile/profile.service.ts +9 -3
  635. package/src/realtime/realtime-tick.coalescer.spec.ts +92 -0
  636. package/src/realtime/realtime-tick.coalescer.ts +60 -0
  637. package/src/realtime/realtime.service.spec.ts +33 -0
  638. package/src/realtime/realtime.service.ts +28 -2
  639. package/src/redis/redis-kv.service.ts +261 -0
  640. package/src/redis/redis-master.spec.ts +111 -0
  641. package/src/redis/redis-master.ts +86 -0
  642. package/src/redis/redis-pubsub.ts +27 -3
  643. package/src/redis/redis.module.ts +17 -0
  644. package/src/session/session.service.spec.ts +121 -42
  645. package/src/session/session.service.ts +279 -82
  646. package/src/setting/setting.service.ts +44 -3
  647. package/src/task/task.service.spec.ts +41 -0
  648. package/src/task/task.service.ts +53 -13
  649. package/src/token/token.service.spec.ts +90 -0
  650. package/src/token/token.service.ts +48 -2
  651. package/src/user/user-credential.util.ts +14 -5
  652. package/src/user/user.service.ts +2 -12
  653. package/src/user/user.sort.ts +25 -0
  654. package/src/utils/abbreviate-name.spec.ts +50 -0
  655. package/src/utils/abbreviate-name.ts +44 -0
  656. package/src/utils/date-range-query.dto.ts +56 -0
  657. package/src/utils/date-range.spec.ts +175 -0
  658. package/src/utils/date-range.ts +246 -0
  659. package/src/webhook-integration/webhook-utils.spec.ts +67 -0
  660. package/src/webhook-integration/webhook-utils.ts +26 -0
  661. package/src/whatsapp-sender/whatsapp-recipients.spec.ts +89 -0
  662. package/src/whatsapp-sender/whatsapp-recipients.ts +83 -0
  663. package/src/whatsapp-sender/whatsapp-sender.service.spec.ts +112 -0
  664. package/src/whatsapp-sender/whatsapp-sender.service.ts +58 -5
@@ -5,6 +5,7 @@ import {
5
5
  Page,
6
6
  PageHeader,
7
7
  PaginationFooter,
8
+ SortableTableHead,
8
9
  } from '@/components/entity-list';
9
10
  import { Badge } from '@/components/ui/badge';
10
11
  import { Button } from '@/components/ui/button';
@@ -32,6 +33,7 @@ import {
32
33
  } from '@/components/ui/tooltip';
33
34
  import { useDebounce } from '@/hooks/use-debounce';
34
35
  import { usePersistedPageSize } from '@/hooks/use-persisted-page-size';
36
+ import { useTableSort, type SortableColumn } from '@/hooks/use-table-sort';
35
37
  import { formatDateTime } from '@/lib/format-date';
36
38
  import { useApp, useQuery } from '@hed-hog/next-app-provider';
37
39
  import { Pencil, ShieldAlert, Sparkles } from 'lucide-react';
@@ -51,6 +53,25 @@ import {
51
53
  const DEFAULT_PAGE_SIZES = [6, 12, 24, 48, 96] as const;
52
54
  const ALL = 'all';
53
55
 
56
+ type AiInstructionSortField =
57
+ | 'slug'
58
+ | 'name'
59
+ | 'layer'
60
+ | 'module_slug'
61
+ | 'version'
62
+ | 'updated_at';
63
+
64
+ const SORT_COLUMNS: readonly SortableColumn<AiInstructionSortField>[] = [
65
+ 'slug',
66
+ 'name',
67
+ 'layer',
68
+ 'module_slug',
69
+ 'version',
70
+ { field: 'updated_at', initialOrder: 'desc' },
71
+ ];
72
+
73
+ const DEFAULT_SORT = { field: 'layer', order: 'asc' } as const;
74
+
54
75
  export default function AiInstructionPage() {
55
76
  const { request, currentLocaleCode, getSettingValue } = useApp();
56
77
  const t = useTranslations('core.AiInstructionPage');
@@ -122,6 +143,11 @@ export default function AiInstructionPage() {
122
143
  });
123
144
  const [searchQuery, setSearchQuery] = useState('');
124
145
  const debouncedSearch = useDebounce(searchQuery, 400);
146
+ const sort = useTableSort<AiInstructionSortField>({
147
+ columns: SORT_COLUMNS,
148
+ defaultSort: DEFAULT_SORT,
149
+ onSortChange: () => setPage(1),
150
+ });
125
151
 
126
152
  const [editing, setEditing] = useState<AiInstruction | null>(null);
127
153
 
@@ -159,7 +185,9 @@ export default function AiInstructionPage() {
159
185
  return map;
160
186
  }, [registry]);
161
187
 
162
- const { data, isLoading, refetch } = useQuery<PaginatedResponse<AiInstruction>>({
188
+ const { data, isLoading, refetch } = useQuery<
189
+ PaginatedResponse<AiInstruction>
190
+ >({
163
191
  queryKey: [
164
192
  'ai-instructions',
165
193
  page,
@@ -168,15 +196,20 @@ export default function AiInstructionPage() {
168
196
  layerFilter,
169
197
  moduleFilter,
170
198
  statusFilter,
199
+ sort.sortField,
200
+ sort.sortOrder,
171
201
  ],
172
202
  queryFn: async () => {
173
203
  const params = new URLSearchParams();
174
204
  params.set('page', String(page));
175
205
  params.set('pageSize', String(pageSize));
206
+ params.set('sortField', sort.sortField);
207
+ params.set('sortOrder', sort.sortOrder);
176
208
  if (debouncedSearch) params.set('search', debouncedSearch);
177
209
  if (layerFilter !== ALL) params.set('layer', layerFilter);
178
210
  if (moduleFilter !== ALL) params.set('module_slug', moduleFilter);
179
- if (statusFilter !== ALL) params.set('is_active', String(statusFilter === 'active'));
211
+ if (statusFilter !== ALL)
212
+ params.set('is_active', String(statusFilter === 'active'));
180
213
 
181
214
  const response = await request<PaginatedResponse<AiInstruction>>({
182
215
  url: `/ai-instruction?${params.toString()}`,
@@ -205,7 +238,9 @@ export default function AiInstructionPage() {
205
238
  <div className="flex flex-wrap items-center gap-1">
206
239
  {entry ? (
207
240
  <Badge variant={entry.db_matches_fallback ? 'outline' : 'secondary'}>
208
- {entry.db_matches_fallback ? t('badgeDefault') : t('badgeCustomized')}
241
+ {entry.db_matches_fallback
242
+ ? t('badgeDefault')
243
+ : t('badgeCustomized')}
209
244
  </Badge>
210
245
  ) : null}
211
246
  {instruction.is_locked ? (
@@ -289,14 +324,33 @@ export default function AiInstructionPage() {
289
324
  <Table>
290
325
  <TableHeader>
291
326
  <TableRow>
292
- <TableHead>Slug</TableHead>
293
- <TableHead>{t('columnName')}</TableHead>
294
- <TableHead>{t('columnLayer')}</TableHead>
295
- <TableHead>{t('columnModule')}</TableHead>
327
+ <SortableTableHead
328
+ label="Slug"
329
+ {...sort.getSortProps('slug')}
330
+ />
331
+ <SortableTableHead
332
+ label={t('columnName')}
333
+ {...sort.getSortProps('name')}
334
+ />
335
+ <SortableTableHead
336
+ label={t('columnLayer')}
337
+ {...sort.getSortProps('layer')}
338
+ />
339
+ <SortableTableHead
340
+ label={t('columnModule')}
341
+ {...sort.getSortProps('module_slug')}
342
+ />
296
343
  <TableHead>{t('columnParams')}</TableHead>
297
344
  <TableHead>{t('columnState')}</TableHead>
298
- <TableHead className="text-right">v</TableHead>
299
- <TableHead>{t('columnUpdatedAt')}</TableHead>
345
+ <SortableTableHead
346
+ align="right"
347
+ label="v"
348
+ {...sort.getSortProps('version')}
349
+ />
350
+ <SortableTableHead
351
+ label={t('columnUpdatedAt')}
352
+ {...sort.getSortProps('updated_at')}
353
+ />
300
354
  <TableHead className="w-12" />
301
355
  </TableRow>
302
356
  </TableHeader>
@@ -315,12 +369,16 @@ export default function AiInstructionPage() {
315
369
  <TableCell className="max-w-72 font-mono text-xs">
316
370
  <Tooltip>
317
371
  <TooltipTrigger asChild>
318
- <span className="block truncate">{instruction.slug}</span>
372
+ <span className="block truncate">
373
+ {instruction.slug}
374
+ </span>
319
375
  </TooltipTrigger>
320
376
  <TooltipContent>{instruction.slug}</TooltipContent>
321
377
  </Tooltip>
322
378
  </TableCell>
323
- <TableCell className="max-w-60 truncate">{instruction.name}</TableCell>
379
+ <TableCell className="max-w-60 truncate">
380
+ {instruction.name}
381
+ </TableCell>
324
382
  <TableCell>
325
383
  <Badge variant="outline">
326
384
  {t(`layer_${instruction.layer}` as never)}
@@ -328,7 +386,9 @@ export default function AiInstructionPage() {
328
386
  </TableCell>
329
387
  <TableCell>
330
388
  {instruction.module_slug ? (
331
- <Badge variant="secondary">{instruction.module_slug}</Badge>
389
+ <Badge variant="secondary">
390
+ {instruction.module_slug}
391
+ </Badge>
332
392
  ) : (
333
393
  '—'
334
394
  )}
@@ -351,7 +411,7 @@ export default function AiInstructionPage() {
351
411
  <Button
352
412
  variant="outline"
353
413
  size="icon"
354
- title={t('edit')}
414
+ tooltip={t('edit')}
355
415
  onClick={(event) => {
356
416
  event.stopPropagation();
357
417
  setEditing(instruction);
@@ -387,7 +447,10 @@ export default function AiInstructionPage() {
387
447
  pageSizeOptions={pageSizeOptions}
388
448
  />
389
449
 
390
- <Sheet open={Boolean(editing)} onOpenChange={(open) => !open && setEditing(null)}>
450
+ <Sheet
451
+ open={Boolean(editing)}
452
+ onOpenChange={(open) => !open && setEditing(null)}
453
+ >
391
454
  <ResizableSheetContent
392
455
  sheetId="core-ai-instruction-form-sheet"
393
456
  defaultWidth={900}
@@ -398,7 +461,9 @@ export default function AiInstructionPage() {
398
461
  >
399
462
  <SheetHeader>
400
463
  <SheetTitle>{editing?.name}</SheetTitle>
401
- <SheetDescription className="font-mono text-xs">{editing?.slug}</SheetDescription>
464
+ <SheetDescription className="font-mono text-xs">
465
+ {editing?.slug}
466
+ </SheetDescription>
402
467
  </SheetHeader>
403
468
 
404
469
  <div className="px-4 pb-6">
@@ -0,0 +1,166 @@
1
+ 'use client';
2
+
3
+ import { Button } from '@/components/ui/button';
4
+ import { useApp } from '@hed-hog/next-app-provider';
5
+ import { ImageDown, Loader, RefreshCw } from 'lucide-react';
6
+ import { useTranslations } from 'next-intl';
7
+ import Link from 'next/link';
8
+ import { useCallback, useEffect, useState } from 'react';
9
+ import { toast } from 'sonner';
10
+ import { ByteSizeInput } from './byte-size-input';
11
+
12
+ /**
13
+ * Mesmo default do backend (`DEFAULT_IMAGE_OPTIMIZE_MIN_SIZE`): a primeira onda mira nos
14
+ * arquivos grandes, que concentram o peso do acervo.
15
+ */
16
+ const DEFAULT_MIN_SIZE = 300 * 1024;
17
+
18
+ type OptimizeImagesResponse = {
19
+ dryRun: boolean;
20
+ minSize: number;
21
+ total: number;
22
+ totalBytes: number;
23
+ queued: number;
24
+ remaining?: number;
25
+ };
26
+
27
+ function formatBytes(bytes: number): string {
28
+ if (!Number.isFinite(bytes) || bytes <= 0) return '0 B';
29
+ const units = ['B', 'KB', 'MB', 'GB', 'TB'];
30
+ const exponent = Math.min(
31
+ units.length - 1,
32
+ Math.floor(Math.log(bytes) / Math.log(1024)),
33
+ );
34
+ const value = bytes / 1024 ** exponent;
35
+ return `${value >= 100 || exponent === 0 ? Math.round(value) : value.toFixed(1)} ${units[exponent]}`;
36
+ }
37
+
38
+ /**
39
+ * Ação de manutenção do subgrupo `image-optimization`: reaplica as settings desta mesma
40
+ * tela às imagens que já estão no storage.
41
+ *
42
+ * As settings acima só valem para uploads novos — quem subiu antes continua com o
43
+ * arquivo original. A prévia (dry-run) vem antes do botão de propósito: o acervo passa de
44
+ * meio milhão de arquivos, e enfileirar sem saber o tamanho da onda é o que se quer
45
+ * evitar.
46
+ */
47
+ export function ImageOptimizationAction() {
48
+ const t = useTranslations('core.Configurations.imageOptimization');
49
+ const { request } = useApp();
50
+
51
+ const [minSize, setMinSize] = useState(DEFAULT_MIN_SIZE);
52
+ const [preview, setPreview] = useState<OptimizeImagesResponse | null>(null);
53
+ const [isLoadingPreview, setIsLoadingPreview] = useState(false);
54
+ const [isQueueing, setIsQueueing] = useState(false);
55
+
56
+ const loadPreview = useCallback(
57
+ async (size: number) => {
58
+ setIsLoadingPreview(true);
59
+ try {
60
+ const response = await request<OptimizeImagesResponse>({
61
+ url: '/queue/jobs/optimize-images',
62
+ method: 'POST',
63
+ data: { minSize: size, dryRun: true },
64
+ });
65
+ setPreview(response.data);
66
+ } catch {
67
+ setPreview(null);
68
+ } finally {
69
+ setIsLoadingPreview(false);
70
+ }
71
+ },
72
+ [request],
73
+ );
74
+
75
+ useEffect(() => {
76
+ void loadPreview(DEFAULT_MIN_SIZE);
77
+ }, [loadPreview]);
78
+
79
+ const handleQueue = async () => {
80
+ setIsQueueing(true);
81
+ try {
82
+ const response = await request<OptimizeImagesResponse>({
83
+ url: '/queue/jobs/optimize-images',
84
+ method: 'POST',
85
+ data: { minSize },
86
+ });
87
+ const { queued, remaining } = response.data;
88
+
89
+ toast.success(t('queuedSuccess', { count: queued }), {
90
+ description: remaining ? t('queuedRemaining', { count: remaining }) : undefined,
91
+ });
92
+
93
+ await loadPreview(minSize);
94
+ } catch {
95
+ toast.error(t('queueFailed'));
96
+ } finally {
97
+ setIsQueueing(false);
98
+ }
99
+ };
100
+
101
+ const hasCandidates = (preview?.total ?? 0) > 0;
102
+
103
+ return (
104
+ <div className="flex min-w-0 flex-col gap-3 border-t border-border pt-4 md:flex-row md:items-center md:justify-between md:gap-4">
105
+ <div className="min-w-0 flex-1">
106
+ <label className="block font-semibold">{t('title')}</label>
107
+ <p className="text-muted-foreground text-sm wrap-break-word">
108
+ {t('description')}
109
+ </p>
110
+ <p className="mt-1 text-sm">
111
+ {isLoadingPreview ? (
112
+ <span className="text-muted-foreground inline-flex items-center gap-2">
113
+ <Loader className="h-3 w-3 animate-spin" />
114
+ {t('previewLoading')}
115
+ </span>
116
+ ) : preview ? (
117
+ <span className="font-medium">
118
+ {t('preview', {
119
+ count: preview.total,
120
+ size: formatBytes(preview.totalBytes),
121
+ })}
122
+ </span>
123
+ ) : (
124
+ <span className="text-muted-foreground">{t('previewFailed')}</span>
125
+ )}
126
+ </p>
127
+ <p className="text-muted-foreground mt-1 text-xs">
128
+ {t.rich('queueHint', {
129
+ link: (chunks) => (
130
+ <Link href="/queue/jobs" className="underline">
131
+ {chunks}
132
+ </Link>
133
+ ),
134
+ })}
135
+ </p>
136
+ </div>
137
+
138
+ <div className="flex w-full min-w-0 flex-col items-stretch gap-2 md:w-auto md:flex-row md:items-center md:justify-end">
139
+ <ByteSizeInput
140
+ value={minSize}
141
+ onChange={setMinSize}
142
+ persistKey="image-optimize-min-size"
143
+ disabled={isQueueing}
144
+ />
145
+ <Button
146
+ type="button"
147
+ variant="outline"
148
+ onClick={() => void loadPreview(minSize)}
149
+ disabled={isLoadingPreview || isQueueing}
150
+ title={t('refresh')}
151
+ >
152
+ <RefreshCw className={isLoadingPreview ? 'animate-spin' : undefined} />
153
+ <span className="md:sr-only">{t('refresh')}</span>
154
+ </Button>
155
+ <Button
156
+ type="button"
157
+ onClick={handleQueue}
158
+ disabled={isQueueing || isLoadingPreview || !hasCandidates}
159
+ >
160
+ {isQueueing ? <Loader className="animate-spin" /> : <ImageDown />}
161
+ {t('queueAction')}
162
+ </Button>
163
+ </div>
164
+ </div>
165
+ );
166
+ }
@@ -1,14 +1,15 @@
1
1
  import '@testing-library/jest-dom/vitest';
2
2
  import { fireEvent, render, screen, waitFor } from '@testing-library/react';
3
3
  import { beforeEach, describe, expect, it, vi } from 'vitest';
4
- import type { Setting } from '@hed-hog/api-types';
4
+ import type { Setting, SettingEntityFilter } from '@hed-hog/api-types';
5
5
  import { SettingField } from './setting-field';
6
6
 
7
7
  /**
8
- * O que estes testes protegem é o registry `INTEGRATION_PROFILE_SETTINGS`: qual
9
- * setting vira picker e com que filtro. O `EntityPicker` de verdade tem teste
10
- * próprio, então aqui ele é um stub que dispara `loadOptions` e renderiza cada
11
- * resultado como um botão.
8
+ * O que estes testes protegem é a leitura de `setting.entity_filter`: como o
9
+ * filtro declarado no `setting_group.yaml` da biblioteca vira query string do
10
+ * picker, e o que acontece quando ele falta ou vem torto. O `EntityPicker` de
11
+ * verdade tem teste próprio, então aqui ele é um stub que dispara `loadOptions`
12
+ * e renderiza cada resultado como um botão.
12
13
  */
13
14
  type StubProfile = {
14
15
  id: number;
@@ -92,15 +93,43 @@ vi.mock('@hed-hog/next-app-provider', () => ({
92
93
  }),
93
94
  }));
94
95
 
96
+ /** Tipos de perfil com tradução própria em `messages/core/*.json`. */
97
+ const TRANSLATED_PROFILE_TYPES = [
98
+ 'ai',
99
+ 'email',
100
+ 'whatsapp',
101
+ 'storage',
102
+ 'oauth',
103
+ 'payment',
104
+ 'infrastructure',
105
+ 'shipping',
106
+ 'captcha',
107
+ 'video',
108
+ 'fiscal',
109
+ 'generic',
110
+ ];
111
+
95
112
  vi.mock('next-intl', () => ({
96
113
  useTranslations: () => {
97
- const t = (key: string) => key;
98
- t.has = () => false;
114
+ // Devolve a própria chave (com os parâmetros, quando houver) para o teste
115
+ // afirmar qual chave o componente escolheu. `t.has` responde como o
116
+ // next-intl responderia com os arquivos de mensagem reais, porque a escolha
117
+ // entre a chave do tipo e a genérica passa exatamente por ele.
118
+ const t = (key: string, values?: Record<string, unknown>) =>
119
+ values ? `${key}:${JSON.stringify(values)}` : key;
120
+ t.has = (key: string) =>
121
+ TRANSLATED_PROFILE_TYPES.some((type) =>
122
+ key.startsWith(`profileTypes.${type}.`)
123
+ ) || key === 'profileProviders.kubernetes';
99
124
  return t;
100
125
  },
101
126
  }));
102
127
 
103
- function buildSetting(slug: string, value = ''): Setting {
128
+ function buildSetting(
129
+ slug: string,
130
+ entityFilter: SettingEntityFilter | string | null = null,
131
+ value = ''
132
+ ): Setting {
104
133
  return {
105
134
  id: 1,
106
135
  slug,
@@ -108,6 +137,7 @@ function buildSetting(slug: string, value = ''): Setting {
108
137
  component: 'entity-picker',
109
138
  value,
110
139
  user_override: false,
140
+ entity_filter: entityFilter,
111
141
  } as unknown as Setting;
112
142
  }
113
143
 
@@ -133,57 +163,52 @@ beforeEach(() => {
133
163
  });
134
164
 
135
165
  describe('SettingField / settings de perfil de integração', () => {
136
- it('renderiza picker de IA para sac.ai.integration-profile-id', async () => {
166
+ it('usa o typeSlug declarado na setting e a tradução do tipo', async () => {
137
167
  render(
138
- <SettingField setting={buildSetting('sac.ai.integration-profile-id')} />
168
+ <SettingField
169
+ setting={buildSetting('sac.ai.integration-profile-id', {
170
+ typeSlug: 'ai',
171
+ })}
172
+ />
139
173
  );
140
174
 
141
175
  expect(screen.getByTestId('picker-placeholder')).toHaveTextContent(
142
- 'selectAiProfile'
176
+ 'profileTypes.ai.placeholder'
143
177
  );
144
178
  await waitFor(() => expect(lastProfileQuery()?.get('typeSlug')).toBe('ai'));
145
179
  });
146
180
 
147
- it('filtra por whatsapp no aviso de aprovação por WhatsApp', async () => {
148
- render(
149
- <SettingField
150
- setting={buildSetting(
151
- 'operations.approval-notifications.whatsapp-integration-profile-id'
152
- )}
153
- />
154
- );
181
+ it.each([
182
+ ['operations.approval-notifications.whatsapp-integration-profile-id', 'whatsapp'],
183
+ ['operations.approval-notifications.email-integration-profile-id', 'email'],
184
+ ['lms-digest-notify-email-profile-id', 'email'],
185
+ ['lms-digest-notify-whatsapp-profile-id', 'whatsapp'],
186
+ ['lms-celebration-notify-email-profile-id', 'email'],
187
+ ['lms-celebration-notify-whatsapp-profile-id', 'whatsapp'],
188
+ ['lms-class-reminder-notify-email-profile-id', 'email'],
189
+ ['lms-class-reminder-notify-whatsapp-profile-id', 'whatsapp'],
190
+ ])('filtra %s pelo tipo %s', async (slug, typeSlug) => {
191
+ render(<SettingField setting={buildSetting(slug, { typeSlug })} />);
155
192
 
156
193
  await waitFor(() =>
157
- expect(lastProfileQuery()?.get('typeSlug')).toBe('whatsapp')
194
+ expect(lastProfileQuery()?.get('typeSlug')).toBe(typeSlug)
158
195
  );
159
196
  });
160
197
 
161
- it('filtra por e-mail no aviso de aprovação por e-mail', async () => {
198
+ it('filtra o campo de frete por transportadora, e não por qualquer perfil', async () => {
162
199
  render(
163
200
  <SettingField
164
- setting={buildSetting(
165
- 'operations.approval-notifications.email-integration-profile-id'
166
- )}
201
+ setting={buildSetting('commerce-shipping-profile-id', {
202
+ typeSlug: 'shipping',
203
+ })}
167
204
  />
168
205
  );
169
206
 
170
- await waitFor(() =>
171
- expect(lastProfileQuery()?.get('typeSlug')).toBe('email')
207
+ expect(screen.getByTestId('picker-placeholder')).toHaveTextContent(
208
+ 'profileTypes.shipping.placeholder'
172
209
  );
173
- });
174
-
175
- it.each([
176
- ['lms-digest-notify-email-profile-id', 'email'],
177
- ['lms-digest-notify-whatsapp-profile-id', 'whatsapp'],
178
- ['lms-celebration-notify-email-profile-id', 'email'],
179
- ['lms-celebration-notify-whatsapp-profile-id', 'whatsapp'],
180
- ['lms-class-reminder-notify-email-profile-id', 'email'],
181
- ['lms-class-reminder-notify-whatsapp-profile-id', 'whatsapp'],
182
- ])('filtra %s pelo canal %s', async (slug, typeSlug) => {
183
- render(<SettingField setting={buildSetting(slug)} />);
184
-
185
210
  await waitFor(() =>
186
- expect(lastProfileQuery()?.get('typeSlug')).toBe(typeSlug)
211
+ expect(lastProfileQuery()?.get('typeSlug')).toBe('shipping')
187
212
  );
188
213
  });
189
214
 
@@ -204,7 +229,12 @@ describe('SettingField / settings de perfil de integração', () => {
204
229
  ]);
205
230
 
206
231
  render(
207
- <SettingField setting={buildSetting('mail-integration-profile-id')} />
232
+ <SettingField
233
+ setting={buildSetting('mail-integration-profile-id', {
234
+ typeSlug: 'email',
235
+ excludeProviders: ['imap'],
236
+ })}
237
+ />
208
238
  );
209
239
 
210
240
  await waitFor(() =>
@@ -214,7 +244,14 @@ describe('SettingField / settings de perfil de integração', () => {
214
244
  });
215
245
 
216
246
  it('estreita o picker de OAuth pelo provider', async () => {
217
- render(<SettingField setting={buildSetting('oauth-google-profile-id')} />);
247
+ render(
248
+ <SettingField
249
+ setting={buildSetting('oauth-google-profile-id', {
250
+ typeSlug: 'oauth',
251
+ providerSlug: 'google-oauth',
252
+ })}
253
+ />
254
+ );
218
255
 
219
256
  await waitFor(() => {
220
257
  const query = lastProfileQuery();
@@ -241,7 +278,10 @@ describe('SettingField / settings de perfil de integração', () => {
241
278
 
242
279
  render(
243
280
  <SettingField
244
- setting={buildSetting('commerce-default-payment-profile-id')}
281
+ setting={buildSetting('commerce-default-payment-profile-id', {
282
+ typeSlug: 'payment',
283
+ excludeProviders: ['google_play'],
284
+ })}
245
285
  />
246
286
  );
247
287
 
@@ -251,11 +291,67 @@ describe('SettingField / settings de perfil de integração', () => {
251
291
  expect(screen.queryByTestId('option-play-prod')).not.toBeInTheDocument();
252
292
  });
253
293
 
254
- it('lista perfis de todos os tipos quando o slug não está mapeado', async () => {
294
+ it('nomeia os botões pelo provider quando ele tem nome próprio', async () => {
295
+ render(
296
+ <SettingField
297
+ setting={buildSetting('hedhog.k8s_integration_profile_id', {
298
+ typeSlug: 'infrastructure',
299
+ providerSlug: 'kubernetes',
300
+ })}
301
+ />
302
+ );
303
+
304
+ await waitFor(() =>
305
+ expect(
306
+ // O rotulo vem da prop `tooltip` do Button, que tambem gera o aria-label.
307
+ screen.getByRole('button', {
308
+ name: 'createProfileAria:{"profile":"profileProviders.kubernetes"}',
309
+ })
310
+ ).toBeInTheDocument()
311
+ );
312
+ });
313
+
314
+ it('aceita o filtro como string JSON, para coluna de texto', async () => {
315
+ render(
316
+ <SettingField
317
+ setting={buildSetting(
318
+ 'commerce-shipping-profile-id',
319
+ '{"typeSlug":"shipping"}'
320
+ )}
321
+ />
322
+ );
323
+
324
+ await waitFor(() =>
325
+ expect(lastProfileQuery()?.get('typeSlug')).toBe('shipping')
326
+ );
327
+ });
328
+
329
+ it.each([
330
+ ['string quebrada', '{'],
331
+ ['array', [] as unknown as SettingEntityFilter],
332
+ ['typeSlug que não é texto', { typeSlug: 42 } as unknown as SettingEntityFilter],
333
+ ])(
334
+ 'cai na rede de segurança com filtro inválido (%s), sem quebrar a tela',
335
+ async (_caso, filtroInvalido) => {
336
+ render(
337
+ <SettingField
338
+ setting={buildSetting('commerce-shipping-profile-id', filtroInvalido)}
339
+ />
340
+ );
341
+
342
+ expect(screen.getByTestId('picker-placeholder')).toHaveTextContent(
343
+ 'profileTypes.generic.placeholder'
344
+ );
345
+ await waitFor(() => expect(lastProfileQuery()).not.toBeNull());
346
+ expect(lastProfileQuery()?.get('typeSlug')).toBeNull();
347
+ }
348
+ );
349
+
350
+ it('lista perfis de todos os tipos quando a setting não tem entity_filter', async () => {
255
351
  render(<SettingField setting={buildSetting('nova-lib-ai-profile-id')} />);
256
352
 
257
353
  expect(screen.getByTestId('picker-placeholder')).toHaveTextContent(
258
- 'selectIntegrationProfile'
354
+ 'profileTypes.generic.placeholder'
259
355
  );
260
356
  await waitFor(() => expect(lastProfileQuery()).not.toBeNull());
261
357
  expect(lastProfileQuery()?.get('typeSlug')).toBeNull();
@@ -282,7 +378,11 @@ describe('SettingField / settings de perfil de integração', () => {
282
378
  ]);
283
379
 
284
380
  render(
285
- <SettingField setting={buildSetting('sac.ai.integration-profile-id')} />
381
+ <SettingField
382
+ setting={buildSetting('sac.ai.integration-profile-id', {
383
+ typeSlug: 'ai',
384
+ })}
385
+ />
286
386
  );
287
387
 
288
388
  await waitFor(() =>