ecliptica/server/routers/easy-project/db.js

411 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { v4: uuid } = require('uuid')
const ObjectId = require('mongodb').ObjectID
const { getDB } = require('../../utils/mongo')
const { _idToId, checkDB, _idToIdArray, filterId } = require('./utils')
let db = null
const USERS_COLL = 'ep_users'
const PROJECTS_COLL = 'ep_all_projects'
const PROJECT_TASKS_COLL = 'ep_projects_tasks'
const PROJECT_MEMBERS_COLL = 'ep_projects_members'
const PROJECT_STATUSES_COLL = 'ep_projects_statuses'
const PROJECT_TYPES_COLL = 'ep_projects_types'
const connect = async () => {
db = await getDB('easy-project')
if (db === null) throw new Error('Нет подключения к базе данных')
}
connect()
const hashPassword = (password, salt = uuid(), salt2 = uuid(), salt3 = uuid()) => ({
password: (password.split('').join(salt) + salt2 + password.split('').join(salt3)).split('-').reverse().join('-'),
salt,
salt2,
salt3,
})
const registrationUser = async ({ email, login, password, ...rest }) => {
checkDB(db)
const usersCollection = db.collection(USERS_COLL)
const userExist = await usersCollection.find({
$or: [{
login,
}, {
email,
}],
}).toArray()
if (userExist.length) {
if (userExist[0].login === login) {
throw new Error('Логин уже занят')
}
if (userExist[0].email === email) {
throw new Error('Email уже занят')
}
}
const { password: hash, salt, salt2, salt3 } = hashPassword(password)
const user = {
salt,
salt2,
salt3,
hash,
login,
email,
...rest,
}
const { insertedId } = await usersCollection.insertOne(user)
user.id = insertedId
}
const signInUser = async ({ email, password }) => {
checkDB(db)
const usersCollection = db.collection(USERS_COLL)
const [userCandidate] = await usersCollection.find({
email,
}).toArray()
if (!userCandidate) {
throw new Error('Email или пароль не корректный')
}
const { salt, salt2, salt3, hash, ...cleanUser } = userCandidate
const { password: hashFromDb } = hashPassword(password, salt, salt2, salt3)
if (hash !== hashFromDb) {
throw new Error('Email или пароль не корректный')
}
return cleanUser
}
const getMyProjects = async (userId) => {
checkDB(db)
const userFilterById = filterId(userId)
const projectCollection = db.collection(PROJECTS_COLL)
const usersCollection = db.collection(USERS_COLL)
let projectList = await projectCollection.find({
$or: [{
userId,
}, {
members: {
$in: [userId],
},
}],
}).toArray()
if (projectList) {
const [userAuthor] = await usersCollection.find(userFilterById).toArray()
for (let index = 0; index < projectList.length; index++) {
projectList[index].author = userAuthor
projectList[index] = _idToId(projectList[index])
}
return projectList
}
return []
}
const deleteProjectById = async (projectId) => {
checkDB(db)
const projectCollection = db.collection(PROJECTS_COLL)
const projectFilterById = filterId(projectId)
const deleted = await projectCollection.deleteOne(projectFilterById)
return deleted
}
const getMyProjectById = async (userId, projectId) => {
checkDB(db)
const projectCollection = db.collection(PROJECTS_COLL)
const usersCollection = db.collection(USERS_COLL)
const userFilterById = filterId(userId)
const [userAuthor] = await usersCollection.find(userFilterById).toArray()
const projectFilter = filterId(projectId)
let [projectMyExist] = await projectCollection.find(projectFilter).toArray()
const members = await usersCollection.find({
_id: {
$in: projectMyExist.members.map((memberId) => new ObjectId(memberId)),
},
}).toArray()
projectMyExist.members = members.map((m) => ({
value: m._id, label: m.email,
}))
projectMyExist.author = userAuthor
projectMyExist = _idToId(projectMyExist)
return projectMyExist
}
const newProject = async ({
title,
code,
userId,
members,
}) => {
checkDB(db)
if (!title || !code) {
throw new Error('Fields can\'t be empty')
}
const projectCollection = db.collection(PROJECTS_COLL)
const project = {
title,
code,
userId,
created: Date.now(),
changed: Date.now(),
changedBy: userId,
taskIndex: 0,
members,
}
await projectCollection.insertOne(project)
return _idToId(project)
}
const updateProject = async ({ projectId, title, code, members }) => {
checkDB(db)
if (!title || !code) {
throw new Error('Fields can\'t be empty')
}
const projectCollection = db.collection(PROJECTS_COLL)
const projectFilterById = filterId(projectId)
const updatedProject = await projectCollection.updateOne(projectFilterById, {
$set: {
title,
code,
changed: Date.now(),
members,
},
})
return updatedProject
}
// TODO: Совмещение projectId с userId ИЛИ поиск по memberIds
const getProjectById = async ({ projectId }) => {
checkDB(db)
const projectFilterById = filterId(projectId)
const projectCollection = db.collection(PROJECTS_COLL)
const [projectExist] = await projectCollection.find(projectFilterById).toArray()
return projectExist
}
const getTaskById = async ({ taskId, userId }) => {
checkDB(db)
if (taskId) {
const userFilterById = filterId(userId)
const taskFilterById = filterId(taskId)
const taskCollection = db.collection(PROJECT_TASKS_COLL)
const usersCollection = db.collection(USERS_COLL)
let [taskExist] = await taskCollection.find(taskFilterById).toArray()
if (taskExist) {
const [userAuthor] = await usersCollection.find(userFilterById).toArray()
taskExist.author = userAuthor
return _idToId(taskExist)
}
}
return {
}
}
const createTask = async ({ taskData, authorId, projectId }) => {
checkDB(db)
const projectCollection = db.collection(PROJECTS_COLL)
const projectFilterById = filterId(projectId)
const [projectExist] = await projectCollection.find(projectFilterById).toArray()
if (!projectExist) {
throw new Error('The project not exists [createTask]')
}
const nextIndex = projectExist.taskIndex + 1
const taskCollection = db.collection(PROJECT_TASKS_COLL)
const { type, status, ...taskRest } = taskData
const task = {
...taskRest,
type: Number(type),
status: Number(status),
changed: Date.now(),
created: Date.now(),
taskIndex: nextIndex,
authorId,
projectId,
}
await projectCollection.updateOne(projectFilterById, {
$set: {
taskIndex: nextIndex,
projectChanged: Date.now(),
},
})
await taskCollection.insertOne(task)
return _idToId(task)
}
const getTaskListByProjectId = async ({ projectId }) => {
checkDB(db)
const projectFilterById = filterId(projectId)
const projectCollection = db.collection(PROJECTS_COLL)
const [projectExist] = await projectCollection.find(projectId).toArray()
if (!projectExist) {
throw new Error('The project not exists [getTaskListByProjectId]')
}
const taskCollection = db.collection(PROJECT_TASKS_COLL)
let taskListCandidate = await taskCollection.find({
projectId,
}).toArray()
// if (taskListCandidate.length > 0) {
// for (let index = 0; index < taskListCandidate.length; index++) {
// // const [userAuthor] = await usersCollection.find(userFilterById).toArray()
// // taskListCandidate[index].author = userAuthor
// projectExist[index] = _idToId(projectExist[index])
// }
// }
taskListCandidate = _idToIdArray(taskListCandidate)
return taskListCandidate
}
const editTask = async ({ taskData, projectId, authorId, taskId }) => {
checkDB(db)
const taskCollection = db.collection(PROJECT_TASKS_COLL)
const projectCollection = db.collection(PROJECTS_COLL)
const taskFilterById = filterId(taskId)
const projectFilterById = filterId(projectId)
const { type, status, ...taskRest } = taskData
const updatedTask = await taskCollection.updateOne(taskFilterById, {
$set: {
type: Number(type),
status: Number(status),
...taskRest,
},
})
await projectCollection.updateOne(projectFilterById, {
$set: {
projectChanged: Date.now(),
},
})
return updatedTask
}
const deleteTaskById = async (taskId) => {
checkDB(db)
const taskCollection = db.collection(PROJECT_TASKS_COLL)
const taskFilterById = filterId(taskId)
const deleted = await taskCollection.deleteOne(taskFilterById)
return deleted
}
const getAllUsers = async () => {
checkDB(db)
const usersCollection = db.collection(USERS_COLL)
let allUsers = await usersCollection.find().toArray()
return _idToIdArray(allUsers)
}
// const getProjectMember = async () => {
// checkDB(db)
// const usersCollection = db.collection(USERS_COLL)
// let allUsers = await usersCollection.find().toArray()
// return _idToIdArray(allUsers)
// }
const updateProjectMembers = async (projectData, members) => {
checkDB(db)
const memberCollection = db.collection(PROJECT_MEMBERS_COLL)
await memberCollection.deleteMany({
projectId: projectData.id,
})
const membersAdd = []
for (let memberIndex = 0; memberIndex < members.length; memberIndex++) {
const member = {
projectId: projectData.id,
memberId: members[memberIndex].value,
}
membersAdd.push(member)
}
const { insertedData } = await memberCollection.insertMany(membersAdd)
return insertedData
}
module.exports = {
connect,
registrationUser,
signInUser,
getMyProjects,
deleteProjectById,
newProject,
createTask,
editTask,
deleteTaskById,
getTaskListByProjectId,
getProjectById,
getMyProjectById,
getTaskById,
updateProject,
getAllUsers,
updateProjectMembers,
}