329 lines
9.3 KiB
JavaScript
329 lines
9.3 KiB
JavaScript
const express = require('express');
|
|
const db = require('../db/models');
|
|
const wrapAsync = require('../helpers').wrapAsync;
|
|
const router = express.Router();
|
|
const sjs = require('sequelize-json-schema');
|
|
const { getWidget, askGpt } = require('../services/openai');
|
|
const { LocalAIApi } = require('../ai/LocalAIApi');
|
|
|
|
const loadRolesModules = () => {
|
|
try {
|
|
return {
|
|
RolesService: require('../services/roles'),
|
|
RolesDBApi: require('../db/api/roles'),
|
|
};
|
|
} catch (error) {
|
|
console.error('Roles modules are missing. Advanced roles are required for this endpoint.', error);
|
|
const err = new Error('Roles modules are missing. Advanced roles are required for this endpoint.');
|
|
err.originalError = error;
|
|
throw err;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @swagger
|
|
* /api/roles/roles-info/{infoId}:
|
|
* delete:
|
|
* security:
|
|
* - bearerAuth: []
|
|
* tags: [Roles]
|
|
* summary: Remove role information by ID
|
|
* description: Remove specific role information by ID
|
|
* parameters:
|
|
* - in: path
|
|
* name: infoId
|
|
* description: ID of role information to remove
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* - in: query
|
|
* name: userId
|
|
* description: ID of the user
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* - in: query
|
|
* name: key
|
|
* description: Key of the role information to remove
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* responses:
|
|
* 200:
|
|
* description: Role information successfully removed
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* user:
|
|
* type: string
|
|
* description: The user information
|
|
* 400:
|
|
* description: Invalid ID or key supplied
|
|
* 401:
|
|
* $ref: "#/components/responses/UnauthorizedError"
|
|
* 404:
|
|
* description: Role not found
|
|
* 500:
|
|
* description: Some server error
|
|
*/
|
|
|
|
router.delete(
|
|
'/roles-info/:infoId',
|
|
wrapAsync(async (req, res) => {
|
|
const { RolesService } = loadRolesModules();
|
|
const role = await RolesService.removeRoleInfoById(
|
|
req.query.infoId,
|
|
req.query.roleId,
|
|
req.query.key,
|
|
req.currentUser,
|
|
);
|
|
|
|
res.status(200).send(role);
|
|
}),
|
|
);
|
|
|
|
/**
|
|
* @swagger
|
|
* /api/roles/role-info/{roleId}:
|
|
* get:
|
|
* security:
|
|
* - bearerAuth: []
|
|
* tags: [Roles]
|
|
* summary: Get role information by key
|
|
* description: Get specific role information by key
|
|
* parameters:
|
|
* - in: path
|
|
* name: roleId
|
|
* description: ID of role to get information for
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* - in: query
|
|
* name: key
|
|
* description: Key of the role information to retrieve
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* responses:
|
|
* 200:
|
|
* description: Role information successfully received
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* info:
|
|
* type: string
|
|
* description: The role information
|
|
* 400:
|
|
* description: Invalid ID or key supplied
|
|
* 401:
|
|
* $ref: "#/components/responses/UnauthorizedError"
|
|
* 404:
|
|
* description: Role not found
|
|
* 500:
|
|
* description: Some server error
|
|
*/
|
|
|
|
router.get(
|
|
'/info-by-key',
|
|
wrapAsync(async (req, res) => {
|
|
const { RolesService, RolesDBApi } = loadRolesModules();
|
|
const roleId = req.query.roleId;
|
|
const key = req.query.key;
|
|
const currentUser = req.currentUser;
|
|
let info = await RolesService.getRoleInfoByKey(
|
|
key,
|
|
roleId,
|
|
currentUser,
|
|
);
|
|
const role = await RolesDBApi.findBy({ id: roleId });
|
|
if (!role?.role_customization) {
|
|
await Promise.all(["pie", "bar"].map(async (e) => {
|
|
const schema = await sjs.getSequelizeSchema(db.sequelize, {});
|
|
const payload = {
|
|
description: `Create some cool ${e} chart`,
|
|
modelDefinition: schema.definitions,
|
|
};
|
|
const widgetId = await getWidget(payload, currentUser?.id, roleId);
|
|
if (widgetId) {
|
|
await RolesService.addRoleInfo(
|
|
roleId,
|
|
currentUser?.id,
|
|
'widgets',
|
|
widgetId,
|
|
req.currentUser,
|
|
);
|
|
}
|
|
}))
|
|
info = await RolesService.getRoleInfoByKey(
|
|
key,
|
|
roleId,
|
|
currentUser,
|
|
);
|
|
}
|
|
res.status(200).send(info);
|
|
}),
|
|
);
|
|
|
|
router.post(
|
|
'/create_widget',
|
|
wrapAsync(async (req, res) => {
|
|
const { RolesService } = loadRolesModules();
|
|
const { description, userId, roleId } = req.body;
|
|
|
|
const currentUser = req.currentUser;
|
|
const schema = await sjs.getSequelizeSchema(db.sequelize, {});
|
|
const payload = {
|
|
description,
|
|
modelDefinition: schema.definitions,
|
|
};
|
|
|
|
const widgetId = await getWidget(payload, userId, roleId);
|
|
|
|
if (widgetId) {
|
|
await RolesService.addRoleInfo(
|
|
roleId,
|
|
userId,
|
|
'widgets',
|
|
widgetId,
|
|
currentUser,
|
|
);
|
|
|
|
return res.status(200).send(widgetId);
|
|
} else {
|
|
return res.status(400).send(widgetId);
|
|
}
|
|
}),
|
|
);
|
|
|
|
/**
|
|
* @swagger
|
|
* /api/openai/response:
|
|
* post:
|
|
* security:
|
|
* - bearerAuth: []
|
|
* tags: [OpenAI]
|
|
* summary: Proxy a Responses API request
|
|
* description: Sends the payload to the Flatlogic AI proxy and returns the response.
|
|
* requestBody:
|
|
* required: true
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* input:
|
|
* type: array
|
|
* description: List of messages with roles and content.
|
|
* items:
|
|
* type: object
|
|
* properties:
|
|
* role:
|
|
* type: string
|
|
* content:
|
|
* type: string
|
|
* options:
|
|
* type: object
|
|
* description: Optional polling controls.
|
|
* properties:
|
|
* poll_interval:
|
|
* type: number
|
|
* poll_timeout:
|
|
* type: number
|
|
* responses:
|
|
* 200:
|
|
* description: AI response received
|
|
* 400:
|
|
* description: Invalid request
|
|
* 401:
|
|
* $ref: "#/components/responses/UnauthorizedError"
|
|
* 502:
|
|
* description: Proxy error
|
|
*/
|
|
router.post(
|
|
'/response',
|
|
wrapAsync(async (req, res) => {
|
|
const body = req.body || {};
|
|
const options = body.options || {};
|
|
const payload = { ...body };
|
|
delete payload.options;
|
|
|
|
const response = await LocalAIApi.createResponse(payload, options);
|
|
|
|
if (response.success) {
|
|
return res.status(200).send(response);
|
|
}
|
|
|
|
console.error('AI proxy error:', response);
|
|
const status = response.error === 'input_missing' ? 400 : 502;
|
|
return res.status(status).send(response);
|
|
}),
|
|
);
|
|
|
|
/**
|
|
* @swagger
|
|
* /api/openai/ask:
|
|
* post:
|
|
* security:
|
|
* - bearerAuth: []
|
|
* tags: [OpenAI]
|
|
* summary: Ask a question to ChatGPT
|
|
* description: Send a question through the Flatlogic AI proxy and get a response
|
|
* requestBody:
|
|
* required: true
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* prompt:
|
|
* type: string
|
|
* description: The question to ask ChatGPT
|
|
* responses:
|
|
* 200:
|
|
* description: Question successfully answered
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* success:
|
|
* type: boolean
|
|
* description: Whether the request was successful
|
|
* data:
|
|
* type: string
|
|
* description: The answer from ChatGPT
|
|
* 400:
|
|
* description: Invalid request
|
|
* 401:
|
|
* $ref: "#/components/responses/UnauthorizedError"
|
|
* 500:
|
|
* description: Some server error
|
|
*/
|
|
router.post(
|
|
'/ask-gpt',
|
|
wrapAsync(async (req, res) => {
|
|
const { prompt } = req.body;
|
|
if (!prompt) {
|
|
return res.status(400).send({
|
|
success: false,
|
|
error: 'Prompt is required',
|
|
});
|
|
}
|
|
|
|
const response = await askGpt(prompt);
|
|
|
|
if (response.success) {
|
|
return res.status(200).send(response);
|
|
} else {
|
|
return res.status(500).send(response);
|
|
}
|
|
}),
|
|
);
|
|
|
|
|
|
module.exports = router;
|