npx sequelize-cli migration:generate --name create-favorites-table
// src/database/migration/XXXXXXXXXXXXXX-create-favorites-table.js

'use strict';

module.exports = {
  async up (queryInterface, Sequelize) {
    await queryInterface.createTable('favorites', {
      user_id: {
        allowNull: false,
        type: Sequelize.DataTypes.INTEGER,
        references: { model: 'users', key: 'id' },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE'
      },
      course_id: {
        allowNull: false,
        type: Sequelize.DataTypes.INTEGER,
        references: { model: 'courses', key: 'id' },
        onUpdate: 'CASCADE',
        onDelete: 'CASCADE'
      },
      created_at: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updated_at: {
        allowNull: false,
        type: Sequelize.DATE
      }
    })
  },

  async down (queryInterface, Sequelize) {
    await queryInterface.dropTable('favorites')
  }
};
npx sequelize-cli db:migrate
// src/models/Favorite.ts

import { DataTypes, Model } from "sequelize"
import { sequelize } from "../database"
import { CourseInstance } from "./Course"
import { UserInstance } from "./User"

export interface Favorite {
  userId: number
  courseId: number
}

export interface FavoriteInstance extends Model<Favorite>, Favorite {
  Course?: CourseInstance
  User?: UserInstance
}

export const Favorite = sequelize.define<FavoriteInstance, Favorite>('Favorite', {
  userId: {
    allowNull: false,
    primaryKey: true,
    type: DataTypes.INTEGER,
    references: {
      model: 'users',
      key: 'id'
    },
    onUpdate: 'CASCADE',
    onDelete: 'CASCADE'
  },
  courseId: {
    allowNull: false,
    primaryKey: true,
    type: DataTypes.INTEGER,
    references: {
      model: 'courses',
      key: 'id'
    },
    onUpdate: 'CASCADE',
    onDelete: 'CASCADE'
  }
})
// src/models/index.ts

import { Category } from './Category'
import { Course } from './Course'
import { Episode } from './Episode'
import { Favorite } from './Favorite'
import { User } from './User'

Category.hasMany(Course)

Course.belongsTo(Category)
Course.hasMany(Episode)
Course.belongsToMany(User, { through: Favorite })
Course.hasMany(Favorite, { as: 'favoritesUsers', foreignKey: 'course_id' })

Episode.belongsTo(Course)

Favorite.belongsTo(Course)
Favorite.belongsTo(User)

User.belongsToMany(Course, { through: Favorite })
User.hasMany(Favorite, { as: 'favoritesCourses', foreignKey: 'user_id' })

export {
  Category,
  Course,
  Episode,
	Favorite,
  User
}
// src/services/favoriteService.ts

import { Favorite } from "../models/favorite"

export const favoriteService = {
	create: async (userId: number, courseId: number) => {
    const favorite = await Favorite.create({
      userId,
      courseId
    })

    return favorite
  },
}
// src/controllers/favoritesController.ts

import { Response } from 'express'
import { AuthenticatedRequest } from "../middlewares/auth";
import { favoriteService } from '../services/favoriteService'

export const favoritesController = {
 // POST /favorites
  save: async (req: AuthenticatedRequest, res: Response) => {
    const userId = req.user!.id
    const { courseId } = req.body

    try {
      const favorite = await favoriteService.create(userId, courseId)
      return res.status(201).json(favorite)
    } catch (err) {
      if (err instanceof Error) {
        return res.status(400).json({ message: err.message })
      }
    }
  }
}
// src/routes.ts

// ...

import { episodesController } from './controllers/episodesController'
import { favoritesController } from './controllers/favoritesController'

// ...

router.post('/favorites', ensureAuth, favoritesController.save)

export { router }