@qwickapps/server 1.7.0 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (335) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/README.md +13 -116
  3. package/dist/src/core/control-panel.d.ts.map +1 -1
  4. package/dist/src/core/control-panel.js +6 -4
  5. package/dist/src/core/control-panel.js.map +1 -1
  6. package/dist/src/core/gateway.d.ts.map +1 -1
  7. package/dist/src/core/gateway.js +24 -2
  8. package/dist/src/core/gateway.js.map +1 -1
  9. package/dist/src/core/plugin-registry.d.ts +15 -2
  10. package/dist/src/core/plugin-registry.d.ts.map +1 -1
  11. package/dist/src/core/plugin-registry.js.map +1 -1
  12. package/dist/src/index.d.ts +2 -2
  13. package/dist/src/index.d.ts.map +1 -1
  14. package/dist/src/index.js +9 -3
  15. package/dist/src/index.js.map +1 -1
  16. package/dist/src/plugins/api-keys/api-keys-plugin.d.ts +5 -2
  17. package/dist/src/plugins/api-keys/api-keys-plugin.d.ts.map +1 -1
  18. package/dist/src/plugins/api-keys/api-keys-plugin.js +61 -19
  19. package/dist/src/plugins/api-keys/api-keys-plugin.js.map +1 -1
  20. package/dist/src/plugins/api-keys/index.d.ts +0 -4
  21. package/dist/src/plugins/api-keys/index.d.ts.map +1 -1
  22. package/dist/src/plugins/api-keys/index.js +2 -3
  23. package/dist/src/plugins/api-keys/index.js.map +1 -1
  24. package/dist/src/plugins/api-keys/stores/postgres-store.d.ts.map +1 -1
  25. package/dist/src/plugins/api-keys/stores/postgres-store.js +29 -0
  26. package/dist/src/plugins/api-keys/stores/postgres-store.js.map +1 -1
  27. package/dist/src/plugins/api-keys/types.d.ts +9 -3
  28. package/dist/src/plugins/api-keys/types.d.ts.map +1 -1
  29. package/dist/src/plugins/api-keys/types.js.map +1 -1
  30. package/dist/src/plugins/auth/auth-plugin.d.ts.map +1 -1
  31. package/dist/src/plugins/auth/auth-plugin.js +4 -2
  32. package/dist/src/plugins/auth/auth-plugin.js.map +1 -1
  33. package/dist/src/plugins/auth/env-config.d.ts.map +1 -1
  34. package/dist/src/plugins/auth/env-config.js +1 -0
  35. package/dist/src/plugins/auth/env-config.js.map +1 -1
  36. package/dist/src/plugins/auth/index.d.ts +0 -4
  37. package/dist/src/plugins/auth/index.d.ts.map +1 -1
  38. package/dist/src/plugins/auth/index.js +2 -3
  39. package/dist/src/plugins/auth/index.js.map +1 -1
  40. package/dist/src/plugins/bans/bans-plugin.d.ts +5 -2
  41. package/dist/src/plugins/bans/bans-plugin.d.ts.map +1 -1
  42. package/dist/src/plugins/bans/bans-plugin.js +71 -25
  43. package/dist/src/plugins/bans/bans-plugin.js.map +1 -1
  44. package/dist/src/plugins/bans/index.d.ts +1 -5
  45. package/dist/src/plugins/bans/index.d.ts.map +1 -1
  46. package/dist/src/plugins/bans/index.js +3 -4
  47. package/dist/src/plugins/bans/index.js.map +1 -1
  48. package/dist/src/plugins/bans/stores/in-memory-store.d.ts +34 -0
  49. package/dist/src/plugins/bans/stores/in-memory-store.d.ts.map +1 -0
  50. package/dist/src/plugins/bans/stores/in-memory-store.js +97 -0
  51. package/dist/src/plugins/bans/stores/in-memory-store.js.map +1 -0
  52. package/dist/src/plugins/bans/stores/index.d.ts +1 -0
  53. package/dist/src/plugins/bans/stores/index.d.ts.map +1 -1
  54. package/dist/src/plugins/bans/stores/index.js +1 -0
  55. package/dist/src/plugins/bans/stores/index.js.map +1 -1
  56. package/dist/src/plugins/bans/types.d.ts +13 -6
  57. package/dist/src/plugins/bans/types.d.ts.map +1 -1
  58. package/dist/src/plugins/cache-plugin.d.ts +35 -16
  59. package/dist/src/plugins/cache-plugin.d.ts.map +1 -1
  60. package/dist/src/plugins/cache-plugin.js +299 -20
  61. package/dist/src/plugins/cache-plugin.js.map +1 -1
  62. package/dist/src/plugins/cms/cms-plugin.d.ts.map +1 -1
  63. package/dist/src/plugins/cms/cms-plugin.js +3 -1
  64. package/dist/src/plugins/cms/cms-plugin.js.map +1 -1
  65. package/dist/src/plugins/devices/devices-plugin.d.ts +5 -2
  66. package/dist/src/plugins/devices/devices-plugin.d.ts.map +1 -1
  67. package/dist/src/plugins/devices/devices-plugin.js +62 -26
  68. package/dist/src/plugins/devices/devices-plugin.js.map +1 -1
  69. package/dist/src/plugins/devices/index.d.ts +0 -4
  70. package/dist/src/plugins/devices/index.d.ts.map +1 -1
  71. package/dist/src/plugins/devices/index.js +2 -3
  72. package/dist/src/plugins/devices/index.js.map +1 -1
  73. package/dist/src/plugins/entitlements/entitlements-plugin.d.ts +5 -2
  74. package/dist/src/plugins/entitlements/entitlements-plugin.d.ts.map +1 -1
  75. package/dist/src/plugins/entitlements/entitlements-plugin.js +78 -41
  76. package/dist/src/plugins/entitlements/entitlements-plugin.js.map +1 -1
  77. package/dist/src/plugins/entitlements/index.d.ts +1 -5
  78. package/dist/src/plugins/entitlements/index.d.ts.map +1 -1
  79. package/dist/src/plugins/entitlements/index.js +3 -4
  80. package/dist/src/plugins/entitlements/index.js.map +1 -1
  81. package/dist/src/plugins/entitlements/sources/in-memory-source.d.ts +9 -0
  82. package/dist/src/plugins/entitlements/sources/in-memory-source.d.ts.map +1 -0
  83. package/dist/src/plugins/entitlements/sources/in-memory-source.js +65 -0
  84. package/dist/src/plugins/entitlements/sources/in-memory-source.js.map +1 -0
  85. package/dist/src/plugins/entitlements/sources/index.d.ts +1 -0
  86. package/dist/src/plugins/entitlements/sources/index.d.ts.map +1 -1
  87. package/dist/src/plugins/entitlements/sources/index.js +1 -0
  88. package/dist/src/plugins/entitlements/sources/index.js.map +1 -1
  89. package/dist/src/plugins/entitlements/types.d.ts +9 -2
  90. package/dist/src/plugins/entitlements/types.d.ts.map +1 -1
  91. package/dist/src/plugins/health-plugin.d.ts.map +1 -1
  92. package/dist/src/plugins/health-plugin.js +1 -0
  93. package/dist/src/plugins/health-plugin.js.map +1 -1
  94. package/dist/src/plugins/index.d.ts +4 -4
  95. package/dist/src/plugins/index.d.ts.map +1 -1
  96. package/dist/src/plugins/index.js +4 -4
  97. package/dist/src/plugins/index.js.map +1 -1
  98. package/dist/src/plugins/logs-plugin.d.ts.map +1 -1
  99. package/dist/src/plugins/logs-plugin.js +49 -1
  100. package/dist/src/plugins/logs-plugin.js.map +1 -1
  101. package/dist/src/plugins/maintenance-plugin.d.ts.map +1 -1
  102. package/dist/src/plugins/maintenance-plugin.js +39 -0
  103. package/dist/src/plugins/maintenance-plugin.js.map +1 -1
  104. package/dist/src/plugins/notifications/index.d.ts +0 -4
  105. package/dist/src/plugins/notifications/index.d.ts.map +1 -1
  106. package/dist/src/plugins/notifications/index.js +2 -3
  107. package/dist/src/plugins/notifications/index.js.map +1 -1
  108. package/dist/src/plugins/notifications/notifications-plugin.d.ts +5 -2
  109. package/dist/src/plugins/notifications/notifications-plugin.d.ts.map +1 -1
  110. package/dist/src/plugins/notifications/notifications-plugin.js +46 -13
  111. package/dist/src/plugins/notifications/notifications-plugin.js.map +1 -1
  112. package/dist/src/plugins/parental/index.d.ts +0 -4
  113. package/dist/src/plugins/parental/index.d.ts.map +1 -1
  114. package/dist/src/plugins/parental/index.js +2 -3
  115. package/dist/src/plugins/parental/index.js.map +1 -1
  116. package/dist/src/plugins/parental/parental-plugin.d.ts +5 -2
  117. package/dist/src/plugins/parental/parental-plugin.d.ts.map +1 -1
  118. package/dist/src/plugins/parental/parental-plugin.js +60 -24
  119. package/dist/src/plugins/parental/parental-plugin.js.map +1 -1
  120. package/dist/src/plugins/postgres-plugin.d.ts +3 -1
  121. package/dist/src/plugins/postgres-plugin.d.ts.map +1 -1
  122. package/dist/src/plugins/postgres-plugin.js +18 -8
  123. package/dist/src/plugins/postgres-plugin.js.map +1 -1
  124. package/dist/src/plugins/preferences/index.d.ts +0 -4
  125. package/dist/src/plugins/preferences/index.d.ts.map +1 -1
  126. package/dist/src/plugins/preferences/index.js +2 -3
  127. package/dist/src/plugins/preferences/index.js.map +1 -1
  128. package/dist/src/plugins/preferences/preferences-plugin.d.ts +5 -2
  129. package/dist/src/plugins/preferences/preferences-plugin.d.ts.map +1 -1
  130. package/dist/src/plugins/preferences/preferences-plugin.js +63 -19
  131. package/dist/src/plugins/preferences/preferences-plugin.js.map +1 -1
  132. package/dist/src/plugins/profiles/index.d.ts +0 -4
  133. package/dist/src/plugins/profiles/index.d.ts.map +1 -1
  134. package/dist/src/plugins/profiles/index.js +2 -3
  135. package/dist/src/plugins/profiles/index.js.map +1 -1
  136. package/dist/src/plugins/profiles/profiles-plugin.d.ts +5 -2
  137. package/dist/src/plugins/profiles/profiles-plugin.d.ts.map +1 -1
  138. package/dist/src/plugins/profiles/profiles-plugin.js +60 -26
  139. package/dist/src/plugins/profiles/profiles-plugin.js.map +1 -1
  140. package/dist/src/plugins/profiles/types.d.ts +9 -2
  141. package/dist/src/plugins/profiles/types.d.ts.map +1 -1
  142. package/dist/src/plugins/qwickbrain/index.d.ts +0 -4
  143. package/dist/src/plugins/qwickbrain/index.d.ts.map +1 -1
  144. package/dist/src/plugins/qwickbrain/index.js +2 -3
  145. package/dist/src/plugins/qwickbrain/index.js.map +1 -1
  146. package/dist/src/plugins/qwickbrain/qwickbrain-plugin.d.ts.map +1 -1
  147. package/dist/src/plugins/qwickbrain/qwickbrain-plugin.js +117 -0
  148. package/dist/src/plugins/qwickbrain/qwickbrain-plugin.js.map +1 -1
  149. package/dist/src/plugins/rate-limit/index.d.ts +0 -4
  150. package/dist/src/plugins/rate-limit/index.d.ts.map +1 -1
  151. package/dist/src/plugins/rate-limit/index.js +2 -3
  152. package/dist/src/plugins/rate-limit/index.js.map +1 -1
  153. package/dist/src/plugins/subscriptions/index.d.ts +0 -4
  154. package/dist/src/plugins/subscriptions/index.d.ts.map +1 -1
  155. package/dist/src/plugins/subscriptions/index.js +2 -3
  156. package/dist/src/plugins/subscriptions/index.js.map +1 -1
  157. package/dist/src/plugins/subscriptions/subscriptions-plugin.d.ts +5 -2
  158. package/dist/src/plugins/subscriptions/subscriptions-plugin.d.ts.map +1 -1
  159. package/dist/src/plugins/subscriptions/subscriptions-plugin.js +63 -29
  160. package/dist/src/plugins/subscriptions/subscriptions-plugin.js.map +1 -1
  161. package/dist/src/plugins/subscriptions/types.d.ts +8 -2
  162. package/dist/src/plugins/subscriptions/types.d.ts.map +1 -1
  163. package/dist/src/plugins/tenants/index.d.ts +1 -1
  164. package/dist/src/plugins/tenants/index.d.ts.map +1 -1
  165. package/dist/src/plugins/tenants/index.js +1 -1
  166. package/dist/src/plugins/tenants/index.js.map +1 -1
  167. package/dist/src/plugins/tenants/stores/in-memory-store.d.ts +59 -0
  168. package/dist/src/plugins/tenants/stores/in-memory-store.d.ts.map +1 -0
  169. package/dist/src/plugins/tenants/stores/in-memory-store.js +257 -0
  170. package/dist/src/plugins/tenants/stores/in-memory-store.js.map +1 -0
  171. package/dist/src/plugins/tenants/stores/index.d.ts +8 -0
  172. package/dist/src/plugins/tenants/stores/index.d.ts.map +1 -0
  173. package/dist/src/plugins/tenants/stores/index.js +8 -0
  174. package/dist/src/plugins/tenants/stores/index.js.map +1 -0
  175. package/dist/src/plugins/tenants/tenants-plugin.d.ts +5 -2
  176. package/dist/src/plugins/tenants/tenants-plugin.d.ts.map +1 -1
  177. package/dist/src/plugins/tenants/tenants-plugin.js +93 -60
  178. package/dist/src/plugins/tenants/tenants-plugin.js.map +1 -1
  179. package/dist/src/plugins/tenants/types.d.ts +8 -2
  180. package/dist/src/plugins/tenants/types.d.ts.map +1 -1
  181. package/dist/src/plugins/usage/index.d.ts +0 -4
  182. package/dist/src/plugins/usage/index.d.ts.map +1 -1
  183. package/dist/src/plugins/usage/index.js +2 -3
  184. package/dist/src/plugins/usage/index.js.map +1 -1
  185. package/dist/src/plugins/usage/usage-plugin.d.ts +5 -2
  186. package/dist/src/plugins/usage/usage-plugin.d.ts.map +1 -1
  187. package/dist/src/plugins/usage/usage-plugin.js +57 -23
  188. package/dist/src/plugins/usage/usage-plugin.js.map +1 -1
  189. package/dist/src/plugins/users/index.d.ts +1 -1
  190. package/dist/src/plugins/users/index.d.ts.map +1 -1
  191. package/dist/src/plugins/users/index.js +1 -1
  192. package/dist/src/plugins/users/index.js.map +1 -1
  193. package/dist/src/plugins/users/stores/in-memory-store.d.ts +36 -0
  194. package/dist/src/plugins/users/stores/in-memory-store.d.ts.map +1 -0
  195. package/dist/src/plugins/users/stores/in-memory-store.js +122 -0
  196. package/dist/src/plugins/users/stores/in-memory-store.js.map +1 -0
  197. package/dist/src/plugins/users/stores/index.d.ts +1 -0
  198. package/dist/src/plugins/users/stores/index.d.ts.map +1 -1
  199. package/dist/src/plugins/users/stores/index.js +1 -0
  200. package/dist/src/plugins/users/stores/index.js.map +1 -1
  201. package/dist/src/plugins/users/types.d.ts +7 -2
  202. package/dist/src/plugins/users/types.d.ts.map +1 -1
  203. package/dist/src/plugins/users/users-plugin.d.ts +5 -2
  204. package/dist/src/plugins/users/users-plugin.d.ts.map +1 -1
  205. package/dist/src/plugins/users/users-plugin.js +56 -23
  206. package/dist/src/plugins/users/users-plugin.js.map +1 -1
  207. package/dist/ui/src/api/controlPanelApi.d.ts +10 -1
  208. package/dist/ui/src/api/controlPanelApi.d.ts.map +1 -1
  209. package/dist/ui/src/api/controlPanelApi.js.map +1 -1
  210. package/dist/ui/src/dashboard/PluginWidgetRenderer.d.ts +3 -1
  211. package/dist/ui/src/dashboard/PluginWidgetRenderer.d.ts.map +1 -1
  212. package/dist/ui/src/dashboard/PluginWidgetRenderer.js +5 -1
  213. package/dist/ui/src/dashboard/PluginWidgetRenderer.js.map +1 -1
  214. package/dist/ui/src/dashboard/builtInWidgets.d.ts.map +1 -1
  215. package/dist/ui/src/dashboard/builtInWidgets.js +13 -1
  216. package/dist/ui/src/dashboard/builtInWidgets.js.map +1 -1
  217. package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.d.ts +11 -0
  218. package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.d.ts.map +1 -0
  219. package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.js +77 -0
  220. package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.js.map +1 -0
  221. package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.d.ts +10 -0
  222. package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.d.ts.map +1 -0
  223. package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.js +14 -0
  224. package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.js.map +1 -0
  225. package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.d.ts +10 -0
  226. package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.d.ts.map +1 -0
  227. package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.js +14 -0
  228. package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.js.map +1 -0
  229. package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.d.ts +11 -0
  230. package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.d.ts.map +1 -0
  231. package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.js +96 -0
  232. package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.js.map +1 -0
  233. package/dist/ui/src/dashboard/widgets/SeedManagementWidget.d.ts +10 -0
  234. package/dist/ui/src/dashboard/widgets/SeedManagementWidget.d.ts.map +1 -0
  235. package/dist/ui/src/dashboard/widgets/SeedManagementWidget.js +55 -0
  236. package/dist/ui/src/dashboard/widgets/SeedManagementWidget.js.map +1 -0
  237. package/dist/ui/src/dashboard/widgets/ServiceControlWidget.d.ts +10 -0
  238. package/dist/ui/src/dashboard/widgets/ServiceControlWidget.d.ts.map +1 -0
  239. package/dist/ui/src/dashboard/widgets/ServiceControlWidget.js +14 -0
  240. package/dist/ui/src/dashboard/widgets/ServiceControlWidget.js.map +1 -0
  241. package/dist/ui/src/dashboard/widgets/index.d.ts +6 -0
  242. package/dist/ui/src/dashboard/widgets/index.d.ts.map +1 -1
  243. package/dist/ui/src/dashboard/widgets/index.js +6 -0
  244. package/dist/ui/src/dashboard/widgets/index.js.map +1 -1
  245. package/dist/ui/src/pages/DashboardPage.js +1 -1
  246. package/dist/ui/src/pages/DashboardPage.js.map +1 -1
  247. package/dist-ui/assets/index-0gzisPdy.js +528 -0
  248. package/dist-ui/assets/{index-lm1yX6UD.js.map → index-0gzisPdy.js.map} +1 -1
  249. package/dist-ui/index.html +1 -1
  250. package/dist-ui-lib/index.js +3109 -2774
  251. package/dist-ui-lib/index.js.map +1 -1
  252. package/dist-ui-lib/src/api/controlPanelApi.d.ts +10 -1
  253. package/dist-ui-lib/src/dashboard/PluginWidgetRenderer.d.ts +3 -1
  254. package/dist-ui-lib/src/dashboard/widgets/CacheMaintenanceWidget.d.ts +10 -0
  255. package/dist-ui-lib/src/dashboard/widgets/DatabaseOpsWidget.d.ts +9 -0
  256. package/dist-ui-lib/src/dashboard/widgets/EnvironmentConfigWidget.d.ts +9 -0
  257. package/dist-ui-lib/src/dashboard/widgets/LogsMaintenanceWidget.d.ts +10 -0
  258. package/dist-ui-lib/src/dashboard/widgets/SeedManagementWidget.d.ts +9 -0
  259. package/dist-ui-lib/src/dashboard/widgets/ServiceControlWidget.d.ts +9 -0
  260. package/dist-ui-lib/src/dashboard/widgets/index.d.ts +6 -0
  261. package/package.json +12 -6
  262. package/src/core/control-panel.ts +6 -4
  263. package/src/core/gateway.ts +25 -2
  264. package/src/core/plugin-registry.ts +15 -2
  265. package/src/index.ts +53 -0
  266. package/src/plugins/api-keys/api-keys-plugin.ts +64 -20
  267. package/src/plugins/api-keys/index.ts +2 -5
  268. package/src/plugins/api-keys/stores/postgres-store.ts +30 -0
  269. package/src/plugins/api-keys/types.ts +9 -3
  270. package/src/plugins/auth/auth-plugin.ts +4 -2
  271. package/src/plugins/auth/env-config.ts +1 -0
  272. package/src/plugins/auth/index.ts +3 -5
  273. package/src/plugins/bans/bans-plugin.ts +71 -26
  274. package/src/plugins/bans/index.ts +4 -6
  275. package/src/plugins/bans/stores/in-memory-store.ts +106 -0
  276. package/src/plugins/bans/stores/index.ts +1 -0
  277. package/src/plugins/bans/types.ts +13 -6
  278. package/src/plugins/cache-plugin.test.ts +2 -2
  279. package/src/plugins/cache-plugin.ts +331 -30
  280. package/src/plugins/cms/cms-plugin.ts +3 -1
  281. package/src/plugins/devices/devices-plugin.ts +62 -27
  282. package/src/plugins/devices/index.ts +3 -5
  283. package/src/plugins/entitlements/entitlements-plugin.ts +81 -43
  284. package/src/plugins/entitlements/index.ts +4 -6
  285. package/src/plugins/entitlements/sources/in-memory-source.ts +76 -0
  286. package/src/plugins/entitlements/sources/index.ts +1 -0
  287. package/src/plugins/entitlements/types.ts +9 -2
  288. package/src/plugins/health-plugin.ts +1 -0
  289. package/src/plugins/index.ts +4 -1
  290. package/src/plugins/logs-plugin.ts +55 -1
  291. package/src/plugins/maintenance-plugin.ts +43 -0
  292. package/src/plugins/notifications/index.ts +3 -5
  293. package/src/plugins/notifications/notifications-plugin.ts +49 -19
  294. package/src/plugins/parental/index.ts +3 -5
  295. package/src/plugins/parental/parental-plugin.ts +63 -25
  296. package/src/plugins/postgres-plugin.test.ts +2 -2
  297. package/src/plugins/postgres-plugin.ts +20 -9
  298. package/src/plugins/preferences/index.ts +3 -5
  299. package/src/plugins/preferences/preferences-plugin.ts +66 -20
  300. package/src/plugins/profiles/index.ts +3 -5
  301. package/src/plugins/profiles/profiles-plugin.ts +60 -27
  302. package/src/plugins/profiles/types.ts +9 -2
  303. package/src/plugins/qwickbrain/index.ts +3 -5
  304. package/src/plugins/qwickbrain/qwickbrain-plugin.ts +135 -0
  305. package/src/plugins/rate-limit/index.ts +3 -5
  306. package/src/plugins/subscriptions/index.ts +3 -5
  307. package/src/plugins/subscriptions/subscriptions-plugin.ts +63 -30
  308. package/src/plugins/subscriptions/types.ts +8 -2
  309. package/src/plugins/tenants/index.ts +1 -1
  310. package/src/plugins/tenants/stores/in-memory-store.ts +335 -0
  311. package/src/plugins/tenants/stores/index.ts +13 -0
  312. package/src/plugins/tenants/tenants-plugin.ts +97 -62
  313. package/src/plugins/tenants/types.ts +8 -2
  314. package/src/plugins/usage/index.ts +3 -5
  315. package/src/plugins/usage/usage-plugin.ts +60 -26
  316. package/src/plugins/users/index.ts +1 -1
  317. package/src/plugins/users/stores/in-memory-store.ts +140 -0
  318. package/src/plugins/users/stores/index.ts +1 -0
  319. package/src/plugins/users/types.ts +7 -2
  320. package/src/plugins/users/users-plugin.ts +56 -24
  321. package/src/testing/index.ts +1 -0
  322. package/src/testing/pg-mem-pool.ts +33 -0
  323. package/ui/src/api/controlPanelApi.ts +10 -1
  324. package/ui/src/dashboard/PluginWidgetRenderer.tsx +8 -0
  325. package/ui/src/dashboard/builtInWidgets.tsx +19 -1
  326. package/ui/src/dashboard/widgets/CacheMaintenanceWidget.tsx +195 -0
  327. package/ui/src/dashboard/widgets/DatabaseOpsWidget.tsx +29 -0
  328. package/ui/src/dashboard/widgets/EnvironmentConfigWidget.tsx +29 -0
  329. package/ui/src/dashboard/widgets/LogsMaintenanceWidget.tsx +247 -0
  330. package/ui/src/dashboard/widgets/SeedManagementWidget.tsx +128 -0
  331. package/ui/src/dashboard/widgets/ServiceControlWidget.tsx +29 -0
  332. package/ui/src/dashboard/widgets/index.ts +6 -0
  333. package/ui/src/pages/DashboardPage.tsx +2 -2
  334. package/ui/src/pages/MaintenancePage.tsx +1 -1
  335. package/dist-ui/assets/index-lm1yX6UD.js +0 -528
