feat: add routes for external API requests and operation logs, add sessionId property

main
adriano 2024-07-30 12:01:48 -03:00
parent b96b05ad83
commit 14c0303c78
7 changed files with 214 additions and 78 deletions

10
app.js
View File

@ -28,13 +28,13 @@ const notFoundMiddlware = require('./middleware/not-found')
//middleware //middleware
app.set('trust proxy', 1) app.set('trust proxy', 1)
app.use(rateLimiter({ // app.use(rateLimiter({
windowMs: 15 * 60 * 1000, // windowMs: 15 * 60 * 1000,
max: 60, // max: 60,
})) // }))
// Security packages // Security packages
app.use(helmet()) // app.use(helmet())
app.use(cors()) app.use(cors())
app.use(xss()) app.use(xss())

View File

@ -7,6 +7,8 @@ const {
const API_Usage = require("../models/API_Usage.js") const API_Usage = require("../models/API_Usage.js")
const billingSumUsage = require("../utils/billingSumUsage.js") const billingSumUsage = require("../utils/billingSumUsage.js")
const moment = require('moment') const moment = require('moment')
const API_Call = require("../models/API_Call.js")
const API_Operation = require("../models/API_Operation.js")
const setApiPricing = async (req, res) => { const setApiPricing = async (req, res) => {
@ -18,74 +20,67 @@ const setApiPricing = async (req, res) => {
'billingBy', 'billingBy',
'billingUnit']) 'billingUnit'])
const apiPricing = await API_Pricing.create({ const normalizedProvider = provider.trim().toLowerCase()
provider: provider.trim().toLowerCase(), const normalizedProduct = product.trim().toLowerCase()
product: product.trim().toLowerCase(),
const filter = { provider: normalizedProvider, product: normalizedProduct }
const update = {
provider: normalizedProvider,
product: normalizedProduct,
currency, currency,
price, price,
billingBy, billingBy,
billingUnit, billingUnit,
type type
}) }
const options = { new: true, upsert: true }
const apiPricing = await API_Pricing.findOneAndUpdate(filter, update, options)
res.status(StatusCodes.OK).json({ apiPricing }) res.status(StatusCodes.OK).json({ apiPricing })
} }
const registerUsage = async (req, res) => { const registerUsage = async (req, res) => {
const { const {
provider, provider,
product, product,
usage, usage,
callerId, callerId,
sessionId,
companyId, companyId,
quantityOfOperationAttempts, quantityOfOperationAttempts,
chosenOperation,
requestLogsOpenAI,
responseErrorLogsOpenAI,
quantityOfCallsToFalconFlowAPI,
requestLogsFalconFlowAPI,
responseErrorLogsFalconFlowAPI,
} = req.body } = req.body
mustContainProperties(req, [ mustContainProperties(req, [
'companyId', 'companyId',
'callerId', 'callerId',
'sessionId',
'quantityOfOperationAttempts', 'quantityOfOperationAttempts',
'chosenOperation',
'requestLogsOpenAI',
// 'responseErrorLogsOpenAI',
'quantityOfCallsToFalconFlowAPI',
'requestLogsFalconFlowAPI',
// 'responseErrorLogsFalconFlowAPI',
'provider', 'provider',
'product', 'product',
'usage', 'usage',
]) ])
const apiPricing = await API_Pricing.findOne({ const apiPricing = await API_Pricing.findOne({
provider: provider.trim().toLowerCase(), provider: provider.trim().toLowerCase(),
product: product.trim().toLowerCase(), product: product.trim().toLowerCase(),
}) })
if (apiPricing) {
const { price, billingBy, billingUnit } = apiPricing if (apiPricing) {
const { price, billingBy, billingUnit } = apiPricing
const apiUsage = await API_Usage.create({ const apiUsage = await API_Usage.create({
provider: provider.trim().toLowerCase(), provider: provider.trim().toLowerCase(),
product: product.trim().toLowerCase(), product: product.trim().toLowerCase(),
callerId, callerId,
sessionId,
quantityOfOperationAttempts, quantityOfOperationAttempts,
chosenOperation,
requestLogsOpenAI,
responseErrorLogsOpenAI,
quantityOfCallsToFalconFlowAPI,
requestLogsFalconFlowAPI,
responseErrorLogsFalconFlowAPI,
usage, usage,
price, price,
billingBy, billingBy,
billingUnit, billingUnit,
companyId, companyId,
total_cost: calculateApiUsage(price, billingUnit, usage, billingBy) total_cost: calculateApiUsage(price, billingUnit, usage, billingBy)
}) })
@ -98,6 +93,62 @@ const registerUsage = async (req, res) => {
} }
const registerAPICall = async (req, res) => {
const {
callerId,
companyId,
sessionId,
type,
requestLogs,
responseError,
quantityOfAPICall
} = req.body
mustContainProperties(req, [
'companyId',
'callerId',
'sessionId'
])
const apiCall = await API_Call.create({
callerId,
companyId,
sessionId,
type,
requestLogs,
responseError,
quantityOfAPICall
})
res.status(StatusCodes.OK).json({ apiCall })
}
const registerOperation = async (req, res) => {
const {
callerId,
companyId,
sessionId,
operation,
} = req.body
mustContainProperties(req, [
'companyId',
'callerId',
'sessionId',
'operation'
])
const apiOperation = await API_Operation.create({
callerId,
companyId,
sessionId,
operation
})
res.status(StatusCodes.OK).json({ apiOperation })
}
const getUsage = async (req, res) => { const getUsage = async (req, res) => {
const { startDate, endDate, companyId, } = req.body const { startDate, endDate, companyId, } = req.body
@ -124,5 +175,7 @@ const getUsage = async (req, res) => {
module.exports = { module.exports = {
setApiPricing, setApiPricing,
registerUsage, registerUsage,
registerAPICall,
registerOperation,
getUsage getUsage
} }

36
models/API_Call.js 100644
View File

@ -0,0 +1,36 @@
const mongoose = require('../db/connect')
const { Schema } = mongoose
const apiCall = new Schema({
companyId: {
type: String,
required: true,
},
callerId: {
type: String,
required: true,
},
sessionId: {
type: String,
required: true,
},
type: {
type: String,
enum: ['IAProvider', 'externalAPI',],
},
requestLogs: {
type: String,
},
responseError: {
type: String,
},
quantityOfAPICall: {
type: String,
},
}, { timestamps: true })
const API_Call = mongoose.model('API_Call', apiCall)
module.exports = API_Call

View File

@ -0,0 +1,27 @@
const mongoose = require('../db/connect')
const { Schema } = mongoose
const apiOperation = new Schema({
companyId: {
type: String,
required: true,
},
callerId: {
type: String,
required: true,
},
sessionId: {
type: String,
required: true,
},
operation: {
type: String,
required: true,
},
}, { timestamps: true })
const API_Operation = mongoose.model('API_Operation', apiOperation)
module.exports = API_Operation

View File

@ -11,33 +11,37 @@ const apiUsage = new Schema({
type: String, type: String,
required: true, required: true,
}, },
sessionId: {
type: String,
required: true,
},
quantityOfOperationAttempts: { quantityOfOperationAttempts: {
type: String, type: String,
required: true, required: true,
}, },
chosenOperation: { // chosenOperation: {
type: String, // type: String,
required: true, // required: true,
}, // },
requestLogsOpenAI: { // requestLogsOpenAI: {
type: String, // type: String,
required: true, // required: true,
}, // },
responseErrorLogsOpenAI: { // responseErrorLogsOpenAI: {
type: String, // type: String,
}, // },
quantityOfCallsToFalconFlowAPI: { // quantityOfCallsToFalconFlowAPI: {
type: String, // type: String,
required: true, // required: true,
}, // },
requestLogsFalconFlowAPI: { // requestLogsFalconFlowAPI: {
type: String, // type: String,
required: true, // required: true,
}, // },
responseErrorLogsFalconFlowAPI: { // responseErrorLogsFalconFlowAPI: {
type: String, // type: String,
required: true, // required: true,
}, // },
provider: { provider: {
type: String, type: String,
required: true, required: true,

View File

@ -1,11 +1,13 @@
const express = require('express') const express = require('express')
const router = express.Router() const router = express.Router()
const { authorization, } = require('../middleware/authentication') const { authorization, } = require('../middleware/authentication')
const { setApiPricing, registerUsage, getUsage} = require('../controllers/apiUsagePricing') const { setApiPricing, registerUsage, getUsage, registerAPICall, registerOperation} = require('../controllers/apiUsagePricing')
router.route('/create').post(authorization, setApiPricing) router.route('/create').post(authorization, setApiPricing)
router.route('/usage').post(authorization, registerUsage) router.route('/usage').post(authorization, registerUsage)
router.route('/report').post(authorization, getUsage) router.route('/report').post(authorization, getUsage)
router.route('/api-call').post(authorization, registerAPICall)
router.route('/api-operation').post(authorization, registerOperation)

View File

@ -24,68 +24,82 @@ paths:
properties: properties:
companyId: companyId:
type: string type: string
description: Company identifier
example: "1" example: "1"
callerId: callerId:
type: string type: string
description: Identifier of the person who made the call
example: "17988310949" example: "17988310949"
quantityOfOperationAttempts: quantityOfOperationAttempts:
type: string type: string
description: Number of attempts to perform the operation made by the person who made the call
example: "2" example: "2"
chosenOperation: chosenOperation:
type: string type: string
description: Operation chosen by the person who made the call
example: "unblokUser" example: "unblokUser"
requestLogsOpenAI: requestLogsOpenAI:
type: string type: string
description: Response logs of requests made to openai
example: "{}" example: "{}"
responseErrorLogsOpenAI: responseErrorLogsOpenAI:
type: string type: string
description: Openai error request response logs
example: "{}" example: "{}"
quantityOfCallsToFalconFlowAPI: quantityOfCallsToFalconFlowAPI:
type: string type: string
description: Number of requests made to third-party api
example: "2" example: "2"
requestLogsFalconFlowAPI: requestLogsFalconFlowAPI:
type: string type: string
description: Response logs of requests made to third-party api
example: "{}" example: "{}"
responseErrorLogsFalconFlowAPI: responseErrorLogsFalconFlowAPI:
type: string type: string
description: Third-party api error request response logs
example: "{}" example: "{}"
provider: provider:
type: string type: string
description: Identifier of the organization providing the AI solution
example: "openai" example: "openai"
product: product:
type: string type: string
description: Product provided by the organization that is providing AI solution
example: "whisper" example: "whisper"
usage: usage:
type: integer type: string
description: "Using the API. The product Whisper should be sent in seconds" description: "Time in seconds"
example: 15 example: "15"
required: required:
- companyId - companyId
- callerId - callerId
- quantityOfOperationAttempts - quantityOfOperationAttempts
- chosenOperation - chosenOperation
- requestLogsOpenAI - requestLogsOpenAI
- responseErrorLogsOpenAI
- quantityOfCallsToFalconFlowAPI - quantityOfCallsToFalconFlowAPI
- requestLogsFalconFlowAPI - requestLogsFalconFlowAPI
- responseErrorLogsFalconFlowAPI
- provider - provider
- product - product
- usage - usage
required: true required: true
responses: responses:
'200': '200':
description: '' description: 'Successful response'
headers: {} content:
application/json:
example:
apiUsage:
companyId: "1"
callerId: "17988310949"
quantityOfOperationAttempts: "2"
chosenOperation: "unblokUser"
requestLogsOpenAI: "{}"
responseErrorLogsOpenAI: "{}"
quantityOfCallsToFalconFlowAPI: "2"
requestLogsFalconFlowAPI: "{}"
responseErrorLogsFalconFlowAPI: "{}"
provider: "openai"
product: "whisper"
usage: 15
price: "0.006"
billingBy: "minute"
billingUnit: 1
total_cost: "0.0015000000"
_id: "66a8df390cbb7371c4ade653"
createdAt: "2024-07-30T12:40:25.782Z"
updatedAt: "2024-07-30T12:40:25.782Z"
__v: 0
deprecated: false deprecated: false
security: security:
- bearer: [] - bearer: []