93 lines
2.4 KiB
JavaScript
93 lines
2.4 KiB
JavaScript
// src/models/user.model.js
|
|
// 사용자 모델
|
|
|
|
const { DataTypes } = require('sequelize');
|
|
const bcrypt = require('bcryptjs');
|
|
|
|
module.exports = (sequelize) => {
|
|
const User = sequelize.define('User', {
|
|
id: {
|
|
type: DataTypes.UUID,
|
|
defaultValue: DataTypes.UUIDV4,
|
|
primaryKey: true,
|
|
},
|
|
email: {
|
|
type: DataTypes.STRING(255),
|
|
allowNull: false,
|
|
unique: true,
|
|
validate: {
|
|
isEmail: true,
|
|
},
|
|
comment: '이메일 (로그인 ID)',
|
|
},
|
|
password: {
|
|
type: DataTypes.STRING(255),
|
|
allowNull: false,
|
|
comment: '비밀번호 (해시)',
|
|
},
|
|
name: {
|
|
type: DataTypes.STRING(100),
|
|
allowNull: false,
|
|
comment: '사용자 이름',
|
|
},
|
|
role: {
|
|
type: DataTypes.ENUM('user', 'admin'),
|
|
defaultValue: 'user',
|
|
comment: '역할 (user: 일반 사용자, admin: 관리자)',
|
|
},
|
|
status: {
|
|
type: DataTypes.ENUM('active', 'inactive', 'suspended'),
|
|
defaultValue: 'active',
|
|
comment: '계정 상태',
|
|
},
|
|
plan: {
|
|
type: DataTypes.ENUM('free', 'basic', 'pro', 'enterprise'),
|
|
defaultValue: 'free',
|
|
comment: '요금제 플랜',
|
|
},
|
|
monthlyTokenLimit: {
|
|
type: DataTypes.INTEGER,
|
|
defaultValue: 100000, // 무료 플랜 기본 10만 토큰
|
|
comment: '월간 토큰 한도',
|
|
},
|
|
lastLoginAt: {
|
|
type: DataTypes.DATE,
|
|
allowNull: true,
|
|
comment: '마지막 로그인 시간',
|
|
},
|
|
}, {
|
|
tableName: 'users',
|
|
timestamps: true,
|
|
underscored: true,
|
|
hooks: {
|
|
// 비밀번호 해싱
|
|
beforeCreate: async (user) => {
|
|
if (user.password) {
|
|
const salt = await bcrypt.genSalt(10);
|
|
user.password = await bcrypt.hash(user.password, salt);
|
|
}
|
|
},
|
|
beforeUpdate: async (user) => {
|
|
if (user.changed('password')) {
|
|
const salt = await bcrypt.genSalt(10);
|
|
user.password = await bcrypt.hash(user.password, salt);
|
|
}
|
|
},
|
|
},
|
|
});
|
|
|
|
// 인스턴스 메서드: 비밀번호 검증
|
|
User.prototype.validatePassword = async function(password) {
|
|
return bcrypt.compare(password, this.password);
|
|
};
|
|
|
|
// 인스턴스 메서드: 안전한 JSON 변환 (비밀번호 제외)
|
|
User.prototype.toSafeJSON = function() {
|
|
const values = { ...this.get() };
|
|
delete values.password;
|
|
return values;
|
|
};
|
|
|
|
return User;
|
|
};
|