Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into S24/daniel/create-pas…
Browse files Browse the repository at this point in the history
…sword-frontend
  • Loading branch information
DanZfsd committed Nov 9, 2024
2 parents c0e0f09 + da373cc commit 610e173
Show file tree
Hide file tree
Showing 18 changed files with 427 additions and 90 deletions.
27 changes: 20 additions & 7 deletions backend/typescript/middlewares/validators/userValidators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ export const createUserDtoValidator = async (
if (!validatePrimitive(req.body.role, "string")) {
return res.status(400).send(getApiValidationError("role", "string"));
}
if (!validatePrimitive(req.body.password, "string")) {
return res.status(400).send(getApiValidationError("password", "string"));
}
if (
req.body.skillLevel !== undefined &&
req.body.skillLevel !== null &&
Expand Down Expand Up @@ -63,16 +60,32 @@ export const updateUserDtoValidator = async (
res: Response,
next: NextFunction,
) => {
if (!validatePrimitive(req.body.firstName, "string")) {
if (
req.body.firstName !== undefined &&
req.body.firstName !== null &&
!validatePrimitive(req.body.firstName, "string")
) {
return res.status(400).send(getApiValidationError("firstName", "string"));
}
if (!validatePrimitive(req.body.lastName, "string")) {
if (
req.body.lastName !== undefined &&
req.body.lastName !== null &&
!validatePrimitive(req.body.lastName, "string")
) {
return res.status(400).send(getApiValidationError("lastName", "string"));
}
if (!validatePrimitive(req.body.email, "string")) {
if (
req.body.email !== undefined &&
req.body.email !== null &&
!validatePrimitive(req.body.email, "string")
) {
return res.status(400).send(getApiValidationError("email", "string"));
}
if (!validatePrimitive(req.body.role, "string")) {
if (
req.body.role !== undefined &&
req.body.role !== null &&
!validatePrimitive(req.body.role, "string")
) {
return res.status(400).send(getApiValidationError("role", "string"));
}
if (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { DataType } from "sequelize-typescript";

import { Migration } from "../umzug";

const TABLE_NAME = "user_animal_types";

export const up: Migration = async ({ context: sequelize }) => {
await sequelize.getQueryInterface().createTable(TABLE_NAME, {
user_id: {
type: DataType.INTEGER,
allowNull: false,
primaryKey: true,
references: {
model: "users",
key: "id",
},
onUpdate: "CASCADE",
onDelete: "CASCADE",
},
animal_type_id: {
type: DataType.INTEGER,
allowNull: false,
primaryKey: true,
references: {
model: "animal_types",
key: "id",
},
onUpdate: "CASCADE",
onDelete: "CASCADE",
},
});
};

export const down: Migration = async ({ context: sequelize }) => {
await sequelize.getQueryInterface().dropTable(TABLE_NAME);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { DataType } from "sequelize-typescript";

import { Migration } from "../umzug";

const TABLE_NAME = "behaviour_level_details";
const CONSTRAINT_NAME = "unique_behaviour_level";

export const up: Migration = async ({ context: sequelize }) => {
await sequelize.getQueryInterface().createTable(TABLE_NAME, {
id: {
type: DataType.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true,
},
behaviour_id: {
type: DataType.INTEGER,
allowNull: false,
references: {
model: "behaviours",
key: "id",
},
},
level: {
type: DataType.INTEGER,
validate: {
min: 1,
max: 4,
},
allowNull: false,
},
description: {
type: DataType.STRING,
allowNull: true,
},
training_instructions: {
type: DataType.STRING,
allowNull: true,
},
});

await sequelize.getQueryInterface().addConstraint(TABLE_NAME, {
fields: ["behaviour_id", "level"],
type: "unique",
name: CONSTRAINT_NAME,
});
};

export const down: Migration = async ({ context: sequelize }) => {
await sequelize
.getQueryInterface()
.removeConstraint(TABLE_NAME, CONSTRAINT_NAME);

await sequelize.getQueryInterface().dropTable(TABLE_NAME);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { DataType } from "sequelize-typescript";
import { Migration } from "../umzug";

const TABLE_NAME = "behaviours";

export const up: Migration = async ({ context: sequelize }) => {
await sequelize
.getQueryInterface()
.addColumn(TABLE_NAME, "parent_behaviour_id", {
type: DataType.INTEGER,
allowNull: true,
references: {
model: "behaviours",
key: "id",
},
});
};

export const down: Migration = async ({ context: sequelize }) => {
await sequelize
.getQueryInterface()
.removeColumn(TABLE_NAME, "parent_behaviour_id");
};
14 changes: 12 additions & 2 deletions backend/typescript/models/behaviour.model.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import { Column, Model, Table } from "sequelize-typescript";
import {
Column,
DataType,
ForeignKey,
Model,
Table,
} from "sequelize-typescript";

@Table({ timestamps: false, tableName: "behaviours" })
export default class Behaviour extends Model {
@Column
@Column({ type: DataType.STRING, allowNull: false })
behaviour_name!: string;

@ForeignKey(() => Behaviour)
@Column({ type: DataType.INTEGER })
parent_behaviour_id?: number | null;
}
24 changes: 24 additions & 0 deletions backend/typescript/models/behaviourLevelDetails.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
Column,
Model,
Table,
ForeignKey,
DataType,
} from "sequelize-typescript";
import Behaviour from "./behaviour.model";

@Table({ timestamps: false, tableName: "behaviour_level_details" })
export default class BehaviourLevelDetails extends Model {
@ForeignKey(() => Behaviour)
@Column({ type: DataType.INTEGER, allowNull: false })
behaviour_id!: number;

@Column({ type: DataType.INTEGER, allowNull: false })
level!: number;

@Column({ type: DataType.STRING, allowNull: true })
description?: string;

@Column({ type: DataType.STRING, allowNull: true })
training_instructions?: string;
}
12 changes: 11 additions & 1 deletion backend/typescript/models/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import * as path from "path";
import { Sequelize } from "sequelize-typescript";
import User from "./user.model";
import AnimalType from "./animalType.model";
import UserAnimalType from "./userAnimalType.model";
import defineRelationships from "./modelRelationships";

const DATABASE_URL =
process.env.NODE_ENV === "production"
Expand All @@ -8,6 +12,12 @@ const DATABASE_URL =
: `postgres://${process.env.POSTGRES_USER}:${process.env.POSTGRES_PASSWORD}@${process.env.DB_HOST}:5432/${process.env.POSTGRES_DB_DEV}`;

/* eslint-disable-next-line import/prefer-default-export */
export const sequelize = new Sequelize(DATABASE_URL, {
const sequelize = new Sequelize(DATABASE_URL, {
models: [path.join(__dirname, "/*.model.ts")],
});

sequelize.addModels([User, AnimalType, UserAnimalType]);

defineRelationships();

export { sequelize, User, AnimalType, UserAnimalType };
7 changes: 7 additions & 0 deletions backend/typescript/models/modelRelationships.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import User from "./user.model";
import AnimalType from "./animalType.model";
import UserAnimalType from "./userAnimalType.model";

export default function defineRelationships(): void {
User.belongsToMany(AnimalType, { through: UserAnimalType });
}
26 changes: 26 additions & 0 deletions backend/typescript/models/userAnimalType.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
Column,
DataType,
Model,
Table,
ForeignKey,
PrimaryKey,
} from "sequelize-typescript";
import User from "./user.model";
import AnimalType from "./animalType.model";

@Table({
tableName: "User_AnimalTypes",
timestamps: true,
})
export default class UserAnimalType extends Model {
@ForeignKey(() => User)
@PrimaryKey
@Column({ type: DataType.INTEGER, allowNull: false })
user_id!: number;

@ForeignKey(() => AnimalType)
@PrimaryKey
@Column({ type: DataType.INTEGER, allowNull: false })
animal_type_id!: number;
}
4 changes: 1 addition & 3 deletions backend/typescript/rest/authRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import IAuthService from "../services/interfaces/authService";
import IEmailService from "../services/interfaces/emailService";
import IUserService from "../services/interfaces/userService";
import { getErrorMessage } from "../utilities/errorUtils";
import { Role, UserStatus } from "../types";
import { Role } from "../types";

const authRouter: Router = Router();
const userService: IUserService = new UserService();
Expand Down Expand Up @@ -53,12 +53,10 @@ authRouter.post("/register", registerRequestValidator, async (req, res) => {
lastName: req.body.lastName,
email: req.body.email,
role: req.body.role ?? Role.VOLUNTEER,
status: req.body.status ?? UserStatus.ACTIVE, // TODO: make this default to inactive once user registration flow is done
skillLevel: req.body.skillLevel ?? null,
canSeeAllLogs: req.body.canSeeAllLogs ?? null,
canAssignUsersToTasks: req.body.canAssignUsersToTasks ?? null,
phoneNumber: req.body.phoneNumber ?? null,
password: req.body.password,
});

const authDTO = await authService.generateToken(
Expand Down
Loading

0 comments on commit 610e173

Please sign in to comment.