@intranefr/superbackend 1.4.3

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 (188) hide show
  1. package/.commiat +4 -0
  2. package/.env.example +47 -0
  3. package/README.md +110 -0
  4. package/index.js +94 -0
  5. package/package.json +67 -0
  6. package/public/css/styles.css +139 -0
  7. package/public/js/animations.js +41 -0
  8. package/sdk/error-tracking/browser/package.json +16 -0
  9. package/sdk/error-tracking/browser/src/core.js +270 -0
  10. package/sdk/error-tracking/browser/src/embed.js +18 -0
  11. package/sdk/error-tracking/browser/src/index.js +1 -0
  12. package/server.js +5 -0
  13. package/src/admin/endpointRegistry.js +300 -0
  14. package/src/controllers/admin.controller.js +321 -0
  15. package/src/controllers/adminAssets.controller.js +530 -0
  16. package/src/controllers/adminAssetsStorage.controller.js +260 -0
  17. package/src/controllers/adminEjsVirtual.controller.js +354 -0
  18. package/src/controllers/adminFeatureFlags.controller.js +155 -0
  19. package/src/controllers/adminHeadless.controller.js +1071 -0
  20. package/src/controllers/adminI18n.controller.js +604 -0
  21. package/src/controllers/adminJsonConfigs.controller.js +97 -0
  22. package/src/controllers/adminLlm.controller.js +273 -0
  23. package/src/controllers/adminMigration.controller.js +257 -0
  24. package/src/controllers/adminSeoConfig.controller.js +515 -0
  25. package/src/controllers/adminStats.controller.js +121 -0
  26. package/src/controllers/adminUploadNamespaces.controller.js +208 -0
  27. package/src/controllers/assets.controller.js +248 -0
  28. package/src/controllers/auth.controller.js +93 -0
  29. package/src/controllers/billing.controller.js +223 -0
  30. package/src/controllers/featureFlags.controller.js +35 -0
  31. package/src/controllers/forms.controller.js +217 -0
  32. package/src/controllers/globalSettings.controller.js +252 -0
  33. package/src/controllers/headlessCrud.controller.js +126 -0
  34. package/src/controllers/i18n.controller.js +12 -0
  35. package/src/controllers/invite.controller.js +249 -0
  36. package/src/controllers/jsonConfigs.controller.js +19 -0
  37. package/src/controllers/metrics.controller.js +149 -0
  38. package/src/controllers/notificationAdmin.controller.js +264 -0
  39. package/src/controllers/notifications.controller.js +131 -0
  40. package/src/controllers/org.controller.js +357 -0
  41. package/src/controllers/orgAdmin.controller.js +491 -0
  42. package/src/controllers/stripeAdmin.controller.js +410 -0
  43. package/src/controllers/user.controller.js +361 -0
  44. package/src/controllers/userAdmin.controller.js +277 -0
  45. package/src/controllers/waitingList.controller.js +167 -0
  46. package/src/controllers/webhook.controller.js +200 -0
  47. package/src/middleware/auth.js +66 -0
  48. package/src/middleware/errorCapture.js +170 -0
  49. package/src/middleware/headlessApiTokenAuth.js +57 -0
  50. package/src/middleware/org.js +108 -0
  51. package/src/middleware.js +901 -0
  52. package/src/models/ActionEvent.js +31 -0
  53. package/src/models/ActivityLog.js +41 -0
  54. package/src/models/Asset.js +84 -0
  55. package/src/models/AuditEvent.js +93 -0
  56. package/src/models/EmailLog.js +28 -0
  57. package/src/models/ErrorAggregate.js +72 -0
  58. package/src/models/FormSubmission.js +41 -0
  59. package/src/models/GlobalSetting.js +38 -0
  60. package/src/models/HeadlessApiToken.js +24 -0
  61. package/src/models/HeadlessModelDefinition.js +41 -0
  62. package/src/models/I18nEntry.js +77 -0
  63. package/src/models/I18nLocale.js +33 -0
  64. package/src/models/Invite.js +70 -0
  65. package/src/models/JsonConfig.js +46 -0
  66. package/src/models/Notification.js +60 -0
  67. package/src/models/Organization.js +57 -0
  68. package/src/models/OrganizationMember.js +43 -0
  69. package/src/models/StripeCatalogItem.js +77 -0
  70. package/src/models/StripeWebhookEvent.js +57 -0
  71. package/src/models/User.js +89 -0
  72. package/src/models/VirtualEjsFile.js +60 -0
  73. package/src/models/VirtualEjsFileVersion.js +43 -0
  74. package/src/models/VirtualEjsGroupChange.js +32 -0
  75. package/src/models/WaitingList.js +41 -0
  76. package/src/models/Webhook.js +63 -0
  77. package/src/models/Workflow.js +29 -0
  78. package/src/models/WorkflowExecution.js +12 -0
  79. package/src/routes/admin.routes.js +26 -0
  80. package/src/routes/adminAssets.routes.js +28 -0
  81. package/src/routes/adminAssetsStorage.routes.js +13 -0
  82. package/src/routes/adminAudit.routes.js +196 -0
  83. package/src/routes/adminEjsVirtual.routes.js +17 -0
  84. package/src/routes/adminErrors.routes.js +164 -0
  85. package/src/routes/adminFeatureFlags.routes.js +12 -0
  86. package/src/routes/adminHeadless.routes.js +38 -0
  87. package/src/routes/adminI18n.routes.js +22 -0
  88. package/src/routes/adminJsonConfigs.routes.js +15 -0
  89. package/src/routes/adminLlm.routes.js +12 -0
  90. package/src/routes/adminMigration.routes.js +81 -0
  91. package/src/routes/adminSeoConfig.routes.js +20 -0
  92. package/src/routes/adminUploadNamespaces.routes.js +13 -0
  93. package/src/routes/assets.routes.js +21 -0
  94. package/src/routes/auth.routes.js +12 -0
  95. package/src/routes/billing.routes.js +11 -0
  96. package/src/routes/errorTracking.routes.js +31 -0
  97. package/src/routes/featureFlags.routes.js +9 -0
  98. package/src/routes/forms.routes.js +9 -0
  99. package/src/routes/formsAdmin.routes.js +13 -0
  100. package/src/routes/globalSettings.routes.js +18 -0
  101. package/src/routes/headless.routes.js +15 -0
  102. package/src/routes/i18n.routes.js +8 -0
  103. package/src/routes/invite.routes.js +9 -0
  104. package/src/routes/jsonConfigs.routes.js +8 -0
  105. package/src/routes/log.routes.js +111 -0
  106. package/src/routes/metrics.routes.js +9 -0
  107. package/src/routes/notificationAdmin.routes.js +15 -0
  108. package/src/routes/notifications.routes.js +12 -0
  109. package/src/routes/org.routes.js +31 -0
  110. package/src/routes/orgAdmin.routes.js +20 -0
  111. package/src/routes/publicAssets.routes.js +7 -0
  112. package/src/routes/stripeAdmin.routes.js +20 -0
  113. package/src/routes/user.routes.js +22 -0
  114. package/src/routes/userAdmin.routes.js +15 -0
  115. package/src/routes/waitingList.routes.js +13 -0
  116. package/src/routes/waitingListAdmin.routes.js +9 -0
  117. package/src/routes/webhook.routes.js +32 -0
  118. package/src/routes/workflowWebhook.routes.js +54 -0
  119. package/src/routes/workflows.routes.js +110 -0
  120. package/src/services/assets.service.js +110 -0
  121. package/src/services/audit.service.js +62 -0
  122. package/src/services/auditLogger.js +165 -0
  123. package/src/services/ejsVirtual.service.js +614 -0
  124. package/src/services/email.service.js +351 -0
  125. package/src/services/errorLogger.js +221 -0
  126. package/src/services/featureFlags.service.js +202 -0
  127. package/src/services/forms.service.js +214 -0
  128. package/src/services/globalSettings.service.js +49 -0
  129. package/src/services/headlessApiTokens.service.js +158 -0
  130. package/src/services/headlessCrypto.service.js +31 -0
  131. package/src/services/headlessModels.service.js +356 -0
  132. package/src/services/i18n.service.js +314 -0
  133. package/src/services/i18nInferredKeys.service.js +337 -0
  134. package/src/services/jsonConfigs.service.js +392 -0
  135. package/src/services/llm.service.js +749 -0
  136. package/src/services/migration.service.js +581 -0
  137. package/src/services/migrationAssets/fsLocal.js +58 -0
  138. package/src/services/migrationAssets/index.js +134 -0
  139. package/src/services/migrationAssets/s3.js +75 -0
  140. package/src/services/migrationAssets/sftp.js +92 -0
  141. package/src/services/notification.service.js +212 -0
  142. package/src/services/objectStorage.service.js +514 -0
  143. package/src/services/seoConfig.service.js +402 -0
  144. package/src/services/storage.js +150 -0
  145. package/src/services/stripe.service.js +185 -0
  146. package/src/services/stripeHelper.service.js +264 -0
  147. package/src/services/uploadNamespaces.service.js +326 -0
  148. package/src/services/webhook.service.js +157 -0
  149. package/src/services/workflow.service.js +271 -0
  150. package/src/utils/asyncHandler.js +5 -0
  151. package/src/utils/encryption.js +80 -0
  152. package/src/utils/jwt.js +40 -0
  153. package/src/utils/orgRoles.js +156 -0
  154. package/src/utils/validation.js +26 -0
  155. package/src/utils/webhookRetry.js +93 -0
  156. package/views/admin-assets.ejs +444 -0
  157. package/views/admin-audit.ejs +283 -0
  158. package/views/admin-coolify-deploy.ejs +207 -0
  159. package/views/admin-dashboard-home.ejs +291 -0
  160. package/views/admin-dashboard.ejs +397 -0
  161. package/views/admin-ejs-virtual.ejs +280 -0
  162. package/views/admin-errors.ejs +368 -0
  163. package/views/admin-feature-flags.ejs +390 -0
  164. package/views/admin-forms.ejs +526 -0
  165. package/views/admin-global-settings.ejs +436 -0
  166. package/views/admin-headless.ejs +2020 -0
  167. package/views/admin-i18n-locales.ejs +221 -0
  168. package/views/admin-i18n.ejs +728 -0
  169. package/views/admin-json-configs.ejs +410 -0
  170. package/views/admin-llm.ejs +884 -0
  171. package/views/admin-metrics.ejs +274 -0
  172. package/views/admin-migration.ejs +814 -0
  173. package/views/admin-notifications.ejs +430 -0
  174. package/views/admin-organizations.ejs +984 -0
  175. package/views/admin-seo-config.ejs +673 -0
  176. package/views/admin-stripe-pricing.ejs +558 -0
  177. package/views/admin-test.ejs +342 -0
  178. package/views/admin-users.ejs +452 -0
  179. package/views/admin-waiting-list.ejs +547 -0
  180. package/views/admin-webhooks.ejs +329 -0
  181. package/views/admin-workflows.ejs +310 -0
  182. package/views/partials/admin-assets-script.ejs +2022 -0
  183. package/views/partials/admin-test-sidebar.ejs +14 -0
  184. package/views/partials/dashboard/nav-items.ejs +66 -0
  185. package/views/partials/dashboard/palette.ejs +63 -0
  186. package/views/partials/dashboard/sidebar.ejs +21 -0
  187. package/views/partials/dashboard/tab-bar.ejs +26 -0
  188. package/views/partials/footer.ejs +3 -0
