@intranefr/superbackend 1.4.3 → 1.5.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 (65) hide show
  1. package/.env.example +6 -1
  2. package/README.md +5 -5
  3. package/index.js +23 -5
  4. package/package.json +5 -2
  5. package/public/sdk/ui-components.iife.js +191 -0
  6. package/sdk/error-tracking/browser/package.json +4 -3
  7. package/sdk/error-tracking/browser/src/embed.js +29 -0
  8. package/sdk/ui-components/browser/src/index.js +228 -0
  9. package/src/controllers/admin.controller.js +139 -1
  10. package/src/controllers/adminHeadless.controller.js +82 -0
  11. package/src/controllers/adminMigration.controller.js +5 -1
  12. package/src/controllers/adminScripts.controller.js +229 -0
  13. package/src/controllers/adminTerminals.controller.js +39 -0
  14. package/src/controllers/adminUiComponents.controller.js +315 -0
  15. package/src/controllers/adminUiComponentsAi.controller.js +34 -0
  16. package/src/controllers/orgAdmin.controller.js +286 -0
  17. package/src/controllers/uiComponentsPublic.controller.js +118 -0
  18. package/src/middleware/auth.js +7 -0
  19. package/src/middleware.js +119 -0
  20. package/src/models/HeadlessModelDefinition.js +10 -0
  21. package/src/models/ScriptDefinition.js +42 -0
  22. package/src/models/ScriptRun.js +22 -0
  23. package/src/models/UiComponent.js +29 -0
  24. package/src/models/UiComponentProject.js +26 -0
  25. package/src/models/UiComponentProjectComponent.js +18 -0
  26. package/src/routes/admin.routes.js +2 -0
  27. package/src/routes/adminHeadless.routes.js +6 -0
  28. package/src/routes/adminScripts.routes.js +21 -0
  29. package/src/routes/adminTerminals.routes.js +13 -0
  30. package/src/routes/adminUiComponents.routes.js +29 -0
  31. package/src/routes/llmUi.routes.js +26 -0
  32. package/src/routes/orgAdmin.routes.js +5 -0
  33. package/src/routes/uiComponentsPublic.routes.js +9 -0
  34. package/src/services/consoleOverride.service.js +291 -0
  35. package/src/services/email.service.js +17 -1
  36. package/src/services/headlessExternalModels.service.js +292 -0
  37. package/src/services/headlessModels.service.js +26 -6
  38. package/src/services/scriptsRunner.service.js +259 -0
  39. package/src/services/terminals.service.js +152 -0
  40. package/src/services/terminalsWs.service.js +100 -0
  41. package/src/services/uiComponentsAi.service.js +312 -0
  42. package/src/services/uiComponentsCrypto.service.js +39 -0
  43. package/src/services/webhook.service.js +2 -2
  44. package/src/services/workflow.service.js +1 -1
  45. package/src/utils/encryption.js +5 -3
  46. package/views/admin-coolify-deploy.ejs +1 -1
  47. package/views/admin-dashboard-home.ejs +1 -1
  48. package/views/admin-dashboard.ejs +1 -1
  49. package/views/admin-errors.ejs +2 -2
  50. package/views/admin-global-settings.ejs +3 -3
  51. package/views/admin-headless.ejs +294 -24
  52. package/views/admin-json-configs.ejs +8 -1
  53. package/views/admin-llm.ejs +2 -2
  54. package/views/admin-organizations.ejs +365 -9
  55. package/views/admin-scripts.ejs +497 -0
  56. package/views/admin-seo-config.ejs +1 -1
  57. package/views/admin-terminals.ejs +328 -0
  58. package/views/admin-test.ejs +3 -3
  59. package/views/admin-ui-components.ejs +709 -0
  60. package/views/admin-users.ejs +440 -4
  61. package/views/admin-webhooks.ejs +1 -1
  62. package/views/admin-workflows.ejs +1 -1
  63. package/views/partials/admin-assets-script.ejs +3 -3
  64. package/views/partials/dashboard/nav-items.ejs +3 -0
  65. package/views/partials/dashboard/palette.ejs +1 -1
