@qwickapps/server 1.8.1 → 1.9.0

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 (231) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +4 -4
  3. package/dist/src/core/control-panel.d.ts.map +1 -1
  4. package/dist/src/core/control-panel.js +10 -7
  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 +46 -47
  8. package/dist/src/core/gateway.js.map +1 -1
  9. package/dist/src/plugins/api-keys/ApiKeysManagementPage.d.ts.map +1 -1
  10. package/dist/src/plugins/api-keys/ApiKeysManagementPage.js +1 -1
  11. package/dist/src/plugins/api-keys/ApiKeysManagementPage.js.map +1 -1
  12. package/dist/src/plugins/api-keys/ApiKeysStatusWidget.d.ts.map +1 -1
  13. package/dist/src/plugins/api-keys/ApiKeysStatusWidget.js +1 -1
  14. package/dist/src/plugins/api-keys/ApiKeysStatusWidget.js.map +1 -1
  15. package/dist/src/plugins/auth/AuthManagementPage.d.ts.map +1 -1
  16. package/dist/src/plugins/auth/AuthManagementPage.js +1 -1
  17. package/dist/src/plugins/auth/AuthManagementPage.js.map +1 -1
  18. package/dist/src/plugins/auth/AuthStatusWidget.d.ts.map +1 -1
  19. package/dist/src/plugins/auth/AuthStatusWidget.js +1 -1
  20. package/dist/src/plugins/auth/AuthStatusWidget.js.map +1 -1
  21. package/dist/src/plugins/auth/auth-plugin.d.ts.map +1 -1
  22. package/dist/src/plugins/auth/auth-plugin.js +9 -0
  23. package/dist/src/plugins/auth/auth-plugin.js.map +1 -1
  24. package/dist/src/plugins/bans/BansManagementPage.d.ts.map +1 -1
  25. package/dist/src/plugins/bans/BansManagementPage.js +1 -1
  26. package/dist/src/plugins/bans/BansManagementPage.js.map +1 -1
  27. package/dist/src/plugins/bans/BansStatusWidget.d.ts.map +1 -1
  28. package/dist/src/plugins/bans/BansStatusWidget.js +1 -1
  29. package/dist/src/plugins/bans/BansStatusWidget.js.map +1 -1
  30. package/dist/src/plugins/cache/CacheManagementPage.js +1 -1
  31. package/dist/src/plugins/cache/CacheManagementPage.js.map +1 -1
  32. package/dist/src/plugins/cache/CacheStatusWidget.js +1 -1
  33. package/dist/src/plugins/cache/CacheStatusWidget.js.map +1 -1
  34. package/dist/src/plugins/devices/DevicesManagementPage.d.ts.map +1 -1
  35. package/dist/src/plugins/devices/DevicesManagementPage.js +1 -1
  36. package/dist/src/plugins/devices/DevicesManagementPage.js.map +1 -1
  37. package/dist/src/plugins/devices/DevicesStatusWidget.d.ts.map +1 -1
  38. package/dist/src/plugins/devices/DevicesStatusWidget.js +1 -1
  39. package/dist/src/plugins/devices/DevicesStatusWidget.js.map +1 -1
  40. package/dist/src/plugins/diagnostics/DiagnosticsManagementPage.js +1 -1
  41. package/dist/src/plugins/diagnostics/DiagnosticsManagementPage.js.map +1 -1
  42. package/dist/src/plugins/diagnostics/DiagnosticsStatusWidget.js +1 -1
  43. package/dist/src/plugins/diagnostics/DiagnosticsStatusWidget.js.map +1 -1
  44. package/dist/src/plugins/entitlements/EntitlementsManagementPage.d.ts.map +1 -1
  45. package/dist/src/plugins/entitlements/EntitlementsManagementPage.js +1 -1
  46. package/dist/src/plugins/entitlements/EntitlementsManagementPage.js.map +1 -1
  47. package/dist/src/plugins/entitlements/EntitlementsStatusWidget.d.ts.map +1 -1
  48. package/dist/src/plugins/entitlements/EntitlementsStatusWidget.js +1 -1
  49. package/dist/src/plugins/entitlements/EntitlementsStatusWidget.js.map +1 -1
  50. package/dist/src/plugins/health/HealthManagementPage.js +1 -1
  51. package/dist/src/plugins/health/HealthManagementPage.js.map +1 -1
  52. package/dist/src/plugins/health/HealthStatusWidget.js +1 -1
  53. package/dist/src/plugins/health/HealthStatusWidget.js.map +1 -1
  54. package/dist/src/plugins/logs/LogsManagementPage.js +1 -1
  55. package/dist/src/plugins/logs/LogsManagementPage.js.map +1 -1
  56. package/dist/src/plugins/logs/LogsStatusWidget.js +1 -1
  57. package/dist/src/plugins/logs/LogsStatusWidget.js.map +1 -1
  58. package/dist/src/plugins/maintenance/MaintenanceManagementPage.js +1 -1
  59. package/dist/src/plugins/maintenance/MaintenanceManagementPage.js.map +1 -1
  60. package/dist/src/plugins/maintenance/MaintenanceStatusWidget.js +1 -1
  61. package/dist/src/plugins/maintenance/MaintenanceStatusWidget.js.map +1 -1
  62. package/dist/src/plugins/maintenance/SeedManagementPage.js +1 -1
  63. package/dist/src/plugins/maintenance/SeedManagementPage.js.map +1 -1
  64. package/dist/src/plugins/maintenance/seed-executor.js +2 -2
  65. package/dist/src/plugins/maintenance/seed-executor.js.map +1 -1
  66. package/dist/src/plugins/maintenance-plugin.d.ts +2 -0
  67. package/dist/src/plugins/maintenance-plugin.d.ts.map +1 -1
  68. package/dist/src/plugins/maintenance-plugin.js +402 -2
  69. package/dist/src/plugins/maintenance-plugin.js.map +1 -1
  70. package/dist/src/plugins/notifications/NotificationsManagementPage.js +1 -1
  71. package/dist/src/plugins/notifications/NotificationsManagementPage.js.map +1 -1
  72. package/dist/src/plugins/notifications/NotificationsStatusWidget.d.ts.map +1 -1
  73. package/dist/src/plugins/notifications/NotificationsStatusWidget.js +1 -1
  74. package/dist/src/plugins/notifications/NotificationsStatusWidget.js.map +1 -1
  75. package/dist/src/plugins/parental/ParentalManagementPage.d.ts.map +1 -1
  76. package/dist/src/plugins/parental/ParentalManagementPage.js +1 -1
  77. package/dist/src/plugins/parental/ParentalManagementPage.js.map +1 -1
  78. package/dist/src/plugins/parental/ParentalStatusWidget.d.ts.map +1 -1
  79. package/dist/src/plugins/parental/ParentalStatusWidget.js +1 -1
  80. package/dist/src/plugins/parental/ParentalStatusWidget.js.map +1 -1
  81. package/dist/src/plugins/postgres/PostgresManagementPage.js +1 -1
  82. package/dist/src/plugins/postgres/PostgresManagementPage.js.map +1 -1
  83. package/dist/src/plugins/postgres/PostgresStatusWidget.js +1 -1
  84. package/dist/src/plugins/postgres/PostgresStatusWidget.js.map +1 -1
  85. package/dist/src/plugins/preferences/PreferencesManagementPage.d.ts.map +1 -1
  86. package/dist/src/plugins/preferences/PreferencesManagementPage.js +1 -1
  87. package/dist/src/plugins/preferences/PreferencesManagementPage.js.map +1 -1
  88. package/dist/src/plugins/preferences/PreferencesStatusWidget.d.ts.map +1 -1
  89. package/dist/src/plugins/preferences/PreferencesStatusWidget.js +1 -1
  90. package/dist/src/plugins/preferences/PreferencesStatusWidget.js.map +1 -1
  91. package/dist/src/plugins/profiles/ProfilesManagementPage.d.ts.map +1 -1
  92. package/dist/src/plugins/profiles/ProfilesManagementPage.js +1 -1
  93. package/dist/src/plugins/profiles/ProfilesManagementPage.js.map +1 -1
  94. package/dist/src/plugins/profiles/ProfilesStatusWidget.d.ts.map +1 -1
  95. package/dist/src/plugins/profiles/ProfilesStatusWidget.js +1 -1
  96. package/dist/src/plugins/profiles/ProfilesStatusWidget.js.map +1 -1
  97. package/dist/src/plugins/qwickbrain/QwickbrainManagementPage.js +1 -1
  98. package/dist/src/plugins/qwickbrain/QwickbrainManagementPage.js.map +1 -1
  99. package/dist/src/plugins/qwickbrain/QwickbrainStatusWidget.d.ts.map +1 -1
  100. package/dist/src/plugins/qwickbrain/QwickbrainStatusWidget.js +1 -1
  101. package/dist/src/plugins/qwickbrain/QwickbrainStatusWidget.js.map +1 -1
  102. package/dist/src/plugins/rate-limit/RateLimitManagementPage.js +1 -1
  103. package/dist/src/plugins/rate-limit/RateLimitManagementPage.js.map +1 -1
  104. package/dist/src/plugins/rate-limit/RateLimitStatusWidget.d.ts.map +1 -1
  105. package/dist/src/plugins/rate-limit/RateLimitStatusWidget.js +1 -1
  106. package/dist/src/plugins/rate-limit/RateLimitStatusWidget.js.map +1 -1
  107. package/dist/src/plugins/subscriptions/SubscriptionsManagementPage.d.ts.map +1 -1
  108. package/dist/src/plugins/subscriptions/SubscriptionsManagementPage.js +1 -1
  109. package/dist/src/plugins/subscriptions/SubscriptionsManagementPage.js.map +1 -1
  110. package/dist/src/plugins/subscriptions/SubscriptionsStatusWidget.d.ts.map +1 -1
  111. package/dist/src/plugins/subscriptions/SubscriptionsStatusWidget.js +1 -1
  112. package/dist/src/plugins/subscriptions/SubscriptionsStatusWidget.js.map +1 -1
  113. package/dist/src/plugins/usage/UsageManagementPage.d.ts.map +1 -1
  114. package/dist/src/plugins/usage/UsageManagementPage.js +1 -1
  115. package/dist/src/plugins/usage/UsageManagementPage.js.map +1 -1
  116. package/dist/src/plugins/usage/UsageStatusWidget.d.ts.map +1 -1
  117. package/dist/src/plugins/usage/UsageStatusWidget.js +1 -1
  118. package/dist/src/plugins/usage/UsageStatusWidget.js.map +1 -1
  119. package/dist/src/plugins/users/UsersManagementPage.js +1 -1
  120. package/dist/src/plugins/users/UsersManagementPage.js.map +1 -1
  121. package/dist/src/plugins/users/UsersStatusWidget.js +1 -1
  122. package/dist/src/plugins/users/UsersStatusWidget.js.map +1 -1
  123. package/dist/ui/src/api/clientBuilder.d.ts +3 -3
  124. package/dist/ui/src/api/clientBuilder.js +5 -5
  125. package/dist/ui/src/api/clientBuilder.js.map +1 -1
  126. package/dist/ui/src/api/controlPanelApi.js +19 -19
  127. package/dist/ui/src/api/controlPanelApi.js.map +1 -1
  128. package/dist/ui/src/components/ControlPanelApp.d.ts.map +1 -1
  129. package/dist/ui/src/components/ControlPanelApp.js +5 -4
  130. package/dist/ui/src/components/ControlPanelApp.js.map +1 -1
  131. package/dist/ui/src/dashboard/builtInWidgets.d.ts.map +1 -1
  132. package/dist/ui/src/dashboard/builtInWidgets.js +3 -1
  133. package/dist/ui/src/dashboard/builtInWidgets.js.map +1 -1
  134. package/dist/ui/src/dashboard/widgets/CMSMaintenanceWidget.js +8 -8
  135. package/dist/ui/src/dashboard/widgets/CMSMaintenanceWidget.js.map +1 -1
  136. package/dist/ui/src/dashboard/widgets/CMSStatusWidget.js +2 -2
  137. package/dist/ui/src/dashboard/widgets/CMSStatusWidget.js.map +1 -1
  138. package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.js +4 -4
  139. package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.js.map +1 -1
  140. package/dist/ui/src/dashboard/widgets/DatabaseOperationsWidget.d.ts.map +1 -1
  141. package/dist/ui/src/dashboard/widgets/DatabaseOperationsWidget.js +2 -1
  142. package/dist/ui/src/dashboard/widgets/DatabaseOperationsWidget.js.map +1 -1
  143. package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.js +6 -6
  144. package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.js.map +1 -1
  145. package/dist/ui/src/dashboard/widgets/MigrationManagementWidget.d.ts +8 -0
  146. package/dist/ui/src/dashboard/widgets/MigrationManagementWidget.d.ts.map +1 -0
  147. package/dist/ui/src/dashboard/widgets/MigrationManagementWidget.js +132 -0
  148. package/dist/ui/src/dashboard/widgets/MigrationManagementWidget.js.map +1 -0
  149. package/dist/ui/src/dashboard/widgets/SeedManagementWidget.js +6 -6
  150. package/dist/ui/src/dashboard/widgets/SeedManagementWidget.js.map +1 -1
  151. package/dist/ui/src/dashboard/widgets/index.d.ts +1 -0
  152. package/dist/ui/src/dashboard/widgets/index.d.ts.map +1 -1
  153. package/dist/ui/src/dashboard/widgets/index.js +1 -0
  154. package/dist/ui/src/dashboard/widgets/index.js.map +1 -1
  155. package/dist-ui/assets/{index-DRG9n0cx.css → index-De-dCl_t.css} +1 -1
  156. package/dist-ui/assets/{index-D-4HKPkw.js → index-DnEQCOGR.js} +112 -109
  157. package/dist-ui/assets/{index-D-4HKPkw.js.map → index-DnEQCOGR.js.map} +1 -1
  158. package/dist-ui/index.html +2 -2
  159. package/dist-ui-lib/index.js +2623 -2441
  160. package/dist-ui-lib/index.js.map +1 -1
  161. package/dist-ui-lib/src/api/clientBuilder.d.ts +3 -3
  162. package/dist-ui-lib/src/dashboard/widgets/MigrationManagementWidget.d.ts +7 -0
  163. package/dist-ui-lib/src/dashboard/widgets/index.d.ts +1 -0
  164. package/package.json +5 -2
  165. package/src/core/control-panel.ts +10 -7
  166. package/src/core/gateway.ts +48 -51
  167. package/src/plugins/api-keys/ApiKeysManagementPage.tsx +1 -1
  168. package/src/plugins/api-keys/ApiKeysStatusWidget.tsx +1 -1
  169. package/src/plugins/auth/AuthManagementPage.tsx +1 -1
  170. package/src/plugins/auth/AuthStatusWidget.tsx +1 -1
  171. package/src/plugins/auth/adapters/supertokens-adapter.ts +9 -13
  172. package/src/plugins/auth/auth-plugin.ts +10 -0
  173. package/src/plugins/auth/env-config.ts +1 -0
  174. package/src/plugins/auth/types.ts +2 -0
  175. package/src/plugins/bans/BansManagementPage.tsx +1 -1
  176. package/src/plugins/bans/BansStatusWidget.tsx +1 -1
  177. package/src/plugins/cache/CacheManagementPage.tsx +1 -1
  178. package/src/plugins/cache/CacheStatusWidget.tsx +1 -1
  179. package/src/plugins/devices/DevicesManagementPage.tsx +1 -1
  180. package/src/plugins/devices/DevicesStatusWidget.tsx +1 -1
  181. package/src/plugins/diagnostics/DiagnosticsManagementPage.tsx +1 -1
  182. package/src/plugins/diagnostics/DiagnosticsStatusWidget.tsx +1 -1
  183. package/src/plugins/entitlements/EntitlementsManagementPage.tsx +1 -1
  184. package/src/plugins/entitlements/EntitlementsStatusWidget.tsx +1 -1
  185. package/src/plugins/health/HealthManagementPage.tsx +1 -1
  186. package/src/plugins/health/HealthStatusWidget.tsx +1 -1
  187. package/src/plugins/logs/LogsManagementPage.tsx +1 -1
  188. package/src/plugins/logs/LogsStatusWidget.tsx +1 -1
  189. package/src/plugins/maintenance/MaintenanceManagementPage.tsx +1 -1
  190. package/src/plugins/maintenance/MaintenanceStatusWidget.tsx +1 -1
  191. package/src/plugins/maintenance/SeedManagementPage.tsx +1 -1
  192. package/src/plugins/maintenance/seed-executor.ts +7 -6
  193. package/src/plugins/maintenance-plugin.ts +501 -5
  194. package/src/plugins/notifications/NotificationsManagementPage.tsx +1 -1
  195. package/src/plugins/notifications/NotificationsStatusWidget.tsx +1 -1
  196. package/src/plugins/parental/ParentalManagementPage.tsx +1 -1
  197. package/src/plugins/parental/ParentalStatusWidget.tsx +1 -1
  198. package/src/plugins/postgres/PostgresManagementPage.tsx +1 -1
  199. package/src/plugins/postgres/PostgresStatusWidget.tsx +1 -1
  200. package/src/plugins/preferences/PreferencesManagementPage.tsx +1 -1
  201. package/src/plugins/preferences/PreferencesStatusWidget.tsx +1 -1
  202. package/src/plugins/profiles/ProfilesManagementPage.tsx +1 -1
  203. package/src/plugins/profiles/ProfilesStatusWidget.tsx +1 -1
  204. package/src/plugins/qwickbrain/QwickbrainManagementPage.tsx +1 -1
  205. package/src/plugins/qwickbrain/QwickbrainStatusWidget.tsx +1 -1
  206. package/src/plugins/rate-limit/RateLimitManagementPage.tsx +1 -1
  207. package/src/plugins/rate-limit/RateLimitStatusWidget.tsx +1 -1
  208. package/src/plugins/subscriptions/SubscriptionsManagementPage.tsx +1 -1
  209. package/src/plugins/subscriptions/SubscriptionsStatusWidget.tsx +1 -1
  210. package/src/plugins/usage/UsageManagementPage.tsx +1 -1
  211. package/src/plugins/usage/UsageStatusWidget.tsx +1 -1
  212. package/src/plugins/users/UsersManagementPage.tsx +1 -1
  213. package/src/plugins/users/UsersStatusWidget.tsx +1 -1
  214. package/ui/src/App.tsx +4 -3
  215. package/ui/src/api/clientBuilder.ts +5 -5
  216. package/ui/src/api/controlPanelApi.ts +19 -19
  217. package/ui/src/components/ControlPanelApp.tsx +5 -4
  218. package/ui/src/dashboard/builtInWidgets.tsx +3 -0
  219. package/ui/src/dashboard/widgets/AuthStatusWidget.tsx +3 -8
  220. package/ui/src/dashboard/widgets/CMSMaintenanceWidget.tsx +8 -8
  221. package/ui/src/dashboard/widgets/CMSStatusWidget.tsx +2 -2
  222. package/ui/src/dashboard/widgets/CacheMaintenanceWidget.tsx +4 -4
  223. package/ui/src/dashboard/widgets/DatabaseOperationsWidget.tsx +2 -1
  224. package/ui/src/dashboard/widgets/LogsMaintenanceWidget.tsx +6 -6
  225. package/ui/src/dashboard/widgets/MigrationManagementWidget.tsx +319 -0
  226. package/ui/src/dashboard/widgets/SeedManagementWidget.tsx +6 -6
  227. package/ui/src/dashboard/widgets/index.ts +1 -0
  228. package/ui/src/hooks/useJobStream.ts +2 -2
  229. package/ui/src/pages/ContentOpsJobsPage.tsx +3 -3
  230. package/ui/src/pages/PluginPage.tsx +1 -1
  231. package/ui/src/pages/TenantsManagementPage.tsx +1 -1
