@open-mercato/core 0.4.8-develop-6b37dabfa2 → 0.4.8-develop-84f3678a58

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 (330) hide show
  1. package/agentic/standalone-guide.md +235 -0
  2. package/dist/generated/entities/customer_role/index.js +27 -0
  3. package/dist/generated/entities/customer_role/index.js.map +7 -0
  4. package/dist/generated/entities/customer_role_acl/index.js +19 -0
  5. package/dist/generated/entities/customer_role_acl/index.js.map +7 -0
  6. package/dist/generated/entities/customer_user/index.js +37 -0
  7. package/dist/generated/entities/customer_user/index.js.map +7 -0
  8. package/dist/generated/entities/customer_user_acl/index.js +19 -0
  9. package/dist/generated/entities/customer_user_acl/index.js.map +7 -0
  10. package/dist/generated/entities/customer_user_email_verification/index.js +17 -0
  11. package/dist/generated/entities/customer_user_email_verification/index.js.map +7 -0
  12. package/dist/generated/entities/customer_user_invitation/index.js +33 -0
  13. package/dist/generated/entities/customer_user_invitation/index.js.map +7 -0
  14. package/dist/generated/entities/customer_user_password_reset/index.js +15 -0
  15. package/dist/generated/entities/customer_user_password_reset/index.js.map +7 -0
  16. package/dist/generated/entities/customer_user_role/index.js +13 -0
  17. package/dist/generated/entities/customer_user_role/index.js.map +7 -0
  18. package/dist/generated/entities/customer_user_session/index.js +21 -0
  19. package/dist/generated/entities/customer_user_session/index.js.map +7 -0
  20. package/dist/generated/entities/organization/index.js +2 -0
  21. package/dist/generated/entities/organization/index.js.map +2 -2
  22. package/dist/generated/entities.ids.generated.js +14 -1
  23. package/dist/generated/entities.ids.generated.js.map +2 -2
  24. package/dist/generated/entity-fields-registry.js +18 -0
  25. package/dist/generated/entity-fields-registry.js.map +2 -2
  26. package/dist/modules/auth/services/rbacService.js +3 -9
  27. package/dist/modules/auth/services/rbacService.js.map +2 -2
  28. package/dist/modules/customer_accounts/acl.js +12 -0
  29. package/dist/modules/customer_accounts/acl.js.map +7 -0
  30. package/dist/modules/customer_accounts/api/admin/roles/[id]/acl.js +87 -0
  31. package/dist/modules/customer_accounts/api/admin/roles/[id]/acl.js.map +7 -0
  32. package/dist/modules/customer_accounts/api/admin/roles/[id].js +216 -0
  33. package/dist/modules/customer_accounts/api/admin/roles/[id].js.map +7 -0
  34. package/dist/modules/customer_accounts/api/admin/roles.js +189 -0
  35. package/dist/modules/customer_accounts/api/admin/roles.js.map +7 -0
  36. package/dist/modules/customer_accounts/api/admin/users/[id]/reset-password.js +69 -0
  37. package/dist/modules/customer_accounts/api/admin/users/[id]/reset-password.js.map +7 -0
  38. package/dist/modules/customer_accounts/api/admin/users/[id]/verify-email.js +64 -0
  39. package/dist/modules/customer_accounts/api/admin/users/[id]/verify-email.js.map +7 -0
  40. package/dist/modules/customer_accounts/api/admin/users/[id].js +253 -0
  41. package/dist/modules/customer_accounts/api/admin/users/[id].js.map +7 -0
  42. package/dist/modules/customer_accounts/api/admin/users-invite.js +78 -0
  43. package/dist/modules/customer_accounts/api/admin/users-invite.js.map +7 -0
  44. package/dist/modules/customer_accounts/api/admin/users.js +251 -0
  45. package/dist/modules/customer_accounts/api/admin/users.js.map +7 -0
  46. package/dist/modules/customer_accounts/api/email/verify.js +59 -0
  47. package/dist/modules/customer_accounts/api/email/verify.js.map +7 -0
  48. package/dist/modules/customer_accounts/api/interceptors.js +5 -0
  49. package/dist/modules/customer_accounts/api/interceptors.js.map +7 -0
  50. package/dist/modules/customer_accounts/api/invitations/accept.js +114 -0
  51. package/dist/modules/customer_accounts/api/invitations/accept.js.map +7 -0
  52. package/dist/modules/customer_accounts/api/login.js +143 -0
  53. package/dist/modules/customer_accounts/api/login.js.map +7 -0
  54. package/dist/modules/customer_accounts/api/magic-link/request.js +78 -0
  55. package/dist/modules/customer_accounts/api/magic-link/request.js.map +7 -0
  56. package/dist/modules/customer_accounts/api/magic-link/verify.js +114 -0
  57. package/dist/modules/customer_accounts/api/magic-link/verify.js.map +7 -0
  58. package/dist/modules/customer_accounts/api/password/reset-confirm.js +59 -0
  59. package/dist/modules/customer_accounts/api/password/reset-confirm.js.map +7 -0
  60. package/dist/modules/customer_accounts/api/password/reset-request.js +77 -0
  61. package/dist/modules/customer_accounts/api/password/reset-request.js.map +7 -0
  62. package/dist/modules/customer_accounts/api/portal/events/stream.js +163 -0
  63. package/dist/modules/customer_accounts/api/portal/events/stream.js.map +7 -0
  64. package/dist/modules/customer_accounts/api/portal/feature-check.js +57 -0
  65. package/dist/modules/customer_accounts/api/portal/feature-check.js.map +7 -0
  66. package/dist/modules/customer_accounts/api/portal/logout.js +64 -0
  67. package/dist/modules/customer_accounts/api/portal/logout.js.map +7 -0
  68. package/dist/modules/customer_accounts/api/portal/notifications/[id]/dismiss.js +49 -0
  69. package/dist/modules/customer_accounts/api/portal/notifications/[id]/dismiss.js.map +7 -0
  70. package/dist/modules/customer_accounts/api/portal/notifications/[id]/read.js +49 -0
  71. package/dist/modules/customer_accounts/api/portal/notifications/[id]/read.js.map +7 -0
  72. package/dist/modules/customer_accounts/api/portal/notifications/mark-all-read.js +46 -0
  73. package/dist/modules/customer_accounts/api/portal/notifications/mark-all-read.js.map +7 -0
  74. package/dist/modules/customer_accounts/api/portal/notifications/unread-count.js +42 -0
  75. package/dist/modules/customer_accounts/api/portal/notifications/unread-count.js.map +7 -0
  76. package/dist/modules/customer_accounts/api/portal/notifications.js +105 -0
  77. package/dist/modules/customer_accounts/api/portal/notifications.js.map +7 -0
  78. package/dist/modules/customer_accounts/api/portal/password-change.js +57 -0
  79. package/dist/modules/customer_accounts/api/portal/password-change.js.map +7 -0
  80. package/dist/modules/customer_accounts/api/portal/profile.js +135 -0
  81. package/dist/modules/customer_accounts/api/portal/profile.js.map +7 -0
  82. package/dist/modules/customer_accounts/api/portal/sessions/[id].js +62 -0
  83. package/dist/modules/customer_accounts/api/portal/sessions/[id].js.map +7 -0
  84. package/dist/modules/customer_accounts/api/portal/sessions-refresh.js +75 -0
  85. package/dist/modules/customer_accounts/api/portal/sessions-refresh.js.map +7 -0
  86. package/dist/modules/customer_accounts/api/portal/sessions.js +77 -0
  87. package/dist/modules/customer_accounts/api/portal/sessions.js.map +7 -0
  88. package/dist/modules/customer_accounts/api/portal/users/[id]/roles.js +90 -0
  89. package/dist/modules/customer_accounts/api/portal/users/[id]/roles.js.map +7 -0
  90. package/dist/modules/customer_accounts/api/portal/users/[id].js +71 -0
  91. package/dist/modules/customer_accounts/api/portal/users/[id].js.map +7 -0
  92. package/dist/modules/customer_accounts/api/portal/users-invite.js +92 -0
  93. package/dist/modules/customer_accounts/api/portal/users-invite.js.map +7 -0
  94. package/dist/modules/customer_accounts/api/portal/users.js +79 -0
  95. package/dist/modules/customer_accounts/api/portal/users.js.map +7 -0
  96. package/dist/modules/customer_accounts/api/signup.js +121 -0
  97. package/dist/modules/customer_accounts/api/signup.js.map +7 -0
  98. package/dist/modules/customer_accounts/backend/customer_accounts/[id]/page.js +491 -0
  99. package/dist/modules/customer_accounts/backend/customer_accounts/[id]/page.js.map +7 -0
  100. package/dist/modules/customer_accounts/backend/customer_accounts/[id]/page.meta.js +15 -0
  101. package/dist/modules/customer_accounts/backend/customer_accounts/[id]/page.meta.js.map +7 -0
  102. package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js +343 -0
  103. package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js.map +7 -0
  104. package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.meta.js +16 -0
  105. package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.meta.js.map +7 -0
  106. package/dist/modules/customer_accounts/backend/customer_accounts/roles/create/page.js +180 -0
  107. package/dist/modules/customer_accounts/backend/customer_accounts/roles/create/page.js.map +7 -0
  108. package/dist/modules/customer_accounts/backend/customer_accounts/roles/create/page.meta.js +16 -0
  109. package/dist/modules/customer_accounts/backend/customer_accounts/roles/create/page.meta.js.map +7 -0
  110. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +176 -0
  111. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +7 -0
  112. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.meta.js +33 -0
  113. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.meta.js.map +7 -0
  114. package/dist/modules/customer_accounts/backend/page.js +466 -0
  115. package/dist/modules/customer_accounts/backend/page.js.map +7 -0
  116. package/dist/modules/customer_accounts/backend/page.meta.js +35 -0
  117. package/dist/modules/customer_accounts/backend/page.meta.js.map +7 -0
  118. package/dist/modules/customer_accounts/ce.js +26 -0
  119. package/dist/modules/customer_accounts/ce.js.map +7 -0
  120. package/dist/modules/customer_accounts/data/enrichers.js +85 -0
  121. package/dist/modules/customer_accounts/data/enrichers.js.map +7 -0
  122. package/dist/modules/customer_accounts/data/entities.js +377 -0
  123. package/dist/modules/customer_accounts/data/entities.js.map +7 -0
  124. package/dist/modules/customer_accounts/data/extensions.js +8 -0
  125. package/dist/modules/customer_accounts/data/extensions.js.map +7 -0
  126. package/dist/modules/customer_accounts/data/validators.js +111 -0
  127. package/dist/modules/customer_accounts/data/validators.js.map +7 -0
  128. package/dist/modules/customer_accounts/di.js +17 -0
  129. package/dist/modules/customer_accounts/di.js.map +7 -0
  130. package/dist/modules/customer_accounts/events.js +28 -0
  131. package/dist/modules/customer_accounts/events.js.map +7 -0
  132. package/dist/modules/customer_accounts/index.js +15 -0
  133. package/dist/modules/customer_accounts/index.js.map +7 -0
  134. package/dist/modules/customer_accounts/lib/customerAuth.js +71 -0
  135. package/dist/modules/customer_accounts/lib/customerAuth.js.map +7 -0
  136. package/dist/modules/customer_accounts/lib/customerAuthServer.js +29 -0
  137. package/dist/modules/customer_accounts/lib/customerAuthServer.js.map +7 -0
  138. package/dist/modules/customer_accounts/lib/rateLimiter.js +63 -0
  139. package/dist/modules/customer_accounts/lib/rateLimiter.js.map +7 -0
  140. package/dist/modules/customer_accounts/lib/tokenGenerator.js +12 -0
  141. package/dist/modules/customer_accounts/lib/tokenGenerator.js.map +7 -0
  142. package/dist/modules/customer_accounts/migrations/Migration20260313222043.js +49 -0
  143. package/dist/modules/customer_accounts/migrations/Migration20260313222043.js.map +7 -0
  144. package/dist/modules/customer_accounts/notifications.client.js +47 -0
  145. package/dist/modules/customer_accounts/notifications.client.js.map +7 -0
  146. package/dist/modules/customer_accounts/notifications.js +46 -0
  147. package/dist/modules/customer_accounts/notifications.js.map +7 -0
  148. package/dist/modules/customer_accounts/search.js +120 -0
  149. package/dist/modules/customer_accounts/search.js.map +7 -0
  150. package/dist/modules/customer_accounts/services/customerInvitationService.js +87 -0
  151. package/dist/modules/customer_accounts/services/customerInvitationService.js.map +7 -0
  152. package/dist/modules/customer_accounts/services/customerRbacService.js +109 -0
  153. package/dist/modules/customer_accounts/services/customerRbacService.js.map +7 -0
  154. package/dist/modules/customer_accounts/services/customerSessionService.js +75 -0
  155. package/dist/modules/customer_accounts/services/customerSessionService.js.map +7 -0
  156. package/dist/modules/customer_accounts/services/customerTokenService.js +91 -0
  157. package/dist/modules/customer_accounts/services/customerTokenService.js.map +7 -0
  158. package/dist/modules/customer_accounts/services/customerUserService.js +92 -0
  159. package/dist/modules/customer_accounts/services/customerUserService.js.map +7 -0
  160. package/dist/modules/customer_accounts/setup.js +179 -0
  161. package/dist/modules/customer_accounts/setup.js.map +7 -0
  162. package/dist/modules/customer_accounts/subscribers/autoLinkCrm.js +54 -0
  163. package/dist/modules/customer_accounts/subscribers/autoLinkCrm.js.map +7 -0
  164. package/dist/modules/customer_accounts/subscribers/autoLinkCrmReverse.js +68 -0
  165. package/dist/modules/customer_accounts/subscribers/autoLinkCrmReverse.js.map +7 -0
  166. package/dist/modules/customer_accounts/subscribers/notifyStaffOnSignup.js +29 -0
  167. package/dist/modules/customer_accounts/subscribers/notifyStaffOnSignup.js.map +7 -0
  168. package/dist/modules/customer_accounts/translations.js +9 -0
  169. package/dist/modules/customer_accounts/translations.js.map +7 -0
  170. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js +63 -0
  171. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js.map +7 -0
  172. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.js +17 -0
  173. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.js.map +7 -0
  174. package/dist/modules/customer_accounts/widgets/injection/company-users/widget.client.js +55 -0
  175. package/dist/modules/customer_accounts/widgets/injection/company-users/widget.client.js.map +7 -0
  176. package/dist/modules/customer_accounts/widgets/injection/company-users/widget.js +17 -0
  177. package/dist/modules/customer_accounts/widgets/injection/company-users/widget.js.map +7 -0
  178. package/dist/modules/customer_accounts/widgets/injection-table.js +26 -0
  179. package/dist/modules/customer_accounts/widgets/injection-table.js.map +7 -0
  180. package/dist/modules/customer_accounts/workers/cleanupExpiredSessions.js +23 -0
  181. package/dist/modules/customer_accounts/workers/cleanupExpiredSessions.js.map +7 -0
  182. package/dist/modules/customer_accounts/workers/cleanupExpiredTokens.js +38 -0
  183. package/dist/modules/customer_accounts/workers/cleanupExpiredTokens.js.map +7 -0
  184. package/dist/modules/directory/api/get/organizations/lookup.js +83 -0
  185. package/dist/modules/directory/api/get/organizations/lookup.js.map +7 -0
  186. package/dist/modules/directory/commands/organizations.js +32 -1
  187. package/dist/modules/directory/commands/organizations.js.map +2 -2
  188. package/dist/modules/directory/data/entities.js +6 -2
  189. package/dist/modules/directory/data/entities.js.map +2 -2
  190. package/dist/modules/directory/data/validators.js +3 -0
  191. package/dist/modules/directory/data/validators.js.map +2 -2
  192. package/dist/modules/directory/migrations/Migration20260314143323.js +15 -0
  193. package/dist/modules/directory/migrations/Migration20260314143323.js.map +7 -0
  194. package/dist/modules/directory/setup.js +36 -0
  195. package/dist/modules/directory/setup.js.map +2 -2
  196. package/dist/modules/payment_gateways/migrations/Migration20260313222043.js +15 -0
  197. package/dist/modules/payment_gateways/migrations/Migration20260313222043.js.map +7 -0
  198. package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js +131 -0
  199. package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js.map +7 -0
  200. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +96 -0
  201. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +7 -0
  202. package/dist/modules/portal/frontend/[orgSlug]/portal/page.js +94 -0
  203. package/dist/modules/portal/frontend/[orgSlug]/portal/page.js.map +7 -0
  204. package/dist/modules/portal/frontend/[orgSlug]/portal/profile/page.js +89 -0
  205. package/dist/modules/portal/frontend/[orgSlug]/portal/profile/page.js.map +7 -0
  206. package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js +104 -0
  207. package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js.map +7 -0
  208. package/dist/modules/portal/index.js +11 -0
  209. package/dist/modules/portal/index.js.map +7 -0
  210. package/dist/modules/portal/setup.js +23 -0
  211. package/dist/modules/portal/setup.js.map +7 -0
  212. package/generated/entities/customer_role/index.ts +12 -0
  213. package/generated/entities/customer_role_acl/index.ts +8 -0
  214. package/generated/entities/customer_user/index.ts +17 -0
  215. package/generated/entities/customer_user_acl/index.ts +8 -0
  216. package/generated/entities/customer_user_email_verification/index.ts +7 -0
  217. package/generated/entities/customer_user_invitation/index.ts +15 -0
  218. package/generated/entities/customer_user_password_reset/index.ts +6 -0
  219. package/generated/entities/customer_user_role/index.ts +5 -0
  220. package/generated/entities/customer_user_session/index.ts +9 -0
  221. package/generated/entities/organization/index.ts +1 -0
  222. package/generated/entities.ids.generated.ts +14 -1
  223. package/generated/entity-fields-registry.ts +18 -0
  224. package/package.json +3 -3
  225. package/src/modules/auth/services/rbacService.ts +3 -9
  226. package/src/modules/customer_accounts/AGENTS.md +377 -0
  227. package/src/modules/customer_accounts/acl.ts +8 -0
  228. package/src/modules/customer_accounts/api/admin/roles/[id]/acl.ts +98 -0
  229. package/src/modules/customer_accounts/api/admin/roles/[id].ts +246 -0
  230. package/src/modules/customer_accounts/api/admin/roles.ts +212 -0
  231. package/src/modules/customer_accounts/api/admin/users/[id]/reset-password.ts +78 -0
  232. package/src/modules/customer_accounts/api/admin/users/[id]/verify-email.ts +72 -0
  233. package/src/modules/customer_accounts/api/admin/users/[id].ts +289 -0
  234. package/src/modules/customer_accounts/api/admin/users-invite.ts +86 -0
  235. package/src/modules/customer_accounts/api/admin/users.ts +280 -0
  236. package/src/modules/customer_accounts/api/email/verify.ts +66 -0
  237. package/src/modules/customer_accounts/api/interceptors.ts +3 -0
  238. package/src/modules/customer_accounts/api/invitations/accept.ts +128 -0
  239. package/src/modules/customer_accounts/api/login.ts +163 -0
  240. package/src/modules/customer_accounts/api/magic-link/request.ts +87 -0
  241. package/src/modules/customer_accounts/api/magic-link/verify.ts +132 -0
  242. package/src/modules/customer_accounts/api/password/reset-confirm.ts +69 -0
  243. package/src/modules/customer_accounts/api/password/reset-request.ts +87 -0
  244. package/src/modules/customer_accounts/api/portal/events/stream.ts +209 -0
  245. package/src/modules/customer_accounts/api/portal/feature-check.ts +60 -0
  246. package/src/modules/customer_accounts/api/portal/logout.ts +71 -0
  247. package/src/modules/customer_accounts/api/portal/notifications/[id]/dismiss.ts +54 -0
  248. package/src/modules/customer_accounts/api/portal/notifications/[id]/read.ts +54 -0
  249. package/src/modules/customer_accounts/api/portal/notifications/mark-all-read.ts +49 -0
  250. package/src/modules/customer_accounts/api/portal/notifications/unread-count.ts +45 -0
  251. package/src/modules/customer_accounts/api/portal/notifications.ts +115 -0
  252. package/src/modules/customer_accounts/api/portal/password-change.ts +65 -0
  253. package/src/modules/customer_accounts/api/portal/profile.ts +151 -0
  254. package/src/modules/customer_accounts/api/portal/sessions/[id].ts +70 -0
  255. package/src/modules/customer_accounts/api/portal/sessions-refresh.ts +87 -0
  256. package/src/modules/customer_accounts/api/portal/sessions.ts +84 -0
  257. package/src/modules/customer_accounts/api/portal/users/[id]/roles.ts +106 -0
  258. package/src/modules/customer_accounts/api/portal/users/[id].ts +81 -0
  259. package/src/modules/customer_accounts/api/portal/users-invite.ts +103 -0
  260. package/src/modules/customer_accounts/api/portal/users.ts +86 -0
  261. package/src/modules/customer_accounts/api/signup.ts +136 -0
  262. package/src/modules/customer_accounts/backend/customer_accounts/[id]/page.meta.ts +11 -0
  263. package/src/modules/customer_accounts/backend/customer_accounts/[id]/page.tsx +607 -0
  264. package/src/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.meta.ts +12 -0
  265. package/src/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.tsx +385 -0
  266. package/src/modules/customer_accounts/backend/customer_accounts/roles/create/page.meta.ts +12 -0
  267. package/src/modules/customer_accounts/backend/customer_accounts/roles/create/page.tsx +203 -0
  268. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.meta.ts +31 -0
  269. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +217 -0
  270. package/src/modules/customer_accounts/backend/page.meta.ts +33 -0
  271. package/src/modules/customer_accounts/backend/page.tsx +535 -0
  272. package/src/modules/customer_accounts/ce.ts +22 -0
  273. package/src/modules/customer_accounts/data/enrichers.ts +117 -0
  274. package/src/modules/customer_accounts/data/entities.ts +302 -0
  275. package/src/modules/customer_accounts/data/extensions.ts +4 -0
  276. package/src/modules/customer_accounts/data/validators.ts +128 -0
  277. package/src/modules/customer_accounts/di.ts +15 -0
  278. package/src/modules/customer_accounts/events.ts +28 -0
  279. package/src/modules/customer_accounts/i18n/de.json +176 -0
  280. package/src/modules/customer_accounts/i18n/en.json +176 -0
  281. package/src/modules/customer_accounts/i18n/es.json +176 -0
  282. package/src/modules/customer_accounts/i18n/pl.json +176 -0
  283. package/src/modules/customer_accounts/index.ts +13 -0
  284. package/src/modules/customer_accounts/lib/customerAuth.ts +85 -0
  285. package/src/modules/customer_accounts/lib/customerAuthServer.ts +54 -0
  286. package/src/modules/customer_accounts/lib/rateLimiter.ts +36 -0
  287. package/src/modules/customer_accounts/lib/tokenGenerator.ts +9 -0
  288. package/src/modules/customer_accounts/migrations/.snapshot-open-mercato.json +1255 -0
  289. package/src/modules/customer_accounts/migrations/Migration20260313222043.ts +62 -0
  290. package/src/modules/customer_accounts/notifications.client.ts +46 -0
  291. package/src/modules/customer_accounts/notifications.ts +44 -0
  292. package/src/modules/customer_accounts/search.ts +134 -0
  293. package/src/modules/customer_accounts/services/customerInvitationService.ts +109 -0
  294. package/src/modules/customer_accounts/services/customerRbacService.ts +144 -0
  295. package/src/modules/customer_accounts/services/customerSessionService.ts +90 -0
  296. package/src/modules/customer_accounts/services/customerTokenService.ts +98 -0
  297. package/src/modules/customer_accounts/services/customerUserService.ts +105 -0
  298. package/src/modules/customer_accounts/setup.ts +212 -0
  299. package/src/modules/customer_accounts/subscribers/autoLinkCrm.ts +65 -0
  300. package/src/modules/customer_accounts/subscribers/autoLinkCrmReverse.ts +78 -0
  301. package/src/modules/customer_accounts/subscribers/notifyStaffOnSignup.ts +32 -0
  302. package/src/modules/customer_accounts/translations.ts +5 -0
  303. package/src/modules/customer_accounts/widgets/injection/account-status/widget.client.tsx +89 -0
  304. package/src/modules/customer_accounts/widgets/injection/account-status/widget.ts +16 -0
  305. package/src/modules/customer_accounts/widgets/injection/company-users/widget.client.tsx +78 -0
  306. package/src/modules/customer_accounts/widgets/injection/company-users/widget.ts +16 -0
  307. package/src/modules/customer_accounts/widgets/injection-table.ts +24 -0
  308. package/src/modules/customer_accounts/workers/cleanupExpiredSessions.ts +33 -0
  309. package/src/modules/customer_accounts/workers/cleanupExpiredTokens.ts +51 -0
  310. package/src/modules/directory/api/get/organizations/lookup.ts +92 -0
  311. package/src/modules/directory/commands/organizations.ts +34 -1
  312. package/src/modules/directory/data/entities.ts +5 -1
  313. package/src/modules/directory/data/validators.ts +4 -0
  314. package/src/modules/directory/migrations/.snapshot-open-mercato.json +20 -1
  315. package/src/modules/directory/migrations/Migration20260314143323.ts +15 -0
  316. package/src/modules/directory/setup.ts +41 -0
  317. package/src/modules/payment_gateways/migrations/.snapshot-open-mercato.json +4 -1
  318. package/src/modules/payment_gateways/migrations/Migration20260313222043.ts +17 -0
  319. package/src/modules/portal/frontend/[orgSlug]/portal/dashboard/page.tsx +158 -0
  320. package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +120 -0
  321. package/src/modules/portal/frontend/[orgSlug]/portal/page.tsx +118 -0
  322. package/src/modules/portal/frontend/[orgSlug]/portal/profile/page.tsx +112 -0
  323. package/src/modules/portal/frontend/[orgSlug]/portal/signup/page.tsx +138 -0
  324. package/src/modules/portal/i18n/de.json +93 -0
  325. package/src/modules/portal/i18n/en.json +93 -0
  326. package/src/modules/portal/i18n/es.json +93 -0
  327. package/src/modules/portal/i18n/pl.json +93 -0
  328. package/src/modules/portal/index.ts +9 -0
  329. package/src/modules/portal/setup.ts +23 -0
  330. package/src/modules/shipping_carriers/migrations/.snapshot-open-mercato.json +226 -0
