// models/Asset.js const { DataTypes } = require("sequelize"); const sequelize = require("../../config/db.config"); const Asset = sequelize.define("Asset", { // ─── Identity ───────────────────────────────────────────────────────────── asset_id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true }, uuid: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, allowNull: false, unique: true }, // ─── File info ──────────────────────────────────────────────────────────── original_name: { type: DataTypes.STRING(255), allowNull: false }, display_name: { type: DataTypes.STRING(255), allowNull: false }, file_url: { type: DataTypes.STRING(512), allowNull: false }, file_size: { type: DataTypes.BIGINT, allowNull: false }, mime_type: { type: DataTypes.STRING(100), allowNull: false }, extension: { type: DataTypes.STRING(20) }, checksum: { type: DataTypes.STRING(64) }, // ─── Classification ─────────────────────────────────────────────────────── file_type: { type: DataTypes.ENUM("image", "video", "document", "other"), allowNull: false, defaultValue: "other", }, // ─── Image & video dimensions ───────────────────────────────────────────── width: { type: DataTypes.INTEGER }, height: { type: DataTypes.INTEGER }, // ─── Video-specific ─────────────────────────────────────────────────────── duration: { type: DataTypes.FLOAT }, // seconds resolution: { type: DataTypes.STRING(20) }, // "1080p", "720p", "4K" frame_rate: { type: DataTypes.FLOAT }, // fps bitrate: { type: DataTypes.BIGINT }, // bps video_codec: { type: DataTypes.STRING(50) }, // "H.264", "H.265" audio_codec: { type: DataTypes.STRING(50) }, // "AAC", "MP3" thumbnail_url: { type: DataTypes.STRING(512) }, // face of the video / doc preview // ─── Description ────────────────────────────────────────────────────────── description: { type: DataTypes.TEXT }, // ─── Storage ────────────────────────────────────────────────────────────── storage_provider: { type: DataTypes.ENUM("local", "s3", "gcs", "cloudinary", "chibisafe", "other"), defaultValue: "local", }, storage_bucket: { type: DataTypes.STRING(255) }, storage_key: { type: DataTypes.STRING(512) }, // ─── Access control ─────────────────────────────────────────────────────── is_public: { type: DataTypes.BOOLEAN, defaultValue: false, }, access_level: { type: DataTypes.ENUM("public", "private", "restricted"), defaultValue: "private", }, // ─── Polymorphic ownership ──────────────────────────────────────────────── owner_type: { type: DataTypes.STRING(100) }, // e.g. "Course", "Channel", "Post", "User" owner_id: { type: DataTypes.BIGINT }, // ─── Who did what ───────────────────────────────────────────────────────── uploadedBy: { type: DataTypes.BIGINT, allowNull: false }, deletedBy: { type: DataTypes.BIGINT, allowNull: true }, // ─── Soft delete ────────────────────────────────────────────────────────── deletedAt: { type: DataTypes.DATE, allowNull: true, defaultValue: null }, }, { tableName: "assets", timestamps: true, // createdAt, updatedAt paranoid: false, indexes: [ { fields: ["uuid"] }, { fields: ["owner_type", "owner_id"] }, { fields: ["uploadedBy"] }, { fields: ["file_type"] }, { fields: ["deletedAt"] }, ], }); module.exports = Asset;