@@ -0,0 +1,257 @@
1
+ /**
2
+ * In-memory Tenant Store for Demo/Testing
3
+ *
4
+ * Implements the TenantStore interface with in-memory storage.
5
+ * Pre-populated with demo tenants and memberships.
6
+ */
7
+ /**
8
+ * Default demo user ID used for pre-populated tenants.
9
+ * Matches the user ID assigned by basic auth guard.
10
+ */
11
+ export const DEMO_USER_ID = 'basic-auth-user';
12
+ /**
13
+ * Creates an in-memory tenant store for demo/testing purposes.
14
+ * Pre-populated with 4 demo tenants (organization, group, department, user).
15
+ *
16
+ * This store is NOT suitable for production use - data is lost on restart.
17
+ * Use postgresTenantsStore for production deployments.
18
+ *
19
+ * @param options - Configuration options for the store
20
+ * @returns TenantStore implementation with in-memory storage
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * import { createInMemoryTenantStore } from '@qwickapps/server';
25
+ *
26
+ * const store = createInMemoryTenantStore({
27
+ * demoUserId: 'test-user-123',
28
+ * logger: console,
29
+ * });
30
+ *
31
+ * await store.initialize();
32
+ * const tenants = await store.getTenantsForUser('test-user-123');
33
+ * ```
34
+ */
35
+ export function createInMemoryTenantStore(options = {}) {
36
+ const demoUserId = options.demoUserId || DEMO_USER_ID;
37
+ const logger = options.logger || {
38
+ info: (msg) => console.log(msg),
39
+ debug: (msg) => console.log(msg),
40
+ };
41
+ const tenants = new Map();
42
+ const memberships = new Map();
43
+ let tenantIdCounter = 1;
44
+ let membershipIdCounter = 1;
45
+ // Pre-populate demo tenants
46
+ const demoTenants = [
47
+ { name: 'Acme Corporation', type: 'organization', owner_id: demoUserId },
48
+ { name: 'Engineering Team', type: 'group', owner_id: demoUserId },
49
+ { name: 'Finance Department', type: 'department', owner_id: demoUserId },
50
+ { name: 'Demo User Workspace', type: 'user', owner_id: demoUserId },
51
+ ];
52
+ demoTenants.forEach((t) => {
53
+ const id = `tenant-${tenantIdCounter++}`;
54
+ const tenant = {
55
+ id,
56
+ name: t.name,
57
+ type: t.type,
58
+ owner_id: t.owner_id,
59
+ metadata: {},
60
+ created_at: new Date(),
61
+ updated_at: new Date(),
62
+ };
63
+ tenants.set(id, tenant);
64
+ // Auto-create membership for owner
65
+ const membershipId = `membership-${membershipIdCounter++}`;
66
+ const membership = {
67
+ id: membershipId,
68
+ tenant_id: id,
69
+ user_id: t.owner_id,
70
+ role: 'owner',
71
+ joined_at: new Date(),
72
+ };
73
+ memberships.set(membershipId, membership);
74
+ });
75
+ return {
76
+ name: 'in-memory',
77
+ async initialize() {
78
+ logger.info('[InMemoryTenantStore] Initialized with demo tenants');
79
+ },
80
+ async getById(id) {
81
+ return tenants.get(id) || null;
82
+ },
83
+ async getByIds(ids) {
84
+ return ids.map((id) => tenants.get(id)).filter((t) => t !== undefined);
85
+ },
86
+ async getByName(name) {
87
+ for (const tenant of tenants.values()) {
88
+ if (tenant.name.toLowerCase() === name.toLowerCase()) {
89
+ return tenant;
90
+ }
91
+ }
92
+ return null;
93
+ },
94
+ async create(input) {
95
+ const id = `tenant-${tenantIdCounter++}`;
96
+ const tenant = {
97
+ id,
98
+ name: input.name,
99
+ type: input.type,
100
+ owner_id: input.owner_id,
101
+ metadata: input.metadata || {},
102
+ created_at: new Date(),
103
+ updated_at: new Date(),
104
+ };
105
+ tenants.set(id, tenant);
106
+ // Auto-create membership for owner
107
+ const membershipId = `membership-${membershipIdCounter++}`;
108
+ const membership = {
109
+ id: membershipId,
110
+ tenant_id: id,
111
+ user_id: input.owner_id,
112
+ role: 'owner',
113
+ joined_at: new Date(),
114
+ };
115
+ memberships.set(membershipId, membership);
116
+ return tenant;
117
+ },
118
+ async update(id, input) {
119
+ const tenant = tenants.get(id);
120
+ if (!tenant)
121
+ return null;
122
+ const updated = {
123
+ ...tenant,
124
+ ...input,
125
+ id: tenant.id, // Preserve ID
126
+ created_at: tenant.created_at, // Preserve created_at
127
+ updated_at: new Date(),
128
+ };
129
+ tenants.set(id, updated);
130
+ return updated;
131
+ },
132
+ async delete(id) {
133
+ // Delete all memberships for this tenant
134
+ for (const [key, membership] of memberships.entries()) {
135
+ if (membership.tenant_id === id) {
136
+ memberships.delete(key);
137
+ }
138
+ }
139
+ return tenants.delete(id);
140
+ },
141
+ async search(params = {}) {
142
+ let result = Array.from(tenants.values());
143
+ if (params.query) {
144
+ const query = params.query.toLowerCase();
145
+ result = result.filter((t) => t.name.toLowerCase().includes(query));
146
+ }
147
+ if (params.type) {
148
+ result = result.filter((t) => t.type === params.type);
149
+ }
150
+ if (params.owner_id) {
151
+ result = result.filter((t) => t.owner_id === params.owner_id);
152
+ }
153
+ const sortBy = params.sortBy || 'created_at';
154
+ const sortOrder = params.sortOrder || 'desc';
155
+ result.sort((a, b) => {
156
+ const aVal = a[sortBy];
157
+ const bVal = b[sortBy];
158
+ if (aVal == null || bVal == null)
159
+ return 0;
160
+ if (aVal < bVal)
161
+ return sortOrder === 'asc' ? -1 : 1;
162
+ if (aVal > bVal)
163
+ return sortOrder === 'asc' ? 1 : -1;
164
+ return 0;
165
+ });
166
+ const total = result.length;
167
+ const page = params.page || 1;
168
+ const limit = params.limit || 20;
169
+ const offset = (page - 1) * limit;
170
+ result = result.slice(offset, offset + limit);
171
+ return {
172
+ tenants: result,
173
+ total,
174
+ page,
175
+ limit,
176
+ totalPages: Math.ceil(total / limit),
177
+ };
178
+ },
179
+ async getTenantsForUser(userId) {
180
+ const userMemberships = Array.from(memberships.values()).filter((m) => m.user_id === userId);
181
+ const results = [];
182
+ for (const membership of userMemberships) {
183
+ const tenant = tenants.get(membership.tenant_id);
184
+ if (tenant) {
185
+ results.push({
186
+ ...tenant,
187
+ user_role: membership.role,
188
+ membership,
189
+ });
190
+ }
191
+ }
192
+ return results;
193
+ },
194
+ async getTenantForUser(tenantId, userId) {
195
+ const membership = await this.getMembership(tenantId, userId);
196
+ if (!membership)
197
+ return null;
198
+ const tenant = tenants.get(tenantId);
199
+ if (!tenant)
200
+ return null;
201
+ return {
202
+ ...tenant,
203
+ user_role: membership.role,
204
+ membership,
205
+ };
206
+ },
207
+ async getMembers(tenantId) {
208
+ return Array.from(memberships.values()).filter((m) => m.tenant_id === tenantId);
209
+ },
210
+ async getMembership(tenantId, userId) {
211
+ for (const membership of memberships.values()) {
212
+ if (membership.tenant_id === tenantId && membership.user_id === userId) {
213
+ return membership;
214
+ }
215
+ }
216
+ return null;
217
+ },
218
+ async addMember(input) {
219
+ const id = `membership-${membershipIdCounter++}`;
220
+ const membership = {
221
+ id,
222
+ tenant_id: input.tenant_id,
223
+ user_id: input.user_id,
224
+ role: input.role,
225
+ joined_at: new Date(),
226
+ };
227
+ memberships.set(id, membership);
228
+ return membership;
229
+ },
230
+ async updateMember(tenantId, userId, input) {
231
+ for (const membership of memberships.values()) {
232
+ if (membership.tenant_id === tenantId && membership.user_id === userId) {
233
+ const updated = {
234
+ ...membership,
235
+ ...input,
236
+ };
237
+ memberships.set(membership.id, updated);
238
+ return updated;
239
+ }
240
+ }
241
+ return null;
242
+ },
243
+ async removeMember(tenantId, userId) {
244
+ for (const [key, membership] of memberships.entries()) {
245
+ if (membership.tenant_id === tenantId && membership.user_id === userId) {
246
+ memberships.delete(key);
247
+ return true;
248
+ }
249
+ }
250
+ return false;
251
+ },
252
+ async shutdown() {
253
+ logger.info('[InMemoryTenantStore] Shutdown');
254
+ },
255
+ };
256
+ }
257
+ //# sourceMappingURL=in-memory-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-store.js","sourceRoot":"","sources":["../../../../../src/plugins/tenants/stores/in-memory-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tenant Stores Index
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+ export { postgresTenantStore } from './postgres-store.js';
7
+ export { createInMemoryTenantStore as inMemoryTenantStore, DEMO_USER_ID, type InMemoryStoreLogger, type InMemoryTenantStoreOptions, } from './in-memory-store.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/tenants/stores/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EACL,yBAAyB,IAAI,mBAAmB,EAChD,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,GAChC,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tenant Stores Index
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+ export { postgresTenantStore } from './postgres-store.js';
7
+ export { createInMemoryTenantStore as inMemoryTenantStore, DEMO_USER_ID, } from './in-memory-store.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/plugins/tenants/stores/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EACL,yBAAyB,IAAI,mBAAmB,EAChD,YAAY,GAGb,MAAM,sBAAsB,CAAC"}
@@ -12,9 +12,12 @@
12
12
  import type { Plugin } from '../../core/plugin-registry.js';