@@ -0,0 +1,49 @@
1
+ import { NextResponse } from "next/server";
2
+ import { z } from "zod";
3
+ import { getCustomerAuthFromRequest } from "@open-mercato/core/modules/customer_accounts/lib/customerAuth";
4
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
5
+ import { Notification } from "@open-mercato/core/modules/notifications/data/entities";
6
+ const metadata = {};
7
+ async function PUT(req, { params }) {
8
+ const auth = await getCustomerAuthFromRequest(req);
9
+ if (!auth) {
10
+ return NextResponse.json({ ok: false, error: "Authentication required" }, { status: 401 });
11
+ }
12
+ const container = await createRequestContainer();
13
+ const em = container.resolve("em");
14
+ const notification = await em.findOne(Notification, {
15
+ id: params.id,
16
+ recipientUserId: auth.sub,
17
+ tenantId: auth.tenantId
18
+ });
19
+ if (!notification) {
20
+ return NextResponse.json({ ok: false, error: "Notification not found" }, { status: 404 });
21
+ }
22
+ notification.status = "dismissed";
23
+ notification.dismissedAt = /* @__PURE__ */ new Date();
24
+ await em.flush();
25
+ return NextResponse.json({ ok: true });
26
+ }
27
+ const successSchema = z.object({ ok: z.literal(true) });
28
+ const errorSchema = z.object({ ok: z.literal(false), error: z.string() });
29
+ const methodDoc = {
30
+ summary: "Dismiss notification",
31
+ description: "Dismisses a single notification for the authenticated customer user.",
32
+ tags: ["Customer Portal"],
33
+ responses: [{ status: 200, description: "Notification dismissed", schema: successSchema }],
34
+ errors: [
35
+ { status: 401, description: "Not authenticated", schema: errorSchema },
36
+ { status: 404, description: "Notification not found", schema: errorSchema }
37
+ ]
38
+ };
39
+ const openApi = {
40
+ summary: "Dismiss customer notification",
41
+ pathParams: z.object({ id: z.string().uuid() }),
42
+ methods: { PUT: methodDoc }
43
+ };
44
+ export {
45
+ PUT,
46
+ metadata,
47
+ openApi
48
+ };
49
+ //# sourceMappingURL=dismiss.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/customer_accounts/api/portal/notifications/%5Bid%5D/dismiss.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc, OpenApiMethodDoc } from '@open-mercato/shared/lib/openapi'\nimport { getCustomerAuthFromRequest } from '@open-mercato/core/modules/customer_accounts/lib/customerAuth'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { Notification } from '@open-mercato/core/modules/notifications/data/entities'\n\nexport const metadata: { path?: string } = {}\n\nexport async function PUT(req: Request, { params }: { params: { id: string } }) {\n const auth = await getCustomerAuthFromRequest(req)\n if (!auth) {\n return NextResponse.json({ ok: false, error: 'Authentication required' }, { status: 401 })\n }\n\n const container = await createRequestContainer()\n const em = container.resolve('em') as import('@mikro-orm/postgresql').EntityManager\n\n const notification = await em.findOne(Notification, {\n id: params.id,\n recipientUserId: auth.sub,\n tenantId: auth.tenantId,\n })\n\n if (!notification) {\n return NextResponse.json({ ok: false, error: 'Notification not found' }, { status: 404 })\n }\n\n notification.status = 'dismissed'\n notification.dismissedAt = new Date()\n await em.flush()\n\n return NextResponse.json({ ok: true })\n}\n\nconst successSchema = z.object({ ok: z.literal(true) })\nconst errorSchema = z.object({ ok: z.literal(false), error: z.string() })\n\nconst methodDoc: OpenApiMethodDoc = {\n summary: 'Dismiss notification',\n description: 'Dismisses a single notification for the authenticated customer user.',\n tags: ['Customer Portal'],\n responses: [{ status: 200, description: 'Notification dismissed', schema: successSchema }],\n errors: [\n { status: 401, description: 'Not authenticated', schema: errorSchema },\n { status: 404, description: 'Notification not found', schema: errorSchema },\n ],\n}\n\nexport const openApi: OpenApiRouteDoc = {\n summary: 'Dismiss customer notification',\n pathParams: z.object({ id: z.string().uuid() }),\n methods: { PUT: methodDoc },\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAElB,SAAS,kCAAkC;AAC3C,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AAEtB,MAAM,WAA8B,CAAC;AAE5C,eAAsB,IAAI,KAAc,EAAE,OAAO,GAA+B;AAC9E,QAAM,OAAO,MAAM,2BAA2B,GAAG;AACjD,MAAI,CAAC,MAAM;AACT,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,0BAA0B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC3F;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,KAAK,UAAU,QAAQ,IAAI;AAEjC,QAAM,eAAe,MAAM,GAAG,QAAQ,cAAc;AAAA,IAClD,IAAI,OAAO;AAAA,IACX,iBAAiB,KAAK;AAAA,IACtB,UAAU,KAAK;AAAA,EACjB,CAAC;AAED,MAAI,CAAC,cAAc;AACjB,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,yBAAyB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC1F;AAEA,eAAa,SAAS;AACtB,eAAa,cAAc,oBAAI,KAAK;AACpC,QAAM,GAAG,MAAM;AAEf,SAAO,aAAa,KAAK,EAAE,IAAI,KAAK,CAAC;AACvC;AAEA,MAAM,gBAAgB,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC;AACtD,MAAM,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,KAAK,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC;AAExE,MAAM,YAA8B;AAAA,EAClC,SAAS;AAAA,EACT,aAAa;AAAA,EACb,MAAM,CAAC,iBAAiB;AAAA,EACxB,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,0BAA0B,QAAQ,cAAc,CAAC;AAAA,EACzF,QAAQ;AAAA,IACN,EAAE,QAAQ,KAAK,aAAa,qBAAqB,QAAQ,YAAY;AAAA,IACrE,EAAE,QAAQ,KAAK,aAAa,0BAA0B,QAAQ,YAAY;AAAA,EAC5E;AACF;AAEO,MAAM,UAA2B;AAAA,EACtC,SAAS;AAAA,EACT,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAAA,EAC9C,SAAS,EAAE,KAAK,UAAU;AAC5B;",
6
+ "names": []
7
+ }
@@ -0,0 +1,49 @@
1
+ import { NextResponse } from "next/server";
2
+ import { z } from "zod";
3
+ import { getCustomerAuthFromRequest } from "@open-mercato/core/modules/customer_accounts/lib/customerAuth";
4
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
5
+ import { Notification } from "@open-mercato/core/modules/notifications/data/entities";
6
+ const metadata = {};
7
+ async function PUT(req, { params }) {
8
+ const auth = await getCustomerAuthFromRequest(req);
9
+ if (!auth) {
10
+ return NextResponse.json({ ok: false, error: "Authentication required" }, { status: 401 });
11
+ }
12
+ const container = await createRequestContainer();
13
+ const em = container.resolve("em");
14
+ const notification = await em.findOne(Notification, {
15
+ id: params.id,
16
+ recipientUserId: auth.sub,
17
+ tenantId: auth.tenantId
18
+ });
19
+ if (!notification) {
20
+ return NextResponse.json({ ok: false, error: "Notification not found" }, { status: 404 });
21
+ }
22
+ notification.status = "read";
23
+ notification.readAt = /* @__PURE__ */ new Date();
24
+ await em.flush();
25
+ return NextResponse.json({ ok: true });
26
+ }
27
+ const successSchema = z.object({ ok: z.literal(true) });
28
+ const errorSchema = z.object({ ok: z.literal(false), error: z.string() });
29
+ const methodDoc = {
30
+ summary: "Mark notification as read",
31
+ description: "Marks a single notification as read for the authenticated customer user.",
32
+ tags: ["Customer Portal"],
33
+ responses: [{ status: 200, description: "Notification marked as read", schema: successSchema }],
34
+ errors: [
35
+ { status: 401, description: "Not authenticated", schema: errorSchema },
36
+ { status: 404, description: "Notification not found", schema: errorSchema }
37
+ ]
38
+ };
39
+ const openApi = {
40
+ summary: "Mark notification as read",
41
+ pathParams: z.object({ id: z.string().uuid() }),
42
+ methods: { PUT: methodDoc }
43
+ };
44
+ export {
45
+ PUT,
46
+ metadata,
47
+ openApi
48
+ };
49
+ //# sourceMappingURL=read.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/customer_accounts/api/portal/notifications/%5Bid%5D/read.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc, OpenApiMethodDoc } from '@open-mercato/shared/lib/openapi'\nimport { getCustomerAuthFromRequest } from '@open-mercato/core/modules/customer_accounts/lib/customerAuth'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { Notification } from '@open-mercato/core/modules/notifications/data/entities'\n\nexport const metadata: { path?: string } = {}\n\nexport async function PUT(req: Request, { params }: { params: { id: string } }) {\n const auth = await getCustomerAuthFromRequest(req)\n if (!auth) {\n return NextResponse.json({ ok: false, error: 'Authentication required' }, { status: 401 })\n }\n\n const container = await createRequestContainer()\n const em = container.resolve('em') as import('@mikro-orm/postgresql').EntityManager\n\n const notification = await em.findOne(Notification, {\n id: params.id,\n recipientUserId: auth.sub,\n tenantId: auth.tenantId,\n })\n\n if (!notification) {\n return NextResponse.json({ ok: false, error: 'Notification not found' }, { status: 404 })\n }\n\n notification.status = 'read'\n notification.readAt = new Date()\n await em.flush()\n\n return NextResponse.json({ ok: true })\n}\n\nconst successSchema = z.object({ ok: z.literal(true) })\nconst errorSchema = z.object({ ok: z.literal(false), error: z.string() })\n\nconst methodDoc: OpenApiMethodDoc = {\n summary: 'Mark notification as read',\n description: 'Marks a single notification as read for the authenticated customer user.',\n tags: ['Customer Portal'],\n responses: [{ status: 200, description: 'Notification marked as read', schema: successSchema }],\n errors: [\n { status: 401, description: 'Not authenticated', schema: errorSchema },\n { status: 404, description: 'Notification not found', schema: errorSchema },\n ],\n}\n\nexport const openApi: OpenApiRouteDoc = {\n summary: 'Mark notification as read',\n pathParams: z.object({ id: z.string().uuid() }),\n methods: { PUT: methodDoc },\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAElB,SAAS,kCAAkC;AAC3C,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AAEtB,MAAM,WAA8B,CAAC;AAE5C,eAAsB,IAAI,KAAc,EAAE,OAAO,GAA+B;AAC9E,QAAM,OAAO,MAAM,2BAA2B,GAAG;AACjD,MAAI,CAAC,MAAM;AACT,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,0BAA0B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC3F;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,KAAK,UAAU,QAAQ,IAAI;AAEjC,QAAM,eAAe,MAAM,GAAG,QAAQ,cAAc;AAAA,IAClD,IAAI,OAAO;AAAA,IACX,iBAAiB,KAAK;AAAA,IACtB,UAAU,KAAK;AAAA,EACjB,CAAC;AAED,MAAI,CAAC,cAAc;AACjB,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,yBAAyB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC1F;AAEA,eAAa,SAAS;AACtB,eAAa,SAAS,oBAAI,KAAK;AAC/B,QAAM,GAAG,MAAM;AAEf,SAAO,aAAa,KAAK,EAAE,IAAI,KAAK,CAAC;AACvC;AAEA,MAAM,gBAAgB,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC;AACtD,MAAM,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,KAAK,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC;AAExE,MAAM,YAA8B;AAAA,EAClC,SAAS;AAAA,EACT,aAAa;AAAA,EACb,MAAM,CAAC,iBAAiB;AAAA,EACxB,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,+BAA+B,QAAQ,cAAc,CAAC;AAAA,EAC9F,QAAQ;AAAA,IACN,EAAE,QAAQ,KAAK,aAAa,qBAAqB,QAAQ,YAAY;AAAA,IACrE,EAAE,QAAQ,KAAK,aAAa,0BAA0B,QAAQ,YAAY;AAAA,EAC5E;AACF;AAEO,MAAM,UAA2B;AAAA,EACtC,SAAS;AAAA,EACT,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAAA,EAC9C,SAAS,EAAE,KAAK,UAAU;AAC5B;",
6
+ "names": []
7
+ }
@@ -0,0 +1,46 @@
1
+ import { NextResponse } from "next/server";
2
+ import { z } from "zod";
3
+ import { getCustomerAuthFromRequest } from "@open-mercato/core/modules/customer_accounts/lib/customerAuth";
4
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
5
+ import { Notification } from "@open-mercato/core/modules/notifications/data/entities";
6
+ const metadata = {};
7
+ async function PUT(req) {
8
+ const auth = await getCustomerAuthFromRequest(req);
9
+ if (!auth) {
10
+ return NextResponse.json({ ok: false, error: "Authentication required" }, { status: 401 });
11
+ }
12
+ const container = await createRequestContainer();
13
+ const em = container.resolve("em");
14
+ const now = /* @__PURE__ */ new Date();
15
+ const count = await em.nativeUpdate(Notification, {
16
+ recipientUserId: auth.sub,
17
+ tenantId: auth.tenantId,
18
+ status: "unread"
19
+ }, {
20
+ status: "read",
21
+ readAt: now
22
+ });
23
+ return NextResponse.json({ ok: true, count });
24
+ }
25
+ const successSchema = z.object({
26
+ ok: z.literal(true),
27
+ count: z.number()
28
+ });
29
+ const errorSchema = z.object({ ok: z.literal(false), error: z.string() });
30
+ const methodDoc = {
31
+ summary: "Mark all notifications as read",
32
+ description: "Marks all unread notifications as read for the authenticated customer user.",
33
+ tags: ["Customer Portal"],
34
+ responses: [{ status: 200, description: "All notifications marked as read", schema: successSchema }],
35
+ errors: [{ status: 401, description: "Not authenticated", schema: errorSchema }]
36
+ };
37
+ const openApi = {
38
+ summary: "Mark all customer notifications as read",
39
+ methods: { PUT: methodDoc }
40
+ };
41
+ export {
42
+ PUT,
43
+ metadata,
44
+ openApi
45
+ };
46
+ //# sourceMappingURL=mark-all-read.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/modules/customer_accounts/api/portal/notifications/mark-all-read.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc, OpenApiMethodDoc } from '@open-mercato/shared/lib/openapi'\nimport { getCustomerAuthFromRequest } from '@open-mercato/core/modules/customer_accounts/lib/customerAuth'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { Notification } from '@open-mercato/core/modules/notifications/data/entities'\n\nexport const metadata: { path?: string } = {}\n\nexport async function PUT(req: Request) {\n const auth = await getCustomerAuthFromRequest(req)\n if (!auth) {\n return NextResponse.json({ ok: false, error: 'Authentication required' }, { status: 401 })\n }\n\n const container = await createRequestContainer()\n const em = container.resolve('em') as import('@mikro-orm/postgresql').EntityManager\n\n const now = new Date()\n const count = await em.nativeUpdate(Notification, {\n recipientUserId: auth.sub,\n tenantId: auth.tenantId,\n status: 'unread',\n }, {\n status: 'read',\n readAt: now,\n })\n\n return NextResponse.json({ ok: true, count })\n}\n\nconst successSchema = z.object({\n ok: z.literal(true),\n count: z.number(),\n})\nconst errorSchema = z.object({ ok: z.literal(false), error: z.string() })\n\nconst methodDoc: OpenApiMethodDoc = {\n summary: 'Mark all notifications as read',\n description: 'Marks all unread notifications as read for the authenticated customer user.',\n tags: ['Customer Portal'],\n responses: [{ status: 200, description: 'All notifications marked as read', schema: successSchema }],\n errors: [{ status: 401, description: 'Not authenticated', schema: errorSchema }],\n}\n\nexport const openApi: OpenApiRouteDoc = {\n summary: 'Mark all customer notifications as read',\n methods: { PUT: methodDoc },\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAElB,SAAS,kCAAkC;AAC3C,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AAEtB,MAAM,WAA8B,CAAC;AAE5C,eAAsB,IAAI,KAAc;AACtC,QAAM,OAAO,MAAM,2BAA2B,GAAG;AACjD,MAAI,CAAC,MAAM;AACT,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,0BAA0B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC3F;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,KAAK,UAAU,QAAQ,IAAI;AAEjC,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,QAAQ,MAAM,GAAG,aAAa,cAAc;AAAA,IAChD,iBAAiB,KAAK;AAAA,IACtB,UAAU,KAAK;AAAA,IACf,QAAQ;AAAA,EACV,GAAG;AAAA,IACD,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AAED,SAAO,aAAa,KAAK,EAAE,IAAI,MAAM,MAAM,CAAC;AAC9C;AAEA,MAAM,gBAAgB,EAAE,OAAO;AAAA,EAC7B,IAAI,EAAE,QAAQ,IAAI;AAAA,EAClB,OAAO,EAAE,OAAO;AAClB,CAAC;AACD,MAAM,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,KAAK,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC;AAExE,MAAM,YAA8B;AAAA,EAClC,SAAS;AAAA,EACT,aAAa;AAAA,EACb,MAAM,CAAC,iBAAiB;AAAA,EACxB,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,oCAAoC,QAAQ,cAAc,CAAC;AAAA,EACnG,QAAQ,CAAC,EAAE,QAAQ,KAAK,aAAa,qBAAqB,QAAQ,YAAY,CAAC;AACjF;AAEO,MAAM,UAA2B;AAAA,EACtC,SAAS;AAAA,EACT,SAAS,EAAE,KAAK,UAAU;AAC5B;",
6
+ "names": []
7
+ }
@@ -0,0 +1,42 @@
1
+ import { NextResponse } from "next/server";
2
+ import { z } from "zod";
3
+ import { getCustomerAuthFromRequest } from "@open-mercato/core/modules/customer_accounts/lib/customerAuth";
4
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
5
+ import { Notification } from "@open-mercato/core/modules/notifications/data/entities";
6
+ const metadata = {};
7
+ async function GET(req) {
8
+ const auth = await getCustomerAuthFromRequest(req);
9
+ if (!auth) {
10
+ return NextResponse.json({ ok: false, error: "Authentication required" }, { status: 401 });
11
+ }
12
+ const container = await createRequestContainer();
13
+ const em = container.resolve("em");
14
+ const unreadCount = await em.count(Notification, {
15
+ recipientUserId: auth.sub,
16
+ tenantId: auth.tenantId,
17
+ status: "unread"
18
+ });
19
+ return NextResponse.json({ ok: true, unreadCount });
20
+ }
21
+ const successSchema = z.object({
22
+ ok: z.literal(true),
23
+ unreadCount: z.number()
24
+ });
25
+ const errorSchema = z.object({ ok: z.literal(false), error: z.string() });
26
+ const methodDoc = {
27
+ summary: "Get unread notification count",
28
+ description: "Returns the number of unread notifications for the authenticated customer user.",
29
+ tags: ["Customer Portal"],
30
+ responses: [{ status: 200, description: "Unread count", schema: successSchema }],
31
+ errors: [{ status: 401, description: "Not authenticated", schema: errorSchema }]
32
+ };
33
+ const openApi = {
34
+ summary: "Customer unread notification count",
35
+ methods: { GET: methodDoc }
36
+ };
37
+ export {
38
+ GET,
39
+ metadata,
40
+ openApi
41
+ };
42
+ //# sourceMappingURL=unread-count.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/modules/customer_accounts/api/portal/notifications/unread-count.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc, OpenApiMethodDoc } from '@open-mercato/shared/lib/openapi'\nimport { getCustomerAuthFromRequest } from '@open-mercato/core/modules/customer_accounts/lib/customerAuth'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { Notification } from '@open-mercato/core/modules/notifications/data/entities'\n\nexport const metadata: { path?: string } = {}\n\nexport async function GET(req: Request) {\n const auth = await getCustomerAuthFromRequest(req)\n if (!auth) {\n return NextResponse.json({ ok: false, error: 'Authentication required' }, { status: 401 })\n }\n\n const container = await createRequestContainer()\n const em = container.resolve('em') as import('@mikro-orm/postgresql').EntityManager\n\n const unreadCount = await em.count(Notification, {\n recipientUserId: auth.sub,\n tenantId: auth.tenantId,\n status: 'unread',\n })\n\n return NextResponse.json({ ok: true, unreadCount })\n}\n\nconst successSchema = z.object({\n ok: z.literal(true),\n unreadCount: z.number(),\n})\nconst errorSchema = z.object({ ok: z.literal(false), error: z.string() })\n\nconst methodDoc: OpenApiMethodDoc = {\n summary: 'Get unread notification count',\n description: 'Returns the number of unread notifications for the authenticated customer user.',\n tags: ['Customer Portal'],\n responses: [{ status: 200, description: 'Unread count', schema: successSchema }],\n errors: [{ status: 401, description: 'Not authenticated', schema: errorSchema }],\n}\n\nexport const openApi: OpenApiRouteDoc = {\n summary: 'Customer unread notification count',\n methods: { GET: methodDoc },\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAElB,SAAS,kCAAkC;AAC3C,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AAEtB,MAAM,WAA8B,CAAC;AAE5C,eAAsB,IAAI,KAAc;AACtC,QAAM,OAAO,MAAM,2BAA2B,GAAG;AACjD,MAAI,CAAC,MAAM;AACT,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,0BAA0B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC3F;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,KAAK,UAAU,QAAQ,IAAI;AAEjC,QAAM,cAAc,MAAM,GAAG,MAAM,cAAc;AAAA,IAC/C,iBAAiB,KAAK;AAAA,IACtB,UAAU,KAAK;AAAA,IACf,QAAQ;AAAA,EACV,CAAC;AAED,SAAO,aAAa,KAAK,EAAE,IAAI,MAAM,YAAY,CAAC;AACpD;AAEA,MAAM,gBAAgB,EAAE,OAAO;AAAA,EAC7B,IAAI,EAAE,QAAQ,IAAI;AAAA,EAClB,aAAa,EAAE,OAAO;AACxB,CAAC;AACD,MAAM,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,KAAK,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC;AAExE,MAAM,YAA8B;AAAA,EAClC,SAAS;AAAA,EACT,aAAa;AAAA,EACb,MAAM,CAAC,iBAAiB;AAAA,EACxB,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,gBAAgB,QAAQ,cAAc,CAAC;AAAA,EAC/E,QAAQ,CAAC,EAAE,QAAQ,KAAK,aAAa,qBAAqB,QAAQ,YAAY,CAAC;AACjF;AAEO,MAAM,UAA2B;AAAA,EACtC,SAAS;AAAA,EACT,SAAS,EAAE,KAAK,UAAU;AAC5B;",
6
+ "names": []
7
+ }
@@ -0,0 +1,105 @@
1
+ import { NextResponse } from "next/server";
2
+ import { z } from "zod";
3
+ import { getCustomerAuthFromRequest } from "@open-mercato/core/modules/customer_accounts/lib/customerAuth";
4
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
5
+ import { Notification } from "@open-mercato/core/modules/notifications/data/entities";
6
+ import { toNotificationDto } from "@open-mercato/core/modules/notifications/lib/notificationMapper";
7
+ const metadata = {};
8
+ async function GET(req) {
9
+ const auth = await getCustomerAuthFromRequest(req);
10
+ if (!auth) {
11
+ return NextResponse.json({ ok: false, error: "Authentication required" }, { status: 401 });
12
+ }
13
+ const url = new URL(req.url);
14
+ const page = Math.max(1, parseInt(url.searchParams.get("page") || "1", 10) || 1);
15
+ const rawPageSize = parseInt(url.searchParams.get("pageSize") || "50", 10) || 50;
16
+ const pageSize = Math.min(Math.max(1, rawPageSize), 100);
17
+ const status = url.searchParams.get("status") || void 0;
18
+ const since = url.searchParams.get("since") || void 0;
19
+ const container = await createRequestContainer();
20
+ const em = container.resolve("em");
21
+ const where = {
22
+ recipientUserId: auth.sub,
23
+ tenantId: auth.tenantId
24
+ };
25
+ if (status) {
26
+ where.status = status;
27
+ } else {
28
+ where.status = { $ne: "dismissed" };
29
+ }
30
+ if (since) {
31
+ const sinceDate = new Date(since);
32
+ if (!isNaN(sinceDate.getTime())) {
33
+ where.createdAt = { $gte: sinceDate };
34
+ }
35
+ }
36
+ const offset = (page - 1) * pageSize;
37
+ const [items, total] = await Promise.all([
38
+ em.find(Notification, where, {
39
+ orderBy: { createdAt: "DESC" },
40
+ limit: pageSize,
41
+ offset
42
+ }),
43
+ em.count(Notification, where)
44
+ ]);
45
+ return NextResponse.json({
46
+ ok: true,
47
+ items: items.map(toNotificationDto),
48
+ total,
49
+ page,
50
+ pageSize
51
+ });
52
+ }
53
+ const notificationDtoSchema = z.object({
54
+ id: z.string().uuid(),
55
+ type: z.string(),
56
+ title: z.string(),
57
+ body: z.string().nullable().optional(),
58
+ titleKey: z.string().nullable().optional(),
59
+ bodyKey: z.string().nullable().optional(),
60
+ titleVariables: z.record(z.string(), z.string()).nullable().optional(),
61
+ bodyVariables: z.record(z.string(), z.string()).nullable().optional(),
62
+ icon: z.string().nullable().optional(),
63
+ severity: z.enum(["info", "warning", "success", "error"]),
64
+ status: z.enum(["unread", "read", "actioned", "dismissed"]),
65
+ actions: z.array(z.object({
66
+ id: z.string(),
67
+ label: z.string(),
68
+ labelKey: z.string().optional(),
69
+ variant: z.string().optional(),
70
+ icon: z.string().optional()
71
+ })),
72
+ primaryActionId: z.string().optional(),
73
+ sourceModule: z.string().nullable().optional(),
74
+ sourceEntityType: z.string().nullable().optional(),
75
+ sourceEntityId: z.string().nullable().optional(),
76
+ linkHref: z.string().nullable().optional(),
77
+ createdAt: z.string().datetime(),
78
+ readAt: z.string().datetime().nullable(),
79
+ actionTaken: z.string().nullable().optional()
80
+ });
81
+ const listResponseSchema = z.object({
82
+ ok: z.literal(true),
83
+ items: z.array(notificationDtoSchema),
84
+ total: z.number(),
85
+ page: z.number(),
86
+ pageSize: z.number()
87
+ });
88
+ const errorSchema = z.object({ ok: z.literal(false), error: z.string() });
89
+ const methodDoc = {
90
+ summary: "List customer notifications",
91
+ description: "Returns paginated notifications for the authenticated customer user. Dismissed notifications are excluded by default unless ?status=dismissed is specified.",
92
+ tags: ["Customer Portal"],
93
+ responses: [{ status: 200, description: "Notification list", schema: listResponseSchema }],
94
+ errors: [{ status: 401, description: "Not authenticated", schema: errorSchema }]
95
+ };
96
+ const openApi = {
97
+ summary: "Customer notifications",
98
+ methods: { GET: methodDoc }
99
+ };
100
+ export {
101
+ GET,
102
+ metadata,
103
+ openApi
104
+ };
105
+ //# sourceMappingURL=notifications.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/customer_accounts/api/portal/notifications.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc, OpenApiMethodDoc } from '@open-mercato/shared/lib/openapi'\nimport { getCustomerAuthFromRequest } from '@open-mercato/core/modules/customer_accounts/lib/customerAuth'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { Notification } from '@open-mercato/core/modules/notifications/data/entities'\nimport { toNotificationDto } from '@open-mercato/core/modules/notifications/lib/notificationMapper'\n\nexport const metadata: { path?: string } = {}\n\nexport async function GET(req: Request) {\n const auth = await getCustomerAuthFromRequest(req)\n if (!auth) {\n return NextResponse.json({ ok: false, error: 'Authentication required' }, { status: 401 })\n }\n\n const url = new URL(req.url)\n const page = Math.max(1, parseInt(url.searchParams.get('page') || '1', 10) || 1)\n const rawPageSize = parseInt(url.searchParams.get('pageSize') || '50', 10) || 50\n const pageSize = Math.min(Math.max(1, rawPageSize), 100)\n const status = url.searchParams.get('status') || undefined\n const since = url.searchParams.get('since') || undefined\n\n const container = await createRequestContainer()\n const em = container.resolve('em') as import('@mikro-orm/postgresql').EntityManager\n\n const where: Record<string, unknown> = {\n recipientUserId: auth.sub,\n tenantId: auth.tenantId,\n }\n\n if (status) {\n where.status = status\n } else {\n where.status = { $ne: 'dismissed' }\n }\n\n if (since) {\n const sinceDate = new Date(since)\n if (!isNaN(sinceDate.getTime())) {\n where.createdAt = { $gte: sinceDate }\n }\n }\n\n const offset = (page - 1) * pageSize\n\n const [items, total] = await Promise.all([\n em.find(Notification, where, {\n orderBy: { createdAt: 'DESC' },\n limit: pageSize,\n offset,\n }),\n em.count(Notification, where),\n ])\n\n return NextResponse.json({\n ok: true,\n items: items.map(toNotificationDto),\n total,\n page,\n pageSize,\n })\n}\n\nconst notificationDtoSchema = z.object({\n id: z.string().uuid(),\n type: z.string(),\n title: z.string(),\n body: z.string().nullable().optional(),\n titleKey: z.string().nullable().optional(),\n bodyKey: z.string().nullable().optional(),\n titleVariables: z.record(z.string(), z.string()).nullable().optional(),\n bodyVariables: z.record(z.string(), z.string()).nullable().optional(),\n icon: z.string().nullable().optional(),\n severity: z.enum(['info', 'warning', 'success', 'error']),\n status: z.enum(['unread', 'read', 'actioned', 'dismissed']),\n actions: z.array(z.object({\n id: z.string(),\n label: z.string(),\n labelKey: z.string().optional(),\n variant: z.string().optional(),\n icon: z.string().optional(),\n })),\n primaryActionId: z.string().optional(),\n sourceModule: z.string().nullable().optional(),\n sourceEntityType: z.string().nullable().optional(),\n sourceEntityId: z.string().nullable().optional(),\n linkHref: z.string().nullable().optional(),\n createdAt: z.string().datetime(),\n readAt: z.string().datetime().nullable(),\n actionTaken: z.string().nullable().optional(),\n})\n\nconst listResponseSchema = z.object({\n ok: z.literal(true),\n items: z.array(notificationDtoSchema),\n total: z.number(),\n page: z.number(),\n pageSize: z.number(),\n})\n\nconst errorSchema = z.object({ ok: z.literal(false), error: z.string() })\n\nconst methodDoc: OpenApiMethodDoc = {\n summary: 'List customer notifications',\n description: 'Returns paginated notifications for the authenticated customer user. Dismissed notifications are excluded by default unless ?status=dismissed is specified.',\n tags: ['Customer Portal'],\n responses: [{ status: 200, description: 'Notification list', schema: listResponseSchema }],\n errors: [{ status: 401, description: 'Not authenticated', schema: errorSchema }],\n}\n\nexport const openApi: OpenApiRouteDoc = {\n summary: 'Customer notifications',\n methods: { GET: methodDoc },\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,57 @@
1
+ import { NextResponse } from "next/server";
2
+ import { z } from "zod";
3
+ import { getCustomerAuthFromRequest } from "@open-mercato/core/modules/customer_accounts/lib/customerAuth";
4
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
5
+ import { passwordChangeSchema } from "@open-mercato/core/modules/customer_accounts/data/validators";
6
+ const metadata = {};
7
+ async function POST(req) {
8
+ const auth = await getCustomerAuthFromRequest(req);
9
+ if (!auth) {
10
+ return NextResponse.json({ ok: false, error: "Authentication required" }, { status: 401 });
11
+ }
12
+ let body;
13
+ try {
14
+ body = await req.json();
15
+ } catch {
16
+ return NextResponse.json({ ok: false, error: "Invalid request body" }, { status: 400 });
17
+ }
18
+ const parsed = passwordChangeSchema.safeParse(body);
19
+ if (!parsed.success) {
20
+ return NextResponse.json({ ok: false, error: "Validation failed" }, { status: 400 });
21
+ }
22
+ const container = await createRequestContainer();
23
+ const customerUserService = container.resolve("customerUserService");
24
+ const user = await customerUserService.findById(auth.sub, auth.tenantId);
25
+ if (!user) {
26
+ return NextResponse.json({ ok: false, error: "User not found" }, { status: 404 });
27
+ }
28
+ const currentValid = await customerUserService.verifyPassword(user, parsed.data.currentPassword);
29
+ if (!currentValid) {
30
+ return NextResponse.json({ ok: false, error: "Current password is incorrect" }, { status: 400 });
31
+ }
32
+ await customerUserService.updatePassword(user, parsed.data.newPassword);
33
+ return NextResponse.json({ ok: true });
34
+ }
35
+ const successSchema = z.object({ ok: z.literal(true) });
36
+ const errorSchema = z.object({ ok: z.literal(false), error: z.string() });
37
+ const methodDoc = {
38
+ summary: "Change customer password",
39
+ description: "Changes the authenticated customer user password after verifying the current password.",
40
+ tags: ["Customer Portal"],
41
+ requestBody: { schema: passwordChangeSchema },
42
+ responses: [{ status: 200, description: "Password changed", schema: successSchema }],
43
+ errors: [
44
+ { status: 400, description: "Current password incorrect or validation failed", schema: errorSchema },
45
+ { status: 401, description: "Not authenticated", schema: errorSchema }
46
+ ]
47
+ };
48
+ const openApi = {
49
+ summary: "Change customer password",
50
+ methods: { POST: methodDoc }
51
+ };
52
+ export {
53
+ POST,
54
+ metadata,
55
+ openApi
56
+ };
57
+ //# sourceMappingURL=password-change.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/customer_accounts/api/portal/password-change.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc, OpenApiMethodDoc } from '@open-mercato/shared/lib/openapi'\nimport { getCustomerAuthFromRequest } from '@open-mercato/core/modules/customer_accounts/lib/customerAuth'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { CustomerUserService } from '@open-mercato/core/modules/customer_accounts/services/customerUserService'\nimport { passwordChangeSchema } from '@open-mercato/core/modules/customer_accounts/data/validators'\n\nexport const metadata: { path?: string } = {}\n\nexport async function POST(req: Request) {\n const auth = await getCustomerAuthFromRequest(req)\n if (!auth) {\n return NextResponse.json({ ok: false, error: 'Authentication required' }, { status: 401 })\n }\n\n let body: unknown\n try {\n body = await req.json()\n } catch {\n return NextResponse.json({ ok: false, error: 'Invalid request body' }, { status: 400 })\n }\n\n const parsed = passwordChangeSchema.safeParse(body)\n if (!parsed.success) {\n return NextResponse.json({ ok: false, error: 'Validation failed' }, { status: 400 })\n }\n\n const container = await createRequestContainer()\n const customerUserService = container.resolve('customerUserService') as CustomerUserService\n\n const user = await customerUserService.findById(auth.sub, auth.tenantId)\n if (!user) {\n return NextResponse.json({ ok: false, error: 'User not found' }, { status: 404 })\n }\n\n const currentValid = await customerUserService.verifyPassword(user, parsed.data.currentPassword)\n if (!currentValid) {\n return NextResponse.json({ ok: false, error: 'Current password is incorrect' }, { status: 400 })\n }\n\n await customerUserService.updatePassword(user, parsed.data.newPassword)\n\n return NextResponse.json({ ok: true })\n}\n\nconst successSchema = z.object({ ok: z.literal(true) })\nconst errorSchema = z.object({ ok: z.literal(false), error: z.string() })\n\nconst methodDoc: OpenApiMethodDoc = {\n summary: 'Change customer password',\n description: 'Changes the authenticated customer user password after verifying the current password.',\n tags: ['Customer Portal'],\n requestBody: { schema: passwordChangeSchema },\n responses: [{ status: 200, description: 'Password changed', schema: successSchema }],\n errors: [\n { status: 400, description: 'Current password incorrect or validation failed', schema: errorSchema },\n { status: 401, description: 'Not authenticated', schema: errorSchema },\n ],\n}\n\nexport const openApi: OpenApiRouteDoc = {\n summary: 'Change customer password',\n methods: { POST: methodDoc },\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAElB,SAAS,kCAAkC;AAC3C,SAAS,8BAA8B;AAEvC,SAAS,4BAA4B;AAE9B,MAAM,WAA8B,CAAC;AAE5C,eAAsB,KAAK,KAAc;AACvC,QAAM,OAAO,MAAM,2BAA2B,GAAG;AACjD,MAAI,CAAC,MAAM;AACT,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,0BAA0B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC3F;AAEA,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,IAAI,KAAK;AAAA,EACxB,QAAQ;AACN,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,uBAAuB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACxF;AAEA,QAAM,SAAS,qBAAqB,UAAU,IAAI;AAClD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,oBAAoB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrF;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,sBAAsB,UAAU,QAAQ,qBAAqB;AAEnE,QAAM,OAAO,MAAM,oBAAoB,SAAS,KAAK,KAAK,KAAK,QAAQ;AACvE,MAAI,CAAC,MAAM;AACT,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,iBAAiB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAClF;AAEA,QAAM,eAAe,MAAM,oBAAoB,eAAe,MAAM,OAAO,KAAK,eAAe;AAC/F,MAAI,CAAC,cAAc;AACjB,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,gCAAgC,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACjG;AAEA,QAAM,oBAAoB,eAAe,MAAM,OAAO,KAAK,WAAW;AAEtE,SAAO,aAAa,KAAK,EAAE,IAAI,KAAK,CAAC;AACvC;AAEA,MAAM,gBAAgB,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC;AACtD,MAAM,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,KAAK,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC;AAExE,MAAM,YAA8B;AAAA,EAClC,SAAS;AAAA,EACT,aAAa;AAAA,EACb,MAAM,CAAC,iBAAiB;AAAA,EACxB,aAAa,EAAE,QAAQ,qBAAqB;AAAA,EAC5C,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,oBAAoB,QAAQ,cAAc,CAAC;AAAA,EACnF,QAAQ;AAAA,IACN,EAAE,QAAQ,KAAK,aAAa,mDAAmD,QAAQ,YAAY;AAAA,IACnG,EAAE,QAAQ,KAAK,aAAa,qBAAqB,QAAQ,YAAY;AAAA,EACvE;AACF;AAEO,MAAM,UAA2B;AAAA,EACtC,SAAS;AAAA,EACT,SAAS,EAAE,MAAM,UAAU;AAC7B;",
6
+ "names": []
7
+ }
@@ -0,0 +1,135 @@
1
+ import { NextResponse } from "next/server";
2
+ import { z } from "zod";
3
+ import { getCustomerAuthFromRequest, requireCustomerFeature } from "@open-mercato/core/modules/customer_accounts/lib/customerAuth";
4
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
5
+ import { CustomerUserRole } from "@open-mercato/core/modules/customer_accounts/data/entities";
6
+ import { profileUpdateSchema } from "@open-mercato/core/modules/customer_accounts/data/validators";
7
+ const metadata = {};
8
+ async function GET(req) {
9
+ const auth = await getCustomerAuthFromRequest(req);
10
+ if (!auth) {
11
+ return NextResponse.json({ ok: false, error: "Authentication required" }, { status: 401 });
12
+ }
13
+ const container = await createRequestContainer();
14
+ const customerUserService = container.resolve("customerUserService");
15
+ const customerRbacService = container.resolve("customerRbacService");
16
+ const em = container.resolve("em");
17
+ const user = await customerUserService.findById(auth.sub, auth.tenantId);
18
+ if (!user) {
19
+ return NextResponse.json({ ok: false, error: "User not found" }, { status: 404 });
20
+ }
21
+ const acl = await customerRbacService.loadAcl(user.id, { tenantId: user.tenantId, organizationId: user.organizationId });
22
+ const userRoles = await em.find(CustomerUserRole, {
23
+ user: user.id,
24
+ deletedAt: null
25
+ }, { populate: ["role"] });
26
+ const roles = userRoles.map((ur) => ({
27
+ id: ur.role.id,
28
+ name: ur.role.name,
29
+ slug: ur.role.slug
30
+ }));
31
+ return NextResponse.json({
32
+ ok: true,
33
+ user: {
34
+ id: user.id,
35
+ email: user.email,
36
+ displayName: user.displayName,
37
+ emailVerified: !!user.emailVerifiedAt,
38
+ customerEntityId: user.customerEntityId,
39
+ personEntityId: user.personEntityId,
40
+ isActive: user.isActive,
41
+ lastLoginAt: user.lastLoginAt,
42
+ createdAt: user.createdAt
43
+ },
44
+ roles,
45
+ resolvedFeatures: acl.features,
46
+ isPortalAdmin: acl.isPortalAdmin
47
+ });
48
+ }
49
+ async function PUT(req) {
50
+ const auth = await getCustomerAuthFromRequest(req);
51
+ if (!auth) {
52
+ return NextResponse.json({ ok: false, error: "Authentication required" }, { status: 401 });
53
+ }
54
+ try {
55
+ requireCustomerFeature(auth, ["portal.account.manage"]);
56
+ } catch (response) {
57
+ return response;
58
+ }
59
+ let body;
60
+ try {
61
+ body = await req.json();
62
+ } catch {
63
+ return NextResponse.json({ ok: false, error: "Invalid request body" }, { status: 400 });
64
+ }
65
+ const parsed = profileUpdateSchema.safeParse(body);
66
+ if (!parsed.success) {
67
+ return NextResponse.json({ ok: false, error: "Validation failed" }, { status: 400 });
68
+ }
69
+ const container = await createRequestContainer();
70
+ const customerUserService = container.resolve("customerUserService");
71
+ const user = await customerUserService.findById(auth.sub, auth.tenantId);
72
+ if (!user) {
73
+ return NextResponse.json({ ok: false, error: "User not found" }, { status: 404 });
74
+ }
75
+ await customerUserService.updateProfile(user, parsed.data);
76
+ return NextResponse.json({
77
+ ok: true,
78
+ user: {
79
+ id: user.id,
80
+ email: user.email,
81
+ displayName: user.displayName
82
+ }
83
+ });
84
+ }
85
+ const profileSchema = z.object({
86
+ ok: z.literal(true),
87
+ user: z.object({
88
+ id: z.string().uuid(),
89
+ email: z.string(),
90
+ displayName: z.string(),
91
+ emailVerified: z.boolean(),
92
+ customerEntityId: z.string().uuid().nullable(),
93
+ personEntityId: z.string().uuid().nullable(),
94
+ isActive: z.boolean(),
95
+ lastLoginAt: z.string().datetime().nullable(),
96
+ createdAt: z.string().datetime()
97
+ }),
98
+ roles: z.array(z.object({ id: z.string().uuid(), name: z.string(), slug: z.string() })),
99
+ resolvedFeatures: z.array(z.string()),
100
+ isPortalAdmin: z.boolean()
101
+ });
102
+ const putSuccessSchema = z.object({
103
+ ok: z.literal(true),
104
+ user: z.object({ id: z.string().uuid(), email: z.string(), displayName: z.string() })
105
+ });
106
+ const errorSchema = z.object({ ok: z.literal(false), error: z.string() });
107
+ const getMethodDoc = {
108
+ summary: "Get customer profile",
109
+ description: "Returns the authenticated customer user profile with roles and permissions.",
110
+ tags: ["Customer Portal"],
111
+ responses: [{ status: 200, description: "Profile data", schema: profileSchema }],
112
+ errors: [{ status: 401, description: "Not authenticated", schema: errorSchema }]
113
+ };
114
+ const putMethodDoc = {
115
+ summary: "Update customer profile",
116
+ description: "Updates the authenticated customer user profile.",
117
+ tags: ["Customer Portal"],
118
+ requestBody: { schema: profileUpdateSchema },
119
+ responses: [{ status: 200, description: "Profile updated", schema: putSuccessSchema }],
120
+ errors: [
121
+ { status: 401, description: "Not authenticated", schema: errorSchema },
122
+ { status: 403, description: "Insufficient permissions", schema: errorSchema }
123
+ ]
124
+ };
125
+ const openApi = {
126
+ summary: "Customer profile",
127
+ methods: { GET: getMethodDoc, PUT: putMethodDoc }
128
+ };
129
+ export {
130
+ GET,
131
+ PUT,
132
+ metadata,
133
+ openApi
134
+ };
135
+ //# sourceMappingURL=profile.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/customer_accounts/api/portal/profile.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc, OpenApiMethodDoc } from '@open-mercato/shared/lib/openapi'\nimport { getCustomerAuthFromRequest, requireCustomerFeature } from '@open-mercato/core/modules/customer_accounts/lib/customerAuth'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { CustomerUserService } from '@open-mercato/core/modules/customer_accounts/services/customerUserService'\nimport { CustomerRbacService } from '@open-mercato/core/modules/customer_accounts/services/customerRbacService'\nimport { CustomerUserRole } from '@open-mercato/core/modules/customer_accounts/data/entities'\nimport { profileUpdateSchema } from '@open-mercato/core/modules/customer_accounts/data/validators'\n\nexport const metadata: { path?: string } = {}\n\nexport async function GET(req: Request) {\n const auth = await getCustomerAuthFromRequest(req)\n if (!auth) {\n return NextResponse.json({ ok: false, error: 'Authentication required' }, { status: 401 })\n }\n\n const container = await createRequestContainer()\n const customerUserService = container.resolve('customerUserService') as CustomerUserService\n const customerRbacService = container.resolve('customerRbacService') as CustomerRbacService\n const em = container.resolve('em') as import('@mikro-orm/postgresql').EntityManager\n\n const user = await customerUserService.findById(auth.sub, auth.tenantId)\n if (!user) {\n return NextResponse.json({ ok: false, error: 'User not found' }, { status: 404 })\n }\n\n const acl = await customerRbacService.loadAcl(user.id, { tenantId: user.tenantId, organizationId: user.organizationId })\n\n const userRoles = await em.find(CustomerUserRole, {\n user: user.id as any,\n deletedAt: null,\n }, { populate: ['role'] })\n const roles = userRoles.map((ur) => ({\n id: (ur.role as any).id,\n name: (ur.role as any).name,\n slug: (ur.role as any).slug,\n }))\n\n return NextResponse.json({\n ok: true,\n user: {\n id: user.id,\n email: user.email,\n displayName: user.displayName,\n emailVerified: !!user.emailVerifiedAt,\n customerEntityId: user.customerEntityId,\n personEntityId: user.personEntityId,\n isActive: user.isActive,\n lastLoginAt: user.lastLoginAt,\n createdAt: user.createdAt,\n },\n roles,\n resolvedFeatures: acl.features,\n isPortalAdmin: acl.isPortalAdmin,\n })\n}\n\nexport async function PUT(req: Request) {\n const auth = await getCustomerAuthFromRequest(req)\n if (!auth) {\n return NextResponse.json({ ok: false, error: 'Authentication required' }, { status: 401 })\n }\n\n try {\n requireCustomerFeature(auth, ['portal.account.manage'])\n } catch (response) {\n return response as NextResponse\n }\n\n let body: unknown\n try {\n body = await req.json()\n } catch {\n return NextResponse.json({ ok: false, error: 'Invalid request body' }, { status: 400 })\n }\n\n const parsed = profileUpdateSchema.safeParse(body)\n if (!parsed.success) {\n return NextResponse.json({ ok: false, error: 'Validation failed' }, { status: 400 })\n }\n\n const container = await createRequestContainer()\n const customerUserService = container.resolve('customerUserService') as CustomerUserService\n\n const user = await customerUserService.findById(auth.sub, auth.tenantId)\n if (!user) {\n return NextResponse.json({ ok: false, error: 'User not found' }, { status: 404 })\n }\n\n await customerUserService.updateProfile(user, parsed.data)\n\n return NextResponse.json({\n ok: true,\n user: {\n id: user.id,\n email: user.email,\n displayName: user.displayName,\n },\n })\n}\n\nconst profileSchema = z.object({\n ok: z.literal(true),\n user: z.object({\n id: z.string().uuid(),\n email: z.string(),\n displayName: z.string(),\n emailVerified: z.boolean(),\n customerEntityId: z.string().uuid().nullable(),\n personEntityId: z.string().uuid().nullable(),\n isActive: z.boolean(),\n lastLoginAt: z.string().datetime().nullable(),\n createdAt: z.string().datetime(),\n }),\n roles: z.array(z.object({ id: z.string().uuid(), name: z.string(), slug: z.string() })),\n resolvedFeatures: z.array(z.string()),\n isPortalAdmin: z.boolean(),\n})\n\nconst putSuccessSchema = z.object({\n ok: z.literal(true),\n user: z.object({ id: z.string().uuid(), email: z.string(), displayName: z.string() }),\n})\nconst errorSchema = z.object({ ok: z.literal(false), error: z.string() })\n\nconst getMethodDoc: OpenApiMethodDoc = {\n summary: 'Get customer profile',\n description: 'Returns the authenticated customer user profile with roles and permissions.',\n tags: ['Customer Portal'],\n responses: [{ status: 200, description: 'Profile data', schema: profileSchema }],\n errors: [{ status: 401, description: 'Not authenticated', schema: errorSchema }],\n}\n\nconst putMethodDoc: OpenApiMethodDoc = {\n summary: 'Update customer profile',\n description: 'Updates the authenticated customer user profile.',\n tags: ['Customer Portal'],\n requestBody: { schema: profileUpdateSchema },\n responses: [{ status: 200, description: 'Profile updated', schema: putSuccessSchema }],\n errors: [\n { status: 401, description: 'Not authenticated', schema: errorSchema },\n { status: 403, description: 'Insufficient permissions', schema: errorSchema },\n ],\n}\n\nexport const openApi: OpenApiRouteDoc = {\n summary: 'Customer profile',\n methods: { GET: getMethodDoc, PUT: putMethodDoc },\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAElB,SAAS,4BAA4B,8BAA8B;AACnE,SAAS,8BAA8B;AAGvC,SAAS,wBAAwB;AACjC,SAAS,2BAA2B;AAE7B,MAAM,WAA8B,CAAC;AAE5C,eAAsB,IAAI,KAAc;AACtC,QAAM,OAAO,MAAM,2BAA2B,GAAG;AACjD,MAAI,CAAC,MAAM;AACT,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,0BAA0B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC3F;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,sBAAsB,UAAU,QAAQ,qBAAqB;AACnE,QAAM,sBAAsB,UAAU,QAAQ,qBAAqB;AACnE,QAAM,KAAK,UAAU,QAAQ,IAAI;AAEjC,QAAM,OAAO,MAAM,oBAAoB,SAAS,KAAK,KAAK,KAAK,QAAQ;AACvE,MAAI,CAAC,MAAM;AACT,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,iBAAiB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAClF;AAEA,QAAM,MAAM,MAAM,oBAAoB,QAAQ,KAAK,IAAI,EAAE,UAAU,KAAK,UAAU,gBAAgB,KAAK,eAAe,CAAC;AAEvH,QAAM,YAAY,MAAM,GAAG,KAAK,kBAAkB;AAAA,IAChD,MAAM,KAAK;AAAA,IACX,WAAW;AAAA,EACb,GAAG,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;AACzB,QAAM,QAAQ,UAAU,IAAI,CAAC,QAAQ;AAAA,IACnC,IAAK,GAAG,KAAa;AAAA,IACrB,MAAO,GAAG,KAAa;AAAA,IACvB,MAAO,GAAG,KAAa;AAAA,EACzB,EAAE;AAEF,SAAO,aAAa,KAAK;AAAA,IACvB,IAAI;AAAA,IACJ,MAAM;AAAA,MACJ,IAAI,KAAK;AAAA,MACT,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,eAAe,CAAC,CAAC,KAAK;AAAA,MACtB,kBAAkB,KAAK;AAAA,MACvB,gBAAgB,KAAK;AAAA,MACrB,UAAU,KAAK;AAAA,MACf,aAAa,KAAK;AAAA,MAClB,WAAW,KAAK;AAAA,IAClB;AAAA,IACA;AAAA,IACA,kBAAkB,IAAI;AAAA,IACtB,eAAe,IAAI;AAAA,EACrB,CAAC;AACH;AAEA,eAAsB,IAAI,KAAc;AACtC,QAAM,OAAO,MAAM,2BAA2B,GAAG;AACjD,MAAI,CAAC,MAAM;AACT,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,0BAA0B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC3F;AAEA,MAAI;AACF,2BAAuB,MAAM,CAAC,uBAAuB,CAAC;AAAA,EACxD,SAAS,UAAU;AACjB,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,IAAI,KAAK;AAAA,EACxB,QAAQ;AACN,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,uBAAuB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACxF;AAEA,QAAM,SAAS,oBAAoB,UAAU,IAAI;AACjD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,oBAAoB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrF;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,sBAAsB,UAAU,QAAQ,qBAAqB;AAEnE,QAAM,OAAO,MAAM,oBAAoB,SAAS,KAAK,KAAK,KAAK,QAAQ;AACvE,MAAI,CAAC,MAAM;AACT,WAAO,aAAa,KAAK,EAAE,IAAI,OAAO,OAAO,iBAAiB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAClF;AAEA,QAAM,oBAAoB,cAAc,MAAM,OAAO,IAAI;AAEzD,SAAO,aAAa,KAAK;AAAA,IACvB,IAAI;AAAA,IACJ,MAAM;AAAA,MACJ,IAAI,KAAK;AAAA,MACT,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,IACpB;AAAA,EACF,CAAC;AACH;AAEA,MAAM,gBAAgB,EAAE,OAAO;AAAA,EAC7B,IAAI,EAAE,QAAQ,IAAI;AAAA,EAClB,MAAM,EAAE,OAAO;AAAA,IACb,IAAI,EAAE,OAAO,EAAE,KAAK;AAAA,IACpB,OAAO,EAAE,OAAO;AAAA,IAChB,aAAa,EAAE,OAAO;AAAA,IACtB,eAAe,EAAE,QAAQ;AAAA,IACzB,kBAAkB,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,IAC7C,gBAAgB,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,IAC3C,UAAU,EAAE,QAAQ;AAAA,IACpB,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,IAC5C,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,CAAC;AAAA,EACD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,GAAG,MAAM,EAAE,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;AAAA,EACtF,kBAAkB,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,EACpC,eAAe,EAAE,QAAQ;AAC3B,CAAC;AAED,MAAM,mBAAmB,EAAE,OAAO;AAAA,EAChC,IAAI,EAAE,QAAQ,IAAI;AAAA,EAClB,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,GAAG,OAAO,EAAE,OAAO,GAAG,aAAa,EAAE,OAAO,EAAE,CAAC;AACtF,CAAC;AACD,MAAM,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,KAAK,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC;AAExE,MAAM,eAAiC;AAAA,EACrC,SAAS;AAAA,EACT,aAAa;AAAA,EACb,MAAM,CAAC,iBAAiB;AAAA,EACxB,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,gBAAgB,QAAQ,cAAc,CAAC;AAAA,EAC/E,QAAQ,CAAC,EAAE,QAAQ,KAAK,aAAa,qBAAqB,QAAQ,YAAY,CAAC;AACjF;AAEA,MAAM,eAAiC;AAAA,EACrC,SAAS;AAAA,EACT,aAAa;AAAA,EACb,MAAM,CAAC,iBAAiB;AAAA,EACxB,aAAa,EAAE,QAAQ,oBAAoB;AAAA,EAC3C,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,mBAAmB,QAAQ,iBAAiB,CAAC;AAAA,EACrF,QAAQ;AAAA,IACN,EAAE,QAAQ,KAAK,aAAa,qBAAqB,QAAQ,YAAY;AAAA,IACrE,EAAE,QAAQ,KAAK,aAAa,4BAA4B,QAAQ,YAAY;AAAA,EAC9E;AACF;AAEO,MAAM,UAA2B;AAAA,EACtC,SAAS;AAAA,EACT,SAAS,EAAE,KAAK,cAAc,KAAK,aAAa;AAClD;",
6
+ "names": []
7
+ }