@@ -0,0 +1,270 @@
1
+ export function createErrorTrackingClient(options) {
2
+ const state = {
3
+ initialized: false,
4
+ config: {
5
+ endpoint: '/api/log/error',
6
+ headers: {},
7
+ getAuthHeader: null,
8
+ maxErrorsPerSession: 50,
9
+ debounceMs: 1000,
10
+ sampleRatePercent: 100,
11
+ ...(options || {}),
12
+ },
13
+ errorCount: 0,
14
+ lastErrorTime: 0,
15
+ lastErrorFingerprint: '',
16
+ originalFetch: null,
17
+ };
18
+
19
+ function randomInt0_99() {
20
+ return Math.floor(Math.random() * 100);
21
+ }
22
+
23
+ function shouldSample() {
24
+ const pct = Number(state.config.sampleRatePercent);
25
+ if (!Number.isFinite(pct)) return true;
26
+ if (pct >= 100) return true;
27
+ if (pct <= 0) return false;
28
+ return randomInt0_99() < pct;
29
+ }
30
+
31
+ function computeFingerprint(errorName, message, url) {
32
+ return `${errorName || ''}|${String(message || '').slice(0, 120)}|${url || ''}`;
33
+ }
34
+
35
+ function shouldReport(fingerprint) {
36
+ if (!shouldSample()) return false;
37
+
38
+ const now = Date.now();
39
+
40
+ if (state.errorCount >= state.config.maxErrorsPerSession) {
41
+ return false;
42
+ }
43
+
44
+ if (fingerprint === state.lastErrorFingerprint && (now - state.lastErrorTime) < state.config.debounceMs) {
45
+ return false;
46
+ }
47
+
48
+ state.lastErrorFingerprint = fingerprint;
49
+ state.lastErrorTime = now;
50
+ state.errorCount += 1;
51
+
52
+ return true;
53
+ }
54
+
55
+ function getRuntime() {
56
+ let appVersion = '';
57
+ try {
58
+ const meta = document.querySelector('meta[name="app-version"]');
59
+ appVersion = meta && meta.content ? meta.content : '';
60
+ } catch (e) {
61
+ appVersion = '';
62
+ }
63
+
64
+ return {
65
+ url: window.location.href,
66
+ referrer: document.referrer || '',
67
+ viewport: `${window.innerWidth}x${window.innerHeight}`,
68
+ locale: navigator.language || '',
69
+ appVersion,
70
+ };
71
+ }
72
+
73
+ function buildHeaders() {
74
+ const headers = { ...(state.config.headers || {}) };
75
+
76
+ const getter = state.config.getAuthHeader;
77
+ if (typeof getter === 'function') {
78
+ try {
79
+ const auth = getter();
80
+ if (auth) headers.authorization = auth;
81
+ } catch (e) {}
82
+ }
83
+
84
+ return headers;
85
+ }
86
+
87
+ function sendError(payload) {
88
+ try {
89
+ const endpoint = state.config.endpoint || '/api/log/error';
90
+ const headers = buildHeaders();
91
+
92
+ if (navigator.sendBeacon) {
93
+ try {
94
+ const blob = new Blob([JSON.stringify(payload)], { type: 'application/json' });
95
+ const ok = navigator.sendBeacon(endpoint, blob);
96
+ if (ok) return;
97
+ } catch (e) {}
98
+ }
99
+
100
+ const xhr = new XMLHttpRequest();
101
+ xhr.open('POST', endpoint, true);
102
+ xhr.setRequestHeader('Content-Type', 'application/json');
103
+ Object.keys(headers || {}).forEach((k) => {
104
+ if (headers[k] != null) xhr.setRequestHeader(k, String(headers[k]));
105
+ });
106
+ xhr.send(JSON.stringify(payload));
107
+ } catch (e) {}
108
+ }
109
+
110
+ function normalizeErrorReason(reason) {
111
+ if (reason instanceof Error) {
112
+ return {
113
+ errorName: reason.name || 'UnhandledRejection',
114
+ message: reason.message,
115
+ stack: reason.stack || '',
116
+ };
117
+ }
118
+
119
+ if (typeof reason === 'string') {
120
+ return { errorName: 'UnhandledRejection', message: reason, stack: '' };
121
+ }
122
+
123
+ try {
124
+ return { errorName: 'UnhandledRejection', message: JSON.stringify(reason), stack: '' };
125
+ } catch (e) {
126
+ return { errorName: 'UnhandledRejection', message: String(reason), stack: '' };
127
+ }
128
+ }
129
+
130
+ function handleWindowError(message, source, lineno, colno, error) {
131
+ const errorName = (error && error.name) || 'Error';
132
+ const errorMessage = (error && error.message) || message || 'Unknown error';
133
+ const stack = (error && error.stack) || '';
134
+
135
+ const fingerprint = computeFingerprint(errorName, errorMessage, source || window.location.href);
136
+ if (!shouldReport(fingerprint)) return;
137
+
138
+ sendError({
139
+ severity: 'error',
140
+ errorName,
141
+ message: errorMessage,
142
+ stack,
143
+ url: source || window.location.href,
144
+ runtime: getRuntime(),
145
+ extra: { lineno, colno },
146
+ });
147
+ }
148
+
149
+ function handleUnhandledRejection(event) {
150
+ const norm = normalizeErrorReason(event && event.reason);
151
+
152
+ const fingerprint = computeFingerprint(norm.errorName, norm.message, window.location.href);
153
+ if (!shouldReport(fingerprint)) return;
154
+
155
+ sendError({
156
+ severity: 'error',
157
+ errorName: norm.errorName,
158
+ message: norm.message,
159
+ stack: norm.stack,
160
+ url: window.location.href,
161
+ runtime: getRuntime(),
162
+ });
163
+ }
164
+
165
+ function wrapFetch() {
166
+ if (state.originalFetch || typeof window.fetch !== 'function') return;
167
+
168
+ state.originalFetch = window.fetch;
169
+ window.fetch = function (input, init) {
170
+ return state.originalFetch.apply(this, arguments).then((response) => {
171
+ try {
172
+ if (response && response.status >= 500) {
173
+ const url = typeof input === 'string' ? input : (input && input.url) || '';
174
+ const method = (init && init.method) || 'GET';
175
+ const fingerprint = computeFingerprint('FetchError', `${response.status} ${url}`, url);
176
+ if (shouldReport(fingerprint)) {
177
+ sendError({
178
+ severity: 'warn',
179
+ errorName: 'FetchError',
180
+ message: `HTTP ${response.status} on ${method} ${url}`,
181
+ request: { method, path: url, statusCode: response.status },
182
+ runtime: getRuntime(),
183
+ });
184
+ }
185
+ }
186
+ } catch (e) {}
187
+ return response;
188
+ }).catch((err) => {
189
+ try {
190
+ const url = typeof input === 'string' ? input : (input && input.url) || '';
191
+ const method = (init && init.method) || 'GET';
192
+ const message = (err && err.message) || String(err);
193
+ const stack = (err && err.stack) || '';
194
+ const fingerprint = computeFingerprint('FetchError', message, url);
195
+ if (shouldReport(fingerprint)) {
196
+ sendError({
197
+ severity: 'error',
198
+ errorName: 'FetchError',
199
+ message,
200
+ stack,
201
+ request: { method, path: url },
202
+ runtime: getRuntime(),
203
+ });
204
+ }
205
+ } catch (e) {}
206
+ throw err;
207
+ });
208
+ };
209
+ }
210
+
211
+ function init(initOptions) {
212
+ if (state.initialized) return;
213
+ if (initOptions) config(initOptions);
214
+
215
+ window.addEventListener('error', (event) => {
216
+ handleWindowError(event && event.message, event && event.filename, event && event.lineno, event && event.colno, event && event.error);
217
+ });
218
+
219
+ window.addEventListener('unhandledrejection', handleUnhandledRejection);
220
+
221
+ wrapFetch();
222
+
223
+ state.initialized = true;
224
+ }
225
+
226
+ function config(next) {
227
+ if (!next || typeof next !== 'object') return;
228
+
229
+ state.config = {
230
+ ...state.config,
231
+ ...next,
232
+ headers: {
233
+ ...(state.config.headers || {}),
234
+ ...(next.headers || {}),
235
+ },
236
+ };
237
+ }
238
+
239
+ function report(error, extra) {
240
+ const errorName = (error && error.name) || 'CustomError';
241
+ const errorMessage = (error && error.message) || String(error);
242
+ const stack = (error && error.stack) || '';
243
+
244
+ const fingerprint = computeFingerprint(errorName, errorMessage, window.location.href);
245
+ if (!shouldReport(fingerprint)) return;
246
+
247
+ sendError({
248
+ severity: 'error',
249
+ errorName,
250
+ message: errorMessage,
251
+ stack,
252
+ url: window.location.href,
253
+ runtime: getRuntime(),
254
+ extra,
255
+ });
256
+ }
257
+
258
+ function teardown() {
259
+ if (!state.initialized) return;
260
+
261
+ try {
262
+ window.fetch = state.originalFetch || window.fetch;
263
+ state.originalFetch = null;
264
+ } catch (e) {}
265
+
266
+ state.initialized = false;
267
+ }
268
+
269
+ return { init, config, report, teardown };
270
+ }
@@ -0,0 +1,18 @@
1
+ import { createErrorTrackingClient } from './core.js';
2
+
3
+ function attachToSaasbackendGlobal() {
4
+ const root = (typeof window !== 'undefined' ? window : undefined);
5
+ if (!root) return;
6
+
7
+ root.saasbackend = root.saasbackend || {};
8
+
9
+ if (!root.saasbackend.errorTracking) {
10
+ root.saasbackend.errorTracking = createErrorTrackingClient();
11
+ }
12
+
13
+ if (root.saasbackend.errorTracking && typeof root.saasbackend.errorTracking.init === 'function') {
14
+ root.saasbackend.errorTracking.init();
15
+ }
16
+ }
17
+
18
+ attachToSaasbackendGlobal();
@@ -0,0 +1 @@
1
+ export { createErrorTrackingClient } from './core.js';
package/server.js ADDED
@@ -0,0 +1,5 @@
1
+ require('dotenv').config();
2
+ const { server } = require('./index');
3
+
4
+ // Start the standalone server
5
+ server();
@@ -0,0 +1,300 @@
1
+ const endpointRegistry = [
2
+ {
3
+ id: "auth",
4
+ title: "Authentication",
5
+ endpoints: [
6
+ {
7
+ id: "register",
8
+ method: "POST",
9
+ path: "/api/auth/register",
10
+ auth: "none",
11
+ bodyExample: { email: "user@example.com", password: "password" },
12
+ },
13
+ {
14
+ id: "login",
15
+ method: "POST",
16
+ path: "/api/auth/login",
17
+ auth: "none",
18
+ bodyExample: { email: "user@example.com", password: "password" },
19
+ },
20
+ {
21
+ id: "refresh",
22
+ method: "POST",
23
+ path: "/api/auth/refresh-token",
24
+ auth: "none",
25
+ bodyExample: { refreshToken: "<refresh_token>" },
26
+ },
27
+ {
28
+ id: "me",
29
+ method: "GET",
30
+ path: "/api/auth/me",
31
+ auth: "jwt",
32
+ },
33
+ ],
34
+ },
35
+ {
36
+ id: "admin-llm",
37
+ title: "AI & LLM Services",
38
+ endpoints: [
39
+ {
40
+ id: "llm-config-get",
41
+ method: "GET",
42
+ path: "/api/admin/llm/config",
43
+ auth: "basic",
44
+ },
45
+ {
46
+ id: "llm-config-save",
47
+ method: "POST",
48
+ path: "/api/admin/llm/config",
49
+ auth: "basic",
50
+ bodyExample: { provider: "openai", apiKey: "sk-...", model: "gpt-4" },
51
+ },
52
+ {
53
+ id: "llm-prompt-test",
54
+ method: "POST",
55
+ path: "/api/admin/llm/prompts/:key/test",
56
+ auth: "basic",
57
+ bodyExample: { inputs: { topic: "SaaS" } },
58
+ },
59
+ {
60
+ id: "llm-audit",
61
+ method: "GET",
62
+ path: "/api/admin/llm/audit",
63
+ auth: "basic",
64
+ },
65
+ {
66
+ id: "llm-costs",
67
+ method: "GET",
68
+ path: "/api/admin/llm/costs",
69
+ auth: "basic",
70
+ },
71
+ ],
72
+ },
73
+ {
74
+ id: "ejs-virtual",
75
+ title: "EJS Virtual Codebase",
76
+ endpoints: [
77
+ {
78
+ id: "ejs-files-list",
79
+ method: "GET",
80
+ path: "/api/admin/ejs-virtual/files",
81
+ auth: "basic",
82
+ },
83
+ {
84
+ id: "ejs-file-get",
85
+ method: "GET",
86
+ path: "/api/admin/ejs-virtual/file?path=index.ejs",
87
+ auth: "basic",
88
+ },
89
+ {
90
+ id: "ejs-file-save",
91
+ method: "PUT",
92
+ path: "/api/admin/ejs-virtual/file",
93
+ auth: "basic",
94
+ bodyExample: { path: "index.ejs", content: "<h1>Hello</h1>" },
95
+ },
96
+ {
97
+ id: "ejs-vibe",
98
+ method: "POST",
99
+ path: "/api/admin/ejs-virtual/vibe",
100
+ auth: "basic",
101
+ bodyExample: { prompt: "Make it more professional" },
102
+ },
103
+ {
104
+ id: "ejs-cache-clear",
105
+ method: "POST",
106
+ path: "/api/admin/ejs-virtual/cache/clear",
107
+ auth: "basic",
108
+ },
109
+ ],
110
+ },
111
+ {
112
+ id: "seo-config",
113
+ title: "SEO & OpenGraph",
114
+ endpoints: [
115
+ {
116
+ id: "seo-get",
117
+ method: "GET",
118
+ path: "/api/admin/seo-config",
119
+ auth: "basic",
120
+ },
121
+ {
122
+ id: "seo-update",
123
+ method: "PUT",
124
+ path: "/api/admin/seo-config",
125
+ auth: "basic",
126
+ bodyExample: { defaultTitle: "My SaaS", defaultDescription: "Best SaaS" },
127
+ },
128
+ {
129
+ id: "seo-ai-views",
130
+ method: "GET",
131
+ path: "/api/admin/seo-config/ai/views",
132
+ auth: "basic",
133
+ },
134
+ {
135
+ id: "seo-ai-generate",
136
+ method: "POST",
137
+ path: "/api/admin/seo-config/ai/generate-entry",
138
+ auth: "basic",
139
+ bodyExample: { path: "/home" },
140
+ },
141
+ {
142
+ id: "seo-og-svg-update",
143
+ method: "PUT",
144
+ path: "/api/admin/seo-config/og/svg",
145
+ auth: "basic",
146
+ bodyExample: { svg: "<svg>...</svg>" },
147
+ },
148
+ {
149
+ id: "seo-og-generate-png",
150
+ method: "POST",
151
+ path: "/api/admin/seo-config/og/generate-png",
152
+ auth: "basic",
153
+ },
154
+ ],
155
+ },
156
+ {
157
+ id: "migration",
158
+ title: "System Migration",
159
+ endpoints: [
160
+ {
161
+ id: "migration-envs",
162
+ method: "GET",
163
+ path: "/api/admin/migration/environments",
164
+ auth: "basic",
165
+ },
166
+ {
167
+ id: "migration-models",
168
+ method: "GET",
169
+ path: "/api/admin/migration/models",
170
+ auth: "basic",
171
+ },
172
+ {
173
+ id: "migration-test",
174
+ method: "POST",
175
+ path: "/api/admin/migration/test-connection",
176
+ auth: "basic",
177
+ bodyExample: { targetUrl: "https://peer.example.com", apiKey: "..." },
178
+ },
179
+ {
180
+ id: "migration-run",
181
+ method: "POST",
182
+ path: "/api/admin/migration/run",
183
+ auth: "basic",
184
+ bodyExample: { envKey: "production", models: ["User"] },
185
+ },
186
+ ],
187
+ },
188
+ {
189
+ id: "billing",
190
+ title: "Billing & Stripe",
191
+ endpoints: [
192
+ {
193
+ id: "stripe-status",
194
+ method: "GET",
195
+ path: "/api/admin/stripe/status",
196
+ auth: "basic",
197
+ },
198
+ {
199
+ id: "stripe-catalog",
200
+ method: "GET",
201
+ path: "/api/admin/stripe/catalog",
202
+ auth: "basic",
203
+ },
204
+ {
205
+ id: "stripe-products",
206
+ method: "GET",
207
+ path: "/api/admin/stripe/products",
208
+ auth: "basic",
209
+ },
210
+ {
211
+ id: "billing-checkout",
212
+ method: "POST",
213
+ path: "/api/billing/create-checkout-session",
214
+ auth: "jwt",
215
+ bodyExample: { priceId: "price_xxx" },
216
+ },
217
+ ],
218
+ },
219
+ {
220
+ id: "admin-users",
221
+ title: "User Management (Admin)",
222
+ endpoints: [
223
+ {
224
+ id: "admin-users-stats",
225
+ method: "GET",
226
+ path: "/api/admin/users/stats",
227
+ auth: "basic",
228
+ },
229
+ {
230
+ id: "admin-users-list",
231
+ method: "GET",
232
+ path: "/api/admin/users",
233
+ auth: "basic",
234
+ },
235
+ {
236
+ id: "admin-users-get",
237
+ method: "GET",
238
+ path: "/api/admin/users/:id",
239
+ auth: "basic",
240
+ },
241
+ ],
242
+ },
243
+ {
244
+ id: "global-settings",
245
+ title: "Global Settings",
246
+ endpoints: [
247
+ {
248
+ id: "global-settings-list",
249
+ method: "GET",
250
+ path: "/api/admin/settings",
251
+ auth: "basic",
252
+ },
253
+ {
254
+ id: "global-setting-get",
255
+ method: "GET",
256
+ path: "/api/admin/settings/:key",
257
+ auth: "basic",
258
+ },
259
+ {
260
+ id: "global-setting-update",
261
+ method: "PUT",
262
+ path: "/api/admin/settings/:key",
263
+ auth: "basic",
264
+ bodyExample: { value: "new-value" },
265
+ },
266
+ ],
267
+ },
268
+ {
269
+ id: "errors-audit",
270
+ title: "Errors & Audit",
271
+ endpoints: [
272
+ {
273
+ id: "errors-list",
274
+ method: "GET",
275
+ path: "/api/admin/errors",
276
+ auth: "basic",
277
+ },
278
+ {
279
+ id: "errors-stats",
280
+ method: "GET",
281
+ path: "/api/admin/errors/stats",
282
+ auth: "basic",
283
+ },
284
+ {
285
+ id: "audit-list",
286
+ method: "GET",
287
+ path: "/api/admin/audit",
288
+ auth: "basic",
289
+ },
290
+ {
291
+ id: "audit-actions",
292
+ method: "GET",
293
+ path: "/api/admin/audit/actions",
294
+ auth: "basic",
295
+ },
296
+ ],
297
+ },
298
+ ];
299
+
300
+ module.exports = endpointRegistry;