feat: added user association to queues

This commit is contained in:
canove
2021-01-08 20:18:11 -03:00
parent 9f99245dc4
commit 3c6d0660d1
15 changed files with 145 additions and 41 deletions

View File

@@ -1,6 +1,6 @@
export default {
secret: process.env.JWT_SECRET || "mysecret",
expiresIn: "15m",
expiresIn: "15d",
refreshSecret: process.env.JWT_REFRESH_SECRET || "myanothersecret",
refreshExpiresIn: "7d"
};

View File

@@ -27,7 +27,7 @@ export const index = async (req: Request, res: Response): Promise<Response> => {
};
export const store = async (req: Request, res: Response): Promise<Response> => {
const { email, password, name, profile } = req.body;
const { email, password, name, profile, queueIds } = req.body;
if (
req.url === "/signup" &&
@@ -42,7 +42,8 @@ export const store = async (req: Request, res: Response): Promise<Response> => {
email,
password,
name,
profile
profile,
queueIds
});
const io = getIO();

View File

@@ -8,6 +8,7 @@ import ContactCustomField from "../models/ContactCustomField";
import Message from "../models/Message";
import Queue from "../models/Queue";
import WhatsappQueue from "../models/WhatsappQueue";
import UserQueue from "../models/UserQueue";
// eslint-disable-next-line
const dbConfig = require("../config/database");
@@ -24,7 +25,8 @@ const models = [
ContactCustomField,
Setting,
Queue,
WhatsappQueue
WhatsappQueue,
UserQueue
];
sequelize.addModels(models);

View File

@@ -0,0 +1,28 @@
import { QueryInterface, DataTypes } from "sequelize";
module.exports = {
up: (queryInterface: QueryInterface) => {
return queryInterface.createTable("UserQueues", {
userId: {
type: DataTypes.INTEGER,
primaryKey: true
},
queueId: {
type: DataTypes.INTEGER,
primaryKey: true
},
createdAt: {
type: DataTypes.DATE,
allowNull: false
},
updatedAt: {
type: DataTypes.DATE,
allowNull: false
}
});
},
down: (queryInterface: QueryInterface) => {
return queryInterface.dropTable("UserQueues");
}
};

View File

@@ -10,6 +10,8 @@ import {
Unique,
BelongsToMany
} from "sequelize-typescript";
import User from "./User";
import UserQueue from "./UserQueue";
import Whatsapp from "./Whatsapp";
import WhatsappQueue from "./WhatsappQueue";
@@ -39,6 +41,9 @@ class Queue extends Model<Queue> {
@BelongsToMany(() => Whatsapp, () => WhatsappQueue)
whatsapps: Array<Whatsapp & { WhatsappQueue: WhatsappQueue }>;
@BelongsToMany(() => User, () => UserQueue)
users: Array<User & { UserQueue: UserQueue }>;
}
export default Queue;

View File

@@ -14,6 +14,7 @@ import {
import Contact from "./Contact";
import Message from "./Message";
import Queue from "./Queue";
import User from "./User";
import Whatsapp from "./Whatsapp";
@@ -64,6 +65,13 @@ class Ticket extends Model<Ticket> {
@BelongsTo(() => Whatsapp)
whatsapp: Whatsapp;
@ForeignKey(() => Queue)
@Column
queueId: number;
@BelongsTo(() => Queue)
queue: Queue;
@HasMany(() => Message)
messages: Message[];
}

View File

@@ -10,10 +10,13 @@ import {
PrimaryKey,
AutoIncrement,
Default,
HasMany
HasMany,
BelongsToMany
} from "sequelize-typescript";
import { hash, compare } from "bcryptjs";
import Ticket from "./Ticket";
import Queue from "./Queue";
import UserQueue from "./UserQueue";
@Table
class User extends Model<User> {
@@ -51,6 +54,9 @@ class User extends Model<User> {
@HasMany(() => Ticket)
tickets: Ticket[];
@BelongsToMany(() => Queue, () => UserQueue)
queues: Queue[];
@BeforeUpdate
@BeforeCreate
static hashPassword = async (instance: User): Promise<void> => {

View File

@@ -0,0 +1,29 @@
import {
Table,
Column,
CreatedAt,
UpdatedAt,
Model,
ForeignKey
} from "sequelize-typescript";
import Queue from "./Queue";
import User from "./User";
@Table
class UserQueue extends Model<UserQueue> {
@ForeignKey(() => User)
@Column
userId: number;
@ForeignKey(() => Queue)
@Column
queueId: number;
@CreatedAt
createdAt: Date;
@UpdatedAt
updatedAt: Date;
}
export default UserQueue;

View File

@@ -7,6 +7,7 @@ interface Request {
email: string;
password: string;
name: string;
queueIds?: number[];
profile?: string;
}
@@ -21,6 +22,7 @@ const CreateUserService = async ({
email,
password,
name,
queueIds = [],
profile = "admin"
}: Request): Promise<Response> => {
const schema = Yup.object().shape({
@@ -47,18 +49,26 @@ const CreateUserService = async ({
throw new AppError(err.message);
}
const user = await User.create({
email,
password,
name,
profile
});
const user = await User.create(
{
email,
password,
name,
profile
},
{ include: ["queues"] }
);
await user.$set("queues", queueIds);
await user.reload();
const serializedUser = {
id: user.id,
name: user.name,
email: user.email,
profile: user.profile
profile: user.profile,
queues: user.queues
};
return serializedUser;

View File

@@ -1,4 +1,5 @@
import { Sequelize, Op } from "sequelize";
import Queue from "../../models/Queue";
import User from "../../models/User";
interface Request {
@@ -19,8 +20,8 @@ const ListUsersService = async ({
const whereCondition = {
[Op.or]: [
{
name: Sequelize.where(
Sequelize.fn("LOWER", Sequelize.col("name")),
"$User.name$": Sequelize.where(
Sequelize.fn("LOWER", Sequelize.col("User.name")),
"LIKE",
`%${searchParam.toLowerCase()}%`
)
@@ -33,10 +34,13 @@ const ListUsersService = async ({
const { count, rows: users } = await User.findAndCountAll({
where: whereCondition,
attributes: ["name", "id", "email", "profile"],
attributes: ["name", "id", "email", "profile", "createdAt"],
limit,
offset,
order: [["createdAt", "DESC"]]
order: [["createdAt", "DESC"]],
include: [
{ model: Queue, as: "queues", attributes: ["id", "name", "color"] }
]
});
const hasMore = count > offset + users.length;

View File

@@ -1,9 +1,13 @@
import User from "../../models/User";
import AppError from "../../errors/AppError";
import Queue from "../../models/Queue";
const ShowUserService = async (id: string | number): Promise<User> => {
const user = await User.findByPk(id, {
attributes: ["name", "id", "email", "profile", "tokenVersion"]
attributes: ["name", "id", "email", "profile", "tokenVersion"],
include: [
{ model: Queue, as: "queues", attributes: ["id", "name", "color"] }
]
});
if (!user) {

View File

@@ -1,13 +1,14 @@
import * as Yup from "yup";
import AppError from "../../errors/AppError";
import User from "../../models/User";
import ShowUserService from "./ShowUserService";
interface UserData {
email?: string;
password?: string;
name?: string;
profile?: string;
queueIds?: number[];
}
interface Request {
@@ -26,14 +27,7 @@ const UpdateUserService = async ({
userData,
userId
}: Request): Promise<Response | undefined> => {
const user = await User.findOne({
where: { id: userId },
attributes: ["name", "id", "email", "profile"]
});
if (!user) {
throw new AppError("ERR_NO_USER_FOUND", 404);
}
const user = await ShowUserService(userId);
const schema = Yup.object().shape({
name: Yup.string().min(2),
@@ -42,7 +36,7 @@ const UpdateUserService = async ({
password: Yup.string()
});
const { email, password, profile, name } = userData;
const { email, password, profile, name, queueIds = [] } = userData;
try {
await schema.validate({ email, password, profile, name });
@@ -57,11 +51,16 @@ const UpdateUserService = async ({
name
});
await user.$set("queues", queueIds);
await user.reload();
const serializedUser = {
id: user.id,
name: user.name,
email: user.email,
profile: user.profile
profile: user.profile,
queues: user.queues
};
return serializedUser;

View File

@@ -18,7 +18,7 @@ interface Response {
const CreateWhatsAppService = async ({
name,
status = "OPENING",
queueIds,
queueIds = [],
isDefault = false
}: Request): Promise<Response> => {
const schema = Yup.object().shape({
@@ -64,14 +64,19 @@ const CreateWhatsAppService = async ({
}
}
const whatsapp = await Whatsapp.create({
name,
status,
isDefault
});
const whatsapp = await Whatsapp.create(
{
name,
status,
isDefault
},
{ include: ["queues"] }
);
await whatsapp.$set("queues", queueIds);
await whatsapp.reload();
return { whatsapp, oldDefaultWhatsapp };
};

View File

@@ -1,8 +1,13 @@
import Whatsapp from "../../models/Whatsapp";
import AppError from "../../errors/AppError";
import Queue from "../../models/Queue";
const ShowWhatsAppService = async (id: string | number): Promise<Whatsapp> => {
const whatsapp = await Whatsapp.findByPk(id);
const whatsapp = await Whatsapp.findByPk(id, {
include: [
{ model: Queue, as: "queues", attributes: ["id", "name", "color"] }
]
});
if (!whatsapp) {
throw new AppError("ERR_NO_WAPP_FOUND", 404);

View File

@@ -3,6 +3,7 @@ import { Op } from "sequelize";
import AppError from "../../errors/AppError";
import Whatsapp from "../../models/Whatsapp";
import ShowWhatsAppService from "./ShowWhatsAppService";
interface WhatsappData {
name?: string;
@@ -50,13 +51,8 @@ const UpdateWhatsAppService = async ({
}
}
const whatsapp = await Whatsapp.findOne({
where: { id: whatsappId }
});
const whatsapp = await ShowWhatsAppService(whatsappId);
if (!whatsapp) {
throw new AppError("ERR_NO_WAPP_FOUND", 404);
}
await whatsapp.update({
name,
status,
@@ -66,6 +62,8 @@ const UpdateWhatsAppService = async ({
await whatsapp.$set("queues", queueIds);
await whatsapp.reload();
return { whatsapp, oldDefaultWhatsapp };
};