/*********************************************************************************************************************************************************************** * File Name: users.mdl.js * Type of Program: Model * Description: Sequelize model for the `users` table. * Stores authentication credentials, account flags, registration type, * role/account type, and a flexible JSONB personal_info column. * Author: rgrgogu * Date Created: Oct. 6, 2025 *********************************************************************************************************************************************************************** * Change History: * DATE AUTHOR LOG DESCRIPTION * Oct. 6, 2025 rgrgogu 001 Initial creation - STAR Phase 1 ***********************************************************************************************************************************************************************/ const { DataTypes } = require('sequelize'); const sequelize = require('../../config/db.config'); const mdl_Users = sequelize.define('User', { user_id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true, label: "User ID", order: 1, hidden: true }, email: { type: DataTypes.STRING(255), allowNull: false, unique: true, label: "Email Address", validate: { isEmail: true }, order: 3 }, password: { type: DataTypes.TEXT, label: "Password" }, is_active: { type: DataTypes.BOOLEAN, defaultValue: true, label: "Active", order: 6 }, is_verified: { type: DataTypes.BOOLEAN, defaultValue: false, label: "Verified", order: 7 }, reg_type: { type: DataTypes.ENUM('google', 'system'), defaultValue: 'system', label: "Registration Type", order: 8 }, /** * acc_type drives RBAC: * - "user" → Client endpoints only * - "staff" → Client + Staff endpoints * - "admin" → All endpoints */ acc_type: { type: DataTypes.ENUM('admin', 'staff', 'user'), defaultValue: 'user', label: "Account Type", order: 9 }, needs_intro: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: true, label: "Needs Intro" }, /** * personal_info JSONB structure: * { * name: { given_name, middle_name, last_name, extension_name, full_name }, * occupation: string, * addresses: [{ street, city, state, zip, country, address_type, full_address }], * phone_number: [{ number, country_code, phone_type, full_number }], * date_of_birth: date, * avatar: { mime_type, name, size, url, uuid }, * album: [{ uuid, file_url, original_name, uploaded_at, order_index }] * } */ personal_info: { type: DataTypes.JSONB, defaultValue: null, label: "Personal Info", order: 2 }, // ── Password policy ───────────────────────────────────────────────────────── must_change_password: { type: DataTypes.BOOLEAN, defaultValue: false, allowNull: false, label: "Must Change Password" }, password_expires_at: { type: DataTypes.DATE, defaultValue: null, allowNull: true, label: "Password Expires At" }, // OTP fields (stored temporarily during verification flow) otp_code: { type: DataTypes.STRING(6), allowNull: true, label: "OTP Code" }, otp_expires_at: { type: DataTypes.DATE, allowNull: true, label: "OTP Expires At" }, // ── Audit trails ──────────────────────────────────────────────────────────── createdBy: { type: DataTypes.BIGINT, allowNull: true, label: "Created By" }, updatedBy: { type: DataTypes.BIGINT, allowNull: true, label: "Modified By" }, deletedBy: { type: DataTypes.BIGINT, allowNull: true, label: "Deleted By" }, }, { tableName: 'users', timestamps: true, paranoid: true, // enables soft delete — sets deleted_at instead of DELETE }); module.exports = mdl_Users;