@@ -0,0 +1,118 @@
1
+ const UiComponent = require('../models/UiComponent');
2
+ const UiComponentProject = require('../models/UiComponentProject');
3
+ const UiComponentProjectComponent = require('../models/UiComponentProjectComponent');
4
+
5
+ const { verifyKey } = require('../services/uiComponentsCrypto.service');
6
+
7
+ function extractProjectKey(req) {
8
+ const headerToken = req.headers['x-project-key'] || req.headers['x-api-key'];
9
+ if (headerToken) return String(headerToken).trim();
10
+ return null;
11
+ }
12
+
13
+ async function loadAndAuthorizeProject(req, res, projectId) {
14
+ const project = await UiComponentProject.findOne({ projectId: String(projectId), isActive: true }).lean();
15
+ if (!project) {
16
+ res.status(404).json({ error: 'Project not found' });
17
+ return null;
18
+ }
19
+
20
+ if (!project.isPublic) {
21
+ const key = extractProjectKey(req);
22
+ const ok = project.apiKeyHash && verifyKey(key, project.apiKeyHash);
23
+ if (!ok) {
24
+ res.status(401).json({ error: 'Invalid project key' });
25
+ return null;
26
+ }
27
+ }
28
+
29
+ return project;
30
+ }
31
+
32
+ exports.getManifest = async (req, res) => {
33
+ try {
34
+ const { projectId } = req.params;
35
+ const project = await loadAndAuthorizeProject(req, res, projectId);
36
+ if (!project) return;
37
+
38
+ const assignments = await UiComponentProjectComponent.find({ projectId: project.projectId, enabled: true }).lean();
39
+ const codes = assignments.map((a) => a.componentCode);
40
+
41
+ const components = await UiComponent.find({
42
+ code: { $in: codes },
43
+ isActive: true,
44
+ })
45
+ .sort({ code: 1 })
46
+ .lean();
47
+
48
+ const docsOnly = String(req.query.docs || '').toLowerCase() === 'true';
49
+
50
+ const out = components.map((c) => {
51
+ const base = {
52
+ code: c.code,
53
+ name: c.name,
54
+ version: c.version,
55
+ };
56
+ if (docsOnly) {
57
+ base.usageMarkdown = c.usageMarkdown;
58
+ } else {
59
+ base.html = c.html;
60
+ base.js = c.js;
61
+ base.css = c.css;
62
+ }
63
+ return base;
64
+ });
65
+
66
+ return res.json({
67
+ project: {
68
+ projectId: project.projectId,
69
+ name: project.name,
70
+ isPublic: project.isPublic,
71
+ allowedOrigins: project.allowedOrigins || [],
72
+ },
73
+ components: out,
74
+ });
75
+ } catch (error) {
76
+ console.error('UI Components getManifest error:', error);
77
+ return res.status(500).json({ error: 'Failed to load manifest' });
78
+ }
79
+ };
80
+
81
+ exports.getComponent = async (req, res) => {
82
+ try {
83
+ const { projectId, code } = req.params;
84
+ const project = await loadAndAuthorizeProject(req, res, projectId);
85
+ if (!project) return;
86
+
87
+ const componentCode = String(code || '').trim().toLowerCase();
88
+
89
+ const assignment = await UiComponentProjectComponent.findOne({
90
+ projectId: project.projectId,
91
+ componentCode,
92
+ enabled: true,
93
+ }).lean();
94
+
95
+ if (!assignment) return res.status(404).json({ error: 'Component not enabled for this project' });
96
+
97
+ const component = await UiComponent.findOne({ code: componentCode, isActive: true }).lean();
98
+ if (!component) return res.status(404).json({ error: 'Component not found' });
99
+
100
+ return res.json({
101
+ project: {
102
+ projectId: project.projectId,
103
+ isPublic: project.isPublic,
104
+ },
105
+ component: {
106
+ code: component.code,
107
+ name: component.name,
108
+ version: component.version,
109
+ html: component.html,
110
+ js: component.js,
111
+ css: component.css,
112
+ },
113
+ });
114
+ } catch (error) {
115
+ console.error('UI Components getComponent error:', error);
116
+ return res.status(500).json({ error: 'Failed to load component' });
117
+ }
118
+ };
@@ -19,6 +19,7 @@ const authenticate = async (req, res, next) => {
19
19
  req.user = user;
20
20
  next();
21
21
  } catch (error) {
22
+ console.error("api authenticate error:", error);
22
23
  return res
23
24
  .status(401)
24
25
  .json({ error: error.message || "Authentication failed" });
@@ -45,6 +46,12 @@ const basicAuth = (req, res, next) => {
45
46
  if (username === adminUsername && password === adminPassword) {
46
47
  next();
47
48
  } else {
49
+ console.error("api basicAuth error:", {
50
+ username,
51
+ password,
52
+ adminUsername,
53
+ adminPassword,
54
+ });
48
55
  res.setHeader("WWW-Authenticate", 'Basic realm="Admin Area"');
49
56
  return res.status(401).json({ error: "Invalid credentials" });
50
57
  }
package/src/middleware.js CHANGED
@@ -7,6 +7,7 @@ const ejs = require("ejs");
7
7
  const { basicAuth } = require("./middleware/auth");
8
8
  const endpointRegistry = require("./admin/endpointRegistry");
9
9
  const { createFeatureFlagsEjsMiddleware } = require("./services/featureFlags.service");
10
+ const consoleOverride = require("./services/consoleOverride.service");
10
11
  const {
11
12
  hookConsoleError,
12
13
  setupProcessHandlers,
@@ -30,6 +31,16 @@ function createMiddleware(options = {}) {
30
31
  const router = express.Router();
31
32
  const adminPath = options.adminPath || "/admin";
32
33
 
34
+ // Expose adminPath and WS attachment helper
35
+ router.adminPath = adminPath;
36
+ router.attachWs = (server) => {
37
+ const { attachTerminalWebsocketServer } = require('./services/terminalsWs.service');
38
+ attachTerminalWebsocketServer(server, { basePathPrefix: adminPath });
39
+ };
40
+
41
+ // Initialize console override service early to capture all logs
42
+ consoleOverride.init();
43
+
33
44
  if (!errorCaptureInitialized) {
34
45
  errorCaptureInitialized = true;
35
46
  hookConsoleError();
@@ -138,6 +149,12 @@ function createMiddleware(options = {}) {
138
149
  // Serve public static files (e.g. /og/og-default.png)
139
150
  router.use(express.static(path.join(__dirname, "..", "public")));
140
151
 
152
+ // Serve browser SDK bundles
153
+ router.use(
154
+ "/public/sdk",
155
+ express.static(path.join(__dirname, "..", "public", "sdk")),
156
+ );
157
+
141
158
  // Serve static files for admin views
142
159
  router.use(
143
160
  `${adminPath}/assets`,
@@ -184,6 +201,70 @@ function createMiddleware(options = {}) {
184
201
  });
185
202
  });
186
203
 
204
+ router.get(`${adminPath}/terminals`, basicAuth, (req, res) => {
205
+ const templatePath = path.join(
206
+ __dirname,
207
+ "..",
208
+ "views",
209
+ "admin-terminals.ejs",
210
+ );
211
+ fs.readFile(templatePath, "utf8", (err, template) => {
212
+ if (err) {
213
+ console.error("Error reading template:", err);
214
+ return res.status(500).send("Error loading page");
215
+ }
216
+ try {
217
+ const html = ejs.render(
218
+ template,
219
+ {
220
+ baseUrl: req.baseUrl,
221
+ adminPath,
222
+ endpointRegistry,
223
+ },
224
+ {
225
+ filename: templatePath,
226
+ },
227
+ );
228
+ res.send(html);
229
+ } catch (renderErr) {
230
+ console.error("Error rendering template:", renderErr);
231
+ res.status(500).send("Error rendering page");
232
+ }
233
+ });
234
+ });
235
+
236
+ router.get(`${adminPath}/scripts`, basicAuth, (req, res) => {
237
+ const templatePath = path.join(
238
+ __dirname,
239
+ "..",
240
+ "views",
241
+ "admin-scripts.ejs",
242
+ );
243
+ fs.readFile(templatePath, "utf8", (err, template) => {
244
+ if (err) {
245
+ console.error("Error reading template:", err);
246
+ return res.status(500).send("Error loading page");
247
+ }
248
+ try {
249
+ const html = ejs.render(
250
+ template,
251
+ {
252
+ baseUrl: req.baseUrl,
253
+ adminPath,
254
+ endpointRegistry,
255
+ },
256
+ {
257
+ filename: templatePath,
258
+ },
259
+ );
260
+ res.send(html);
261
+ } catch (renderErr) {
262
+ console.error("Error rendering template:", renderErr);
263
+ res.status(500).send("Error rendering page");
264
+ }
265
+ });
266
+ });
267
+
187
268
  router.use("/api/admin", require("./routes/admin.routes"));
188
269
  router.use("/api/admin/settings", require("./routes/globalSettings.routes"));
189
270
  router.use(
@@ -200,11 +281,14 @@ function createMiddleware(options = {}) {
200
281
  );
201
282
  router.use("/api/admin/i18n", require("./routes/adminI18n.routes"));
202
283
  router.use("/api/admin/headless", require("./routes/adminHeadless.routes"));
284
+ router.use("/api/admin/scripts", require("./routes/adminScripts.routes"));
285
+ router.use("/api/admin/terminals", require("./routes/adminTerminals.routes"));
203
286
  router.use("/api/admin/assets", require("./routes/adminAssets.routes"));
204
287
  router.use(
205
288
  "/api/admin/upload-namespaces",
206
289
  require("./routes/adminUploadNamespaces.routes"),
207
290
  );
291
+ router.use("/api/admin/ui-components", require("./routes/adminUiComponents.routes"));
208
292
  router.use("/api/admin/migration", require("./routes/adminMigration.routes"));
209
293
  router.use("/api/admin/errors", basicAuth, require("./routes/adminErrors.routes"));
210
294
  router.use("/api/admin/audit", basicAuth, require("./routes/adminAudit.routes"));
@@ -225,6 +309,8 @@ function createMiddleware(options = {}) {
225
309
  router.use("/api/invites", require("./routes/invite.routes"));
226
310
  router.use("/api/log", require("./routes/log.routes"));
227
311
  router.use("/api/error-tracking", require("./routes/errorTracking.routes"));
312
+ router.use("/api/ui-components", require("./routes/uiComponentsPublic.routes"));
313
+ router.use("/api/llm/ui", require("./routes/llmUi.routes"));
228
314
 
229
315
  // Public assets proxy
230
316
  router.use("/public/assets", require("./routes/publicAssets.routes"));
@@ -537,6 +623,39 @@ function createMiddleware(options = {}) {
537
623
  });
538
624
  });
539
625
 
626
+ // Admin UI Components page (protected by basic auth)
627
+ router.get(`${adminPath}/ui-components`, basicAuth, (req, res) => {
628
+ const templatePath = path.join(
629
+ __dirname,
630
+ "..",
631
+ "views",
632
+ "admin-ui-components.ejs",
633
+ );
634
+ fs.readFile(templatePath, "utf8", (err, template) => {
635
+ if (err) {
636
+ console.error("Error reading template:", err);
637
+ return res.status(500).send("Error loading page");
638
+ }
639
+ try {
640
+ const html = ejs.render(
641
+ template,
642
+ {
643
+ baseUrl: req.baseUrl,
644
+ adminPath,
645
+ endpointRegistry,
646
+ },
647
+ {
648
+ filename: templatePath,
649
+ },
650
+ );
651
+ res.send(html);
652
+ } catch (renderErr) {
653
+ console.error("Error rendering template:", renderErr);
654
+ res.status(500).send("Error rendering page");
655
+ }
656
+ });
657
+ });
658
+
540
659
  // Admin JSON configs page (protected by basic auth)
541
660
  router.get(`${adminPath}/json-configs`, basicAuth, (req, res) => {
542
661
  const templatePath = path.join(
@@ -28,6 +28,16 @@ const headlessModelDefinitionSchema = new mongoose.Schema(
28
28
  description: { type: String, default: '' },
29
29
  fields: { type: [headlessFieldSchema], default: [] },
30
30
  indexes: { type: [headlessIndexSchema], default: [] },
31
+ sourceType: { type: String, enum: ['internal', 'external'], default: 'internal', index: true },
32
+ sourceCollectionName: { type: String, default: null, index: true },
33
+ isExternal: { type: Boolean, default: false, index: true },
34
+ inference: {
35
+ enabled: { type: Boolean, default: false },
36
+ lastInferredAt: { type: Date, default: null },
37
+ sampleSize: { type: Number, default: null },
38
+ warnings: { type: [String], default: [] },
39
+ stats: { type: mongoose.Schema.Types.Mixed, default: null },
40
+ },
31
41
  isActive: { type: Boolean, default: true, index: true },
32
42
  version: { type: Number, default: 1 },
33
43
  fieldsHash: { type: String, default: null },
@@ -0,0 +1,42 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ const envVarSchema = new mongoose.Schema(
4
+ {
5
+ key: { type: String, required: true },
6
+ value: { type: String, required: true },
7
+ },
8
+ { _id: false },
9
+ );
10
+
11
+ const scriptDefinitionSchema = new mongoose.Schema(
12
+ {
13
+ name: { type: String, required: true },
14
+ codeIdentifier: { type: String, required: true, unique: true, index: true },
15
+ description: { type: String, default: '' },
16
+ type: { type: String, enum: ['bash', 'node', 'browser'], required: true },
17
+ runner: { type: String, enum: ['host', 'vm2', 'browser'], required: true },
18
+ script: { type: String, required: true },
19
+ defaultWorkingDirectory: { type: String, default: '' },
20
+ env: { type: [envVarSchema], default: [] },
21
+ timeoutMs: { type: Number, default: 5 * 60 * 1000 },
22
+ enabled: { type: Boolean, default: true, index: true },
23
+ },
24
+ { timestamps: true, collection: 'script_definitions' },
25
+ );
26
+
27
+ function normalizeCodeIdentifier(codeIdentifier) {
28
+ return String(codeIdentifier || '')
29
+ .trim()
30
+ .toLowerCase()
31
+ .replace(/\s+/g, '-')
32
+ .replace(/[^a-z0-9_-]/g, '');
33
+ }
34
+
35
+ scriptDefinitionSchema.pre('validate', function preValidate(next) {
36
+ this.codeIdentifier = normalizeCodeIdentifier(this.codeIdentifier);
37
+ next();
38
+ });
39
+
40
+ module.exports =
41
+ mongoose.models.ScriptDefinition ||
42
+ mongoose.model('ScriptDefinition', scriptDefinitionSchema);
@@ -0,0 +1,22 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ const scriptRunSchema = new mongoose.Schema(
4
+ {
5
+ scriptId: { type: mongoose.Schema.Types.ObjectId, ref: 'ScriptDefinition', required: true, index: true },
6
+ status: {
7
+ type: String,
8
+ enum: ['queued', 'running', 'succeeded', 'failed', 'canceled', 'timed_out'],
9
+ default: 'queued',
10
+ index: true,
11
+ },
12
+ trigger: { type: String, enum: ['manual', 'schedule', 'api'], default: 'manual', index: true },
13
+ startedAt: { type: Date, default: null },
14
+ finishedAt: { type: Date, default: null },
15
+ exitCode: { type: Number, default: null },
16
+ outputTail: { type: String, default: '' },
17
+ meta: { type: mongoose.Schema.Types.Mixed, default: null },
18
+ },
19
+ { timestamps: true, collection: 'script_runs' },
20
+ );
21
+
22
+ module.exports = mongoose.models.ScriptRun || mongoose.model('ScriptRun', scriptRunSchema);
@@ -0,0 +1,29 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ const uiComponentSchema = new mongoose.Schema(
4
+ {
5
+ code: {
6
+ type: String,
7
+ required: true,
8
+ unique: true,
9
+ index: true,
10
+ trim: true,
11
+ lowercase: true,
12
+ match: [/^[a-z][a-z0-9_-]{1,63}$/, 'Invalid component code'],
13
+ },
14
+ name: { type: String, required: true, trim: true },
15
+
16
+ html: { type: String, default: '' },
17
+ js: { type: String, default: '' },
18
+ css: { type: String, default: '' },
19
+
20
+ api: { type: mongoose.Schema.Types.Mixed, default: null },
21
+ usageMarkdown: { type: String, default: '' },
22
+
23
+ version: { type: Number, default: 1 },
24
+ isActive: { type: Boolean, default: true, index: true },
25
+ },
26
+ { timestamps: true, collection: 'ui_components' },
27
+ );
28
+
29
+ module.exports = mongoose.models.UiComponent || mongoose.model('UiComponent', uiComponentSchema);
@@ -0,0 +1,26 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ const uiComponentProjectSchema = new mongoose.Schema(
4
+ {
5
+ projectId: {
6
+ type: String,
7
+ required: true,
8
+ unique: true,
9
+ index: true,
10
+ trim: true,
11
+ match: [/^prj_[a-z0-9]{8,32}$/, 'Invalid projectId'],
12
+ },
13
+ name: { type: String, required: true, trim: true },
14
+
15
+ isPublic: { type: Boolean, default: true, index: true },
16
+ apiKeyHash: { type: String, default: null },
17
+
18
+ allowedOrigins: { type: [String], default: [] },
19
+
20
+ isActive: { type: Boolean, default: true, index: true },
21
+ },
22
+ { timestamps: true, collection: 'ui_component_projects' },
23
+ );
24
+
25
+ module.exports = mongoose.models.UiComponentProject ||
26
+ mongoose.model('UiComponentProject', uiComponentProjectSchema);
@@ -0,0 +1,18 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ const uiComponentProjectComponentSchema = new mongoose.Schema(
4
+ {
5
+ projectId: { type: String, required: true, index: true },
6
+ componentCode: { type: String, required: true, index: true },
7
+ enabled: { type: Boolean, default: true, index: true },
8
+ },
9
+ { timestamps: true, collection: 'ui_component_project_components' },
10
+ );
11
+
12
+ uiComponentProjectComponentSchema.index(
13
+ { projectId: 1, componentCode: 1 },
14
+ { unique: true },
15
+ );
16
+
17
+ module.exports = mongoose.models.UiComponentProjectComponent ||
18
+ mongoose.model('UiComponentProjectComponent', uiComponentProjectComponentSchema);
@@ -7,9 +7,11 @@ const { basicAuth } = require('../middleware/auth');
7
7
  router.use(basicAuth);
8
8
 
9
9
  router.get('/users', adminController.getUsers);
10
+ router.post('/users/register', adminController.registerUser);
10
11
  router.get('/users/:id', adminController.getUser);
11
12
  router.put('/users/:id/subscription', adminController.updateUserSubscription);
12
13
  router.patch('/users/:id', adminController.updateUserPassword);
14
+ router.delete('/users/:id', adminController.deleteUser);
13
15
  router.post('/users/:id/reconcile', adminController.reconcileUser);
14
16
  router.post('/generate-token', adminController.generateToken);
15
17
 
@@ -13,6 +13,12 @@ router.post('/models', adminHeadlessController.createModel);
13
13
  router.put('/models/:codeIdentifier', adminHeadlessController.updateModel);
14
14
  router.delete('/models/:codeIdentifier', adminHeadlessController.deleteModel);
15
15
 
16
+ // External models (Mongo collections)
17
+ router.get('/external/collections', adminHeadlessController.listExternalCollections);
18
+ router.post('/external/infer', adminHeadlessController.inferExternalCollection);
19
+ router.post('/external/import', adminHeadlessController.importExternalModel);
20
+ router.post('/models/:codeIdentifier/sync', adminHeadlessController.syncExternalModel);
21
+
16
22
  // Advanced JSON / bulk helpers
17
23
  router.post('/models/validate', adminHeadlessController.validateModelDefinition);
18
24
  router.post('/models/apply', adminHeadlessController.applyModelProposal);
@@ -0,0 +1,21 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+
4
+ const { basicAuth } = require('../middleware/auth');
5
+ const controller = require('../controllers/adminScripts.controller');
6
+
7
+ router.use(basicAuth);
8
+
9
+ router.get('/', controller.listScripts);
10
+ router.post('/', controller.createScript);
11
+ router.get('/runs', controller.listRuns);
12
+ router.get('/runs/:runId', controller.getRun);
13
+ router.get('/runs/:runId/stream', controller.streamRun);
14
+
15
+ router.get('/:id', controller.getScript);
16
+ router.put('/:id', controller.updateScript);
17
+ router.delete('/:id', controller.deleteScript);
18
+
19
+ router.post('/:id/run', controller.runScript);
20
+
21
+ module.exports = router;
@@ -0,0 +1,13 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+
4
+ const { basicAuth } = require('../middleware/auth');
5
+ const controller = require('../controllers/adminTerminals.controller');
6
+
7
+ router.use(basicAuth);
8
+
9
+ router.post('/sessions', controller.createSession);
10
+ router.get('/sessions', controller.listSessions);
11
+ router.delete('/sessions/:sessionId', controller.killSession);
12
+
13
+ module.exports = router;
@@ -0,0 +1,29 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+
4
+ const { basicAuth } = require('../middleware/auth');
5
+ const adminUiComponentsController = require('../controllers/adminUiComponents.controller');
6
+ const adminUiComponentsAiController = require('../controllers/adminUiComponentsAi.controller');
7
+
8
+ router.use(basicAuth);
9
+
10
+ router.get('/projects', adminUiComponentsController.listProjects);
11
+ router.post('/projects', adminUiComponentsController.createProject);
12
+ router.get('/projects/:projectId', adminUiComponentsController.getProject);
13
+ router.put('/projects/:projectId', adminUiComponentsController.updateProject);
14
+ router.delete('/projects/:projectId', adminUiComponentsController.deleteProject);
15
+ router.post('/projects/:projectId/rotate-key', adminUiComponentsController.rotateProjectKey);
16
+
17
+ router.get('/components', adminUiComponentsController.listComponents);
18
+ router.post('/components', adminUiComponentsController.createComponent);
19
+ router.get('/components/:code', adminUiComponentsController.getComponent);
20
+ router.put('/components/:code', adminUiComponentsController.updateComponent);
21
+ router.delete('/components/:code', adminUiComponentsController.deleteComponent);
22
+
23
+ router.get('/projects/:projectId/components', adminUiComponentsController.listProjectAssignments);
24
+ router.post('/projects/:projectId/components/:code', adminUiComponentsController.setAssignment);
25
+ router.delete('/projects/:projectId/components/:code', adminUiComponentsController.deleteAssignment);
26
+
27
+ router.post('/ai/components/:code/propose', adminUiComponentsAiController.propose);
28
+
29
+ module.exports = router;
@@ -0,0 +1,26 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+
4
+ const { basicAuth } = require('../middleware/auth');
5
+ const adminUiComponentsController = require('../controllers/adminUiComponents.controller');
6
+
7
+ router.use(basicAuth);
8
+
9
+ router.get('/projects', adminUiComponentsController.listProjects);
10
+ router.post('/projects', adminUiComponentsController.createProject);
11
+ router.get('/projects/:projectId', adminUiComponentsController.getProject);
12
+ router.put('/projects/:projectId', adminUiComponentsController.updateProject);
13
+ router.delete('/projects/:projectId', adminUiComponentsController.deleteProject);
14
+ router.post('/projects/:projectId/rotate-key', adminUiComponentsController.rotateProjectKey);
15
+
16
+ router.get('/components', adminUiComponentsController.listComponents);
17
+ router.post('/components', adminUiComponentsController.createComponent);
18
+ router.get('/components/:code', adminUiComponentsController.getComponent);
19
+ router.put('/components/:code', adminUiComponentsController.updateComponent);
20
+ router.delete('/components/:code', adminUiComponentsController.deleteComponent);
21
+
22
+ router.get('/projects/:projectId/components', adminUiComponentsController.listProjectAssignments);
23
+ router.post('/projects/:projectId/components/:code', adminUiComponentsController.setAssignment);
24
+ router.delete('/projects/:projectId/components/:code', adminUiComponentsController.deleteAssignment);
25
+
26
+ module.exports = router;
@@ -6,7 +6,12 @@ const orgAdminController = require('../controllers/orgAdmin.controller');
6
6
  const asyncHandler = require('../utils/asyncHandler');
7
7
 
8
8
  router.get('/', basicAuth, asyncHandler(orgAdminController.listOrgs));
9
+ router.post('/', basicAuth, asyncHandler(orgAdminController.createOrganization));
9
10
  router.get('/:orgId', basicAuth, asyncHandler(orgAdminController.getOrg));
11
+ router.put('/:orgId', basicAuth, asyncHandler(orgAdminController.updateOrganization));
12
+ router.patch('/:orgId/disable', basicAuth, asyncHandler(orgAdminController.disableOrganization));
13
+ router.patch('/:orgId/enable', basicAuth, asyncHandler(orgAdminController.enableOrganization));
14
+ router.delete('/:orgId', basicAuth, asyncHandler(orgAdminController.deleteOrganization));
10
15
 
11
16
  router.get('/:orgId/members', basicAuth, asyncHandler(orgAdminController.listMembers));
12
17
  router.patch('/:orgId/members/:memberId', basicAuth, asyncHandler(orgAdminController.updateMember));
@@ -0,0 +1,9 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+
4
+ const uiComponentsPublicController = require('../controllers/uiComponentsPublic.controller');
5
+
6
+ router.get('/projects/:projectId/manifest', uiComponentsPublicController.getManifest);
7
+ router.get('/projects/:projectId/components/:code', uiComponentsPublicController.getComponent);
8
+
9
+ module.exports = router;