13
13
  import type { TenantsPluginConfig, TenantStore } from './types.js';
14
14
  /**
15
- * Create the Tenants plugin
15
+ * Create the Tenants plugin with smart defaults
16
+ *
17
+ * Config is optional - plugin will use defaults and get dependencies from registry.
18
+ * Gracefully handles missing dependencies with clear log messages.
16
19
  */
17
- export declare function createTenantsPlugin(config: TenantsPluginConfig): Plugin;
20
+ export declare function createTenantsPlugin(config?: Partial<TenantsPluginConfig>): Plugin;
18
21
  /**
19
22
  * Helper function to get the tenant store
20
23
  * Used by other plugins to access tenant data
@@ -1 +1 @@
1
- {"version":3,"file":"tenants-plugin.d.ts","sourceRoot":"","sources":["../../../../src/plugins/tenants/tenants-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAgC,MAAM,+BAA+B,CAAC;AAC1F,OAAO,KAAK,EACV,mBAAmB,EACnB,WAAW,EAMZ,MAAM,YAAY,CAAC;AAQpB;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAumBvE;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAK5C;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAqC3E"}
1
+ {"version":3,"file":"tenants-plugin.d.ts","sourceRoot":"","sources":["../../../../src/plugins/tenants/tenants-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAgC,MAAM,+BAA+B,CAAC;AAC1F,OAAO,KAAK,EACV,mBAAmB,EACnB,WAAW,EAMZ,MAAM,YAAY,CAAC;AAUpB;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM,GAAG,MAAM,CAqoBrF;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAK5C;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAqC3E"}
@@ -11,55 +11,25 @@
11
11
  */