@@ -10,7 +10,7 @@ export interface QwickbrainStatusWidgetProps {
10
10
  apiPrefix?: string;
11
11
  }
12
12
 
13
- export function QwickbrainStatusWidget({ apiPrefix = '/api/qwickbrain' }: QwickbrainStatusWidgetProps) {
13
+ export function QwickbrainStatusWidget({ apiPrefix = '/qapi/qwickbrain' }: QwickbrainStatusWidgetProps) {
14
14
  const [stats, setStats] = useState<{
15
15
  totalDocuments: number;
16
16
  indexedRepositories: number;
@@ -31,7 +31,7 @@ interface RateLimitStats {
31
31
  }
32
32
 
33
33
  export const RateLimitManagementPage: React.FC<RateLimitManagementPageProps> = ({
34
- apiPrefix = '/api/rate-limit',
34
+ apiPrefix = '/qapi/rate-limit',
35
35
  }) => {
36
36
  const [rules, setRules] = useState<RateLimitRule[]>([]);
37
37
  const [stats, setStats] = useState<RateLimitStats | null>(null);
@@ -10,7 +10,7 @@ export interface RateLimitStatusWidgetProps {
10
10
  apiPrefix?: string;
11
11
  }
12
12
 
13
- export function RateLimitStatusWidget({ apiPrefix = '/api/rate-limit' }: RateLimitStatusWidgetProps) {
13
+ export function RateLimitStatusWidget({ apiPrefix = '/qapi/rate-limit' }: RateLimitStatusWidgetProps) {
14
14
  const [stats, setStats] = useState<{
15
15
  totalRequests: number;
16
16
  blockedRequests: number;
@@ -23,7 +23,7 @@ interface Subscription {
23
23
  amount?: number;
24
24
  }
25
25
 
26
- export function SubscriptionsManagementPage({ apiPrefix = '/api/subscriptions' }: SubscriptionsManagementPageProps) {
26
+ export function SubscriptionsManagementPage({ apiPrefix = '/qapi/subscriptions' }: SubscriptionsManagementPageProps) {
27
27
  const [activeTab, setActiveTab] = useState<'all' | 'active' | 'expiring' | 'config'>('all');
28
28
  const [subscriptions, setSubscriptions] = useState<Subscription[]>([]);
29
29
  const [loading, setLoading] = useState(true);
@@ -10,7 +10,7 @@ export interface SubscriptionsStatusWidgetProps {
10
10
  apiPrefix?: string;
11
11
  }
12
12
 
13
- export function SubscriptionsStatusWidget({ apiPrefix = '/api/subscriptions' }: SubscriptionsStatusWidgetProps) {
13
+ export function SubscriptionsStatusWidget({ apiPrefix = '/qapi/subscriptions' }: SubscriptionsStatusWidgetProps) {
14
14
  const [stats, setStats] = useState<{
15
15
  totalSubscriptions: number;
16
16
  activeSubscriptions: number;
@@ -21,7 +21,7 @@ interface UsageEvent {
21
21
  metadata?: Record<string, unknown>;
22
22
  }
23
23
 
24
- export function UsageManagementPage({ apiPrefix = '/api/usage' }: UsageManagementPageProps) {
24
+ export function UsageManagementPage({ apiPrefix = '/qapi/usage' }: UsageManagementPageProps) {
25
25
  const [activeTab, setActiveTab] = useState<'recent' | 'features' | 'users' | 'config'>('recent');
26
26
  const [events, setEvents] = useState<UsageEvent[]>([]);
27
27
  const [loading, setLoading] = useState(true);
@@ -10,7 +10,7 @@ export interface UsageStatusWidgetProps {
10
10
  apiPrefix?: string;
11
11
  }
12
12
 
13
- export function UsageStatusWidget({ apiPrefix = '/api/usage' }: UsageStatusWidgetProps) {
13
+ export function UsageStatusWidget({ apiPrefix = '/qapi/usage' }: UsageStatusWidgetProps) {
14
14
  const [stats, setStats] = useState<{
15
15
  totalEvents: number;
16
16
  activeUsers: number;
@@ -33,7 +33,7 @@ interface UsersStats {
33
33
  }
34
34
 
35
35
  export const UsersManagementPage: React.FC<UsersManagementPageProps> = ({
36
- apiPrefix = '/api/users',
36
+ apiPrefix = '/qapi/users',
37
37
  }) => {
38
38
  const [users, setUsers] = useState<User[]>([]);
39
39
  const [stats, setStats] = useState<UsersStats | null>(null);
@@ -25,7 +25,7 @@ interface UsersStats {
25
25
  }
26
26
 
27
27
  export const UsersStatusWidget: React.FC<UsersStatusWidgetProps> = ({
28
- apiPrefix = '/api/users',
28
+ apiPrefix = '/qapi/users',
29
29
  }) => {
30
30
  const [stats, setStats] = useState<UsersStats | null>(null);
31
31
  const [loading, setLoading] = useState(true);
package/ui/src/App.tsx CHANGED
@@ -71,9 +71,10 @@ declare global {
71
71
  */
72
72
  const basePath = window.__APP_BASE_PATH__ ?? '';
73
73
 
74
- // Set API base URL to match the control panel mount path
75
- // When proxied through a gateway at /cpanel, API calls need to go to /cpanel/api
76
- api.setBaseUrl(basePath);
74
+ // Set API base URL - use window.__API_BASE_PATH__ (always '/qapi' for QwickApps Server APIs)
75
+ // When UI is mounted at /cpanel, QwickApps Server APIs are at /qapi (not /cpanel/qapi)
76
+ const apiBasePath = (window as any).__API_BASE_PATH__ ?? '';
77
+ api.setBaseUrl(apiBasePath);
77
78
 
78
79
  // Footer content with QwickApps Server branding
79
80
  const footerContent = (
@@ -21,23 +21,23 @@ export interface RouteManifestEntry {
21
21
  /**
22
22
  * Build typed API client from server manifest
23
23
  *
24
- * Fetches the manifest from /api/client-manifest and generates a nested
24
+ * Fetches the manifest from /client-manifest (baseUrl already includes /qapi) and generates a nested
25
25
  * client object with methods for each route.
26
26
  *
27
- * @param baseUrl - Base URL of the server (e.g., 'http://localhost:3000')
27
+ * @param baseUrl - Base URL for QwickApps Server APIs (e.g., '/qapi' or 'http://localhost:3000/qapi')
28
28
  * @returns Promise resolving to the generated client
29
29
  *
30
30
  * @example
31
31
  * ```typescript
32
- * const client = await buildClientFromManifest<APIClient>('http://localhost:3000');
32
+ * const client = await buildClientFromManifest<APIClient>('/qapi');
33
33
  * const logs = await client.logs.query({ limit: 10 });
34
34
  * ```
35
35
  */
36
36
  export async function buildClientFromManifest<T = any>(
37
37
  baseUrl: string
38
38
  ): Promise<T> {
39
- // Fetch manifest from server
40
- const manifestUrl = `${baseUrl}/api/client-manifest`;
39
+ // Fetch manifest from server (baseUrl already includes /qapi prefix)
40
+ const manifestUrl = `${baseUrl}/client-manifest`;
41
41
  const response = await fetch(manifestUrl);
42
42
 
43
43
  if (!response.ok) {
@@ -701,7 +701,7 @@ class ControlPanelApi {
701
701
  }
702
702
 
703
703
  async acceptInvitation(token: string): Promise<AcceptInvitationResponse> {
704
- const response = await this._fetch(`${this.baseUrl}/api/users/accept-invitation/${encodeURIComponent(token)}`);
704
+ const response = await this._fetch(`${this.baseUrl}/users/accept-invitation/${encodeURIComponent(token)}`);
705
705
  if (!response.ok) {
706
706
  const error = await response.json().catch(() => ({}));
707
707
  throw new Error(error.error || `Accept invitation failed: ${response.statusText}`);
@@ -714,7 +714,7 @@ class ControlPanelApi {
714
714
  params.set('status', 'invited');
715
715
  params.set('limit', '100');
716
716
 
717
- const response = await this._fetch(`${this.baseUrl}/api/users?${params}`);
717
+ const response = await this._fetch(`${this.baseUrl}/users?${params}`);
718
718
  if (!response.ok) {
719
719
  throw new Error(`Invitations request failed: ${response.statusText}`);
720
720
  }
@@ -739,7 +739,7 @@ class ControlPanelApi {
739
739
  duration = Math.max(0, Math.floor((expiresDate.getTime() - now.getTime()) / 1000));
740
740
  }
741
741
 
742
- const response = await this._fetch(`${this.baseUrl}/api/bans/email/${encodeURIComponent(email)}`, {
742
+ const response = await this._fetch(`${this.baseUrl}/bans/email/${encodeURIComponent(email)}`, {
743
743
  method: 'POST',
744
744
  headers: { 'Content-Type': 'application/json' },
745
745
  body: JSON.stringify({ reason, duration }),
@@ -751,7 +751,7 @@ class ControlPanelApi {
751
751
  }
752
752
 
753
753
  async unbanUser(email: string): Promise<void> {
754
- const response = await this._fetch(`${this.baseUrl}/api/bans/email/${encodeURIComponent(email)}`, {
754
+ const response = await this._fetch(`${this.baseUrl}/bans/email/${encodeURIComponent(email)}`, {
755
755
  method: 'DELETE',
756
756
  });
757
757
  if (!response.ok) {
@@ -760,7 +760,7 @@ class ControlPanelApi {
760
760
  }
761
761
 
762
762
  async checkBan(email: string): Promise<{ banned: boolean; ban?: Ban }> {
763
- const response = await this._fetch(`${this.baseUrl}/api/bans/email/${encodeURIComponent(email)}`);
763
+ const response = await this._fetch(`${this.baseUrl}/bans/email/${encodeURIComponent(email)}`);
764
764
  if (!response.ok) {
765
765
  throw new Error(`Ban check failed: ${response.statusText}`);
766
766
  }
@@ -774,7 +774,7 @@ class ControlPanelApi {
774
774
  // ==================
775
775
 
776
776
  async getEntitlements(email: string): Promise<EntitlementResult> {
777
- const response = await this._fetch(`${this.baseUrl}/api/entitlements/${encodeURIComponent(email)}`);
777
+ const response = await this._fetch(`${this.baseUrl}/entitlements/${encodeURIComponent(email)}`);
778
778
  if (!response.ok) {
779
779
  throw new Error(`Entitlements request failed: ${response.statusText}`);
780
780
  }
@@ -782,7 +782,7 @@ class ControlPanelApi {
782
782
  }
783
783
 
784
784
  async refreshEntitlements(email: string): Promise<EntitlementResult> {
785
- const response = await this._fetch(`${this.baseUrl}/api/entitlements/${encodeURIComponent(email)}/refresh`, {
785
+ const response = await this._fetch(`${this.baseUrl}/entitlements/${encodeURIComponent(email)}/refresh`, {
786
786
  method: 'POST',
787
787
  });
788
788
  if (!response.ok) {
@@ -793,7 +793,7 @@ class ControlPanelApi {
793
793
 
794
794
  async checkEntitlement(email: string, entitlement: string): Promise<{ has: boolean }> {
795
795
  const response = await this._fetch(
796
- `${this.baseUrl}/api/entitlements/${encodeURIComponent(email)}/check/${encodeURIComponent(entitlement)}`
796
+ `${this.baseUrl}/entitlements/${encodeURIComponent(email)}/check/${encodeURIComponent(entitlement)}`
797
797
  );
798
798
  if (!response.ok) {
799
799
  throw new Error(`Entitlement check failed: ${response.statusText}`);
@@ -802,7 +802,7 @@ class ControlPanelApi {
802
802
  }
803
803
 
804
804
  async getAvailableEntitlements(): Promise<EntitlementDefinition[]> {
805
- const response = await this._fetch(`${this.baseUrl}/api/entitlements/available`);
805
+ const response = await this._fetch(`${this.baseUrl}/entitlements/available`);
806
806
  if (!response.ok) {
807
807
  throw new Error(`Available entitlements request failed: ${response.statusText}`);
808
808
  }
@@ -811,7 +811,7 @@ class ControlPanelApi {
811
811
  }
812
812
 
813
813
  async grantEntitlement(email: string, entitlement: string): Promise<void> {
814
- const response = await this._fetch(`${this.baseUrl}/api/entitlements/${encodeURIComponent(email)}`, {
814
+ const response = await this._fetch(`${this.baseUrl}/entitlements/${encodeURIComponent(email)}`, {
815
815
  method: 'POST',
816
816
  headers: { 'Content-Type': 'application/json' },
817
817
  body: JSON.stringify({ entitlement }),
@@ -824,7 +824,7 @@ class ControlPanelApi {
824
824
 
825
825
  async revokeEntitlement(email: string, entitlement: string): Promise<void> {
826
826
  const response = await this._fetch(
827
- `${this.baseUrl}/api/entitlements/${encodeURIComponent(email)}/${encodeURIComponent(entitlement)}`,
827
+ `${this.baseUrl}/entitlements/${encodeURIComponent(email)}/${encodeURIComponent(entitlement)}`,
828
828
  { method: 'DELETE' }
829
829
  );
830
830
  if (!response.ok) {
@@ -833,7 +833,7 @@ class ControlPanelApi {
833
833
  }
834
834
 
835
835
  async invalidateEntitlementCache(email: string): Promise<void> {
836
- const response = await this._fetch(`${this.baseUrl}/api/entitlements/cache/${encodeURIComponent(email)}`, {
836
+ const response = await this._fetch(`${this.baseUrl}/entitlements/cache/${encodeURIComponent(email)}`, {
837
837
  method: 'DELETE',
838
838
  });
839
839
  if (!response.ok) {
@@ -896,7 +896,7 @@ class ControlPanelApi {
896
896
  }
897
897
 
898
898
  async getPluginDetail(id: string): Promise<PluginDetailResponse> {
899
- const response = await this._fetch(`${this.baseUrl}/api/plugins/${encodeURIComponent(id)}`);
899
+ const response = await this._fetch(`${this.baseUrl}/plugins/${encodeURIComponent(id)}`);
900
900
  if (!response.ok) {
901
901
  if (response.status === 404) {
902
902
  throw new Error(`Plugin not found: ${id}`);
@@ -957,7 +957,7 @@ class ControlPanelApi {
957
957
  * Delete auth configuration (revert to environment variables)
958
958
  */
959
959
  async deleteAuthConfig(): Promise<{ success: boolean; message: string }> {
960
- const response = await this._fetch(`${this.baseUrl}/api/auth/config`, {
960
+ const response = await this._fetch(`${this.baseUrl}/auth/config`, {
961
961
  method: 'DELETE',
962
962
  });
963
963
  if (!response.ok) {
@@ -979,7 +979,7 @@ class ControlPanelApi {
979
979
  * Test current auth provider connection (uses existing env/runtime config)
980
980
  */
981
981
  async testCurrentAuthProvider(): Promise<TestProviderResponse> {
982
- const response = await this._fetch(`${this.baseUrl}/api/auth/test-current`, {
982
+ const response = await this._fetch(`${this.baseUrl}/auth/test-current`, {
983
983
  method: 'POST',
984
984
  headers: { 'Content-Type': 'application/json' },
985
985
  });
@@ -1019,7 +1019,7 @@ class ControlPanelApi {
1019
1019
  }
1020
1020
 
1021
1021
  async disconnectNotificationsClient(clientId: string): Promise<{ success: boolean }> {
1022
- const response = await this._fetch(`${this.baseUrl}/api/notifications/clients/${encodeURIComponent(clientId)}`, {
1022
+ const response = await this._fetch(`${this.baseUrl}/notifications/clients/${encodeURIComponent(clientId)}`, {
1023
1023
  method: 'DELETE',
1024
1024
  });
1025
1025
  if (!response.ok) {
@@ -1030,7 +1030,7 @@ class ControlPanelApi {
1030
1030
  }
1031
1031
 
1032
1032
  async forceNotificationsReconnect(): Promise<{ success: boolean; message: string }> {
1033
- const response = await this._fetch(`${this.baseUrl}/api/notifications/reconnect`, {
1033
+ const response = await this._fetch(`${this.baseUrl}/notifications/reconnect`, {
1034
1034
  method: 'POST',
1035
1035
  });
1036
1036
  if (!response.ok) {
@@ -1104,7 +1104,7 @@ class ControlPanelApi {
1104
1104
  }
1105
1105
 
1106
1106
  async updatePreferences(preferences: Record<string, unknown>): Promise<PreferencesResponse> {
1107
- const url = `${this.baseUrl}/api/preferences`;
1107
+ const url = `${this.baseUrl}/preferences`;
1108
1108
  const response = await this._fetch(url, {
1109
1109
  method: 'PUT',
1110
1110
  headers: { 'Content-Type': 'application/json' },
@@ -1118,7 +1118,7 @@ class ControlPanelApi {
1118
1118
  }
1119
1119
 
1120
1120
  async deletePreferences(): Promise<void> {
1121
- const url = `${this.baseUrl}/api/preferences`;
1121
+ const url = `${this.baseUrl}/preferences`;
1122
1122
  const response = await this._fetch(url, {
1123
1123
  method: 'DELETE',
1124
1124
  });
@@ -147,10 +147,11 @@ export function ControlPanelApp({
147
147
  // Combine built-in widget components with custom ones
148
148
  const allWidgetComponents = [...getBuiltInWidgetComponents(), ...widgetComponents];
149
149
 
150
- // Configure API base URL - read from injected __APP_BASE_PATH__ if available
151
- // Server injects window.__APP_BASE_PATH__ when control panel is mounted at a base path
152
- // Example: mounted at /cpanel API calls go to /cpanel/api (not /api)
153
- const apiBasePath = (window as any).__APP_BASE_PATH__ || '';
150
+ // Configure API base URL - read from injected __API_BASE_PATH__ if available
151
+ // Server injects window.__APP_BASE_PATH__ for UI routing (e.g., '/cpanel')
152
+ // and window.__API_BASE_PATH__ for QwickApps Server API calls (always '/qapi')
153
+ // Example: UI mounted at /cpanel, but QwickApps Server APIs go to /qapi (not /cpanel/qapi)
154
+ const apiBasePath = (window as any).__API_BASE_PATH__ || '';
154
155
  api.setBaseUrl(apiBasePath);
155
156
 
156
157
  // Fetch version from API
@@ -18,6 +18,7 @@ import {
18
18
  CMSStatusWidget,
19
19
  CMSMaintenanceWidget,
20
20
  SeedManagementWidget,
21
+ MigrationManagementWidget,
21
22
  ServiceControlWidget,
22
23
  EnvironmentConfigWidget,
23
24
  DatabaseOpsWidget,
@@ -40,6 +41,7 @@ export const builtInWidgetComponents: Record<string, React.ComponentType> = {
40
41
  CMSStatusWidget: CMSStatusWidget,
41
42
  CMSMaintenanceWidget: CMSMaintenanceWidget,
42
43
  SeedManagementWidget: SeedManagementWidget,
44
+ MigrationManagementWidget: MigrationManagementWidget,
43
45
  ServiceControlWidget: ServiceControlWidget,
44
46
  EnvironmentConfigWidget: EnvironmentConfigWidget,
45
47
  DatabaseOpsWidget: DatabaseOpsWidget,
@@ -65,6 +67,7 @@ export function getBuiltInWidgetComponents(): WidgetComponent[] {
65
67
  { name: 'CMSStatusWidget', component: CMSStatusWidget },
66
68
  { name: 'CMSMaintenanceWidget', component: CMSMaintenanceWidget },
67
69
  { name: 'SeedManagementWidget', component: SeedManagementWidget },
70
+ { name: 'MigrationManagementWidget', component: MigrationManagementWidget },
68
71
  { name: 'ServiceControlWidget', component: ServiceControlWidget },
69
72
  { name: 'EnvironmentConfigWidget', component: EnvironmentConfigWidget },
70
73
  { name: 'DatabaseOpsWidget', component: DatabaseOpsWidget },
@@ -12,14 +12,9 @@ import { Box, Typography, Chip, CircularProgress, Alert } from '@mui/material';
12
12
  import CheckCircleIcon from '@mui/icons-material/CheckCircle';
13
13
  import ErrorIcon from '@mui/icons-material/Error';
14
14
  import BlockIcon from '@mui/icons-material/Block';
15
- import { api } from '../../api/controlPanelApi';
15
+ import { api, type AuthConfigStatus } from '../../api/controlPanelApi';
16
16
 
17
- interface AuthStatus {
18
- state: 'enabled' | 'disabled' | 'error';
19
- adapter: string | null;
20
- error?: string;
21
- missingVars?: string[];
22
- }
17
+ type AuthStatus = AuthConfigStatus;
23
18
 
24
19
  const adapterLabels: Record<string, string> = {
25
20
  supertokens: 'SuperTokens',
@@ -36,7 +31,7 @@ export function AuthStatusWidget() {
36
31
  useEffect(() => {
37
32
  const fetchStatus = async () => {
38
33
  try {
39
- const data = await api.fetch<AuthStatus>('/auth/config/status');
34
+ const data = await api.getAuthConfigStatus();
40
35
  setStatus(data);
41
36
  } catch (err) {
42
37
  setError(err instanceof Error ? err.message : 'Failed to fetch auth status');
@@ -49,8 +49,8 @@ export function CMSMaintenanceWidget() {
49
49
 
50
50
  const fetchStatus = async () => {
51
51
  try {
52
- const basePath = (window as any).__APP_BASE_PATH__ || '';
53
- const response = await fetch(`${basePath}/api/cms/status`);
52
+ const basePath = (window as any).__API_BASE_PATH__ || '';
53
+ const response = await fetch(`${basePath}/cms/status`);
54
54
  if (!response.ok) {
55
55
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
56
56
  }
@@ -63,8 +63,8 @@ export function CMSMaintenanceWidget() {
63
63
 
64
64
  const fetchSeeds = async () => {
65
65
  try {
66
- const basePath = (window as any).__APP_BASE_PATH__ || '';
67
- const response = await fetch(`${basePath}/api/cms/seeds`);
66
+ const basePath = (window as any).__API_BASE_PATH__ || '';
67
+ const response = await fetch(`${basePath}/cms/seeds`);
68
68
  if (!response.ok) {
69
69
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
70
70
  }
@@ -88,8 +88,8 @@ export function CMSMaintenanceWidget() {
88
88
  setError(null);
89
89
  setSuccess(null);
90
90
  try {
91
- const basePath = (window as any).__APP_BASE_PATH__ || '';
92
- const response = await fetch(`${basePath}/api/cms/restart`, { method: 'POST' });
91
+ const basePath = (window as any).__API_BASE_PATH__ || '';
92
+ const response = await fetch(`${basePath}/cms/restart`, { method: 'POST' });
93
93
  const data = await response.json();
94
94
 
95
95
  if (response.ok) {
@@ -109,8 +109,8 @@ export function CMSMaintenanceWidget() {
109
109
  setSuccess(null);
110
110
 
111
111
  try {
112
- const basePath = (window as any).__APP_BASE_PATH__ || '';
113
- const response = await fetch(`${basePath}/api/cms/seeds/${seedName}/execute`, {
112
+ const basePath = (window as any).__API_BASE_PATH__ || '';
113
+ const response = await fetch(`${basePath}/cms/seeds/${seedName}/execute`, {
114
114
  method: 'POST',
115
115
  });
116
116
  if (!response.ok) {
@@ -35,8 +35,8 @@ export function CMSStatusWidget() {
35
35
 
36
36
  const fetchStatus = async () => {
37
37
  try {
38
- const basePath = (window as any).__APP_BASE_PATH__ || '';
39
- const response = await fetch(`${basePath}/api/cms/status`);
38
+ const basePath = (window as any).__API_BASE_PATH__ || '';
39
+ const response = await fetch(`${basePath}/cms/status`);
40
40
  if (!response.ok) {
41
41
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
42
42
  }
@@ -47,8 +47,8 @@ export function CacheMaintenanceWidget() {
47
47
  setLoading(true);
48
48
  setError(null);
49
49
  try {
50
- const basePath = (window as any).__APP_BASE_PATH__ || '';
51
- const response = await fetch(`${basePath}/api/cache:default/stats`);
50
+ const basePath = (window as any).__API_BASE_PATH__ || '';
51
+ const response = await fetch(`${basePath}/cache:default/stats`);
52
52
  if (!response.ok) {
53
53
  if (response.status === 404) {
54
54
  throw new Error('Cache plugin not configured');
@@ -76,8 +76,8 @@ export function CacheMaintenanceWidget() {
76
76
  setSuccess(null);
77
77
 
78
78
  try {
79
- const basePath = (window as any).__APP_BASE_PATH__ || '';
80
- const response = await fetch(`${basePath}/api/cache:default/flush`, {
79
+ const basePath = (window as any).__API_BASE_PATH__ || '';
80
+ const response = await fetch(`${basePath}/cache:default/flush`, {
81
81
  method: 'POST',
82
82
  headers: { 'Content-Type': 'application/json' },
83
83
  });
@@ -159,7 +159,8 @@ const AdminCredentialsDialog: React.FC<AdminCredentialsDialogProps> = ({
159
159
 
160
160
  export const DatabaseOperationsWidget: React.FC<DatabaseOperationsWidgetProps> = () => {
161
161
  // Use default values since props cannot be passed through WidgetContribution
162
- const apiPrefix = '/api/postgres:default';
162
+ // QwickApps Server plugin routes are at /qapi/* when integrated with Next.js apps
163
+ const apiPrefix = '/qapi/postgres:default';
163
164
  const instanceName = 'default';
164
165
  const [status, setStatus] = useState<DatabaseStatus | null>(null);
165
166
  const [loading, setLoading] = useState(true);
@@ -61,8 +61,8 @@ export function LogsMaintenanceWidget() {
61
61
 
62
62
  const fetchSources = async () => {
63
63
  try {
64
- const basePath = (window as any).__APP_BASE_PATH__ || '';
65
- const response = await fetch(`${basePath}/api/logs/sources`);
64
+ const basePath = (window as any).__API_BASE_PATH__ || '';
65
+ const response = await fetch(`${basePath}/logs/sources`);
66
66
  if (!response.ok) throw new Error('Failed to fetch log sources');
67
67
  const data = await response.json();
68
68
  setSources(data.sources || []);
@@ -80,8 +80,8 @@ export function LogsMaintenanceWidget() {
80
80
  setLoading(true);
81
81
  setError(null);
82
82
  try {
83
- const basePath = (window as any).__APP_BASE_PATH__ || '';
84
- const response = await fetch(`${basePath}/api/logs/stats?source=${selectedSource}`);
83
+ const basePath = (window as any).__API_BASE_PATH__ || '';
84
+ const response = await fetch(`${basePath}/logs/stats?source=${selectedSource}`);
85
85
  if (!response.ok) throw new Error('Failed to fetch log stats');
86
86
  const data = await response.json();
87
87
  setStats(data);
@@ -110,8 +110,8 @@ export function LogsMaintenanceWidget() {
110
110
  setSuccess(null);
111
111
 
112
112
  try {
113
- const basePath = (window as any).__APP_BASE_PATH__ || '';
114
- const response = await fetch(`${basePath}/api/logs/clear`, {
113
+ const basePath = (window as any).__API_BASE_PATH__ || '';
114
+ const response = await fetch(`${basePath}/logs/clear`, {
115
115
  method: 'POST',
116
116
  headers: { 'Content-Type': 'application/json' },
117
117
  body: JSON.stringify({ source: selectedSource }),