Option Purpose
paranoid: true Soft deletes — rows are not removed, deletedAt column is set
underscored: true Convert camelCase → snake_case in DB (firstName → first_name)
const { DataTypes } = require("sequelize");
const { sequelize } = require("../config/db");

const User = sequelize.define(
    "User",
    {
        id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true,
        },

        email: {
            type: DataTypes.STRING,
            allowNull: false,
            unique: true,
            validate: {
                isEmail: true,
            },
        },

        firstName: {
            type: DataTypes.STRING,
            allowNull: false,
        },

        lastName: {
            type: DataTypes.STRING,
            allowNull: false,
        },

        role: {
            type: DataTypes.ENUM("user", "admin", "moderator"),
            defaultValue: "user",
        },

        fullName: {
            type: DataTypes.VIRTUAL,
            get() {
                return `${this.firstName} ${this.lastName}`;
            },
        },
    },
    {
        tableName: "users", // Custom table name
        timestamps: true, // createdAt, updatedAt
        paranoid: true, // Soft deletes (deletedAt)
        underscored: true, // snake_case columns
    },
);

DataTypes

const { DataTypes } = require('sequelize');

const Product = sequelize.define('Product', {
  // String types
  name: DataTypes.STRING,           // VARCHAR(255)
  description: DataTypes.TEXT,      // TEXT
  sku: DataTypes.STRING(50),        // VARCHAR(50)
  
  // Number types
  price: DataTypes.DECIMAL(10, 2),  // DECIMAL
  quantity: DataTypes.INTEGER,       // INTEGER
  rating: DataTypes.FLOAT,          // FLOAT
  
  // Boolean
  isActive: DataTypes.BOOLEAN,
  
  // Date/Time
  releaseDate: DataTypes.DATE,      // DATETIME
  time: DataTypes.TIME,
  dateOnly: DataTypes.DATEONLY,
  
  // JSON
  metadata: DataTypes.JSON,
  
  // Arrays (PostgreSQL only)
  tags: DataTypes.ARRAY(DataTypes.STRING),
  
  // Enum
  status: DataTypes.ENUM('draft', 'published', 'archived'),
  
  // UUID
  uuid: {
    type: DataTypes.UUID,
    defaultValue: DataTypes.UUIDV4,
  },
});

Model Methods

// Instance method
User.prototype.checkPassword = async function (password) {
    return bcrypt.compare(password, this.password);
};

// Class method
User.findByEmail = async function (email) {
    return this.findOne({ where: { email } });
};

//Hooks
User.beforeCreate(async (user) => {
    user.password = await bcrypt.hash(user.password, 10);
});

//Usage
const user = await User.findByEmail("demo@example.com");
const isValid = await user.checkPassword("secret");

CRUD Operations

CREATE

// Create single record
const user = await User.create({
  email: 'john@example.com',
  name: 'John Doe',
});

// Bulk create
const users = await User.bulkCreate([
  { email: 'user1@example.com', name: 'User 1' },
  { email: 'user2@example.com', name: 'User 2' },
]);

// Create with specific fields only
const user = await User.create(
  { email: 'jane@example.com', name: 'Jane', role: 'admin' },
  { fields: ['email', 'name'] }  // Ignore 'role'
);