diff --git a/backend/typescript/constants.ts b/backend/typescript/constants.ts new file mode 100644 index 0000000..ffc0146 --- /dev/null +++ b/backend/typescript/constants.ts @@ -0,0 +1,2 @@ +export const MIN_BEHAVIOUR_LEVEL = 1; +export const MAX_BEHAVIOUR_LEVEL = 4; diff --git a/backend/typescript/migrations/2024.10.22T19.38.07.create-behaviour-level-details-table.ts b/backend/typescript/migrations/2024.10.22T19.38.07.create-behaviour-level-details-table.ts index 59f3180..868e19f 100644 --- a/backend/typescript/migrations/2024.10.22T19.38.07.create-behaviour-level-details-table.ts +++ b/backend/typescript/migrations/2024.10.22T19.38.07.create-behaviour-level-details-table.ts @@ -23,10 +23,6 @@ export const up: Migration = async ({ context: sequelize }) => { }, level: { type: DataType.INTEGER, - validate: { - min: 1, - max: 4, - }, allowNull: false, }, description: { diff --git a/backend/typescript/migrations/2024.10.29T20.20.02.create-user-behaviour-table.ts b/backend/typescript/migrations/2024.10.29T20.20.02.create-user-behaviour-table.ts new file mode 100644 index 0000000..da04cc5 --- /dev/null +++ b/backend/typescript/migrations/2024.10.29T20.20.02.create-user-behaviour-table.ts @@ -0,0 +1,62 @@ +import { DataType } from "sequelize-typescript"; + +import { Migration } from "../umzug"; +import { MAX_BEHAVIOUR_LEVEL, MIN_BEHAVIOUR_LEVEL } from "../constants"; + +const TABLE_NAME = "user_behaviours"; +const CONSTRAINT_NAME = "unique_user_behaviour_skill"; +const CONSTRAINT_NAME_2 = "max_level_interval"; + +export const up: Migration = async ({ context: sequelize }) => { + await sequelize.getQueryInterface().createTable(TABLE_NAME, { + id: { + type: DataType.INTEGER, + allowNull: false, + primaryKey: true, + autoIncrement: true, + }, + user_id: { + type: DataType.INTEGER, + allowNull: false, + references: { + model: "users", + key: "id", + }, + }, + behaviour_id: { + type: DataType.INTEGER, + allowNull: false, + references: { + model: "behaviours", + key: "id", + }, + }, + max_level: { + type: DataType.INTEGER, + allowNull: false, + }, + }); + + await sequelize.getQueryInterface().addConstraint(TABLE_NAME, { + fields: ["behaviour_id", "user_id"], + type: "unique", + name: CONSTRAINT_NAME, + }); + + await sequelize.query( + `ALTER TABLE ${TABLE_NAME} ADD CONSTRAINT ${CONSTRAINT_NAME_2} + CHECK (max_level BETWEEN ${MIN_BEHAVIOUR_LEVEL} AND ${MAX_BEHAVIOUR_LEVEL});`, + ); +}; + +export const down: Migration = async ({ context: sequelize }) => { + await sequelize + .getQueryInterface() + .removeConstraint(TABLE_NAME, CONSTRAINT_NAME); + + await sequelize.query( + `ALTER TABLE ${TABLE_NAME} DROP CONSTRAINT ${CONSTRAINT_NAME_2};`, + ); + + await sequelize.getQueryInterface().dropTable(TABLE_NAME); +}; diff --git a/backend/typescript/migrations/2024.10.29T20.29.50.add-pet-behaviour-columns.ts b/backend/typescript/migrations/2024.10.29T20.29.50.add-pet-behaviour-columns.ts new file mode 100644 index 0000000..c8ec3bc --- /dev/null +++ b/backend/typescript/migrations/2024.10.29T20.29.50.add-pet-behaviour-columns.ts @@ -0,0 +1,40 @@ +import { DataType } from "sequelize-typescript"; +import { Migration } from "../umzug"; +import { MAX_BEHAVIOUR_LEVEL, MIN_BEHAVIOUR_LEVEL } from "../constants"; + +const TABLE_NAME = "pet_behaviours"; +const CONSTRAINT_NAME = "unique_pet_behaviour"; +const CONSTRAINT_NAME_2 = "skill_level_interval"; + +export const up: Migration = async ({ context: sequelize }) => { + await sequelize.getQueryInterface().addColumn(TABLE_NAME, "is_highlighted", { + type: DataType.BOOLEAN, + allowNull: true, + defaultValue: false, + }); + + await sequelize.getQueryInterface().addConstraint(TABLE_NAME, { + fields: ["behaviour_id", "pet_id"], + type: "unique", + name: CONSTRAINT_NAME, + }); + + await sequelize.query( + `ALTER TABLE ${TABLE_NAME} ADD CONSTRAINT ${CONSTRAINT_NAME_2} + CHECK (skill_level BETWEEN ${MIN_BEHAVIOUR_LEVEL} AND ${MAX_BEHAVIOUR_LEVEL});`, + ); +}; + +export const down: Migration = async ({ context: sequelize }) => { + await sequelize + .getQueryInterface() + .removeConstraint(TABLE_NAME, CONSTRAINT_NAME); + + await sequelize + .getQueryInterface() + .removeColumn(TABLE_NAME, "is_highlighted"); + + await sequelize.query( + `ALTER TABLE ${TABLE_NAME} DROP CONSTRAINT ${CONSTRAINT_NAME_2};`, + ); +}; diff --git a/backend/typescript/migrations/2024.11.21T16.49.50.add-constraint-behaviour-level-details-table.ts b/backend/typescript/migrations/2024.11.21T16.49.50.add-constraint-behaviour-level-details-table.ts new file mode 100644 index 0000000..b93ad21 --- /dev/null +++ b/backend/typescript/migrations/2024.11.21T16.49.50.add-constraint-behaviour-level-details-table.ts @@ -0,0 +1,19 @@ +import { DataType } from "sequelize-typescript"; +import { Migration } from "../umzug"; +import { MAX_BEHAVIOUR_LEVEL, MIN_BEHAVIOUR_LEVEL } from "../constants"; + +const TABLE_NAME = "behaviour_level_details"; +const CONSTRAINT_NAME = "level_interval"; + +export const up: Migration = async ({ context: sequelize }) => { + await sequelize.query( + `ALTER TABLE ${TABLE_NAME} ADD CONSTRAINT ${CONSTRAINT_NAME} + CHECK (level BETWEEN ${MIN_BEHAVIOUR_LEVEL} AND ${MAX_BEHAVIOUR_LEVEL});`, + ); +}; + +export const down: Migration = async ({ context: sequelize }) => { + await sequelize.query( + `ALTER TABLE ${TABLE_NAME} DROP CONSTRAINT ${CONSTRAINT_NAME};`, + ); +}; diff --git a/backend/typescript/models/petBehaviour.ts b/backend/typescript/models/petBehaviour.model.ts similarity index 65% rename from backend/typescript/models/petBehaviour.ts rename to backend/typescript/models/petBehaviour.model.ts index 524e0d3..04479d9 100644 --- a/backend/typescript/models/petBehaviour.ts +++ b/backend/typescript/models/petBehaviour.model.ts @@ -4,6 +4,7 @@ import { Table, ForeignKey, BelongsTo, + DataType, } from "sequelize-typescript"; import Behaviour from "./behaviour.model"; import Pet from "./pet.model"; @@ -11,19 +12,22 @@ import Pet from "./pet.model"; @Table({ timestamps: false, tableName: "pet_behaviours" }) export default class PetBehaviour extends Model { @ForeignKey(() => Pet) - @Column({}) + @Column({ type: DataType.INTEGER, allowNull: false }) pet_id!: number; @BelongsTo(() => Pet) pet!: Pet; @ForeignKey(() => Behaviour) - @Column({}) + @Column({ type: DataType.INTEGER, allowNull: false }) behaviour_id!: number; @BelongsTo(() => Behaviour) behaviour!: Behaviour; - @Column({}) + @Column({ type: DataType.INTEGER, allowNull: false }) skill_level!: number; + + @Column({ type: DataType.BOOLEAN, allowNull: true }) + is_highlighted!: boolean; } diff --git a/backend/typescript/models/userBehaviour.model.ts b/backend/typescript/models/userBehaviour.model.ts new file mode 100644 index 0000000..3198945 --- /dev/null +++ b/backend/typescript/models/userBehaviour.model.ts @@ -0,0 +1,30 @@ +import { + Column, + Model, + Table, + ForeignKey, + BelongsTo, + DataType, +} from "sequelize-typescript"; +import Behaviour from "./behaviour.model"; +import User from "./user.model"; + +@Table({ timestamps: false, tableName: "user_behaviours" }) +export default class UserBehaviour extends Model { + @ForeignKey(() => User) + @Column({ type: DataType.INTEGER, allowNull: false }) + user_id!: number; + + @BelongsTo(() => User) + user!: User; + + @ForeignKey(() => Behaviour) + @Column({ type: DataType.INTEGER, allowNull: false }) + behaviour_id!: number; + + @BelongsTo(() => Behaviour) + behaviour!: Behaviour; + + @Column({ type: DataType.INTEGER, allowNull: false }) + max_level!: number; +}