12
12
  import { getUserById } from '../users/users-plugin.js';
13
13
  import { getAuthenticatedUser, isAuthenticated } from '../auth/index.js';
14
+ import { hasPostgres, getPostgres } from '../postgres-plugin.js';
15
+ import { postgresTenantStore } from './stores/index.js';
14
16
  // Store instance and registry for helper access
15
17
  let currentStore = null;
16
18
  let currentRegistry = null;
17
19
  /**
18
- * Create the Tenants plugin
20
+ * Create the Tenants plugin with smart defaults
21
+ *
22
+ * Config is optional - plugin will use defaults and get dependencies from registry.
23
+ * Gracefully handles missing dependencies with clear log messages.
19
24
  */
20
- export function createTenantsPlugin(config) {
21
- const debug = config.debug || false;
22
- const apiPrefix = config.apiPrefix || '/';
23
- const apiEnabled = config.apiEnabled !== false;
24
- function log(message, data) {
25
- if (debug) {
26
- console.log(`[TenantsPlugin] ${message}`, data || '');
27
- }
28
- }
29
- /**
30
- * Helper to check if user has access to a tenant
31
- */
32
- async function canAccessTenant(userId, tenantId) {
33
- try {
34
- const membership = await config.store.getTenantForUser(tenantId, userId);
35
- return membership !== null;
36
- }
37
- catch {
38
- return false;
25
+ export function createTenantsPlugin(config = {}) {
26
+ function log(message, data, isError = false) {
27
+ const prefix = '[TenantsPlugin]';
28
+ if (isError) {
29
+ console.error(`${prefix} ${message}`, data || '');
39
30
  }
40
- }
41
- /**
42
- * Helper to check if user has admin/owner role in a tenant
43
- */
44
- async function canManageTenant(userId, tenantId) {
45
- try {
46
- const membership = await config.store.getTenantForUser(tenantId, userId);
47
- return membership !== null && ['owner', 'admin'].includes(membership.user_role);
48
- }
49
- catch {
50
- return false;
51
- }
52
- }
53
- /**
54
- * Helper to check if user is owner of a tenant
55
- */
56
- async function isOwnerOfTenant(userId, tenantId) {
57
- try {
58
- const membership = await config.store.getTenantForUser(tenantId, userId);
59
- return membership !== null && membership.user_role === 'owner';
60
- }
61
- catch {
62
- return false;
31
+ else if (config.debug) {
32
+ console.log(`${prefix} ${message}`, data || '');
63
33
  }
64
34
  }
65
35
  return {
@@ -67,12 +37,37 @@ export function createTenantsPlugin(config) {
67
37
  name: 'Tenants',
68
38
  version: '1.0.0',
69
39
  async onStart(_pluginConfig, registry) {
40
+ const logger = registry.getLogger('tenants');
41
+ // Check for postgres in registry
42
+ if (!hasPostgres()) {
43
+ logger.warn('No Database! Tenants plugin disabled.');
44
+ registry.registerHealthCheck({
45
+ name: 'tenants-store',
46
+ type: 'custom',
47
+ check: async () => ({
48
+ healthy: false,
49
+ details: {
50
+ error: 'PostgreSQL not available',
51
+ state: 'disabled',
52
+ },
53
+ }),
54
+ });
55
+ return;
56
+ }
57
+ // Smart defaults - get dependencies from registry
58
+ const store = config.store ?? postgresTenantStore({
59
+ pool: () => getPostgres().getPool(),
60
+ autoCreateTables: true,
61
+ });
62
+ const debug = config.debug ?? false;
63
+ const apiPrefix = config.apiPrefix ?? '/tenants';
64
+ const apiEnabled = config.apiEnabled ?? true;
70
65
  log('Starting tenants plugin');
71
66
  // Initialize the store (creates tables if needed)
72
- await config.store.initialize();
67
+ await store.initialize();
73
68
  log('Tenants plugin migrations complete');
74
69
  // Store references for helper access
75
- currentStore = config.store;
70
+ currentStore = store;
76
71
  currentRegistry = registry;
77
72
  // Register health check
78
73
  registry.registerHealthCheck({
@@ -81,7 +76,7 @@ export function createTenantsPlugin(config) {
81
76
  check: async () => {
82
77
  try {
83
78
  // Simple health check - try to search with limit 1
84
- await config.store.search({ limit: 1 });
79
+ await store.search({ limit: 1 });
85
80
  return { healthy: true };
86
81
  }
87
82
  catch {
@@ -89,6 +84,42 @@ export function createTenantsPlugin(config) {
89
84
  }
90
85
  },
91
86
  });
87
+ /**
88
+ * Helper to check if user has access to a tenant
89
+ */
90
+ async function canAccessTenant(userId, tenantId) {
91
+ try {
92
+ const membership = await store.getTenantForUser(tenantId, userId);
93
+ return membership !== null;
94
+ }
95
+ catch {
96
+ return false;
97
+ }
98
+ }
99
+ /**
100
+ * Helper to check if user has admin/owner role in a tenant
101
+ */
102
+ async function canManageTenant(userId, tenantId) {
103
+ try {
104
+ const membership = await store.getTenantForUser(tenantId, userId);
105
+ return membership !== null && ['owner', 'admin'].includes(membership.user_role);
106
+ }
107
+ catch {
108
+ return false;
109
+ }
110
+ }
111
+ /**
112
+ * Helper to check if user is owner of a tenant
113
+ */
114
+ async function isOwnerOfTenant(userId, tenantId) {
115
+ try {
116
+ const membership = await store.getTenantForUser(tenantId, userId);
117
+ return membership !== null && membership.user_role === 'owner';
118
+ }
119
+ catch {
120
+ return false;
121
+ }
122
+ }
92
123
  if (!apiEnabled)
93
124
  return;
94
125
  // ========================================================================
@@ -97,7 +128,7 @@ export function createTenantsPlugin(config) {
97
128
  // List/Search tenants
98
129
  registry.addRoute({
99
130
  method: 'get',
100
- path: apiPrefix,
131
+ path: apiPrefix || '/',
101
132
  pluginId: 'tenants',
102
133
  handler: async (req, res) => {
103
134
  try {
@@ -117,7 +148,7 @@ export function createTenantsPlugin(config) {
117
148
  }
118
149
  // Users can only search their own tenants
119
150
  // Get all tenants user belongs to
120
- const userTenants = await config.store.getTenantsForUser(user.id);
151
+ const userTenants = await store.getTenantsForUser(user.id);
121
152
  res.json({
122
153
  tenants: userTenants,
123
154
  total: userTenants.length,
@@ -160,7 +191,7 @@ export function createTenantsPlugin(config) {
160
191
  message: 'You do not have access to this tenant',
161
192
  });
162
193
  }
163
- const tenant = await config.store.getById(req.params.id);
194
+ const tenant = await store.getById(req.params.id);
164
195
  if (!tenant) {
165
196
  return res.status(404).json({ error: 'Tenant not found' });
166
197
  }
@@ -175,7 +206,7 @@ export function createTenantsPlugin(config) {
175
206
  // Create tenant
176
207
  registry.addRoute({
177
208
  method: 'post',
178
- path: apiPrefix,
209
+ path: apiPrefix || '/',
179
210
  pluginId: 'tenants',
180
211
  handler: async (req, res) => {
181
212
  try {
@@ -219,9 +250,9 @@ export function createTenantsPlugin(config) {
219
250
  message: 'You can only create tenants for yourself',
220
251
  });
221
252
  }
222
- const tenant = await config.store.create(input);
253
+ const tenant = await store.create(input);
223
254
  // Automatically add creator as owner
224
- await config.store.addMember({
255
+ await store.addMember({
225
256
  tenant_id: tenant.id,
226
257
  user_id: user.id,
227
258
  role: 'owner',
@@ -267,7 +298,7 @@ export function createTenantsPlugin(config) {
267
298
  name: req.body.name,
268
299
  metadata: req.body.metadata,
269
300
  };
270
- const tenant = await config.store.update(req.params.id, input);
301
+ const tenant = await store.update(req.params.id, input);
271
302
  if (!tenant) {
272
303
  return res.status(404).json({ error: 'Tenant not found' });
273
304
  }
@@ -308,7 +339,7 @@ export function createTenantsPlugin(config) {
308
339
  message: 'Only owners can delete tenants',
309
340
  });
310
341
  }
311
- const deleted = await config.store.delete(req.params.id);
342
+ const deleted = await store.delete(req.params.id);
312
343
  if (!deleted) {
313
344
  return res.status(404).json({ error: 'Tenant not found' });
314
345
  }
@@ -352,7 +383,7 @@ export function createTenantsPlugin(config) {
352
383
  message: 'You can only view your own tenants',
353
384
  });
354
385
  }
355
- const tenants = await config.store.getTenantsForUser(req.params.userId);
386
+ const tenants = await store.getTenantsForUser(req.params.userId);
356
387
  res.json({ tenants, total: tenants.length });
357
388
  }
358
389
  catch (error) {
@@ -392,7 +423,7 @@ export function createTenantsPlugin(config) {
392
423
  message: 'You do not have access to this tenant',
393
424
  });
394
425
  }
395
- const members = await config.store.getMembers(req.params.tenantId);
426
+ const members = await store.getMembers(req.params.tenantId);
396
427
  res.json({ members, total: members.length });
397
428
  }
398
429
  catch (error) {
@@ -447,7 +478,7 @@ export function createTenantsPlugin(config) {
447
478
  error: `Invalid role. Must be one of: ${validRoles.join(', ')}`,
448
479
  });
449
480
  }
450
- const membership = await config.store.addMember(input);
481
+ const membership = await store.addMember(input);
451
482
  log('Member added to tenant', {
452
483
  tenantId: input.tenant_id,
453
484
  userId: input.user_id,
@@ -503,7 +534,7 @@ export function createTenantsPlugin(config) {
503
534
  error: `Invalid role. Must be one of: ${validRoles.join(', ')}`,
504
535
  });
505
536
  }
506
- const membership = await config.store.updateMember(req.params.tenantId, req.params.userId, input);
537
+ const membership = await store.updateMember(req.params.tenantId, req.params.userId, input);
507
538
  if (!membership) {
508
539
  return res.status(404).json({ error: 'Membership not found' });
509
540
  }
@@ -549,7 +580,7 @@ export function createTenantsPlugin(config) {
549
580
  message: 'Only admins and owners can remove members',
550
581
  });
551
582
  }
552
- const deleted = await config.store.removeMember(req.params.tenantId, req.params.userId);
583
+ const deleted = await store.removeMember(req.params.tenantId, req.params.userId);
553
584
  if (!deleted) {
554
585
  return res.status(404).json({ error: 'Membership not found' });
555
586
  }
@@ -570,7 +601,9 @@ export function createTenantsPlugin(config) {
570
601
  },
571
602
  async onStop() {
572
603
  log('Stopping tenants plugin');
573
- await config.store.shutdown();
604
+ if (currentStore) {
605
+ await currentStore.shutdown();
606
+ }
574
607
  currentStore = null;
575
608
  currentRegistry = null;
576
609
  },