Compare commits
1 Commits
connectme-
...
kazan-expl
| Author | SHA1 | Date | |
|---|---|---|---|
| e9814f36bf |
Binary file not shown.
2123
package-lock.json
generated
2123
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "multi-stub",
|
||||
"version": "1.2.0",
|
||||
"version": "1.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -23,12 +23,10 @@
|
||||
"license": "MIT",
|
||||
"homepage": "https://bitbucket.org/online-mentor/multi-stub#readme",
|
||||
"dependencies": {
|
||||
"ai": "^4.1.13",
|
||||
"axios": "^1.7.7",
|
||||
"bcrypt": "^5.1.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"cookie-parser": "^1.4.5",
|
||||
"cors": "^2.8.5",
|
||||
"axios": "^1.7.9",
|
||||
"bcrypt": "^5.1.1",
|
||||
"body-parser": "^1.20.3",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cross-env": "^7.0.3",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dotenv": "^16.4.7",
|
||||
|
||||
2
server/data/const.js
Normal file
2
server/data/const.js
Normal file
@@ -0,0 +1,2 @@
|
||||
exports.TODO_LIST_MODEL_NAME = 'TODO_LIST'
|
||||
exports.TODO_ITEM_MODEL_NAME = 'TODO_ITEM'
|
||||
23
server/data/model/todo/item.js
Normal file
23
server/data/model/todo/item.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const { Schema, model } = require('mongoose')
|
||||
|
||||
const { TODO_ITEM_MODEL_NAME } = require('../../const')
|
||||
|
||||
const schema = new Schema({
|
||||
title: String,
|
||||
done: { type: Boolean, default: false },
|
||||
closed: Date,
|
||||
created: {
|
||||
type: Date, default: () => new Date().toISOString(),
|
||||
},
|
||||
})
|
||||
|
||||
schema.set('toJSON', {
|
||||
virtuals: true,
|
||||
versionKey: false,
|
||||
})
|
||||
|
||||
schema.virtual('id').get(function () {
|
||||
return this._id.toHexString()
|
||||
})
|
||||
|
||||
exports.ItemModel = model(TODO_ITEM_MODEL_NAME, schema)
|
||||
@@ -1,22 +1,18 @@
|
||||
const { Schema, model } = require('mongoose')
|
||||
|
||||
const { TODO_LIST_MODEL_NAME, TODO_ITEM_MODEL_NAME, TODO_AUTH_USER_MODEL_NAME } = require('../../const')
|
||||
const { TODO_LIST_MODEL_NAME, TODO_ITEM_MODEL_NAME } = require('../../const')
|
||||
|
||||
const schema = new Schema({
|
||||
title: String,
|
||||
created: {
|
||||
type: Date, default: () => new Date().toISOString(),
|
||||
},
|
||||
createdBy: { type: Schema.Types.ObjectId, ref: TODO_AUTH_USER_MODEL_NAME },
|
||||
items: [{ type: Schema.Types.ObjectId, ref: TODO_ITEM_MODEL_NAME }],
|
||||
})
|
||||
|
||||
schema.set('toJSON', {
|
||||
virtuals: true,
|
||||
versionKey: false,
|
||||
transform: function (doc, ret) {
|
||||
delete ret._id
|
||||
}
|
||||
})
|
||||
|
||||
schema.virtual('id').get(function () {
|
||||
@@ -80,7 +80,7 @@ app.use(require("./root"))
|
||||
*/
|
||||
app.use("/kfu-m-24-1", require("./routers/kfu-m-24-1"))
|
||||
app.use("/epja-2024-1", require("./routers/epja-2024-1"))
|
||||
app.use("/v1/todo", require("./routers/todo"))
|
||||
app.use("/todo", require("./routers/todo/routes"))
|
||||
app.use("/dogsitters-finder", require("./routers/dogsitters-finder"))
|
||||
app.use("/kazan-explore", require("./routers/kazan-explore"))
|
||||
app.use("/edateam", require("./routers/edateam-legacy"))
|
||||
@@ -88,8 +88,7 @@ app.use("/dry-wash", require("./routers/dry-wash"))
|
||||
app.use("/freetracker", require("./routers/freetracker"))
|
||||
app.use("/dhs-testing", require("./routers/dhs-testing"))
|
||||
app.use("/gamehub", require("./routers/gamehub"))
|
||||
app.use("/esc", require("./routers/esc"))
|
||||
app.use('/connectme', require('./routers/connectme'))
|
||||
|
||||
|
||||
app.use(require("./error"))
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
const { Router } = require('express')
|
||||
const router = Router()
|
||||
|
||||
router.get('/cities', (request, response) => {
|
||||
response.send(require('./json/cities.json'))
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
@@ -1,85 +0,0 @@
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"title": "Моска"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"title": "Санкт-петербург"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"title": "Новосибирска"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"title": "Екатеринбург"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"title": "Казань"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"title": "Нижний новгород"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"title": "Челябинск"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"title": "Самара"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"title": "Омск"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"title": "Ростов-на-дону"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"title": "Уфа"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"title": "Красноярск"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"title": "Пермь"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"title": "Воронеж"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"title": "Волгоград"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"title": "Краснодар"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"title": "Тюмень"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"title": "Ижевск"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"title": "Барнаул"
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"title": "Владивосток"
|
||||
}
|
||||
],
|
||||
"count": 20
|
||||
}
|
||||
@@ -1,40 +1,16 @@
|
||||
const router = require('express').Router()
|
||||
const {MasterModel} = require('./model/master')
|
||||
const mongoose = require("mongoose")
|
||||
const {OrderModel} = require("./model/order")
|
||||
|
||||
|
||||
router.get("/masters", async (req, res, next) => {
|
||||
router.get('/masters', async (req, res,next) => {
|
||||
try {
|
||||
const masters = await MasterModel.find({});
|
||||
const orders = await OrderModel.find({});
|
||||
|
||||
const mastersWithOrders = masters.map((master) => {
|
||||
const masterOrders = orders.filter((order) => {
|
||||
return (
|
||||
order?.master && order.master.toString() === master._id.toString()
|
||||
);
|
||||
});
|
||||
|
||||
const schedule = masterOrders.map((order) => ({
|
||||
id: order._id,
|
||||
startWashTime: order.startWashTime,
|
||||
endWashTime: order.endWashTime,
|
||||
}));
|
||||
|
||||
return {
|
||||
id: master._id,
|
||||
name: master.name,
|
||||
schedule: schedule,
|
||||
phone: master.phone,
|
||||
};
|
||||
});
|
||||
|
||||
res.status(200).send({ success: true, body: mastersWithOrders });
|
||||
const master = await MasterModel.find({})
|
||||
res.status(200).send({success: true, body: master})
|
||||
} catch (error) {
|
||||
next(error);
|
||||
next(error)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
router.delete('/masters/:id', async (req, res,next) => {
|
||||
const { id } = req.params;
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
const router = require('express').Router()
|
||||
const { OrderModel } = require('./model/order')
|
||||
|
||||
router.post('/orders', async (req, res, next) => {
|
||||
const {startDate, endDate} = req.body
|
||||
|
||||
if (!startDate || !endDate) {
|
||||
throw new Error('startDate and endDate are required')
|
||||
}
|
||||
|
||||
const orders = await OrderModel.find({
|
||||
$or: [
|
||||
{startWashTime: { $gte: new Date(startDate), $lte: new Date(endDate) }},
|
||||
{endWashTime: { $gte: new Date(startDate), $lte: new Date(endDate) }},
|
||||
]
|
||||
})
|
||||
|
||||
res.status(200).send({ success: true, body: orders })
|
||||
router.get('/orders', (req, res) => {
|
||||
res
|
||||
.status(200)
|
||||
.send(require(`./json/arm-orders/success.json`))
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
const router = require('express').Router()
|
||||
const armMasterRouter = require('./arm-master')
|
||||
const armOrdersRouter = require('./arm-orders')
|
||||
const orderRouter = require('./order')
|
||||
|
||||
|
||||
router.use('/arm', armMasterRouter)
|
||||
router.use('/arm', armOrdersRouter)
|
||||
router.use('/order', orderRouter)
|
||||
|
||||
|
||||
module.exports = router
|
||||
|
||||
@@ -2,59 +2,24 @@
|
||||
"success": true,
|
||||
"body": [
|
||||
{
|
||||
"phone": "+79876543210",
|
||||
"carNumber": "А123ВЕ16",
|
||||
"carBody": 1,
|
||||
"carColor": "#ffff00",
|
||||
"startWashTime": "2025-05-12T08:21:00.000Z",
|
||||
"endWashTime": "2025-05-12T08:22:00.000Z",
|
||||
"location": "55.792799704829854,49.11034340707925 Республика Татарстан (Татарстан), Казань, улица Чернышевского",
|
||||
"id": "order1",
|
||||
"carNumber": "A123BC",
|
||||
"startWashTime": "2024-11-24T10:30:00.000Z",
|
||||
"endWashTime": "2024-11-24T16:30:00.000Z",
|
||||
"orderDate": "2024-11-24T08:41:46.366Z",
|
||||
"status": "progress",
|
||||
"notes": "",
|
||||
"created": "2025-01-18T17:43:21.488Z",
|
||||
"updated": "2025-01-18T17:43:21.492Z"
|
||||
"phone": "79001234563",
|
||||
"location": "Казань, ул. Баумана, 1"
|
||||
},
|
||||
{
|
||||
"phone": "89876543210",
|
||||
"carNumber": "К456МН23",
|
||||
"carBody": 2,
|
||||
"carColor": "#ffffff",
|
||||
"startWashTime": "2025-01-12T08:21:00Z",
|
||||
"endWashTime": "2025-01-12T08:22:00Z",
|
||||
"location": "55.808430668108585,49.198608125449255 Республика Татарстан (Татарстан), Казань, улица Академика Губкина, 50/1",
|
||||
"status": "pending",
|
||||
"notes": "заметки заметки заметки заметки заметки заметки заметки заметки заметки заметки заметки заметки заметки заметки заметки",
|
||||
"created": "2025-01-18T17:46:10.388Z",
|
||||
"updated": "2025-01-18T17:46:10.395Z",
|
||||
"id": "678be8e211e62f4a61790cca"
|
||||
},
|
||||
{
|
||||
"phone": "4098765432105",
|
||||
"carNumber": "О789РС777",
|
||||
"carBody": 3,
|
||||
"carColor": "красный",
|
||||
"startWashTime": "2025-08-12T08:21:00.000Z",
|
||||
"endWashTime": "2025-08-12T08:22:00.000Z",
|
||||
"location": "55.78720449830353,49.12111640202319 Республика Татарстан (Татарстан), Казань, улица Пушкина, 5/43",
|
||||
"status": "cancelled",
|
||||
"notes": "Заказ отменен по запросу самого клиента",
|
||||
"created": "2025-01-18T17:47:46.294Z",
|
||||
"updated": "2025-01-18T17:47:46.295Z",
|
||||
"id": "678be8e211e62f4a61790ccb"
|
||||
},
|
||||
{
|
||||
"phone": "+79876543210",
|
||||
"carNumber": "Т123УХ716",
|
||||
"carBody": 99,
|
||||
"carColor": "чайная роза",
|
||||
"startWashTime": "2025-01-11T11:21:00.000Z",
|
||||
"endWashTime": "2025-01-12T11:22:00.000Z",
|
||||
"location": "55.77063673480112,49.22182909159608 Республика Татарстан (Татарстан), Казань, Советский район, микрорайон Азино-2",
|
||||
"id": "order2",
|
||||
"carNumber": "A245BC",
|
||||
"startWashTime": "2024-11-24T11:30:00.000Z",
|
||||
"endWashTime": "2024-11-24T17:30:00.000Z",
|
||||
"orderDate": "2024-11-24T07:40:46.366Z",
|
||||
"status": "progress",
|
||||
"notes": "Клиент остался доволен, предложить в следующий раз акцию",
|
||||
"created": "2025-01-18T17:55:05.691Z",
|
||||
"updated": "2025-01-18T17:55:05.695Z",
|
||||
"id": "678be8e211e62f4a61790ccc"
|
||||
"phone": "79001234567",
|
||||
"location": "Казань, ул. Баумана, 43"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
const orderStatus = {
|
||||
CANCELLED: 'cancelled',
|
||||
PROGRESS: 'progress',
|
||||
PENDING: 'pending',
|
||||
WORKING: 'working',
|
||||
COMPLETE: 'complete',
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
orderStatus
|
||||
}
|
||||
@@ -11,9 +11,6 @@ const schema = new Schema({
|
||||
schema.set('toJSON', {
|
||||
virtuals: true,
|
||||
versionKey: false,
|
||||
transform(_doc, ret) {
|
||||
delete ret._id;
|
||||
}
|
||||
})
|
||||
|
||||
schema.virtual('id').get(function () {
|
||||
|
||||
@@ -1,58 +1,26 @@
|
||||
const { Schema, model } = require('mongoose')
|
||||
const { orderStatus } = require('./const')
|
||||
|
||||
const schema = new Schema({
|
||||
phone: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
carNumber: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
carBody: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
carColor: String,
|
||||
startWashTime: {
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
endWashTime: {
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
location: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
required: true,
|
||||
enum: Object.values(orderStatus)
|
||||
},
|
||||
master: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'dry-wash-master'
|
||||
},
|
||||
notes: String,
|
||||
startWashTime: {type: String, required: true},
|
||||
endWashTime: {type: String, required: true},
|
||||
orderDate: {type: String, required: true},
|
||||
location: {type: String, required: true},
|
||||
phone: {type: String, required: true},
|
||||
status: {type: String, required: true},
|
||||
carNumber: {type: String, required: true},
|
||||
created: {
|
||||
type: Date,
|
||||
default: () => new Date().toISOString(),
|
||||
type: Date, default: () => new Date().toISOString(),
|
||||
},
|
||||
updated: {
|
||||
type: Date,
|
||||
default: () => new Date().toISOString(),
|
||||
type: Date, default: () => new Date().toISOString(),
|
||||
},
|
||||
master: {type: Schema.Types.ObjectId, ref: 'dry-wash-master'},
|
||||
notes: String,
|
||||
})
|
||||
|
||||
schema.set('toJSON', {
|
||||
virtuals: true,
|
||||
versionKey: false,
|
||||
transform(_doc, ret) {
|
||||
delete ret._id
|
||||
}
|
||||
})
|
||||
|
||||
schema.virtual('id').get(function () {
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
const mongoose = require("mongoose")
|
||||
const router = require('express').Router()
|
||||
const { MasterModel } = require('./model/master')
|
||||
const { OrderModel } = require('./model/order')
|
||||
const { orderStatus } = require('./model/const')
|
||||
|
||||
const isValidPhoneNumber = (value) => /^(\+)?\d{9,15}/.test(value)
|
||||
const isValidCarNumber = (value) => /^[авекмнорстух][0-9]{3}[авекмнорстух]{2}[0-9]{2,3}$/i.test(value)
|
||||
const isValidCarBodyType = (value) => typeof value === 'number' && value > 0 && value < 100
|
||||
const isValidCarColor = (value) => value.length < 50 && /^[#a-z0-9а-я-\s,.()]+$/i.test(value)
|
||||
const isValidISODate = (value) => /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:.\d{1,3})?Z$/.test(value)
|
||||
|
||||
const latitudeRe = /^(-?[1-8]?\d(?:\.\d{1,18})?|90(?:\.0{1,18})?)$/
|
||||
const longitudeRe = /^(-?(?:1[0-7]|[1-9])?\d(?:\.\d{1,18})?|180(?:\.0{1,18})?)$/
|
||||
const addressRe = /^[а-я0-9\s,.'-/()]*$/i
|
||||
const isValidLocation = (value) => {
|
||||
if (value.length > 200) {
|
||||
return false
|
||||
}
|
||||
|
||||
const [coordinates, address] = value.split(' ')
|
||||
const [latitude, longitude] = coordinates.split(',')
|
||||
return latitudeRe.test(latitude) && longitudeRe.test(longitude) && addressRe.test(address)
|
||||
}
|
||||
|
||||
const isValidOrderStatus = (value) => Object.values(orderStatus).includes(value)
|
||||
const isValidOrderNotes = (value) => value.length < 500
|
||||
|
||||
const VALIDATION_MESSAGES = {
|
||||
order: {
|
||||
notFound: 'Order not found'
|
||||
},
|
||||
orderId: {
|
||||
invalid: 'Valid order ID is required',
|
||||
},
|
||||
orderStatus: {
|
||||
invalid: 'Invalid order status'
|
||||
},
|
||||
orderNotes: {
|
||||
invalid: 'Invalid order notes'
|
||||
},
|
||||
master: {
|
||||
notFound: 'Master not found'
|
||||
},
|
||||
masterId: {
|
||||
invalid: 'Invalid master ID',
|
||||
},
|
||||
phoneNumber: {
|
||||
required: 'Phone number is required',
|
||||
invalid: 'Invalid phone number'
|
||||
},
|
||||
carNumber: {
|
||||
required: 'Car number is required',
|
||||
invalid: 'Invalid car number'
|
||||
},
|
||||
carBody: {
|
||||
required: 'Car body type is required',
|
||||
invalid: 'Invalid car body type'
|
||||
},
|
||||
carColor: {
|
||||
invalid: 'Invalid car color'
|
||||
},
|
||||
washingBegin: {
|
||||
required: 'Begin time of washing is required',
|
||||
invalid: 'Invalid begin time of washing'
|
||||
},
|
||||
washingEnd: {
|
||||
required: 'End time of washing is required',
|
||||
invalid: 'Invalid end time of washing'
|
||||
},
|
||||
washingLocation: {
|
||||
required: 'Location of washing is required',
|
||||
invalid: 'Invalid location of washing'
|
||||
},
|
||||
}
|
||||
|
||||
router.post('/create', async (req, res, next) => {
|
||||
const bodyErrors = []
|
||||
|
||||
const { customer } = req.body
|
||||
if (!customer.phone) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.phoneNumber.required)
|
||||
} else if (!isValidPhoneNumber(customer.phone)) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.phoneNumber.invalid)
|
||||
}
|
||||
|
||||
const { car } = req.body
|
||||
if (!car.number) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.carNumber.required)
|
||||
} else if (!isValidCarNumber(car.number)) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.carNumber.invalid)
|
||||
}
|
||||
if (!car.body) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.carBody.required)
|
||||
} else if (!isValidCarBodyType(car.body)) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.carBody.invalid)
|
||||
}
|
||||
if (!isValidCarColor(car.color)) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.carColor.invalid)
|
||||
}
|
||||
|
||||
const { washing } = req.body
|
||||
if (!washing.begin) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.washingBegin.required)
|
||||
} else if (!isValidISODate(washing.begin)) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.washingBegin.invalid)
|
||||
}
|
||||
if (!washing.end) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.washingEnd.required)
|
||||
} else if (!isValidISODate(washing.end)) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.washingEnd.invalid)
|
||||
}
|
||||
if (!washing.location) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.washingLocation.required)
|
||||
} else if (!isValidLocation(washing.location)) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.washingLocation.invalid)
|
||||
}
|
||||
|
||||
if (bodyErrors.length > 0) {
|
||||
throw new Error(bodyErrors.join(', '))
|
||||
}
|
||||
|
||||
try {
|
||||
const order = await OrderModel.create({
|
||||
phone: customer.phone,
|
||||
carNumber: car.number,
|
||||
carBody: car.body,
|
||||
carColor: car.color,
|
||||
startWashTime: washing.begin,
|
||||
endWashTime: washing.end,
|
||||
location: washing.location,
|
||||
status: orderStatus.PROGRESS,
|
||||
notes: '',
|
||||
created: new Date().toISOString(),
|
||||
})
|
||||
|
||||
res.status(200).send({ success: true, body: order })
|
||||
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
})
|
||||
|
||||
router.get('/:id', async (req, res, next) => {
|
||||
const { id } = req.params
|
||||
if (!mongoose.Types.ObjectId.isValid(id)) {
|
||||
throw new Error(VALIDATION_MESSAGES.orderId.invalid)
|
||||
}
|
||||
|
||||
try {
|
||||
const order = await OrderModel.findById(id)
|
||||
if (!order) {
|
||||
throw new Error(VALIDATION_MESSAGES.order.notFound)
|
||||
}
|
||||
|
||||
res.status(200).send({ success: true, body: order })
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
})
|
||||
|
||||
router.patch('/:id', async (req, res, next) => {
|
||||
const { id } = req.params
|
||||
if (!mongoose.Types.ObjectId.isValid(id)) {
|
||||
throw new Error(VALIDATION_MESSAGES.orderId.invalid)
|
||||
}
|
||||
|
||||
const bodyErrors = []
|
||||
|
||||
const { status } = req.body
|
||||
if (status) {
|
||||
if (!isValidOrderStatus(status)) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.orderStatus.invalid)
|
||||
}
|
||||
}
|
||||
|
||||
const { master: masterId } = req.body
|
||||
if (masterId) {
|
||||
if (!mongoose.Types.ObjectId.isValid(masterId)) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.masterId.invalid)
|
||||
} else {
|
||||
try {
|
||||
const master = await MasterModel.findById(masterId)
|
||||
if (!master) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.master.notFound)
|
||||
}
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const { notes } = req.body
|
||||
if (notes) {
|
||||
if (!isValidOrderNotes(notes)) {
|
||||
bodyErrors.push(VALIDATION_MESSAGES.orderNotes.invalid)
|
||||
}
|
||||
}
|
||||
|
||||
if (bodyErrors.length > 0) {
|
||||
throw new Error(bodyErrors.join(', '))
|
||||
}
|
||||
|
||||
try {
|
||||
const updateData = {}
|
||||
if (status) {
|
||||
updateData.status = status
|
||||
}
|
||||
if (masterId) {
|
||||
updateData.master = masterId
|
||||
}
|
||||
if (notes) {
|
||||
updateData.notes = notes
|
||||
}
|
||||
updateData.updated = new Date().toISOString()
|
||||
|
||||
const order = await OrderModel.findByIdAndUpdate(
|
||||
id,
|
||||
updateData,
|
||||
{ new: true }
|
||||
)
|
||||
if (!order) {
|
||||
throw new Error(VALIDATION_MESSAGES.order.notFound)
|
||||
}
|
||||
|
||||
res.status(200).send({ success: true, body: order })
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
})
|
||||
|
||||
router.delete('/:id', async (req, res, next) => {
|
||||
const { id } = req.params
|
||||
if (!mongoose.Types.ObjectId.isValid(id)) {
|
||||
throw new Error(VALIDATION_MESSAGES.orderId.invalid)
|
||||
}
|
||||
|
||||
try {
|
||||
const order = await OrderModel.findByIdAndDelete(id, {
|
||||
new: true,
|
||||
})
|
||||
if (!order) {
|
||||
throw new Error(VALIDATION_MESSAGES.order.notFound)
|
||||
}
|
||||
res.status(200).send({ success: true, body: order })
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
@@ -1,12 +0,0 @@
|
||||
const router = require("express").Router();
|
||||
|
||||
router.get('/game-links', (request, response) => {
|
||||
response.send(require('./json/game-links/success.json'))
|
||||
})
|
||||
|
||||
router.get('/4u2k-links', (request, response) => {
|
||||
response.send(require('./json/4u2k-links/success.json'))
|
||||
})
|
||||
;
|
||||
|
||||
module.exports = router;
|
||||
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"data":[
|
||||
{
|
||||
"type": "video",
|
||||
"links": {
|
||||
"l1": "https://www.youtube.com/embed/DsQMLrPdLf8?si=l9X57nHqaSYlxDFf",
|
||||
"l2": "https://www.youtube.com/embed/Dk8AAU_UdVk?si=N8NdYMUCfawdsJGE",
|
||||
"l3": "https://www.youtube.com/embed/HKfDfWrCwEA?si=qPugjiKR8V9eZ-yG",
|
||||
"l4": "https://www.youtube.com/embed/tD-6xHAHrQ4?si=ZFe41gSK8d5gqahW"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "podcast",
|
||||
"links": {
|
||||
"l1": "https://www.youtube.com/embed/RtVs87Nd1MQ?si=i4giUCtbp4Ouqv2W",
|
||||
"l2": "https://www.youtube.com/embed/DfTU5LA_kw8?si=m7fI5Ie9yIGDFCrU",
|
||||
"l3": "https://www.youtube.com/embed/Sp-1fX1Q15I?si=xyealVly9IBMW7Xi",
|
||||
"l4": "https://www.youtube.com/embed/rLYFJYfluRs?si=MjW1beQ-Q9-TAehF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "entertainment",
|
||||
"links": {
|
||||
"l1": "https://www.youtube.com/embed/DiuuglRCchQ?si=8wTVXKbV-mbHuSjW",
|
||||
"l2": "https://www.youtube.com/embed/zmZcIX5PEyo?si=Hbrv32kl0fqcmtV9",
|
||||
"l3": "https://www.youtube.com/embed/Te-TZUjmzFQ?si=fNG16eruoFEY2KNq",
|
||||
"l4": "https://www.youtube.com/embed/si-MQ5qg3zE?si=67mfO6gV80n1ULqo"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"data":[
|
||||
{
|
||||
"title": "ABC",
|
||||
"description": "Мой брат Колян сбацал про меня байку на англицком и несколько фишек кинул для шухера. Англицкий ты вроде знаешь, впряжешься за меня, а?",
|
||||
"link": "https://www.oxfordonlineenglish.com/english-level-test/reading"
|
||||
},
|
||||
{
|
||||
"title": "Алё, меня слышно?",
|
||||
"description": "Мой кент на мобилу текст записал с иностранкой. Понимаешь, о чём тут говорят?",
|
||||
"link": "https://test-english.com/listening/"
|
||||
},
|
||||
{
|
||||
"title": "Анонимное тестирование",
|
||||
"description": "Ты язык-то нормально знаешь? Проверься, никто угарать не будет",
|
||||
"link": "https://www.ego4u.com/en/cram-up/tests"
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
const Router = require('express').Router
|
||||
|
||||
const router = Router()
|
||||
|
||||
router.post('/auth/login', (req, res) => {
|
||||
if (req.body.email === 'qwerty@mail.ru') {
|
||||
res.status(200).send(require('./json/login/login-success.json'))
|
||||
} else {
|
||||
res.status(401).send(require('./json/login/login-error.json'));
|
||||
}
|
||||
})
|
||||
|
||||
router.post('/auth/register', (req, res) => {
|
||||
res.status(400).send(require('./json/registration/registration-error.json'))
|
||||
// res.status(201).send(require('./json/registration/registration-error.json'))
|
||||
})
|
||||
|
||||
router.post('/auth/reset-password', (req, res) => {
|
||||
res.status(200).send(require('./json/reset-password/reset-password-success.json'))
|
||||
// res.status(404).send(require('./json/reset-password/reset-password-error.json'))
|
||||
})
|
||||
|
||||
|
||||
module.exports = router;
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"success": false,
|
||||
"body": null,
|
||||
"errors": [
|
||||
{
|
||||
"code": "AUTH_INVALID_CREDENTIALS",
|
||||
"message": "Неверное имя пользователя или пароль"
|
||||
}
|
||||
],
|
||||
"warnings": []
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"success": true,
|
||||
"body": {
|
||||
"token": "AUTH_TOKEN"
|
||||
},
|
||||
"errors": [],
|
||||
"warnings": []
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"success": false,
|
||||
"body": null,
|
||||
"errors": [
|
||||
{
|
||||
"code": "REGISTRATION_EMAIL_TAKEN",
|
||||
"message": "Электронная почта уже используется"
|
||||
}
|
||||
],
|
||||
"warnings": []
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"success": true,
|
||||
"body": {
|
||||
"userId": "12345",
|
||||
"token": "AUTH_TOKEN"
|
||||
},
|
||||
"errors": [],
|
||||
"warnings": []
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"success": false,
|
||||
"body": null,
|
||||
"errors": [
|
||||
{
|
||||
"code": "RESET_PASSWORD_EMAIL_NOT_FOUND",
|
||||
"message": "Адрес электронной почты не зарегистрирован"
|
||||
}
|
||||
],
|
||||
"warnings": []
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"success": true,
|
||||
"body": {
|
||||
"message": "Отправлено электронное письмо для сброса пароля"
|
||||
},
|
||||
"errors": [],
|
||||
"warnings": []
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
const router = require('express').Router();
|
||||
|
||||
router.use('/performer', require('./dashboard-performer'))
|
||||
router.use('/auth', require('./auth'))
|
||||
router.use('/landing', require('./landing'))
|
||||
|
||||
module.exports = router;
|
||||
@@ -1,29 +0,0 @@
|
||||
const Router = require('express').Router;
|
||||
|
||||
const router = Router()
|
||||
|
||||
const values = {
|
||||
'blocks': 'success',
|
||||
'application': 'success'
|
||||
}
|
||||
|
||||
const timer = (_req, _res, next) => {
|
||||
setTimeout(() => next(), 500)
|
||||
}
|
||||
|
||||
router.use(timer)
|
||||
|
||||
router.get(
|
||||
'/blocks',
|
||||
(req, res) =>
|
||||
res.send(require(`./json/blocks-${values['blocks']}.json`))
|
||||
)
|
||||
|
||||
router.post(
|
||||
'/application',
|
||||
(req, res) => {
|
||||
res.send(require(`./json/application-${values['application']}.json`))
|
||||
}
|
||||
)
|
||||
|
||||
module.exports = router
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"success": false,
|
||||
"body": { },
|
||||
"errors": [
|
||||
"Что-то пошло не так"
|
||||
]
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"success": true,
|
||||
"body": { }
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"success": false,
|
||||
"body": {
|
||||
"blocks": []
|
||||
},
|
||||
"errors": [
|
||||
"Что-то пошло не так"
|
||||
]
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"success": true,
|
||||
"body": {
|
||||
"blocks": [
|
||||
{
|
||||
"titleKey":"block1.title",
|
||||
"textKey":"block1.subtitle",
|
||||
"imageName":"truck1"
|
||||
},
|
||||
{
|
||||
"titleKey":"block2.title",
|
||||
"textKey":"block2.subtitle",
|
||||
"imageName":"truck2"
|
||||
},
|
||||
{
|
||||
"titleKey":"block3.title",
|
||||
"textKey":"block3.subtitle",
|
||||
"imageName":"truck3"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,6 @@ router.get("/game-page", (request, response) => {
|
||||
response.send(require("./json/gamepage/success.json"));
|
||||
});
|
||||
|
||||
router.get("/update-like", (request, response) => {
|
||||
response.send(require("./json/gamepage/success.json"));
|
||||
});
|
||||
|
||||
router.get("/categories", (request, response) => {
|
||||
response.send(require("./json/categories/success.json"));
|
||||
});
|
||||
@@ -20,73 +16,4 @@ router.get("/home", (request, response) => {
|
||||
response.send(require("./json/home-page-data/success.json"));
|
||||
});
|
||||
|
||||
router.get("/all-games", (request, response) => {
|
||||
response.send(require("./json/home-page-data/all-games.json"));
|
||||
});
|
||||
|
||||
|
||||
// // Маршрут для обновления лайков
|
||||
// router.post("/update-like", (request, response) => {
|
||||
// const { username, likes } = request.body;
|
||||
|
||||
// // Эмулируем успешное обновление лайков
|
||||
// console.log(`Лайки для пользователя ${username} обновлены до ${likes}`);
|
||||
|
||||
// response.status(200).json({
|
||||
// success: true,
|
||||
// message: `Лайки для пользователя ${username} обновлены до ${likes}`,
|
||||
// });
|
||||
// });
|
||||
|
||||
|
||||
const fs = require("fs").promises;
|
||||
const path = require("path");
|
||||
|
||||
// Path to JSON file
|
||||
const commentsFilePath = path.join(__dirname, "./json/gamepage/success.json");
|
||||
|
||||
// Read JSON file
|
||||
async function readComments() {
|
||||
const data = await fs.readFile(commentsFilePath, "utf-8");
|
||||
const parsedData = JSON.parse(data);
|
||||
console.log("Прочитанные данные:", parsedData); // Логируем полученные данные
|
||||
return parsedData;
|
||||
}
|
||||
// Write to JSON file
|
||||
async function writeComments(data) {
|
||||
await fs.writeFile(commentsFilePath, JSON.stringify(data, null, 2), "utf-8");
|
||||
}
|
||||
|
||||
// Update likes route
|
||||
router.post("/update-like", async (req, res) => {
|
||||
const { username, likes } = req.body;
|
||||
|
||||
if (!username || likes === undefined) {
|
||||
return res.status(400).json({ success: false, message: "Invalid input" });
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await readComments();
|
||||
const comment = data.data.comments.find((c) => c.username === username);
|
||||
|
||||
if (comment) {
|
||||
comment.likes = likes;
|
||||
await writeComments(data); // Сохраняем обновленные данные в файл
|
||||
|
||||
// Возвращаем актуализированные данные
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: "Likes updated successfully",
|
||||
data: data.data, // Возвращаем актуализированные данные
|
||||
});
|
||||
} else {
|
||||
res.status(404).json({ success: false, message: "Comment not found" });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error updating likes:", error);
|
||||
res.status(500).json({ success: false, message: "Server error" });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
module.exports = router;
|
||||
@@ -8,18 +8,14 @@
|
||||
"price": 259,
|
||||
"old_price": 500,
|
||||
"image": "sales_game1",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"title": "Red Solstice 2 Survivors",
|
||||
"price": 561,
|
||||
"image": "sales_game2",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
@@ -27,9 +23,7 @@
|
||||
"price": 820,
|
||||
"old_price": 1100,
|
||||
"image": "new_game2",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
@@ -37,9 +31,7 @@
|
||||
"price": 990,
|
||||
"old_price": 1200,
|
||||
"image": "leaders_game4",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
@@ -47,9 +39,7 @@
|
||||
"price": 1200,
|
||||
"old_price": 2500,
|
||||
"image": "leaders_game5",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
@@ -57,39 +47,31 @@
|
||||
"price": 600,
|
||||
"old_price": 890,
|
||||
"image": "leaders_game6",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
}
|
||||
],
|
||||
"games2": [
|
||||
{
|
||||
"id": 7,
|
||||
"id": 1,
|
||||
"title": "Alpha League",
|
||||
"price": 299,
|
||||
"image": "new_game1",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": 2,
|
||||
"title": "Sons Of The Forests",
|
||||
"price": 820,
|
||||
"old_price": 1100,
|
||||
"image": "new_game2",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": 3,
|
||||
"title": "Pacific Drives",
|
||||
"price": 1799,
|
||||
"image": "new_game3",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
@@ -97,9 +79,7 @@
|
||||
"price": 990,
|
||||
"old_price": 1200,
|
||||
"image": "leaders_game4",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
@@ -107,9 +87,7 @@
|
||||
"price": 1200,
|
||||
"old_price": 2500,
|
||||
"image": "leaders_game5",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
@@ -117,39 +95,31 @@
|
||||
"price": 600,
|
||||
"old_price": 890,
|
||||
"image": "leaders_game6",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
}
|
||||
],
|
||||
"games3": [
|
||||
{
|
||||
"id": 10,
|
||||
"id": 1,
|
||||
"title": "Elden Ring",
|
||||
"price": 3295,
|
||||
"old_price": 3599,
|
||||
"image": "leaders_game2",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": 2,
|
||||
"title": "Counter-Strike 2",
|
||||
"price": 479,
|
||||
"image": "leaders_game1",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"id": 3,
|
||||
"title": "PUBG: BATTLEGROUNDS",
|
||||
"price": 199,
|
||||
"image": "leaders_game3",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
@@ -157,9 +127,7 @@
|
||||
"price": 990,
|
||||
"old_price": 1200,
|
||||
"image": "leaders_game4",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
@@ -167,9 +135,7 @@
|
||||
"price": 1200,
|
||||
"old_price": 2500,
|
||||
"image": "leaders_game5",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
@@ -177,9 +143,7 @@
|
||||
"price": 600,
|
||||
"old_price": 890,
|
||||
"image": "leaders_game6",
|
||||
"os": "windows",
|
||||
"fav1": "star1",
|
||||
"fav2": "star2"
|
||||
"os": "windows"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,32 +4,21 @@
|
||||
"comments": [
|
||||
{
|
||||
"username": "Пользователь1",
|
||||
"text": "Текст комментария 1",
|
||||
"likes": 9,
|
||||
"rating": 8,
|
||||
"date": "2025-03-01T10:00:00Z"
|
||||
"text": "Текст комментария 1"
|
||||
},
|
||||
{
|
||||
"username": "Пользователь2",
|
||||
"text": "Текст комментария 2",
|
||||
"likes": 7,
|
||||
"rating": 7,
|
||||
"date": "2025-01-01T10:00:00Z"
|
||||
"text": "Текст комментария 2"
|
||||
},
|
||||
{
|
||||
"username": "Пользователь3",
|
||||
"text": "Текст комментария 3",
|
||||
"likes": 5,
|
||||
"rating": 3,
|
||||
"date": "2025-02-01T10:00:00Z"
|
||||
"text": "Текст комментария 3"
|
||||
},
|
||||
{
|
||||
"username": "Пользователь4",
|
||||
"text": "Текст комментария 4",
|
||||
"likes": 15,
|
||||
"rating": 2,
|
||||
"date": "2025-12-01T10:00:00Z"
|
||||
"text": "Текст комментария 4"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "The Witcher 3: Wild Hunt",
|
||||
"image": "game1",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_1",
|
||||
"description": "Эпическая RPG с открытым миром, в которой Геральт из Ривии охотится на монстров и раскрывает политические заговоры.",
|
||||
"category": "RPG"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Red Dead Redemption 2",
|
||||
"image": "game2",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_2",
|
||||
"description": "Приключенческая игра с открытым миром на Диком Западе, рассказывающая историю Артура Моргана.",
|
||||
"category": "Adventures"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Forza Horizon 5",
|
||||
"image": "game3",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_3",
|
||||
"description": "Гоночная игра с огромным открытым миром, действие которой происходит в Мексике.",
|
||||
"category": "Race"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Atomic Heart",
|
||||
"image": "game4",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_4",
|
||||
"description": "Экшен-шутер с элементами RPG, разворачивающийся в альтернативной Советской России.",
|
||||
"category": "Shooters"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Counter-Strike 2",
|
||||
"image": "game5",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_5",
|
||||
"description": "Популярный онлайн-шутер с соревновательным геймплеем и тактическими элементами.",
|
||||
"category": "Shooters"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "Grand Theft Auto V",
|
||||
"image": "game6",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_6",
|
||||
"description": "Игра с открытым миром, где можно погрузиться в криминальный мир Лос-Сантоса.",
|
||||
"category": "Adventures"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "Assassin’s Creed IV: Black Flag",
|
||||
"image": "game7",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_7",
|
||||
"description": "Приключенческая игра о пиратах и морских сражениях в эпоху золотого века пиратства.",
|
||||
"category": "Adventures"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "Spider-Man",
|
||||
"image": "game8",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_8",
|
||||
"description": "Игра о супергерое Человеке-пауке с захватывающими битвами и паркуром по Нью-Йорку.",
|
||||
"category": "Action"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "Assassin’s Creed Mirage",
|
||||
"image": "game9",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_9",
|
||||
"description": "Приключенческая игра с упором на скрытность, вдохновленная классическими частями серии.",
|
||||
"category": "Action"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "Assassin’s Creed Valhalla",
|
||||
"image": "game10",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_10",
|
||||
"description": "RPG с открытым миром о викингах, включающая битвы, исследования и строительство поселений.",
|
||||
"category": "RPG"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "ARK: Survival Evolved",
|
||||
"image": "game11",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_11",
|
||||
"description": "Выживание в открытом мире с динозаврами, строительством и многопользовательскими элементами.",
|
||||
"category": "Simulators"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "FIFA 23",
|
||||
"image": "game12",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_12",
|
||||
"description": "Популярный футбольный симулятор с улучшенной графикой и реалистичным геймплеем.",
|
||||
"category": "Sports"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "Dirt 5",
|
||||
"image": "game13",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_13",
|
||||
"description": "Аркадная гоночная игра с фокусом на ралли и внедорожных соревнованиях.",
|
||||
"category": "Race"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "Cyberpunk 2077",
|
||||
"image": "game14",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_14",
|
||||
"description": "RPG в киберпанк-сеттинге с нелинейным сюжетом и детализированным открытым миром.",
|
||||
"category": "RPG"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "Age of Empires IV",
|
||||
"image": "game15",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_15",
|
||||
"description": "Классическая стратегия в реальном времени с историческими кампаниями.",
|
||||
"category": "Strategies"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "Civilization VI",
|
||||
"image": "game16",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_16",
|
||||
"description": "Глобальная пошаговая стратегия, в которой игроки строят и развивают цивилизации.",
|
||||
"category": "Strategies"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -4,115 +4,87 @@
|
||||
"topSail": [
|
||||
{
|
||||
"image": "game1",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_1"
|
||||
"text": "$10"
|
||||
},
|
||||
{
|
||||
"image": "game2",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_2"
|
||||
"text": "$10"
|
||||
},
|
||||
{
|
||||
"image": "game3",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_3"
|
||||
"text": "$10"
|
||||
},
|
||||
{
|
||||
"image": "game4",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_4"
|
||||
"text": "$10"
|
||||
},
|
||||
{
|
||||
"image": "game5",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_5"
|
||||
"text": "$10"
|
||||
},
|
||||
{
|
||||
"image": "game6",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_6"
|
||||
"text": "$10"
|
||||
},
|
||||
{
|
||||
"image": "game7",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_7"
|
||||
"text": "$10"
|
||||
},
|
||||
{
|
||||
"image": "game8",
|
||||
"text": "$10",
|
||||
"imgPath": "img_top_8"
|
||||
"text": "$10"
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"image": "category1",
|
||||
"text": "гонки",
|
||||
"imgPath": "img_categories_1",
|
||||
"category": "Race"
|
||||
"text": "гонки"
|
||||
},
|
||||
{
|
||||
"image": "category2",
|
||||
"text": "глубокий сюжет",
|
||||
"imgPath": "img_categories_2",
|
||||
"category": ""
|
||||
"text": "глубокий сюжет"
|
||||
},
|
||||
{
|
||||
"image": "category3",
|
||||
"text": "симуляторы",
|
||||
"imgPath": "img_categories_3",
|
||||
"category": "Simulators"
|
||||
"text": "симуляторы"
|
||||
},
|
||||
{
|
||||
"image": "category4",
|
||||
"text": "открытый мир",
|
||||
"imgPath": "img_categories_4",
|
||||
"category": "RPG"
|
||||
"text": "открытый мир"
|
||||
},
|
||||
{
|
||||
"image": "category5",
|
||||
"text": "экшен",
|
||||
"imgPath": "img_categories_5",
|
||||
"category": "Action"
|
||||
"text": "экшен"
|
||||
},
|
||||
{
|
||||
"image": "category6",
|
||||
"text": "стратегии",
|
||||
"imgPath": "img_categories_6",
|
||||
"category": "Strategies"
|
||||
"text": "стратегии"
|
||||
},
|
||||
{
|
||||
"image": "category7",
|
||||
"text": "шутеры",
|
||||
"imgPath": "img_categories_7",
|
||||
"category": "Shooters"
|
||||
"text": "шутеры"
|
||||
},
|
||||
{
|
||||
"image": "category8",
|
||||
"text": "приключения",
|
||||
"imgPath": "img_categories_8",
|
||||
"category": "Adventures"
|
||||
"text": "приключения"
|
||||
}
|
||||
],
|
||||
"news": [
|
||||
{
|
||||
"image": "news1",
|
||||
"text": "Разработчики Delta Force: Hawk Ops представили крупномасштабный режим Havoc Warfare",
|
||||
"imgPath": "img_news_1"
|
||||
"text": "Разработчики Delta Force: Hawk Ops представили крупномасштабный режим Havoc Warfare"
|
||||
},
|
||||
{
|
||||
"image": "news2",
|
||||
"text": "Первый трейлер Assassin’s Creed Shadows — с темнокожим самураем в феодальной Японии",
|
||||
"imgPath": "img_news_2"
|
||||
"text": "Первый трейлер Assassin’s Creed Shadows — с темнокожим самураем в феодальной Японии"
|
||||
},
|
||||
{
|
||||
"image": "news3",
|
||||
"text": "Призрак Цусимы» вышел на ПК — и уже ставит рекорды для Sony",
|
||||
"imgPath": "img_news_3"
|
||||
"text": "Призрак Цусимы» вышел на ПК — и уже ставит рекорды для Sony"
|
||||
},
|
||||
{
|
||||
"image": "news4",
|
||||
"text": "Авторы Skull and Bones расширяют планы на второй сезо",
|
||||
"imgPath": "img_news_4"
|
||||
"text": "Авторы Skull and Bones расширяют планы на второй сезо"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -788,5 +788,121 @@
|
||||
"image_url": "w_six"
|
||||
}
|
||||
]
|
||||
},
|
||||
"history": {
|
||||
"intro_text": "Let's see how well you know UNICS!",
|
||||
"intro_image": "culture",
|
||||
"questions": [
|
||||
{
|
||||
"question": "When was Kazan founded?",
|
||||
"options": [
|
||||
"1005",
|
||||
"1156",
|
||||
"1230",
|
||||
"1323"
|
||||
],
|
||||
"correct_answer": "1005",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "What is the main river flowing through Kazan?",
|
||||
"options": [
|
||||
"Volga",
|
||||
"Kazanka",
|
||||
"Kama",
|
||||
"Izh"
|
||||
],
|
||||
"correct_answer": "Kazanka",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Who was the first khan of Kazan?",
|
||||
"options": [
|
||||
"Ulugh Muhammad",
|
||||
"Akhmat",
|
||||
"Shah Ali",
|
||||
"Mamuka"
|
||||
],
|
||||
"correct_answer": "Ulugh Muhammad",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "What is the name of Kazan's main sports complex where the 2013 Universiade was held?",
|
||||
"options": [
|
||||
"Kazan Arena",
|
||||
"Tatneft Arena",
|
||||
"Bugulma Arena",
|
||||
"Ak Bars Sports Palace"
|
||||
],
|
||||
"correct_answer": "Kazan Arena",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Which mosque in Kazan is considered one of the largest in Russia?",
|
||||
"options": [
|
||||
"Kul Sharif Mosque",
|
||||
"Mari El Mosque",
|
||||
"Aisha Mosque",
|
||||
"Imam Muhammad Mosque"
|
||||
],
|
||||
"correct_answer": "Kul Sharif Mosque",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "What is the name of the square where the Kazan Kremlin and Kul Sharif Mosque are located?",
|
||||
"options": [
|
||||
"Vakhitov Square",
|
||||
"Freedom Square",
|
||||
"Kremlin Square",
|
||||
"Revolution Square"
|
||||
],
|
||||
"correct_answer": "Kremlin Square",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "What symbol of Kazan is depicted on the city's coat of arms?",
|
||||
"options": [
|
||||
"Dragon",
|
||||
"Tiger",
|
||||
"Lion",
|
||||
"Eagle"
|
||||
],
|
||||
"correct_answer": "Dragon",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Who was the architect of the Kazan Kremlin?",
|
||||
"options": [
|
||||
"Ivan Zarudny",
|
||||
"Fyodor Benjamin",
|
||||
"Andrey Ushakov",
|
||||
"Yury Dashevsky"
|
||||
],
|
||||
"correct_answer": "Andrey Ushakov",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Which of these universities is located in Kazan?",
|
||||
"options": [
|
||||
"Moscow State University",
|
||||
"Kazan Federal University",
|
||||
"St. Petersburg Polytechnic University",
|
||||
"Novosibirsk State University"
|
||||
],
|
||||
"correct_answer": "Kazan Federal University",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "What is the name of the largest street in Kazan, which is also the center of the city's nightlife?",
|
||||
"options": [
|
||||
"Kremlin Street",
|
||||
"Bauman Street",
|
||||
"Pushkin Street",
|
||||
"Kayum Nasyri Street"
|
||||
],
|
||||
"correct_answer": "Bauman Street",
|
||||
"image_url": "culture"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -788,5 +788,121 @@
|
||||
"image_url": "w_six"
|
||||
}
|
||||
]
|
||||
},
|
||||
"history": {
|
||||
"intro_text": "Давайте узнаем, насколько вы хорошо знаете историю Казани!",
|
||||
"intro_image": "culture",
|
||||
"questions": [
|
||||
{
|
||||
"question": "Когда Казань была основана?",
|
||||
"options": [
|
||||
"1000 год",
|
||||
"1156 год",
|
||||
"1230 год",
|
||||
"1323 год"
|
||||
],
|
||||
"correct_answer": "1000 год",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Как называется главная река, протекающая через Казань?",
|
||||
"options": [
|
||||
"Волга",
|
||||
"Казанка",
|
||||
"Кама",
|
||||
"Иж"
|
||||
],
|
||||
"correct_answer": "Казанка",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Кто был первым казанским ханом?",
|
||||
"options": [
|
||||
"Улу-Мухаммед",
|
||||
"Ахмат",
|
||||
"Шах-Али",
|
||||
"Мамука"
|
||||
],
|
||||
"correct_answer": "Улу-Мухаммед",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Как называется главный спортивный комплекс Казани, где проводились Универсиада 2013 года?",
|
||||
"options": [
|
||||
"Казан Арена",
|
||||
"Татнефть Арена",
|
||||
"Бугульминская арена",
|
||||
"Дворец спорта \"Ак Барс\""
|
||||
],
|
||||
"correct_answer": "Казан Арена",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Какая мечеть в Казани считается одной из самых больших в России?",
|
||||
"options": [
|
||||
"Мечеть Кул Шариф",
|
||||
"Мечеть Марий Эл",
|
||||
"Мечеть Айша",
|
||||
"Мечеть имама Мухаммада"
|
||||
],
|
||||
"correct_answer": "Мечеть Кул Шариф",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Как называется площадь, на которой расположены Казанский Кремль и мечеть Кул Шариф?",
|
||||
"options": [
|
||||
"Площадь Вахитова",
|
||||
"Площадь Свободы",
|
||||
"Площадь Кремля",
|
||||
"Площадь Революции"
|
||||
],
|
||||
"correct_answer": "Площадь Кремля",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Какой символ Казани изображён на гербе города?",
|
||||
"options": [
|
||||
"Дракон",
|
||||
"Тигр",
|
||||
"Лев",
|
||||
"Орел"
|
||||
],
|
||||
"correct_answer": "Дракон",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Какой архитектор спроектировал Казанский Кремль?",
|
||||
"options": [
|
||||
"Иван Зарудный",
|
||||
"Фёдор Бенжамин",
|
||||
"Андрей Ушаков",
|
||||
"Юрий Дашевский"
|
||||
],
|
||||
"correct_answer": "Андрей Ушаков",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Какой из этих вузов находится в Казани?",
|
||||
"options": [
|
||||
"Московский государственный университет",
|
||||
"Казанский федеральный университет",
|
||||
"Санкт-Петербургский политехнический университет",
|
||||
"Новосибирский государственный университет"
|
||||
],
|
||||
"correct_answer": "Казанский федеральный университет",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Как называется крупнейшая в Казани улица, которая также является центром ночной жизни города?",
|
||||
"options": [
|
||||
"Кремлевская улица",
|
||||
"Баумана улица",
|
||||
"Пушкина улица",
|
||||
"Каюма Насыри улица"
|
||||
],
|
||||
"correct_answer": "Баумана улица",
|
||||
"image_url": "culture"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -788,5 +788,121 @@
|
||||
"image_url": "w_six"
|
||||
}
|
||||
]
|
||||
},
|
||||
"history": {
|
||||
"intro_text": "Әйдәгез, Казан тарихын белүегезне ачыклыйк!",
|
||||
"intro_image": "culture",
|
||||
"questions": [
|
||||
{
|
||||
"question": "Казан кайчан нигезләнгән?",
|
||||
"options": [
|
||||
"1000 ел",
|
||||
"1156 ел",
|
||||
"1230 ел",
|
||||
"1323 ел"
|
||||
],
|
||||
"correct_answer": "1000 ел",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Казан аша агучы төп елга ничек атала?",
|
||||
"options": [
|
||||
"Идел",
|
||||
"Казанка",
|
||||
"Кама",
|
||||
"Иж"
|
||||
],
|
||||
"correct_answer": "Казанка",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Казанның беренче ханы кем булган?",
|
||||
"options": [
|
||||
"Олуг Мөхәммәт",
|
||||
"Әхмәт",
|
||||
"Шаһ-Әли",
|
||||
"Мамука"
|
||||
],
|
||||
"correct_answer": "Олуг Мөхәммәт",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "2013 елда Универсиада узган Казанның төп спорт комплексы ничек атала?",
|
||||
"options": [
|
||||
"Казан Арена",
|
||||
"Татнефть Арена",
|
||||
"Бөгелмә Арена",
|
||||
"Ак Барс спорт сарае"
|
||||
],
|
||||
"correct_answer": "Казан Арена",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Казандагы иң зур мәчетләрнең берсе Россиядәге кайсысы?",
|
||||
"options": [
|
||||
"Кол Шәриф мәчете",
|
||||
"Марий Эл мәчете",
|
||||
"Айша мәчете",
|
||||
"Имам Мөхәммәт мәчете"
|
||||
],
|
||||
"correct_answer": "Кол Шәриф мәчете",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Казан Кремле һәм Кол Шәриф мәчете урнашкан мәйдан ничек атала?",
|
||||
"options": [
|
||||
"Вахитов мәйданы",
|
||||
"Ирек мәйданы",
|
||||
"Кремль мәйданы",
|
||||
"Революция мәйданы"
|
||||
],
|
||||
"correct_answer": "Кремль мәйданы",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Казан гербында кайсы символ сурәтләнгән?",
|
||||
"options": [
|
||||
"Аждаһа",
|
||||
"Юлбарыс",
|
||||
"Арслан",
|
||||
"Бүре"
|
||||
],
|
||||
"correct_answer": "Аждаһа",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Казан Кремленең архитекторын атагыз.",
|
||||
"options": [
|
||||
"Иван Зарудный",
|
||||
"Фёдор Бенжамин",
|
||||
"Андрей Ушаков",
|
||||
"Юрий Дашевский"
|
||||
],
|
||||
"correct_answer": "Андрей Ушаков",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Бу югары уку йортларының кайсысы Казанда урнашкан?",
|
||||
"options": [
|
||||
"Мәскәү дәүләт университеты",
|
||||
"Казан федераль университеты",
|
||||
"Санкт-Петербург политехник университеты",
|
||||
"Новосибирск дәүләт университеты"
|
||||
],
|
||||
"correct_answer": "Казан федераль университеты",
|
||||
"image_url": "culture"
|
||||
},
|
||||
{
|
||||
"question": "Казандагы иң зур урам ничек атала? Ул шулай ук шәһәрнең төнге тормыш үзәге булып тора.",
|
||||
"options": [
|
||||
"Кремль урамы",
|
||||
"Бауман урамы",
|
||||
"Пушкин урамы",
|
||||
"Каюм Насыйри урамы"
|
||||
],
|
||||
"correct_answer": "Бауман урамы",
|
||||
"image_url": "culture"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
[
|
||||
{
|
||||
"id": 0,
|
||||
"description": "1000 часто используемых",
|
||||
"imageFilename": "kart1.jpg"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"description": "10 слов в Data Science",
|
||||
"imageFilename": "kart1.jpg"
|
||||
}
|
||||
]
|
||||
@@ -6,14 +6,18 @@
|
||||
"id": 0,
|
||||
"word": "Tech",
|
||||
"definition": "short for technical, relating to the knowledge, machines, or methods used in science and industry. Tech is a whole industry, which includes IT",
|
||||
"examples": ["“As a DevOps engineer I have been working in Tech since 2020.”"],
|
||||
"examples": [
|
||||
"“As a DevOps engineer I have been working in Tech since 2020.”"
|
||||
],
|
||||
"synonyms": ["IT"]
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"word": "career path",
|
||||
"definition": "the series of jobs or roles that constitute a person's career, especially one in a particular field",
|
||||
"examples": ["“Technology is an evolving field with a variety of available career paths.”"],
|
||||
"examples": [
|
||||
"“Technology is an evolving field with a variety of available career paths.”"
|
||||
],
|
||||
"synonyms": []
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
[{"id":1,"description":"10 слов в Data Science","imageFilename":"kart1.jpg","words":[2,3,4,5,6,7,8,9,10,11,12]}]
|
||||
@@ -1,122 +1,21 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const router = require('express').Router();
|
||||
const router = require("express").Router();
|
||||
|
||||
module.exports = router;
|
||||
|
||||
const dictionaries = require('./dictionaries.json');
|
||||
const words = require('../words/words.json');
|
||||
const data = require("./data/dictionaries.json");
|
||||
const wordsData = require("./data/dictionaryWords.json");
|
||||
|
||||
router.get('/', (req, res) => {
|
||||
res.send(dictionaries);
|
||||
router.get("/", (req, res) => {
|
||||
res.send(data);
|
||||
});
|
||||
|
||||
router.get('/:id', (req, res) => {
|
||||
router.get("/:id", (req, res) => {
|
||||
const id = parseInt(req.params.id);
|
||||
if (!id || isNaN(id)) {
|
||||
return res.status(400).send('Invalid ID'); // Bad request
|
||||
const words = wordsData.find((word) => word.id === id);
|
||||
|
||||
if (!words) {
|
||||
return res.status(404).send("Not found");
|
||||
}
|
||||
|
||||
if (!dictionaries) {
|
||||
return res.status(500).send('No data to update'); // Internal server error
|
||||
}
|
||||
|
||||
const dictionary = dictionaries.find((dictionary) => dictionary.id === id);
|
||||
|
||||
if (!dictionary) {
|
||||
return res.status(404).send('Not found');
|
||||
}
|
||||
const dictionaryWords = dictionary.words.map((wordId) => {
|
||||
const word = words.find((word) => word.id === wordId);
|
||||
return { ...word, ...word };
|
||||
});
|
||||
res.send({ ...dictionary, words: dictionaryWords });
|
||||
});
|
||||
|
||||
router.post('/:id', (req, res) => {
|
||||
const id = parseInt(req.params.id);
|
||||
if (!id || isNaN(id)) {
|
||||
return res.status(400).send('Invalid ID'); // Bad request
|
||||
}
|
||||
|
||||
if (!dictionaries) {
|
||||
return res.status(500).send('No data to update'); // Internal server error
|
||||
}
|
||||
|
||||
const dictionary = dictionaries.find((dictionary) => dictionary.id === id);
|
||||
|
||||
if (!dictionary) {
|
||||
return res.status(404).send('Not found');
|
||||
}
|
||||
|
||||
const newWord = req.body;
|
||||
if (!newWord) {
|
||||
return res.status(400).send('No data to add'); // Bad request
|
||||
}
|
||||
console.log(newWord);
|
||||
if (isNaN(newWord.id)) {
|
||||
return res.status(400).send('Invalid word ID'); // Bad request
|
||||
}
|
||||
dictionary.words.push(newWord.id);
|
||||
|
||||
fs.writeFile(path.join(__dirname, 'dictionaries.json'), JSON.stringify(dictionaries), (err) => {
|
||||
if (err) {
|
||||
console.error(err); // Log the error
|
||||
return res.status(500).send('Error saving data');
|
||||
}
|
||||
res.status(200).json(dictionary); // Send back the updated data
|
||||
});
|
||||
});
|
||||
|
||||
// Put new dictionary to the array of dictionaries
|
||||
router.put('/', (req, res) => {
|
||||
if (!dictionaries || !Array.isArray(dictionaries)) {
|
||||
return res.status(400).send('No array of dictionaries found`');
|
||||
}
|
||||
|
||||
const newData = req.body;
|
||||
|
||||
if (!newData) {
|
||||
return res.status(400).send('No data to add'); // Bad request
|
||||
}
|
||||
|
||||
if (!dictionaries) {
|
||||
return res.status(500).send('No data to update'); // Internal server error
|
||||
}
|
||||
|
||||
const indexedUpdatedData = { ...newData, id: dictionaries.length + 1 }; // Add the new dictionary to the array
|
||||
|
||||
dictionaries.push(indexedUpdatedData); // Add the new dictionary to the array
|
||||
|
||||
fs.writeFile(path.join(__dirname, 'dictionaries.json'), JSON.stringify(dictionaries), (err) => {
|
||||
if (err) {
|
||||
console.error(err); // Log the error
|
||||
return res.status(500).send('Error saving data');
|
||||
}
|
||||
res.status(200).json(dictionaries); // Send back the updated data
|
||||
});
|
||||
});
|
||||
|
||||
router.delete('/:id', (req, res) => {
|
||||
const id = parseInt(req.params.id); // Get the dictionary id from the URL
|
||||
|
||||
if (!id || isNaN(id)) {
|
||||
return res.status(400).send('Invalid ID'); // Bad request
|
||||
}
|
||||
|
||||
const index = dictionaries.findIndex((dictionary) => dictionary.id === id);
|
||||
|
||||
if (index < 0) {
|
||||
return res.status(404).send('Not found'); // Not found
|
||||
}
|
||||
|
||||
dictionaries.splice(index, 1); // Remove the dictionary from the array
|
||||
|
||||
fs.writeFile(path.join(__dirname, 'dictionaries.json'), JSON.stringify(dictionaries), (err) => {
|
||||
if (err) {
|
||||
console.error(err); // Log the error
|
||||
return res.status(500).send('Error saving data');
|
||||
}
|
||||
res.send({ message: `Dictionary with id ${id} deleted` });
|
||||
});
|
||||
res.send(words);
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,614 +0,0 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// src/index.ts
|
||||
var index_exports = {};
|
||||
__export(index_exports, {
|
||||
createGigachat: () => createGigachat,
|
||||
gigachat: () => gigachat
|
||||
});
|
||||
module.exports = __toCommonJS(index_exports);
|
||||
|
||||
// src/gigachat-provider.ts
|
||||
var import_provider_utils4 = require("@ai-sdk/provider-utils");
|
||||
|
||||
// src/gigachat-chat-language-model.ts
|
||||
var import_provider_utils2 = require("@ai-sdk/provider-utils");
|
||||
var import_zod2 = require("zod");
|
||||
|
||||
// src/convert-to-gigachat-chat-messages.ts
|
||||
var import_provider = require("@ai-sdk/provider");
|
||||
function convertToGigachatChatMessages(prompt) {
|
||||
const messages = [];
|
||||
for (let i = 0; i < prompt.length; i++) {
|
||||
const { role, content } = prompt[i];
|
||||
const isLastMessage = i === prompt.length - 1;
|
||||
switch (role) {
|
||||
case "system": {
|
||||
messages.push({ role: "system", content });
|
||||
break;
|
||||
}
|
||||
case "user": {
|
||||
messages.push({
|
||||
role: "user",
|
||||
content: content.map((part) => {
|
||||
switch (part.type) {
|
||||
case "text": {
|
||||
return part.text;
|
||||
}
|
||||
case "image": {
|
||||
throw new import_provider.UnsupportedFunctionalityError({
|
||||
functionality: 'Images should be added in "attachments" object'
|
||||
});
|
||||
}
|
||||
case "file": {
|
||||
throw new import_provider.UnsupportedFunctionalityError({
|
||||
functionality: "File content parts in user messages"
|
||||
});
|
||||
}
|
||||
}
|
||||
}).join("")
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "assistant": {
|
||||
let text = "";
|
||||
let functionCall;
|
||||
for (const part of content) {
|
||||
switch (part.type) {
|
||||
case "text": {
|
||||
text += part.text;
|
||||
break;
|
||||
}
|
||||
case "tool-call": {
|
||||
functionCall = {
|
||||
name: part.toolName,
|
||||
arguments: part.args
|
||||
};
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
const _exhaustiveCheck = part;
|
||||
throw new Error(`Unsupported part: ${_exhaustiveCheck}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
messages.push({
|
||||
role: "assistant",
|
||||
content: text,
|
||||
prefix: isLastMessage ? true : void 0,
|
||||
function_call: functionCall
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "tool": {
|
||||
for (const toolResponse of content) {
|
||||
messages.push({
|
||||
role: "function",
|
||||
name: toolResponse.toolName,
|
||||
content: JSON.stringify(toolResponse.result)
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
const _exhaustiveCheck = role;
|
||||
throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
// src/map-gigachat-finish-reason.ts
|
||||
function mapGigachatFinishReason(finishReason) {
|
||||
switch (finishReason) {
|
||||
case "stop":
|
||||
return "stop";
|
||||
case "length":
|
||||
case "model_length":
|
||||
return "length";
|
||||
case "function_call":
|
||||
return "tool-calls";
|
||||
case "error":
|
||||
return "error";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
// src/gigachat-error.ts
|
||||
var import_provider_utils = require("@ai-sdk/provider-utils");
|
||||
var import_zod = require("zod");
|
||||
var gigachatErrorDataSchema = import_zod.z.object({
|
||||
object: import_zod.z.literal("error"),
|
||||
message: import_zod.z.string(),
|
||||
type: import_zod.z.string(),
|
||||
param: import_zod.z.string().nullable(),
|
||||
code: import_zod.z.string().nullable()
|
||||
});
|
||||
var gigachatFailedResponseHandler = (0, import_provider_utils.createJsonErrorResponseHandler)({
|
||||
errorSchema: gigachatErrorDataSchema,
|
||||
errorToMessage: (data) => data.message
|
||||
});
|
||||
|
||||
// src/get-response-metadata.ts
|
||||
function getResponseMetadata({
|
||||
model,
|
||||
created
|
||||
}) {
|
||||
return {
|
||||
modelId: model != null ? model : void 0,
|
||||
timestamp: created != null ? new Date(created * 1e3) : void 0
|
||||
};
|
||||
}
|
||||
|
||||
// src/gigachat-prepare-tools.ts
|
||||
var import_provider2 = require("@ai-sdk/provider");
|
||||
function prepareTools(mode) {
|
||||
var _a;
|
||||
const tools = ((_a = mode.tools) == null ? void 0 : _a.length) ? mode.tools : void 0;
|
||||
const toolWarnings = [];
|
||||
if (tools == null) {
|
||||
return { tools: void 0, tool_choice: void 0, toolWarnings };
|
||||
}
|
||||
const gigachatTools = [];
|
||||
for (const tool of tools) {
|
||||
if (tool.type === "provider-defined") {
|
||||
toolWarnings.push({ type: "unsupported-tool", tool });
|
||||
} else {
|
||||
gigachatTools.push({
|
||||
type: "function",
|
||||
function: {
|
||||
name: tool.name,
|
||||
description: tool.description,
|
||||
parameters: tool.parameters
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
const toolChoice = mode.toolChoice;
|
||||
if (toolChoice == null) {
|
||||
return { tools: gigachatTools, tool_choice: void 0, toolWarnings };
|
||||
}
|
||||
const type = toolChoice.type;
|
||||
switch (type) {
|
||||
case "auto":
|
||||
case "none":
|
||||
return { tools: gigachatTools, tool_choice: type, toolWarnings };
|
||||
case "required":
|
||||
return { tools: gigachatTools, tool_choice: "any", toolWarnings };
|
||||
// gigachat does not support tool mode directly,
|
||||
// so we filter the tools and force the tool choice through 'any'
|
||||
case "tool":
|
||||
return {
|
||||
tools: gigachatTools.filter((tool) => tool.function.name === toolChoice.toolName),
|
||||
tool_choice: "any",
|
||||
toolWarnings
|
||||
};
|
||||
default: {
|
||||
const _exhaustiveCheck = type;
|
||||
throw new import_provider2.UnsupportedFunctionalityError({
|
||||
functionality: `Unsupported tool choice type: ${_exhaustiveCheck}`
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// src/gigachat-chat-language-model.ts
|
||||
var GigachatChatLanguageModel = class {
|
||||
constructor(modelId, settings, config) {
|
||||
this.specificationVersion = "v1";
|
||||
this.defaultObjectGenerationMode = "json";
|
||||
this.supportsImageUrls = false;
|
||||
this.modelId = modelId;
|
||||
this.settings = settings;
|
||||
this.config = config;
|
||||
}
|
||||
get provider() {
|
||||
return this.config.provider;
|
||||
}
|
||||
getArgs({
|
||||
mode,
|
||||
prompt,
|
||||
maxTokens,
|
||||
temperature,
|
||||
topP,
|
||||
topK,
|
||||
frequencyPenalty,
|
||||
presencePenalty,
|
||||
stopSequences,
|
||||
responseFormat,
|
||||
seed
|
||||
}) {
|
||||
const type = mode.type;
|
||||
const warnings = [];
|
||||
if (topK != null) {
|
||||
warnings.push({
|
||||
type: "unsupported-setting",
|
||||
setting: "topK"
|
||||
});
|
||||
}
|
||||
if (frequencyPenalty != null) {
|
||||
warnings.push({
|
||||
type: "unsupported-setting",
|
||||
setting: "frequencyPenalty"
|
||||
});
|
||||
}
|
||||
if (presencePenalty != null) {
|
||||
warnings.push({
|
||||
type: "unsupported-setting",
|
||||
setting: "presencePenalty"
|
||||
});
|
||||
}
|
||||
if (stopSequences != null) {
|
||||
warnings.push({
|
||||
type: "unsupported-setting",
|
||||
setting: "stopSequences"
|
||||
});
|
||||
}
|
||||
if (responseFormat != null && responseFormat.type === "json" && responseFormat.schema != null) {
|
||||
warnings.push({
|
||||
type: "unsupported-setting",
|
||||
setting: "responseFormat",
|
||||
details: "JSON response format schema is not supported"
|
||||
});
|
||||
}
|
||||
const baseArgs = {
|
||||
// model id:
|
||||
model: this.modelId,
|
||||
// model specific settings:
|
||||
stream: this.settings.stream,
|
||||
repetition_penalty: this.settings.repetition_penalty,
|
||||
update_interval: this.settings.update_interval,
|
||||
// standardized settings:
|
||||
max_tokens: maxTokens,
|
||||
temperature,
|
||||
top_p: topP,
|
||||
// response format:
|
||||
response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? { type: "json_object" } : void 0,
|
||||
// messages:
|
||||
messages: convertToGigachatChatMessages(prompt)
|
||||
};
|
||||
switch (type) {
|
||||
case "regular": {
|
||||
const { tools, tool_choice, toolWarnings } = prepareTools(mode);
|
||||
return {
|
||||
args: { ...baseArgs, tools, tool_choice },
|
||||
warnings: [...warnings, ...toolWarnings]
|
||||
};
|
||||
}
|
||||
case "object-json": {
|
||||
return {
|
||||
args: {
|
||||
...baseArgs,
|
||||
response_format: { type: "json_object" }
|
||||
},
|
||||
warnings
|
||||
};
|
||||
}
|
||||
case "object-tool": {
|
||||
return {
|
||||
args: {
|
||||
...baseArgs,
|
||||
tool_choice: "any",
|
||||
tools: [{ type: "function", function: mode.tool }]
|
||||
},
|
||||
warnings
|
||||
};
|
||||
}
|
||||
default: {
|
||||
const _exhaustiveCheck = type;
|
||||
throw new Error(`Unsupported type: ${_exhaustiveCheck}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
async doGenerate(options) {
|
||||
var _a;
|
||||
const { args, warnings } = this.getArgs(options);
|
||||
const { responseHeaders, value: response } = await (0, import_provider_utils2.postJsonToApi)({
|
||||
url: `${this.config.baseURL}/chat/completions`,
|
||||
headers: (0, import_provider_utils2.combineHeaders)(this.config.headers(), options.headers),
|
||||
body: args,
|
||||
failedResponseHandler: gigachatFailedResponseHandler,
|
||||
successfulResponseHandler: (0, import_provider_utils2.createJsonResponseHandler)(gigachatChatResponseSchema),
|
||||
abortSignal: options.abortSignal,
|
||||
fetch: this.config.fetch
|
||||
});
|
||||
const { messages: rawPrompt, ...rawSettings } = args;
|
||||
const choice = response.choices[0];
|
||||
let text = (_a = choice.message.content) != null ? _a : void 0;
|
||||
const lastMessage = rawPrompt[rawPrompt.length - 1];
|
||||
if (lastMessage.role === "assistant" && (text == null ? void 0 : text.startsWith(lastMessage.content))) {
|
||||
text = text.slice(lastMessage.content.length);
|
||||
}
|
||||
return {
|
||||
text,
|
||||
toolCalls: choice.message.function_call ? [
|
||||
{
|
||||
toolCallType: "function",
|
||||
toolCallId: choice.message.function_call.name,
|
||||
toolName: choice.message.function_call.name,
|
||||
args: JSON.stringify(choice.message.function_call.arguments)
|
||||
}
|
||||
] : [],
|
||||
finishReason: mapGigachatFinishReason(choice.finish_reason),
|
||||
usage: {
|
||||
promptTokens: response.usage.prompt_tokens,
|
||||
completionTokens: response.usage.completion_tokens
|
||||
},
|
||||
rawCall: { rawPrompt, rawSettings },
|
||||
rawResponse: { headers: responseHeaders },
|
||||
request: { body: JSON.stringify(args) },
|
||||
response: getResponseMetadata(response),
|
||||
warnings
|
||||
};
|
||||
}
|
||||
async doStream(options) {
|
||||
const { args, warnings } = this.getArgs(options);
|
||||
const body = { ...args, stream: true };
|
||||
const { responseHeaders, value: response } = await (0, import_provider_utils2.postJsonToApi)({
|
||||
url: `${this.config.baseURL}/chat/completions`,
|
||||
headers: (0, import_provider_utils2.combineHeaders)(this.config.headers(), options.headers),
|
||||
body,
|
||||
failedResponseHandler: gigachatFailedResponseHandler,
|
||||
successfulResponseHandler: (0, import_provider_utils2.createEventSourceResponseHandler)(gigachatChatChunkSchema),
|
||||
abortSignal: options.abortSignal,
|
||||
fetch: this.config.fetch
|
||||
});
|
||||
const { messages: rawPrompt, ...rawSettings } = args;
|
||||
let finishReason = "unknown";
|
||||
let usage = {
|
||||
promptTokens: Number.NaN,
|
||||
completionTokens: Number.NaN
|
||||
};
|
||||
let chunkNumber = 0;
|
||||
let trimLeadingSpace = false;
|
||||
return {
|
||||
stream: response.pipeThrough(
|
||||
new TransformStream({
|
||||
transform(chunk, controller) {
|
||||
if (!chunk.success) {
|
||||
controller.enqueue({ type: "error", error: chunk.error });
|
||||
return;
|
||||
}
|
||||
chunkNumber++;
|
||||
const value = chunk.value;
|
||||
if (chunkNumber === 1) {
|
||||
controller.enqueue({
|
||||
type: "response-metadata",
|
||||
...getResponseMetadata(value)
|
||||
});
|
||||
}
|
||||
if (value.usage != null) {
|
||||
usage = {
|
||||
promptTokens: value.usage.prompt_tokens,
|
||||
completionTokens: value.usage.completion_tokens
|
||||
};
|
||||
}
|
||||
const choice = value.choices[0];
|
||||
if ((choice == null ? void 0 : choice.finish_reason) != null) {
|
||||
finishReason = mapGigachatFinishReason(choice.finish_reason);
|
||||
}
|
||||
if ((choice == null ? void 0 : choice.delta) == null) {
|
||||
return;
|
||||
}
|
||||
const delta = choice.delta;
|
||||
if (chunkNumber <= 2) {
|
||||
const lastMessage = rawPrompt[rawPrompt.length - 1];
|
||||
if (lastMessage.role === "assistant" && delta.content === lastMessage.content.trimEnd()) {
|
||||
if (delta.content.length < lastMessage.content.length) {
|
||||
trimLeadingSpace = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (delta.content != null) {
|
||||
controller.enqueue({
|
||||
type: "text-delta",
|
||||
textDelta: trimLeadingSpace ? delta.content.trimStart() : delta.content
|
||||
});
|
||||
trimLeadingSpace = false;
|
||||
}
|
||||
if (delta.function_call != null) {
|
||||
controller.enqueue({
|
||||
type: "tool-call-delta",
|
||||
toolCallType: "function",
|
||||
toolCallId: delta.function_call.name,
|
||||
toolName: delta.function_call.name,
|
||||
argsTextDelta: JSON.stringify(delta.function_call.arguments)
|
||||
});
|
||||
controller.enqueue({
|
||||
type: "tool-call",
|
||||
toolCallType: "function",
|
||||
toolCallId: delta.function_call.name,
|
||||
toolName: delta.function_call.name,
|
||||
args: JSON.stringify(delta.function_call.arguments)
|
||||
});
|
||||
}
|
||||
},
|
||||
flush(controller) {
|
||||
controller.enqueue({ type: "finish", finishReason, usage });
|
||||
}
|
||||
})
|
||||
),
|
||||
rawCall: { rawPrompt, rawSettings },
|
||||
rawResponse: { headers: responseHeaders },
|
||||
request: { body: JSON.stringify(body) },
|
||||
warnings
|
||||
};
|
||||
}
|
||||
};
|
||||
var gigachatChatResponseSchema = import_zod2.z.object({
|
||||
created: import_zod2.z.number().nullish(),
|
||||
model: import_zod2.z.string().nullish(),
|
||||
choices: import_zod2.z.array(
|
||||
import_zod2.z.object({
|
||||
message: import_zod2.z.object({
|
||||
role: import_zod2.z.literal("assistant"),
|
||||
content: import_zod2.z.string().nullable(),
|
||||
created: import_zod2.z.number().nullish(),
|
||||
name: import_zod2.z.string().nullish(),
|
||||
function_call: import_zod2.z.object({
|
||||
name: import_zod2.z.string(),
|
||||
arguments: import_zod2.z.record(import_zod2.z.any())
|
||||
}).nullish(),
|
||||
data_for_context: import_zod2.z.array(import_zod2.z.object({})).nullish()
|
||||
}),
|
||||
index: import_zod2.z.number(),
|
||||
finish_reason: import_zod2.z.string().nullish()
|
||||
})
|
||||
),
|
||||
object: import_zod2.z.literal("chat.completion"),
|
||||
usage: import_zod2.z.object({
|
||||
prompt_tokens: import_zod2.z.number(),
|
||||
completion_tokens: import_zod2.z.number(),
|
||||
total_tokens: import_zod2.z.number()
|
||||
})
|
||||
});
|
||||
var gigachatChatChunkSchema = import_zod2.z.object({
|
||||
created: import_zod2.z.number().nullish(),
|
||||
model: import_zod2.z.string().nullish(),
|
||||
object: import_zod2.z.literal("chat.completion"),
|
||||
choices: import_zod2.z.array(
|
||||
import_zod2.z.object({
|
||||
delta: import_zod2.z.object({
|
||||
role: import_zod2.z.enum(["assistant"]).optional(),
|
||||
content: import_zod2.z.string().nullish(),
|
||||
functions_state_id: import_zod2.z.string().nullish(),
|
||||
function_call: import_zod2.z.object({
|
||||
name: import_zod2.z.string(),
|
||||
arguments: import_zod2.z.object({})
|
||||
}).nullish()
|
||||
}),
|
||||
finish_reason: import_zod2.z.string().nullish(),
|
||||
index: import_zod2.z.number()
|
||||
})
|
||||
),
|
||||
usage: import_zod2.z.object({
|
||||
prompt_tokens: import_zod2.z.number(),
|
||||
completion_tokens: import_zod2.z.number()
|
||||
}).nullish()
|
||||
});
|
||||
|
||||
// src/gigachat-embedding-model.ts
|
||||
var import_provider3 = require("@ai-sdk/provider");
|
||||
var import_provider_utils3 = require("@ai-sdk/provider-utils");
|
||||
var import_zod3 = require("zod");
|
||||
var GigachatEmbeddingModel = class {
|
||||
constructor(modelId, settings, config) {
|
||||
this.specificationVersion = "v1";
|
||||
this.modelId = modelId;
|
||||
this.settings = settings;
|
||||
this.config = config;
|
||||
}
|
||||
get provider() {
|
||||
return this.config.provider;
|
||||
}
|
||||
get maxEmbeddingsPerCall() {
|
||||
var _a;
|
||||
return (_a = this.settings.maxEmbeddingsPerCall) != null ? _a : 32;
|
||||
}
|
||||
get supportsParallelCalls() {
|
||||
var _a;
|
||||
return (_a = this.settings.supportsParallelCalls) != null ? _a : false;
|
||||
}
|
||||
async doEmbed({
|
||||
values,
|
||||
abortSignal,
|
||||
headers
|
||||
}) {
|
||||
if (values.length > this.maxEmbeddingsPerCall) {
|
||||
throw new import_provider3.TooManyEmbeddingValuesForCallError({
|
||||
provider: this.provider,
|
||||
modelId: this.modelId,
|
||||
maxEmbeddingsPerCall: this.maxEmbeddingsPerCall,
|
||||
values
|
||||
});
|
||||
}
|
||||
const { responseHeaders, value: response } = await (0, import_provider_utils3.postJsonToApi)({
|
||||
url: `${this.config.baseURL}/embeddings`,
|
||||
headers: (0, import_provider_utils3.combineHeaders)(this.config.headers(), headers),
|
||||
body: {
|
||||
model: this.modelId,
|
||||
input: values,
|
||||
encoding_format: "float"
|
||||
},
|
||||
failedResponseHandler: gigachatFailedResponseHandler,
|
||||
successfulResponseHandler: (0, import_provider_utils3.createJsonResponseHandler)(GigachatTextEmbeddingResponseSchema),
|
||||
abortSignal,
|
||||
fetch: this.config.fetch
|
||||
});
|
||||
return {
|
||||
embeddings: response.data.map((item) => item.embedding),
|
||||
usage: response.usage ? { tokens: response.usage.prompt_tokens } : void 0,
|
||||
rawResponse: { headers: responseHeaders }
|
||||
};
|
||||
}
|
||||
};
|
||||
var GigachatTextEmbeddingResponseSchema = import_zod3.z.object({
|
||||
data: import_zod3.z.array(import_zod3.z.object({ embedding: import_zod3.z.array(import_zod3.z.number()) })),
|
||||
usage: import_zod3.z.object({ prompt_tokens: import_zod3.z.number() }).nullish()
|
||||
});
|
||||
|
||||
// src/gigachat-provider.ts
|
||||
function createGigachat(options = {}) {
|
||||
var _a;
|
||||
const baseURL = (_a = (0, import_provider_utils4.withoutTrailingSlash)(options.baseURL)) != null ? _a : "https://gigachat.devices.sberbank.ru/api/v1";
|
||||
const getAccessToken = () => ({});
|
||||
const getHeaders = () => ({
|
||||
Authorization: `Bearer ${(0, import_provider_utils4.loadApiKey)({
|
||||
apiKey: options.apiKey,
|
||||
environmentVariableName: "GIGACHAT_ACCESS_TOKEN",
|
||||
description: "GigaChat"
|
||||
})}`,
|
||||
...options.headers
|
||||
});
|
||||
const createChatModel = (modelId, settings = {}) => new GigachatChatLanguageModel(modelId, settings, {
|
||||
provider: "gigachat.chat",
|
||||
baseURL,
|
||||
headers: getHeaders,
|
||||
fetch: options.fetch
|
||||
});
|
||||
const createEmbeddingModel = (modelId, settings = {}) => new GigachatEmbeddingModel(modelId, settings, {
|
||||
provider: "gigachat.embedding",
|
||||
baseURL,
|
||||
headers: getHeaders,
|
||||
fetch: options.fetch
|
||||
});
|
||||
const provider = function(modelId, settings) {
|
||||
if (new.target) {
|
||||
throw new Error("Gigachat function cannot be called with the new keyword.");
|
||||
}
|
||||
return createChatModel(modelId, settings);
|
||||
};
|
||||
provider.languageModel = createChatModel;
|
||||
provider.chat = createChatModel;
|
||||
provider.embedding = createEmbeddingModel;
|
||||
provider.textEmbedding = createEmbeddingModel;
|
||||
provider.textEmbeddingModel = createEmbeddingModel;
|
||||
return provider;
|
||||
}
|
||||
var gigachat = createGigachat();
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
createGigachat,
|
||||
gigachat
|
||||
});
|
||||
//# sourceMappingURL=index.js.map
|
||||
@@ -1,144 +0,0 @@
|
||||
const axios = require('axios');
|
||||
const https = require('https');
|
||||
const fs = require('fs');
|
||||
const qs = require('querystring');
|
||||
const uuid = require('uuid');
|
||||
|
||||
const router = require('express').Router();
|
||||
|
||||
// vercel/ai package
|
||||
const ai = require('./ai');
|
||||
// gigachat provider for vercel/ai
|
||||
const gigachatProvider = require('./gigachat');
|
||||
|
||||
module.exports = router;
|
||||
|
||||
const path = require('path');
|
||||
//process.env.NODE_EXTRA_CA_CERTS= path.resolve(__dirname, 'certs')
|
||||
//process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
|
||||
|
||||
process.env.GIGACHAT_AUTH =
|
||||
'NWVjYTczYjctNWRkYi00NzExLTg0YTEtMjhlOWVmODM2MjI4OjlmMTBkMGVkLWZjZjktNGZhOS1hNDZjLTc5ZWU1YzExOGExMw==';
|
||||
|
||||
const agent = new https.Agent({
|
||||
rejectUnauthorized: false
|
||||
});
|
||||
|
||||
const gigachat = gigachatProvider.createGigachat({
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'text/event-stream'
|
||||
},
|
||||
fetch: (url, options) => {
|
||||
return axios({
|
||||
method: 'post',
|
||||
maxBodyLength: Infinity,
|
||||
url: url,
|
||||
headers: options.headers,
|
||||
httpsAgent: agent,
|
||||
data: options.body
|
||||
}).then((response) => {
|
||||
return new Response(response.data, {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
headers: response.headers,
|
||||
body: response.data
|
||||
});
|
||||
}).catch((error) => {
|
||||
return new Response(error.message, {
|
||||
status: error.response.status,
|
||||
statusText: error.response.statusText,
|
||||
headers: error.response.headers,
|
||||
body: error.response.data
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
router.use(async (req, res, next) => {
|
||||
const hasToken = process.env.GIGACHAT_ACCESS_TOKEN && process.env.GIGACHAT_EXPIRES_AT != null;
|
||||
const hasExpired = new Date(process.env.GIGACHAT_EXPIRES_AT) <= new Date();
|
||||
if (!hasToken || hasExpired) {
|
||||
let auth = process.env.GIGACHAT_AUTH;
|
||||
let rquid = uuid.v4();
|
||||
|
||||
let config = {
|
||||
method: 'post',
|
||||
maxBodyLength: Infinity,
|
||||
url: 'https://ngw.devices.sberbank.ru:9443/api/v2/oauth',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
Accept: 'application/json',
|
||||
RqUID: rquid,
|
||||
Authorization: 'Basic ' + auth
|
||||
},
|
||||
httpsAgent: agent,
|
||||
data: qs.stringify({
|
||||
scope: 'GIGACHAT_API_PERS'
|
||||
})
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await axios(config);
|
||||
const json = response.data;
|
||||
process.env.GIGACHAT_ACCESS_TOKEN = json.access_token;
|
||||
process.env.GIGACHAT_EXPIRES_AT = json.expires_at;
|
||||
console.log(JSON.stringify(response.data));
|
||||
} catch {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
router.post('/chat', async (req, res) => {
|
||||
const { messages } = req.body;
|
||||
|
||||
const result = ai.streamText({
|
||||
model: gigachat('GigaChat'),
|
||||
system: 'You are a helpful assistant.',
|
||||
messages,
|
||||
stream: true,
|
||||
update_interval: 0.2
|
||||
});
|
||||
|
||||
result.pipeDataStreamToResponse(res);
|
||||
});
|
||||
|
||||
router.post('/new-unit', async (req, res) => {
|
||||
const { prompt } = req.body;
|
||||
|
||||
const systemMessage = `
|
||||
Я хочу, чтобы вы выступали в роли помощника для создания продвинутых текстовых уроков английского языка. Я буду указывать тему и уровень сложности (начинающий, средний, продвинутый), а вы будете предоставлять структурированный план урока в формате Markdown. Урок должен включать только текстовые элементы (без видео, картинок, аудио) и содержать следующие разделы:
|
||||
-Цель урока — конкретный навык или знание, которое освоят студенты.
|
||||
-Лексика
|
||||
-Базовые термины: 5-7 слов/фраз с примерами употребления.
|
||||
-Расширенная лексика: 3-5 идиом, фразовых глаголов или сложных выражений (для среднего/продвинутого уровня).
|
||||
-Грамматический фокус
|
||||
-Правило с пояснением и 3-5 примерами.
|
||||
-Типичные ошибки и как их избежать.
|
||||
-Контекстуализация
|
||||
-Короткий текст (диалог, статья, описание) для анализа с использованием лексики и грамматики урока.
|
||||
-Упражнения
|
||||
-Письменное задание: например, составить предложения/эссе по теме.
|
||||
-Устная практика: ролевые диалоги (текстовые сценарии), описание ситуаций.
|
||||
-Аналитическое задание: исправление ошибок в предложениях, перевод сложных конструкций.
|
||||
-Домашнее задание
|
||||
Текстовые задачи: написание текста, грамматические тесты, поиск синонимов/антонимов.
|
||||
Ответ должен быть оформлен в Markdown, лаконичным, без лишних комментариев, если пишешь блок кода, начинай его с новой строки.
|
||||
`;
|
||||
|
||||
try {
|
||||
const result = ai.streamText({
|
||||
model: gigachat('GigaChat'),
|
||||
system: systemMessage,
|
||||
prompt,
|
||||
stream: true,
|
||||
update_interval: 0.3
|
||||
});
|
||||
|
||||
result.pipeTextStreamToResponse(res);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
@@ -1,17 +1,13 @@
|
||||
const router = require('express').Router();
|
||||
const router = require("express").Router();
|
||||
|
||||
const dictionariesRouter = require('./dictionaries');
|
||||
const unitsRouter = require('./units');
|
||||
const gigachatRouter = require('./gigachat');
|
||||
const dictionariesRouter = require("./dictionaries");
|
||||
module.exports = router;
|
||||
|
||||
const delay =
|
||||
(ms = 250) =>
|
||||
(ms = 1000) =>
|
||||
(req, res, next) => {
|
||||
setTimeout(next, ms);
|
||||
};
|
||||
|
||||
router.use(delay());
|
||||
router.use('/dictionaries', dictionariesRouter);
|
||||
router.use('/units', unitsRouter);
|
||||
router.use('/gigachat', gigachatRouter);
|
||||
router.use("/dictionaries", dictionariesRouter);
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
### Цель урока:
|
||||
Изучение ключевых слов и фраз, связанных с процессом трудоустройства, а также освоение базовой структуры диалога на собеседовании.
|
||||
|
||||
### Лексика:
|
||||
**Базовая лексика:**
|
||||
1. **Job interview** – собеседование при приеме на работу
|
||||
2. **Resume / CV** – резюме
|
||||
3. **Cover letter** – сопроводительное письмо
|
||||
4. **Interviewer** – интервьюер
|
||||
5. **Application form** – анкета при приеме на работу
|
||||
6. **Salary** – зарплата
|
||||
7. **Benefits** – льготы
|
||||
|
||||
**Расширенная лексика:**
|
||||
1. **To apply for a job** – подавать заявку на работу
|
||||
2. **To be offered the job** – получить предложение о работе
|
||||
3. **To negotiate salary** – вести переговоры о зарплате
|
||||
4. **To accept the offer** – принять предложение
|
||||
5. **To decline the offer** – отклонить предложение
|
||||
6. **To resign from your current position** – подать заявление об уходе с текущей работы
|
||||
7. **To start working at the company** – начать работать в компании
|
||||
8. **Probation period** – испытательный срок
|
||||
9. **References** – рекомендации
|
||||
10. **Work experience** – опыт работы
|
||||
|
||||
### Грамматический фокус:
|
||||
**Правило:**
|
||||
Структура простого вопроса на английском языке:
|
||||
- Общий вопрос: "Do you have any questions?"
|
||||
- Специальный вопрос: "What are your strengths and weaknesses?"
|
||||
|
||||
**Пример:**
|
||||
Общий вопрос: "How do you feel about this job opportunity?"
|
||||
Специальный вопрос: "Can you tell me about your previous work experience?"
|
||||
|
||||
**Типичные ошибки и как их избежать:**
|
||||
Ошибка: Неправильное использование порядка слов в вопросах.
|
||||
Решение: Практиковать построение вопросов до автоматизма.
|
||||
|
||||
### Контекстуализация:
|
||||
**Текст для анализа:**
|
||||
"I'm applying for the position of a marketing manager at XYZ Company. Here is my resume."
|
||||
"Thank you for considering me. Can you please tell me more about the responsibilities of this role?"
|
||||
"Sure, let me give you an overview."
|
||||
|
||||
### Упражнения:
|
||||
**Письменное задание:**
|
||||
Составьте список из 5 вопросов, которые вы бы задали на собеседовании. Используйте простые вопросы и специальные вопросы.
|
||||
|
||||
**Устная практика:**
|
||||
Ролевая игра: один студент играет роль интервьюера, другой – кандидата на должность. Меняйтесь ролями.
|
||||
|
||||
**Аналитическое задание:**
|
||||
Найдите и исправьте ошибки в следующем письме:
|
||||
"Dear HR Manager,
|
||||
|
||||
My name is John Smith and I am writing to apply for the position of Sales Representative at ABC Inc. I enclose my resume for your review.
|
||||
|
||||
I believe that my skills and experiences make me an ideal candidate for this position. In my current role as a sales representative at XYZ Corp, I have consistently met or exceeded my sales targets. Additionally, I possess strong communication and negotiation skills which will enable me to effectively represent your products and services.
|
||||
|
||||
If you would like to schedule an interview, please contact me at your convenience. Thank you for your time and consideration.
|
||||
|
||||
Best regards,
|
||||
John Smith"
|
||||
|
||||
### Домашнее задание:
|
||||
**Текстовые задачи:**
|
||||
1. Написать сопроводительное письмо для конкретной вакансии, используя расширенную лексику.
|
||||
2. Составить резюме для воображаемой должности, включая все необходимые разделы.
|
||||
3. Перевести текст собеседования на английский язык, сохраняя структуру и смысл.
|
||||
@@ -1,71 +0,0 @@
|
||||
# Unit 1. Multifunctional Verbs: Be, Have, and Do
|
||||
|
||||
## Overview
|
||||
|
||||
This unit focuses on the use of multifunctional verbs in English. These verbs are able to express multiple meanings depending on their use in a sentence.
|
||||
|
||||
## Learning Objectives
|
||||
|
||||
By the end of this unit, you will be able to:
|
||||
|
||||
- Identify the different forms of the main multifunctional verb.
|
||||
- Explain how these forms can be used interchangeably in sentences.
|
||||
- Demonstrate the correct usage of the three forms of the multifunctional verb by providing sentences and examples.
|
||||
|
||||
## Vocabulary Review
|
||||
|
||||
| Term | Definition |
|
||||
| ---- | -------------------------------------------------------- |
|
||||
| Be | To express a present or ongoing state of being. |
|
||||
| Have | To express ownership or possession. |
|
||||
| Do | To express an action to be done, future action or habit. |
|
||||
|
||||
## Activities
|
||||
|
||||
### Activity 1: Identify the Different Forms of the Main Multifunctional Verb
|
||||
|
||||
- Read through each sentence and identify if the verb is used in its present tense (is), past tense (was/were), or future tense (will, would).
|
||||
- Discuss how this usage can vary depending on context.
|
||||
- Write down sentences that use different forms to illustrate your points.
|
||||
|
||||
1. **Sentence 1**: "The cat is sleeping."
|
||||
|
||||
- Present tense: The cat is sleeping.
|
||||
- Past tense: The cat slept.
|
||||
- Future tense: The cat will sleep.
|
||||
|
||||
2. **Sentence 2**: "I have a dog at home."
|
||||
|
||||
- Present tense: I have a dog.
|
||||
- Past tense: I had a dog.
|
||||
- Future tense: I will have a dog.
|
||||
|
||||
3. **Sentence 3**: "We are going on a hike tomorrow."
|
||||
|
||||
- Present tense: We are going on a hike.
|
||||
- Past tense: We went on a hike.
|
||||
- Future tense: We will go on a hike.
|
||||
|
||||
4. **Sentence 4**: "He has been studying all day."
|
||||
|
||||
- Present tense: He is studying.
|
||||
- Past tense: He studied.
|
||||
- Future tense: He will study.
|
||||
|
||||
5. **Sentence 5**: "We are going to buy some groceries later today."
|
||||
- Present tense: We are going to buy some groceries.
|
||||
- Past tense: We bought some groceries.
|
||||
- Future tense: We will buy some groceries.
|
||||
|
||||
### Activity 2: Explain How These Forms Can Be Used Interchangeably in Sentences
|
||||
|
||||
- Read through a sentence and identify the present, past, and future tense uses.
|
||||
- In pairs, explain why these forms are used interchangeably.
|
||||
- Provide examples of sentences that demonstrate this usage.
|
||||
- Highlight how the context changes the meaning.
|
||||
|
||||
### Activity 3: Correct Usage of the Three Forms of the Multifunctional Verb
|
||||
|
||||
- Read through a sentence and identify which form is being used.
|
||||
- In pairs, discuss why these forms are used in certain situations.
|
||||
- Provide sentences that demonstrate the correct usage of the three forms.
|
||||
@@ -1,74 +0,0 @@
|
||||
# Цель урока
|
||||
|
||||
Изучение структуры документации программы с блоком кода.
|
||||
|
||||
## Лексика
|
||||
|
||||
### Базовая лексика:
|
||||
|
||||
- Documentation – документация
|
||||
- Code block – блок кода
|
||||
- Description – описание
|
||||
- Function – функция
|
||||
- Variable – переменная
|
||||
- Comment – комментарий
|
||||
|
||||
### Расширенная лексика:
|
||||
|
||||
- API – интерфейс прикладного программирования
|
||||
- Method – метод
|
||||
- Class – класс
|
||||
- Library – библиотека
|
||||
- Framework – фреймворк
|
||||
|
||||
## Грамматический фокус
|
||||
|
||||
Правило: Структура документации программы должна включать краткое описание, блок кода и примеры использования.
|
||||
|
||||
Пример:
|
||||
|
||||
Documentation for a program typically includes the following sections:
|
||||
|
||||
1. **Description**: A brief overview of what the program does and its purpose.
|
||||
2. **Code Block**: The actual code that implements the functionality described in the first section.
|
||||
3. **Examples**: One or more examples demonstrating how to use the features described in the documentation.
|
||||
|
||||
Типичные ошибки и как их избежать: Ошибки могут возникнуть из-за недостаточного описания функционала или неправильного форматирования кода. Чтобы избежать этого, важно тщательно проработать каждый раздел документации и убедиться, что все примеры корректны и понятны.
|
||||
|
||||
## Контекстуализация
|
||||
|
||||
Текст для анализа:
|
||||
|
||||
**Description**: This is a simple Python script that calculates the average value of a list of numbers.
|
||||
|
||||
**Code Block**:
|
||||
```python
|
||||
def calculate_average(numbers):
|
||||
"""Calculate the average value of a list of numbers"""
|
||||
return sum(numbers)/len(numbers)
|
||||
```
|
||||
|
||||
Примеры использования:
|
||||
|
||||
```python
|
||||
# Example usage
|
||||
numbers = [10, 20, 30]
|
||||
average = calculate_average(numbers)
|
||||
print("The average value of the list", numbers, "is", average)
|
||||
```
|
||||
|
||||
## Упражнения
|
||||
|
||||
Письменное задание: Написать документацию для простой функции на языке Python, которая принимает список чисел и возвращает среднее значение. Включить описание, код блока и пример использования.
|
||||
|
||||
Устная практика: Ролевой диалог между разработчиком и техническим писателем о структуре и содержании документации программы.
|
||||
|
||||
Аналитическое задание: Проанализировать существующую документацию программы и найти ошибки или неясности. Предложить улучшения.
|
||||
|
||||
## Домашнее задание
|
||||
|
||||
Текстовые задачи:
|
||||
|
||||
- Написать документацию для другой функции на языке Python, используя правильную структуру.
|
||||
- Исправить ошибки в существующей документации программы.
|
||||
- Перевести фрагмент документации на русский язык, сохраняя точность и стиль.
|
||||
@@ -1 +0,0 @@
|
||||
[{"id":1,"filename":"unit-1","name":"Unit 1: Multifunctional Verbs: Be, Have, and Do"},{"id":2,"filename":"unit-2","name":"Документация программы"},{"id":3,"fileName":"job-interview","name":"Job Interview"}]
|
||||
@@ -1,62 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const router = require('express').Router();
|
||||
|
||||
module.exports = router;
|
||||
|
||||
const data = require('./data/units.json');
|
||||
router.get('/', (req, res) => {
|
||||
res.send(data);
|
||||
});
|
||||
|
||||
router.put('/', (req, res) => {
|
||||
const newUnit = req.body;
|
||||
|
||||
if (!newUnit) {
|
||||
return res.status(400).send('No new unit to be added');
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return res.status(500).send('No data to be updated');
|
||||
}
|
||||
|
||||
const newId = data.length + 1;
|
||||
const filename = newUnit.name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
fs.writeFileSync(path.join(__dirname, 'data', `${filename}.md`), newUnit.content);
|
||||
|
||||
data.push({ id: newId, filename: filename, name: newUnit.name });
|
||||
|
||||
fs.writeFileSync(path.join(__dirname, 'data', 'units.json'), JSON.stringify(data));
|
||||
res.status(200).send(data);
|
||||
});
|
||||
|
||||
router.delete('/:id', (req, res) => {
|
||||
const id = parseInt(req.params.id);
|
||||
const index = data.findIndex((unit) => unit.id === id);
|
||||
|
||||
if (index < 0) {
|
||||
return res.status(404).send('Not found');
|
||||
}
|
||||
|
||||
data.splice(index, 1);
|
||||
fs.writeFileSync(path.join(__dirname, 'data', 'units.json'), JSON.stringify(data));
|
||||
res.send({ message: `Unit with ID ${id} deleted` });
|
||||
});
|
||||
|
||||
router.get('/:id', (req, res) => {
|
||||
const id = parseInt(req.params.id);
|
||||
const unit = data.find((unit) => unit.id === id);
|
||||
|
||||
if (!unit) {
|
||||
return res.status(404).send('Not found');
|
||||
}
|
||||
|
||||
const unitFilepath = path.join(__dirname, 'data', `${unit.filename}.md`);
|
||||
const unitContent = fs.readFileSync(unitFilepath, 'utf-8');
|
||||
|
||||
if (!unitContent) {
|
||||
return res.status(404).send('Not found');
|
||||
}
|
||||
|
||||
res.send({ ...unit, content: unitContent });
|
||||
});
|
||||
@@ -1,75 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const router = require("express").Router();
|
||||
|
||||
module.exports = router;
|
||||
|
||||
const words = require("../words/words.json");
|
||||
|
||||
router.get("/", (req, res) => {
|
||||
res.send(words);
|
||||
});
|
||||
|
||||
router.put('/', (req, res) => {
|
||||
const newData = req.body;
|
||||
if (!newData) {
|
||||
return res.status(400).send('No data to add'); // Bad request
|
||||
}
|
||||
if (!words) {
|
||||
return res.status(500).send('No data to update'); // Internal server error
|
||||
}
|
||||
console.log(words.length)
|
||||
const indexedUpdatedData = { ...newData, id: words.length + 1 }; // Add the new word to the array
|
||||
console.log(indexedUpdatedData);
|
||||
words.push(indexedUpdatedData); // Add the new word to the array
|
||||
fs.writeFile(path.join(__dirname, 'words.json'), JSON.stringify(words), (err) => {
|
||||
if (err) {
|
||||
console.error(err); // Log the error
|
||||
return res.status(500).send('Error saving data');
|
||||
}
|
||||
res.status(200).json(indexedUpdatedData);
|
||||
});
|
||||
});
|
||||
|
||||
router.get("/:id", (req, res) => {
|
||||
const id = parseInt(req.params.id);
|
||||
|
||||
if (!id || isNaN(id)) {
|
||||
return res.status(400).send('Invalid ID'); // Bad request
|
||||
}
|
||||
|
||||
if (!words) {
|
||||
return res.status(500).send('No data to update'); // Internal server error
|
||||
}
|
||||
const word = words.find((word) => word.id === id);
|
||||
|
||||
if (!word) {
|
||||
return res.status(404).send("Not found");
|
||||
}
|
||||
res.send(word);
|
||||
});
|
||||
|
||||
router.delete("/:id", (req, res) => {
|
||||
const id = parseInt(req.params.id);
|
||||
if (!id || isNaN(id)) {
|
||||
return res.status(400).send('Invalid ID'); // Bad request
|
||||
}
|
||||
|
||||
const index = words.findIndex((word) => word.id === id);
|
||||
if (index < 0) {
|
||||
return res.status(404).send("Not found");
|
||||
}
|
||||
|
||||
if (!words) {
|
||||
return res.status(500).send('No data to update'); // Internal server error
|
||||
}
|
||||
|
||||
words.splice(index, 1);
|
||||
fs.writeFile(path.join(__dirname, 'words.json'), JSON.stringify(words), (err) => {
|
||||
if (err) {
|
||||
console.error(err); // Log the error
|
||||
return res.status(500).send('Error saving data');
|
||||
}
|
||||
res.send({ message: `Word with id ${id} deleted` });
|
||||
});
|
||||
});
|
||||
@@ -1,136 +0,0 @@
|
||||
[
|
||||
{
|
||||
"id": 12,
|
||||
"word": "Tech",
|
||||
"definition": "short for technical, relating to the knowledge, machines, or methods used in science and industry. Tech is a whole industry, which includes IT",
|
||||
"examples": ["“As a DevOps engineer I have been working in Tech since 2020.”"],
|
||||
"synonyms": ["IT"]
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"word": "career path",
|
||||
"definition": "the series of jobs or roles that constitute a person's career, especially one in a particular field",
|
||||
"examples": ["“Technology is an evolving field with a variety of available career paths.”"],
|
||||
"synonyms": []
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"word": "Machine Learning",
|
||||
"translation": "Машинное обучение",
|
||||
"definition": "An approach to artificial intelligence where computers learn from data without being explicitly programmed.",
|
||||
"synonyms": ["Trainable Algorithms", "Automated Learning"],
|
||||
"examples": [
|
||||
"We used machine learning techniques to forecast product demand.",
|
||||
"The movie recommendation system is based on machine learning algorithms.",
|
||||
"Machine learning helped improve the accuracy of speech recognition in our application."
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"word": "Neural Network",
|
||||
"translation": "Нейронная сеть",
|
||||
"definition": "A mathematical model inspired by the structure and function of biological neural networks, consisting of interconnected nodes organized in layers that can process information.",
|
||||
"synonyms": ["Artificial Neural Network", "Deep Neural Network"],
|
||||
"examples": [
|
||||
"To process large amounts of data, we created a deep learning neural network.",
|
||||
"This neural network is capable of generating realistic images.",
|
||||
"Using neural networks significantly improved the quality of text translation."
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"word": "Algorithm",
|
||||
"translation": "Алгоритм",
|
||||
"definition": "A step-by-step procedure or set of instructions for solving a problem or performing a computation.",
|
||||
"synonyms": ["Procedure", "Method"],
|
||||
"examples": [
|
||||
"The algorithm we developed quickly finds the optimal delivery route.",
|
||||
"This algorithm sorts an array with a minimal number of operations.",
|
||||
"Encryption algorithms ensure secure transmission of data over the internet."
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"word": "Data Model",
|
||||
"translation": "Модель данных",
|
||||
"definition": "An abstract representation of the structure of data, describing how data is organized and related to each other.",
|
||||
"synonyms": ["Data Structure", "Schema"],
|
||||
"examples": [
|
||||
"Our data model allows us to efficiently manage relationships between customers and orders.",
|
||||
"The data model was designed considering scalability and performance requirements.",
|
||||
"This data model is used for storing information about social network users."
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"word": "Regression",
|
||||
"translation": "Регрессия",
|
||||
"definition": "A statistical method used to determine the relationship between one variable and others.",
|
||||
"synonyms": ["Linear Regression", "Nonlinear Regression"],
|
||||
"examples": [
|
||||
"We applied linear regression to analyze the impact of advertising campaigns on sales.",
|
||||
"Results from the regression analysis showed a strong correlation between customer age and purchase frequency.",
|
||||
"Regression helped us assess how changes in environmental conditions affect crop yield."
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"word": "Clustering",
|
||||
"translation": "Кластеризация",
|
||||
"definition": "The process of grouping similar objects into clusters so that objects within the same cluster are more similar to each other than to those in other clusters.",
|
||||
"synonyms": ["Grouping", "Segmentation"],
|
||||
"examples": [
|
||||
"Clustering allowed us to divide customers into several groups according to their purchasing behavior.",
|
||||
"Clustering methods are used to automatically group news by topic.",
|
||||
"As a result of clustering, several market segments were identified, each with its own characteristics."
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"word": "Supervised Learning",
|
||||
"translation": "Обучение с учителем",
|
||||
"definition": "A type of machine learning where the algorithm learns from labeled data, meaning data for which correct answers are known.",
|
||||
"synonyms": ["Controlled Learning", "Labeled Classification"],
|
||||
"examples": [
|
||||
"Supervised learning is used to classify emails as spam or not-spam.",
|
||||
"This approach was used to create a model that predicts real estate prices based on multiple parameters.",
|
||||
"Supervised learning helps diagnose diseases at early stages through medical data analysis."
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"word": "Data Labeling",
|
||||
"translation": "Разметка данных",
|
||||
"definition": "The process of assigning labels or classes to data so it can be used in supervised learning.",
|
||||
"synonyms": ["Data Annotation", "Tagging"],
|
||||
"examples": [
|
||||
"Before starting model training, we labeled the data by assigning each photo an animal category.",
|
||||
"Data labeling includes marking user reviews as positive or negative.",
|
||||
"Text documents were labeled with special tags for subsequent analysis."
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"word": "Hyperparameters",
|
||||
"translation": "Гиперпараметры",
|
||||
"definition": "Parameters that define the structure and behavior of a machine learning model, set before the learning process begins.",
|
||||
"synonyms": ["Model Settings", "Configuration Parameters"],
|
||||
"examples": [
|
||||
"Optimizing hyperparameters enabled us to enhance the performance of our machine learning model.",
|
||||
"Hyperparameters include settings such as the number of layers in a neural network and the learning rate.",
|
||||
"Choosing the right hyperparameters is crucial for achieving high model accuracy."
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"word": "Model Validation",
|
||||
"translation": "Валидация модели",
|
||||
"definition": "The process of evaluating the quality of a model by testing it on new, previously unseen data.",
|
||||
"synonyms": ["Model Testing", "Model Verification"],
|
||||
"examples": [
|
||||
"After completing the training, we validated the model using a test dataset.",
|
||||
"During model validation, its ability to make accurate predictions on new data is checked.",
|
||||
"Validation showed that the model is robust against changes in data and has low generalization error."
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -2,8 +2,6 @@ const { Router } = require('express')
|
||||
const router = Router()
|
||||
|
||||
router.use('/eng-it-lean', require('./eng-it-lean/index'))
|
||||
router.use('/sberhubproject', require('./sberhubproject/index'))
|
||||
router.use('/sber_web', require('./sber_web/index'))
|
||||
|
||||
module.exports = router
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
const router = require('express').Router();
|
||||
const listRouter = require('./questions');
|
||||
const questionRouter = require('./question');
|
||||
|
||||
module.exports = router;
|
||||
|
||||
router.use('/questions', listRouter);
|
||||
router.use('/question', questionRouter);
|
||||
@@ -1,16 +0,0 @@
|
||||
const axios = require('axios');
|
||||
const router = require('express').Router();
|
||||
|
||||
module.exports = router;
|
||||
|
||||
router.get('/:id', async (req, res) => {
|
||||
const id = req.params.id;
|
||||
const baseUrl = 'http://www.db.chgk.info';
|
||||
try {
|
||||
const data = await axios.get(baseUrl + `/questions/${id}`);
|
||||
res.send(data.data);
|
||||
}
|
||||
catch (e) {
|
||||
res.send(undefined);
|
||||
}
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
const axios = require('axios');
|
||||
const router = require('express').Router();
|
||||
|
||||
module.exports = router;
|
||||
|
||||
router.get('/:page', async (req, res) => {
|
||||
const page = req.params.page;
|
||||
const baseUrl = 'http://www.db.chgk.info';
|
||||
try {
|
||||
const data = await axios.get(baseUrl + `/questions?page=${page}&itemsPerPage=15`);
|
||||
res.send(data.data);
|
||||
}
|
||||
catch (e) {
|
||||
res.send(undefined);
|
||||
}
|
||||
});
|
||||
@@ -1,602 +0,0 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Конференция 2025",
|
||||
"description": "Ежегодная конференция по технологиям",
|
||||
"date": "2025-03-15T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Командная встреча",
|
||||
"description": "Ежеквартальная встреча для согласования целей",
|
||||
"date": 1672444800000
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "День рождения",
|
||||
"description": "Празднование 30-летия Ивана",
|
||||
"date": "2025-01-25"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Вебинар",
|
||||
"description": "Онлайн-вебинар по лучшим практикам TypeScript",
|
||||
"date": "2025-02-10T14:30:00Z"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Митап разработчиков",
|
||||
"description": "Встреча разработчиков для обмена опытом",
|
||||
"date": "2025-04-05T18:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "Хакатон",
|
||||
"description": "48-часовой марафон программирования",
|
||||
"date": "2025-05-20T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "Обучение Agile",
|
||||
"description": "Тренинг по методологии Agile",
|
||||
"date": "2025-06-10T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "Презентация продукта",
|
||||
"description": "Анонс нового продукта компании",
|
||||
"date": "2025-07-01T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "Корпоратив",
|
||||
"description": "Ежегодный корпоративный праздник",
|
||||
"date": "2025-08-15T19:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "Обучение DevOps",
|
||||
"description": "Курс по основам DevOps",
|
||||
"date": "2025-09-05T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "Встреча с клиентом",
|
||||
"description": "Обсуждение нового проекта",
|
||||
"date": "2025-10-12T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "Технический семинар",
|
||||
"description": "Семинар по новым технологиям",
|
||||
"date": "2025-11-20T13:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "Рождественская вечеринка",
|
||||
"description": "Празднование Рождества",
|
||||
"date": "2025-12-24T20:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"name": "Планирование года",
|
||||
"description": "Стратегическое планирование на следующий год",
|
||||
"date": "2026-01-10T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"name": "Обучение Python",
|
||||
"description": "Курс для начинающих",
|
||||
"date": "2026-02-15T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"name": "Встреча инвесторов",
|
||||
"description": "Презентация финансовых результатов",
|
||||
"date": "2026-03-01T15:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"name": "Марафон кодирования",
|
||||
"description": "24-часовой марафон",
|
||||
"date": "2026-04-05T12:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "Обучение React",
|
||||
"description": "Продвинутый курс по React",
|
||||
"date": "2026-05-10T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"name": "Конференция AI",
|
||||
"description": "Конференция по искусственному интеллекту",
|
||||
"date": "2026-06-15T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"name": "День открытых дверей",
|
||||
"description": "Знакомство с компанией",
|
||||
"date": "2026-07-01T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"name": "Обучение Docker",
|
||||
"description": "Курс по контейнеризации",
|
||||
"date": "2026-08-10T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"name": "Встреча с партнерами",
|
||||
"description": "Обсуждение сотрудничества",
|
||||
"date": "2026-09-05T13:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"name": "Технический митап",
|
||||
"description": "Обсуждение новых технологий",
|
||||
"date": "2026-10-12T18:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"name": "Хэллоуин",
|
||||
"description": "Корпоративная вечеринка",
|
||||
"date": "2026-10-31T20:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"name": "Обучение Kubernetes",
|
||||
"description": "Курс по оркестрации контейнеров",
|
||||
"date": "2026-11-15T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 26,
|
||||
"name": "Встреча команды",
|
||||
"description": "Обсуждение текущих задач",
|
||||
"date": "2026-12-01T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"name": "Новогодний корпоратив",
|
||||
"description": "Празднование Нового года",
|
||||
"date": "2026-12-31T21:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
"name": "Обучение GraphQL",
|
||||
"description": "Курс по GraphQL",
|
||||
"date": "2027-01-10T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 29,
|
||||
"name": "Конференция Blockchain",
|
||||
"description": "Конференция по блокчейн-технологиям",
|
||||
"date": "2027-02-15T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 30,
|
||||
"name": "Встреча с заказчиком",
|
||||
"description": "Обсуждение требований",
|
||||
"date": "2027-03-01T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 31,
|
||||
"name": "Обучение Node.js",
|
||||
"description": "Курс по серверному JavaScript",
|
||||
"date": "2027-04-05T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 32,
|
||||
"name": "Митап по DevOps",
|
||||
"description": "Обсуждение лучших практик",
|
||||
"date": "2027-05-10T18:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"name": "Конференция Cloud",
|
||||
"description": "Конференция по облачным технологиям",
|
||||
"date": "2027-06-15T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"name": "Обучение Security",
|
||||
"description": "Курс по кибербезопасности",
|
||||
"date": "2027-07-01T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 35,
|
||||
"name": "Встреча с командой",
|
||||
"description": "Планирование спринта",
|
||||
"date": "2027-08-10T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 36,
|
||||
"name": "Обучение AWS",
|
||||
"description": "Курс по Amazon Web Services",
|
||||
"date": "2027-09-05T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 37,
|
||||
"name": "Конференция Big Data",
|
||||
"description": "Конференция по большим данным",
|
||||
"date": "2027-10-12T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 38,
|
||||
"name": "Обучение Machine Learning",
|
||||
"description": "Курс по машинному обучению",
|
||||
"date": "2027-11-15T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 39,
|
||||
"name": "Встреча с инвесторами",
|
||||
"description": "Презентация новых проектов",
|
||||
"date": "2027-12-01T15:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 40,
|
||||
"name": "Новогодний митап",
|
||||
"description": "Подведение итогов года",
|
||||
"date": "2027-12-31T20:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 41,
|
||||
"name": "Обучение Go",
|
||||
"description": "Курс по языку Go",
|
||||
"date": "2028-01-10T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 42,
|
||||
"name": "Конференция IoT",
|
||||
"description": "Конференция по интернету вещей",
|
||||
"date": "2028-02-15T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 43,
|
||||
"name": "Встреча с партнерами",
|
||||
"description": "Обсуждение новых инициатив",
|
||||
"date": "2028-03-01T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 44,
|
||||
"name": "Обучение Rust",
|
||||
"description": "Курс по языку Rust",
|
||||
"date": "2028-04-05T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 45,
|
||||
"name": "Митап по AI",
|
||||
"description": "Обсуждение трендов в AI",
|
||||
"date": "2028-05-10T18:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 46,
|
||||
"name": "Конференция Cybersecurity",
|
||||
"description": "Конференция по кибербезопасности",
|
||||
"date": "2028-06-15T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 47,
|
||||
"name": "Обучение Vue.js",
|
||||
"description": "Курс по фреймворку Vue.js",
|
||||
"date": "2028-07-01T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 48,
|
||||
"name": "Встреча команды",
|
||||
"description": "Обсуждение текущих проектов",
|
||||
"date": "2028-08-10T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 49,
|
||||
"name": "Обучение Angular",
|
||||
"description": "Курс по фреймворку Angular",
|
||||
"date": "2028-09-05T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 50,
|
||||
"name": "Конференция DevOps",
|
||||
"description": "Конференция по DevOps",
|
||||
"date": "2028-10-12T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 51,
|
||||
"name": "Обучение SQL",
|
||||
"description": "Курс по базам данных",
|
||||
"date": "2028-11-15T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 52,
|
||||
"name": "Встреча с клиентом",
|
||||
"description": "Обсуждение новых требований",
|
||||
"date": "2028-12-01T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 53,
|
||||
"name": "Новогодний корпоратив",
|
||||
"description": "Празднование Нового года",
|
||||
"date": "2028-12-31T21:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 54,
|
||||
"name": "Обучение NoSQL",
|
||||
"description": "Курс по NoSQL базам данных",
|
||||
"date": "2029-01-10T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 55,
|
||||
"name": "Конференция Frontend",
|
||||
"description": "Конференция по фронтенд-разработке",
|
||||
"date": "2029-02-15T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 56,
|
||||
"name": "Встреча с командой",
|
||||
"description": "Планирование задач",
|
||||
"date": "2029-03-01T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 57,
|
||||
"name": "Обучение Svelte",
|
||||
"description": "Курс по фреймворку Svelte",
|
||||
"date": "2029-04-05T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 58,
|
||||
"name": "Митап по Backend",
|
||||
"description": "Обсуждение backend-разработки",
|
||||
"date": "2029-05-10T18:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 59,
|
||||
"name": "Конференция Mobile",
|
||||
"description": "Конференция по мобильной разработке",
|
||||
"date": "2029-06-15T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 60,
|
||||
"name": "Обучение Flutter",
|
||||
"description": "Курс по Flutter",
|
||||
"date": "2029-07-01T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 61,
|
||||
"name": "Встреча с партнерами",
|
||||
"description": "Обсуждение новых проектов",
|
||||
"date": "2029-08-10T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 62,
|
||||
"name": "Обучение Kotlin",
|
||||
"description": "Курс по языку Kotlin",
|
||||
"date": "2029-09-05T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 63,
|
||||
"name": "Конференция GameDev",
|
||||
"description": "Конференция по разработке игр",
|
||||
"date": "2029-10-12T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 64,
|
||||
"name": "Обучение Unity",
|
||||
"description": "Курс по Unity",
|
||||
"date": "2029-11-15T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 65,
|
||||
"name": "Встреча с клиентом",
|
||||
"description": "Обсуждение фидбэка",
|
||||
"date": "2029-12-01T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 66,
|
||||
"name": "Новогодний митап",
|
||||
"description": "Подведение итогов года",
|
||||
"date": "2029-12-31T20:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 67,
|
||||
"name": "Обучение Swift",
|
||||
"description": "Курс по языку Swift",
|
||||
"date": "2030-01-10T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 68,
|
||||
"name": "Конференция AR/VR",
|
||||
"description": "Конференция по AR/VR технологиям",
|
||||
"date": "2030-02-15T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 69,
|
||||
"name": "Встреча команды",
|
||||
"description": "Обсуждение текущих задач",
|
||||
"date": "2030-03-01T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 70,
|
||||
"name": "Обучение Dart",
|
||||
"description": "Курс по языку Dart",
|
||||
"date": "2030-04-05T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 71,
|
||||
"name": "Митап по Mobile",
|
||||
"description": "Обсуждение мобильной разработки",
|
||||
"date": "2030-05-10T18:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 72,
|
||||
"name": "Конференция QA",
|
||||
"description": "Конференция по тестированию",
|
||||
"date": "2030-06-15T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 73,
|
||||
"name": "Обучение Selenium",
|
||||
"description": "Курс по автоматизации тестирования",
|
||||
"date": "2030-07-01T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 74,
|
||||
"name": "Встреча с партнерами",
|
||||
"description": "Обсуждение сотрудничества",
|
||||
"date": "2030-08-10T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 75,
|
||||
"name": "Обучение Jenkins",
|
||||
"description": "Курс по CI/CD",
|
||||
"date": "2030-09-05T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 76,
|
||||
"name": "Конференция Automation",
|
||||
"description": "Конференция по автоматизации",
|
||||
"date": "2030-10-12T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 77,
|
||||
"name": "Обучение Git",
|
||||
"description": "Курс по системе контроля версий",
|
||||
"date": "2030-11-15T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 78,
|
||||
"name": "Встреча с клиентом",
|
||||
"description": "Обсуждение новых требований",
|
||||
"date": "2030-12-01T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 79,
|
||||
"name": "Новогодний корпоратив",
|
||||
"description": "Празднование Нового года",
|
||||
"date": "2030-12-31T21:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 80,
|
||||
"name": "Обучение Linux",
|
||||
"description": "Курс по операционной системе Linux",
|
||||
"date": "2031-01-10T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 81,
|
||||
"name": "Конференция Open Source",
|
||||
"description": "Конференция по открытому ПО",
|
||||
"date": "2031-02-15T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 82,
|
||||
"name": "Встреча команды",
|
||||
"description": "Планирование задач",
|
||||
"date": "2031-03-01T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 83,
|
||||
"name": "Обучение Bash",
|
||||
"description": "Курс по скриптингу",
|
||||
"date": "2031-04-05T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 84,
|
||||
"name": "Митап по DevOps",
|
||||
"description": "Обсуждение лучших практик",
|
||||
"date": "2031-05-10T18:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 85,
|
||||
"name": "Конференция Cloud Native",
|
||||
"description": "Конференция по облачным технологиям",
|
||||
"date": "2031-06-15T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 86,
|
||||
"name": "Обучение Terraform",
|
||||
"description": "Курс по инфраструктуре как код",
|
||||
"date": "2031-07-01T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 87,
|
||||
"name": "Встреча с партнерами",
|
||||
"description": "Обсуждение новых проектов",
|
||||
"date": "2031-08-10T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 88,
|
||||
"name": "Обучение Ansible",
|
||||
"description": "Курс по автоматизации",
|
||||
"date": "2031-09-05T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 89,
|
||||
"name": "Конференция Microservices",
|
||||
"description": "Конференция по микросервисам",
|
||||
"date": "2031-10-12T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 90,
|
||||
"name": "Обучение Kafka",
|
||||
"description": "Курс по потоковой обработке данных",
|
||||
"date": "2031-11-15T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 91,
|
||||
"name": "Встреча с клиентом",
|
||||
"description": "Обсуждение фидбэка",
|
||||
"date": "2031-12-01T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 92,
|
||||
"name": "Новогодний митап",
|
||||
"description": "Подведение итогов года",
|
||||
"date": "2031-12-31T20:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 93,
|
||||
"name": "Обучение Prometheus",
|
||||
"description": "Курс по мониторингу",
|
||||
"date": "2032-01-10T14:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 94,
|
||||
"name": "Конференция Monitoring",
|
||||
"description": "Конференция по мониторингу",
|
||||
"date": "2032-02-15T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 95,
|
||||
"name": "Встреча команды",
|
||||
"description": "Обсуждение текущих задач",
|
||||
"date": "2032-03-01T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 96,
|
||||
"name": "Обучение Grafana",
|
||||
"description": "Курс по визуализации данных",
|
||||
"date": "2032-04-05T11:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 97,
|
||||
"name": "Митап по SRE",
|
||||
"description": "Обсуждение Site Reliability Engineering",
|
||||
"date": "2032-05-10T18:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 98,
|
||||
"name": "Конференция Infrastructure",
|
||||
"description": "Конференция по инфраструктуре",
|
||||
"date": "2032-06-15T09:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 99,
|
||||
"name": "Обучение ELK",
|
||||
"description": "Курс по Elasticsearch, Logstash, Kibana",
|
||||
"date": "2032-07-01T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 100,
|
||||
"name": "Встреча с партнерами",
|
||||
"description": "Обсуждение сотрудничества",
|
||||
"date": "2032-08-10T11:00:00Z"
|
||||
}
|
||||
]
|
||||
@@ -1,40 +0,0 @@
|
||||
const router = require('express').Router();
|
||||
|
||||
module.exports = router;
|
||||
|
||||
const data = require('./data/event.json');
|
||||
const users_data = require('../users/data/users.json');
|
||||
|
||||
router.get('/', (req, res) => {
|
||||
res.json(data);
|
||||
});
|
||||
|
||||
router.get('/:pageSize/:page', (req, res) => {
|
||||
const pageSize = parseInt(req.params.pageSize);
|
||||
const page = parseInt(req.params.page);
|
||||
res.json(data.slice(pageSize * (page - 1), pageSize * page));
|
||||
});
|
||||
|
||||
router.post('/', (req, res) => {
|
||||
res.status(201).send();
|
||||
});
|
||||
|
||||
router.delete('/:id', (req, res) => {
|
||||
res.status(204).send();
|
||||
});
|
||||
|
||||
router.post('/:user_id/:action/:id', (req, res) => {
|
||||
const user_id = parseInt(req.params.user_id);
|
||||
const id = parseInt(req.params.id);
|
||||
const action = req.params.action;
|
||||
if (users_data.findIndex((item) => item.id === user_id) === -1 || data.findIndex((item) => item.id === id) === -1) {
|
||||
res.status(404).send();
|
||||
return;
|
||||
}
|
||||
if (action !== 'participate' && action !== 'refuse') {
|
||||
res.status(400).send({ error: 'Invalid action' });
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(201).send({ message: `${action} action processed` });
|
||||
});
|
||||
@@ -1,83 +0,0 @@
|
||||
const { v4: uuidv4 } = require('uuid');
|
||||
const axios = require('axios');
|
||||
const https = require('https');
|
||||
|
||||
process.env.GIGACHAT_AUTH =
|
||||
'YzA2ODg0NTYtYzE3Yi00OGJkLTkyY2MtMzdkM2U0YjE4ZmQ5Ojc0ZWVhN2YxLTI5MWYtNDNiZS05MTY2LWIyZjg5MGY2YWQ3Ng==';
|
||||
|
||||
const agent = new https.Agent({
|
||||
rejectUnauthorized: false
|
||||
});
|
||||
|
||||
class controller {
|
||||
async getText(req, res) {
|
||||
try {
|
||||
const { text } = req.body;
|
||||
|
||||
const headers = {
|
||||
Authorization: `Basic ${process.env.GIGACHAT_AUTH}`,
|
||||
RqUID: uuidv4(),
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
Accept: 'application/json'
|
||||
};
|
||||
|
||||
const access_token = await axios
|
||||
.post('https://ngw.devices.sberbank.ru:9443/api/v2/oauth', encodeURI(`scope=GIGACHAT_API_PERS`), {
|
||||
headers: headers,
|
||||
httpsAgent: agent
|
||||
})
|
||||
.then((response) => {
|
||||
return response.data.access_token;
|
||||
})
|
||||
.catch((error) => {
|
||||
return error;
|
||||
});
|
||||
|
||||
const systemMessage = ` Создай анализ совместимости между двумя людьми и отобрази результат исключительно в формате JSON, который будет результатом работы 'JSON.stringify()'. Он должен состоять из следующих частей:
|
||||
|
||||
1. **Совместимость** в процентах.
|
||||
2. **Список точек соприкосновения**. Перечисли их через запятую.
|
||||
3. **Список потенциальных различий**. Перечисли через запятую.
|
||||
|
||||
Результат должен быть строкой JSON, полученной через 'JSON.stringify()', и не содержать дополнительных пояснений или текста.
|
||||
|
||||
Пример:
|
||||
{"compatibility": 70, "pointsOfContact": ["общие интересы", "совместные увлечения", "взаимное уважение"], "potentialDifferences": ["различные жизненные цели", "противоположные характеры", "несовпадающие ценности"]}
|
||||
`;
|
||||
|
||||
const textAI = await axios
|
||||
.post(
|
||||
'https://gigachat.devices.sberbank.ru/api/v1/chat/completions',
|
||||
JSON.stringify({
|
||||
model: 'GigaChat:latest',
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: systemMessage + text
|
||||
}
|
||||
],
|
||||
profanity_check: true
|
||||
}),
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${access_token}`
|
||||
},
|
||||
httpsAgent: agent
|
||||
}
|
||||
)
|
||||
.then((response) => {
|
||||
return response.data.choices[0].message.content;
|
||||
})
|
||||
.catch((error) => {
|
||||
return error;
|
||||
});
|
||||
|
||||
res.status(200).json({ text: textAI });
|
||||
} catch (e) {
|
||||
res.status(400).json({ message: e });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new controller();
|
||||
@@ -1,6 +0,0 @@
|
||||
const router = require('express').Router();
|
||||
const controller = require('./controller');
|
||||
|
||||
router.post('/', controller.getText);
|
||||
|
||||
module.exports = router;
|
||||
@@ -1,20 +0,0 @@
|
||||
const router = require('express').Router();
|
||||
const interestsRouter = require('./interests');
|
||||
const usersRouter = require('./users');
|
||||
const eventsRouter = require('./events');
|
||||
const gigachatRouter = require('./gigachat');
|
||||
const telegramRouter = require('./telegram');
|
||||
module.exports = router;
|
||||
|
||||
const delay =
|
||||
(ms = 1000) =>
|
||||
(req, res, next) => {
|
||||
setTimeout(next, ms);
|
||||
};
|
||||
|
||||
router.use(delay());
|
||||
router.use('/interests', interestsRouter);
|
||||
router.use('/users', usersRouter);
|
||||
router.use('/events', eventsRouter);
|
||||
router.use('/gigachat', gigachatRouter);
|
||||
router.use('/telegram', telegramRouter);
|
||||
@@ -1,19 +0,0 @@
|
||||
[
|
||||
"Стартапы, поиск команды и нетворкинг",
|
||||
"Искусство, фотография и дизайн",
|
||||
"Музыка",
|
||||
"Хореография",
|
||||
"Спорт, фитнес и ЗОЖ",
|
||||
"Литература и история",
|
||||
"Политика, социология, активизм и дебаты",
|
||||
"Кино и другое многомодальное искусство",
|
||||
"Психология и психическое здоровье",
|
||||
"Соревновательные видеоигры",
|
||||
"Новые технологии, ИИ, техника",
|
||||
"Математика, физика и информатика",
|
||||
"Волонтерство и благотворительность",
|
||||
"Настольные игры",
|
||||
"Путешествия и туризм",
|
||||
"Английский (иностранные языки)",
|
||||
"Цифровые кафедры"
|
||||
]
|
||||
@@ -1,9 +0,0 @@
|
||||
const router = require('express').Router();
|
||||
|
||||
module.exports = router;
|
||||
|
||||
const data = require('./data/interest.json');
|
||||
|
||||
router.get('/', (req, res) => {
|
||||
res.json(data);
|
||||
});
|
||||
@@ -1,24 +0,0 @@
|
||||
const axios = require('axios');
|
||||
|
||||
process.env.TELEGRAM_TOKEN = '7866617284:AAHDOfPQJdKmufOdRgFza6XA8ZWRHPeA_Yc';
|
||||
|
||||
class controller {
|
||||
async sendMessage(req, res) {
|
||||
try {
|
||||
const { chat_id, text } = req.body;
|
||||
|
||||
const response = await axios.get(`https://api.telegram.org/bot${process.env.TELEGRAM_TOKEN}/sendMessage`, {
|
||||
params: {
|
||||
chat_id: chat_id,
|
||||
text: text,
|
||||
parse_mode: 'html'
|
||||
}
|
||||
});
|
||||
res.json(response.data);
|
||||
} catch (e) {
|
||||
res.status(400).json({ message: e.message });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new controller();
|
||||
@@ -1,6 +0,0 @@
|
||||
const router = require('express').Router();
|
||||
const controller = require('./controller');
|
||||
|
||||
router.post('/', controller.sendMessage);
|
||||
|
||||
module.exports = router;
|
||||
@@ -1,233 +0,0 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"username": "Иван Иванов",
|
||||
"photo": "https://i.pravatar.cc/150?img=64",
|
||||
"about": "Разработчик с 10-летним стажем, увлекаюсь новыми технологиями.",
|
||||
"email": "ivan.ivanov@example.com",
|
||||
"interests": [
|
||||
"Новые технологии, ИИ, техника",
|
||||
"Музыка"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"username": "Мария Смирнова",
|
||||
"photo": "https://i.pravatar.cc/150?img=47",
|
||||
"about": "Люблю путешествия и фотографию, обожаю изучать новые культуры.",
|
||||
"email": "maria.smirnova@example.com",
|
||||
"interests": [
|
||||
"Путешествия и туризм",
|
||||
"Искусство, фотография и дизайн"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"username": "Алексей Кузнецов",
|
||||
"photo": "https://i.pravatar.cc/150?img=68",
|
||||
"about": "Финансовый аналитик, интересуюсь инвестициями и рынками.",
|
||||
"email": "aleksey.kuznetsov@example.com",
|
||||
"interests": [
|
||||
"Политика, социология, активизм и дебаты",
|
||||
"Математика, физика и информатика"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"username": "Ольга Петрова",
|
||||
"photo": "https://i.pravatar.cc/150?img=49",
|
||||
"about": "Дизайнер интерьеров, люблю создавать уютные и стильные пространства.",
|
||||
"email": "olga.petrovna@example.com",
|
||||
"interests": [
|
||||
"Искусство, фотография и дизайн",
|
||||
"Кино и другое многомодальное искусство"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"username": "Дмитрий Сидоров",
|
||||
"photo": "https://i.pravatar.cc/150?img=60",
|
||||
"about": "Тренер по фитнесу, придерживаюсь здорового образа жизни.",
|
||||
"email": "dmitriy.sidorov@example.com",
|
||||
"interests": [
|
||||
"Спорт, фитнес и ЗОЖ",
|
||||
"Волонтерство и благотворительность"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"username": "Елена Волкова",
|
||||
"photo": "https://i.pravatar.cc/150?img=42",
|
||||
"about": "Психолог, занимаюсь личностным ростом и развитием.",
|
||||
"email": "elena.volkova@example.com",
|
||||
"interests": [
|
||||
"Психология и психическое здоровье",
|
||||
"Литература и история"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"username": "Артем Морозов",
|
||||
"photo": "https://i.pravatar.cc/150?img=69",
|
||||
"about": "Ведущий мероприятий и организатор, люблю работать с людьми.",
|
||||
"email": "artem.morozov@example.com",
|
||||
"interests": [
|
||||
"Настольные игры",
|
||||
"Кино и другое многомодальное искусство"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"username": "Ирина Фёдорова",
|
||||
"photo": "https://i.pravatar.cc/150?img=48",
|
||||
"about": "Веду блог о моде и стиле, увлекаюсь новыми трендами.",
|
||||
"email": "irina.fedorova@example.com",
|
||||
"interests": [
|
||||
"Мода",
|
||||
"Путешествия и туризм"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"username": "Сергей Чернов",
|
||||
"photo": "https://i.pravatar.cc/150?img=65",
|
||||
"about": "Разработчик мобильных приложений, увлекаюсь игровыми технологиями.",
|
||||
"email": "sergey.chernov@example.com",
|
||||
"interests": [
|
||||
"Соревновательные видеоигры",
|
||||
"Новые технологии, ИИ, техника"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"username": "Татьяна Лебедева",
|
||||
"photo": "https://i.pravatar.cc/150?img=50",
|
||||
"about": "Работаю в области маркетинга, увлекаюсь продвижением брендов.",
|
||||
"email": "tatyana.lebedeva@example.com",
|
||||
"interests": [
|
||||
"Маркетинг",
|
||||
"Литература и история"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"username": "Андрей Васильев",
|
||||
"photo": "https://i.pravatar.cc/150?img=70",
|
||||
"about": "Инженер-программист, увлекаюсь разработкой игр и виртуальной реальностью.",
|
||||
"email": "andrey.vasilyev@example.com",
|
||||
"interests": [
|
||||
"Разработка игр",
|
||||
"Виртуальная реальность"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"username": "Наталья Козлова",
|
||||
"photo": "https://i.pravatar.cc/150?img=51",
|
||||
"about": "Преподаватель литературы, люблю поэзию и классическую литературу.",
|
||||
"email": "natalya.kozlova@example.com",
|
||||
"interests": [
|
||||
"Литература и история",
|
||||
"Образование и наука"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"username": "Павел Новиков",
|
||||
"photo": "https://i.pravatar.cc/150?img=71",
|
||||
"about": "Спортсмен, занимаюсь бегом и триатлоном.",
|
||||
"email": "pavel.novikov@example.com",
|
||||
"interests": [
|
||||
"Спорт, фитнес и ЗОЖ",
|
||||
"Путешествия и туризм"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"username": "Екатерина Михайлова",
|
||||
"photo": "https://i.pravatar.cc/150?img=52",
|
||||
"about": "Архитектор, увлекаюсь современным дизайном и урбанистикой.",
|
||||
"email": "ekaterina.mikhailova@example.com",
|
||||
"interests": [
|
||||
"Искусство, фотография и дизайн",
|
||||
"Урбанистика"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"username": "Виктор Соколов",
|
||||
"photo": "https://i.pravatar.cc/150?img=72",
|
||||
"about": "Бизнес-консультант, помогаю компаниям развиваться.",
|
||||
"email": "viktor.sokolov@example.com",
|
||||
"interests": [
|
||||
"Бизнес и предпринимательство",
|
||||
"Политика, социология, активизм и дебаты"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"username": "Анна Павлова",
|
||||
"photo": "https://i.pravatar.cc/150?img=53",
|
||||
"about": "Художник, работаю в стиле абстракционизма.",
|
||||
"email": "anna.pavlova@example.com",
|
||||
"interests": [
|
||||
"Искусство, фотография и дизайн",
|
||||
"Кино и другое многомодальное искусство"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"username": "Денис Иванов",
|
||||
"photo": "https://i.pravatar.cc/150?img=73",
|
||||
"about": "Ученый, занимаюсь исследованиями в области биотехнологий.",
|
||||
"email": "denis.ivanov@example.com",
|
||||
"interests": [
|
||||
"Биология и биотехнологии",
|
||||
"Образование и наука"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"username": "Людмила Кузнецова",
|
||||
"photo": "https://i.pravatar.cc/150?img=54",
|
||||
"about": "Повар, специализируюсь на авторской кухне.",
|
||||
"email": "lyudmila.kuznetsova@example.com",
|
||||
"interests": [
|
||||
"Кулинария",
|
||||
"Путешествия и туризм"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"username": "Григорий Петров",
|
||||
"photo": "https://i.pravatar.cc/150?img=74",
|
||||
"about": "Музыкант, играю на гитаре и пишу песни.",
|
||||
"email": "grigoriy.petrov@example.com",
|
||||
"interests": [
|
||||
"Музыка",
|
||||
"Кино и другое многомодальное искусство"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"username": "Валентина Семенова",
|
||||
"photo": "https://i.pravatar.cc/150?img=55",
|
||||
"about": "Врач, специализируюсь на профилактической медицине.",
|
||||
"email": "valentina.semenova@example.com",
|
||||
"interests": [
|
||||
"Медицина и здоровье",
|
||||
"Спорт, фитнес и ЗОЖ"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1252744945,
|
||||
"username": "Моряков Сергей",
|
||||
"photo": "https://i.pravatar.cc/150?img=50",
|
||||
"about": "Люблю путешествия и фотографию, обожаю изучать новые культуры.",
|
||||
"email": "maria.smirnova@example.com",
|
||||
"interests": [
|
||||
"Путешествия и туризм",
|
||||
"Искусство, фотография и дизайн"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,48 +0,0 @@
|
||||
const router = require('express').Router();
|
||||
|
||||
module.exports = router;
|
||||
|
||||
const data = require('./data/users.json');
|
||||
|
||||
router.get('/', (req, res) => {
|
||||
res.json(data);
|
||||
});
|
||||
|
||||
router.get('/:pageSize/:page', (req, res) => {
|
||||
const pageSize = parseInt(req.params.pageSize);
|
||||
const page = parseInt(req.params.page);
|
||||
res.json(data.slice(pageSize * (page - 1), pageSize * page));
|
||||
});
|
||||
|
||||
router.get('/:id', (req, res) => {
|
||||
const userId = parseInt(req.params.id);
|
||||
res.json(data.find((item) => item.id === userId));
|
||||
});
|
||||
|
||||
router.post('/', (req, res) => {
|
||||
res.status(201).send();
|
||||
});
|
||||
|
||||
router.post('/:to_id/:action/:from_id', (req, res) => {
|
||||
const to_id = parseInt(req.params.to_id);
|
||||
const from_id = parseInt(req.params.from_id);
|
||||
const action = req.params.action;
|
||||
if (data.findIndex((item) => item.id === to_id) === -1 || data.findIndex((item) => item.id === from_id) === -1) {
|
||||
res.status(404).send();
|
||||
return;
|
||||
}
|
||||
if (action !== 'like' && action !== 'dislike') {
|
||||
res.status(400).send({ error: 'Invalid action' });
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(201).send({ message: `${action} action processed` });
|
||||
});
|
||||
|
||||
router.put('/:id', (req, res) => {
|
||||
res.status(204).send();
|
||||
});
|
||||
|
||||
router.delete('/:id', (req, res) => {
|
||||
res.status(204).send();
|
||||
});
|
||||
BIN
server/routers/old/bushou/images/60px-%E4%B8%80-bigseal.svg.png
Normal file
BIN
server/routers/old/bushou/images/60px-%E4%B8%80-bigseal.svg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 377 B |
BIN
server/routers/old/bushou/images/60px-%E4%B8%80-bronze.svg.png
Normal file
BIN
server/routers/old/bushou/images/60px-%E4%B8%80-bronze.svg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 470 B |
BIN
server/routers/old/bushou/images/60px-%E4%B8%80-clerical.svg.png
Normal file
BIN
server/routers/old/bushou/images/60px-%E4%B8%80-clerical.svg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 578 B |
BIN
server/routers/old/bushou/images/60px-%E4%B8%80-oracle.svg.png
Normal file
BIN
server/routers/old/bushou/images/60px-%E4%B8%80-oracle.svg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 481 B |
BIN
server/routers/old/bushou/images/60px-%E4%B8%80-seal.svg.png
Normal file
BIN
server/routers/old/bushou/images/60px-%E4%B8%80-seal.svg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 368 B |
BIN
server/routers/old/bushou/images/60px-%E4%B8%80-silk.svg.png
Normal file
BIN
server/routers/old/bushou/images/60px-%E4%B8%80-silk.svg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 593 B |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user