first commit
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Niolla
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is proprietary and confidential.
|
||||
* Unauthorized copying, modification, distribution, or use
|
||||
* of this file, via any medium, is strictly prohibited.
|
||||
*/
|
||||
|
||||
// app/models/userActivities.model.js
|
||||
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const UserActivity = sequelize.define(
|
||||
"UserActivity",
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
},
|
||||
user_id: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
username: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
activity_description: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
activity_type: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
},
|
||||
module:{
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
},
|
||||
activity_time: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false,
|
||||
},
|
||||
activity_date:{
|
||||
type: DataTypes.DATEONLY,
|
||||
allowNull: false,
|
||||
}
|
||||
},
|
||||
{
|
||||
tableName: "UserActivity",
|
||||
timestamps: true,
|
||||
},
|
||||
);
|
||||
|
||||
return UserActivity;
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Niolla
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is proprietary and confidential.
|
||||
* Unauthorized copying, modification, distribution, or use
|
||||
* of this file, via any medium, is strictly prohibited.
|
||||
*/
|
||||
|
||||
// app/models/document/document.model.js
|
||||
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const document = sequelize.define(
|
||||
"Document",
|
||||
{
|
||||
doc_id:{
|
||||
type: DataTypes.STRING,
|
||||
primaryKey: true,
|
||||
},
|
||||
reference_no: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
doc_type: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
defaultValue: "N/A"
|
||||
},
|
||||
data: {
|
||||
type: DataTypes.JSON,
|
||||
allowNull: false,
|
||||
},
|
||||
status: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
defaultValue: "DRAFT",
|
||||
}
|
||||
},
|
||||
{
|
||||
tableName: "Document",
|
||||
timestamps: true,
|
||||
},
|
||||
);
|
||||
|
||||
return document;
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Niolla
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is proprietary and confidential.
|
||||
* Unauthorized copying, modification, distribution, or use
|
||||
* of this file, via any medium, is strictly prohibited.
|
||||
*/
|
||||
|
||||
// app/models/document/documentType.model.js
|
||||
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const documentType = sequelize.define(
|
||||
"DocumentType",
|
||||
{
|
||||
id:{
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
},
|
||||
doc_type_name: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
defaultValue: "N/A"
|
||||
},
|
||||
description: {
|
||||
type: DataTypes.JSON,
|
||||
allowNull: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
tableName: "DocumentType",
|
||||
timestamps: true,
|
||||
},
|
||||
);
|
||||
|
||||
return documentType;
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Niolla
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is proprietary and confidential.
|
||||
* Unauthorized copying, modification, distribution, or use
|
||||
* of this file, via any medium, is strictly prohibited.
|
||||
*/
|
||||
|
||||
// app/models/index.js
|
||||
|
||||
|
||||
const { Sequelize, DataTypes } = require("sequelize");
|
||||
const dbConfig = require("../config/db.config");
|
||||
|
||||
let loggingOption = false;
|
||||
|
||||
if(process.env.NODE_ENV === 'production') {
|
||||
loggingOption = true;
|
||||
}
|
||||
|
||||
const sequelize = new Sequelize(
|
||||
dbConfig.DB,
|
||||
dbConfig.USER,
|
||||
dbConfig.PASSWORD,
|
||||
{
|
||||
host: dbConfig.HOST,
|
||||
port: dbConfig.PORT,
|
||||
dialect: dbConfig.DIALECT,
|
||||
pool: dbConfig.pool,
|
||||
logging: loggingOption
|
||||
}
|
||||
);
|
||||
|
||||
const db = {};
|
||||
|
||||
db.Sequelize = Sequelize;
|
||||
db.sequelize = sequelize;
|
||||
|
||||
/* Register db models */
|
||||
|
||||
// User and Authentication
|
||||
db.User = require("./user/user.model")(sequelize, DataTypes);
|
||||
db.UserActivity = require("./activities/userActivities.model")(sequelize, DataTypes);
|
||||
db.Profile = require("./user/profile.model")(sequelize, DataTypes);
|
||||
|
||||
// Uploads
|
||||
db.Upload = require("./upload/upload.model")(sequelize, DataTypes);
|
||||
|
||||
// Roles and Permissions
|
||||
db.roles = require("./permission/role.model")(sequelize, DataTypes);
|
||||
db.permission = require("./permission/permission.model")(sequelize, DataTypes);
|
||||
db.rolePermission = require("./permission/rolePermission.model")(sequelize, DataTypes);
|
||||
db.userPermission = require("./permission/userPermission.model")(sequelize, DataTypes);
|
||||
|
||||
// Document Management
|
||||
db.Document = require("./document/document.model")(sequelize, DataTypes);
|
||||
db.DocumentType = require("./document/documentType.model")(sequelize, DataTypes);
|
||||
|
||||
// Reference Numbers
|
||||
db.referenceNumber = require("./referenceNumbers/referenceNumber.model")(sequelize, DataTypes);
|
||||
|
||||
// Notifications
|
||||
db.notification = require("./notification/notification.model")(sequelize, DataTypes);
|
||||
db.userNotification = require("./notification/userNotification.model")(sequelize, DataTypes);
|
||||
|
||||
/* Associations */
|
||||
Object.keys(db).forEach(model => {
|
||||
if (db[model].associate) {
|
||||
db[model].associate(db);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
module.exports = db;
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Niolla
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is proprietary and confidential.
|
||||
* Unauthorized copying, modification, distribution, or use
|
||||
* of this file, via any medium, is strictly prohibited.
|
||||
*/
|
||||
|
||||
// app/models/notification/notification.model.js
|
||||
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const notification = sequelize.define(
|
||||
"notification",
|
||||
{
|
||||
notification_id: {
|
||||
type: DataTypes.STRING,
|
||||
primaryKey: true,
|
||||
},
|
||||
notificationHeadline: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
notificationDescription: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: true,
|
||||
},
|
||||
notificationType: {
|
||||
type: DataTypes.ENUM("USER", "ANNOUNCEMENT"),
|
||||
allowNull: false,
|
||||
},
|
||||
isActive: {
|
||||
type: DataTypes.BOOLEAN,
|
||||
defaultValue: true,
|
||||
},
|
||||
dateCreated: {
|
||||
type: DataTypes.DATE,
|
||||
defaultValue: DataTypes.NOW,
|
||||
},
|
||||
},
|
||||
{
|
||||
tableName: "notification",
|
||||
timestamps: true,
|
||||
},
|
||||
);
|
||||
|
||||
notification.associate = (models) => {
|
||||
notification.hasMany(models.userNotification, {
|
||||
foreignKey: "notification_id",
|
||||
as: "users",
|
||||
});
|
||||
};
|
||||
|
||||
return notification;
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Niolla
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is proprietary and confidential.
|
||||
* Unauthorized copying, modification, distribution, or use
|
||||
* of this file, via any medium, is strictly prohibited.
|
||||
*/
|
||||
|
||||
// app/models/notification/userNotification.model.js
|
||||
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const userNotification = sequelize.define(
|
||||
"userNotification",
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
},
|
||||
user_id: {
|
||||
type: DataTypes.STRING(255),
|
||||
allowNull: false,
|
||||
collate: "utf8mb4_general_ci",
|
||||
},
|
||||
notification_id: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
isRead: {
|
||||
type: DataTypes.BOOLEAN,
|
||||
defaultValue: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
tableName: "user_notification",
|
||||
timestamps: true,
|
||||
},
|
||||
);
|
||||
|
||||
userNotification.associate = (models) => {
|
||||
userNotification.belongsTo(models.User, {
|
||||
foreignKey: "user_id",
|
||||
constraints: false,
|
||||
});
|
||||
|
||||
userNotification.belongsTo(models.notification, {
|
||||
foreignKey: "notification_id",
|
||||
constraints: false,
|
||||
});
|
||||
};
|
||||
|
||||
return userNotification;
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Niolla
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is proprietary and confidential.
|
||||
* Unauthorized copying, modification, distribution, or use
|
||||
* of this file, via any medium, is strictly prohibited.
|
||||
*/
|
||||
|
||||
// app/models/permission/permission.model.js
|
||||
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const permission = sequelize.define(
|
||||
"permission",
|
||||
{
|
||||
permission_id: {
|
||||
type: DataTypes.STRING,
|
||||
primaryKey: true,
|
||||
},
|
||||
permissionName: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
permissionDescription: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: true,
|
||||
},
|
||||
page:{
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
module:{
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
action: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
}
|
||||
},
|
||||
{
|
||||
tableName: "permission",
|
||||
timestamps: true,
|
||||
},
|
||||
);
|
||||
|
||||
permission.associate = (db) => {
|
||||
permission.hasMany(db.userPermission, {
|
||||
foreignKey: "permission_id",
|
||||
as: "userPermissions"
|
||||
});
|
||||
permission.hasMany(db.rolePermission, {
|
||||
foreignKey: "permission_id",
|
||||
as: "rolePermissions"
|
||||
});
|
||||
};
|
||||
|
||||
return permission;
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Niolla
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is proprietary and confidential.
|
||||
* Unauthorized copying, modification, distribution, or use
|
||||
* of this file, via any medium, is strictly prohibited.
|
||||
*/
|
||||
|
||||
// app/models/permission/role.model.js
|
||||
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const roles = sequelize.define(
|
||||
"roles",
|
||||
{
|
||||
role_id: {
|
||||
type: DataTypes.STRING,
|
||||
primaryKey: true
|
||||
},
|
||||
roleName: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
roleDescription: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: true
|
||||
}
|
||||
},
|
||||
{
|
||||
tableName: "roles",
|
||||
timestamps: true
|
||||
}
|
||||
);
|
||||
|
||||
roles.associate = (db) => {
|
||||
roles.hasMany(db.rolePermission, {
|
||||
foreignKey: "role_id",
|
||||
as: "rolePermissions"
|
||||
});
|
||||
};
|
||||
|
||||
return roles;
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Niolla
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is proprietary and confidential.
|
||||
* Unauthorized copying, modification, distribution, or use
|
||||
* of this file, via any medium, is strictly prohibited.
|
||||
*/
|
||||
|
||||
// app/models/permission/rolePermission.model.js
|
||||
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const rolePermission = sequelize.define(
|
||||
"rolePermission",
|
||||
{
|
||||
rp_id: {
|
||||
type: DataTypes.STRING,
|
||||
primaryKey: true
|
||||
},
|
||||
role_id: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
permission_id: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
}
|
||||
},
|
||||
{
|
||||
tableName: "rolePermission",
|
||||
timestamps: true
|
||||
}
|
||||
);
|
||||
|
||||
rolePermission.associate = (db) => {
|
||||
rolePermission.belongsTo(db.roles, {
|
||||
foreignKey: "role_id",
|
||||
as: "role"
|
||||
});
|
||||
rolePermission.belongsTo(db.permission, {
|
||||
foreignKey: "permission_id",
|
||||
as: "permission"
|
||||
});
|
||||
};
|
||||
|
||||
return rolePermission;
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Niolla
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is proprietary and confidential.
|
||||
* Unauthorized copying, modification, distribution, or use
|
||||
* of this file, via any medium, is strictly prohibited.
|
||||
*/
|
||||
|
||||
// app/models/permission/userPermission.model.js
|
||||
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const userPermission = sequelize.define(
|
||||
"userPermission",
|
||||
{
|
||||
up_id: {
|
||||
type: DataTypes.INTEGER,
|
||||
primaryKey: true,
|
||||
autoIncrement: true
|
||||
},
|
||||
user_id: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
permission_id: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
}
|
||||
},
|
||||
{
|
||||
tableName: "userPermission",
|
||||
timestamps: true
|
||||
}
|
||||
);
|
||||
|
||||
userPermission.associate = (db) => {
|
||||
userPermission.belongsTo(db.permission, {
|
||||
foreignKey: "permission_id",
|
||||
as: "permission"
|
||||
});
|
||||
userPermission.belongsTo(db.User, {
|
||||
foreignKey: "user_id",
|
||||
as: "user"
|
||||
});
|
||||
};
|
||||
|
||||
return userPermission;
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Niolla
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is proprietary and confidential.
|
||||
* Unauthorized copying, modification, distribution, or use
|
||||
* of this file, via any medium, is strictly prohibited.
|
||||
*/
|
||||
|
||||
// app/models/referenceNumbers/referenceNumber.model.js
|
||||
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const ReferenceNumber = sequelize.define(
|
||||
"ReferenceNumber",
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.STRING,
|
||||
primaryKey: true,
|
||||
},
|
||||
|
||||
// Unique sequence scope
|
||||
sequence_key: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
},
|
||||
|
||||
current_number: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 0,
|
||||
},
|
||||
|
||||
last_ref_number: {
|
||||
type: DataTypes.STRING,
|
||||
},
|
||||
},
|
||||
{
|
||||
tableName: "referenceNumbers",
|
||||
timestamps: true,
|
||||
}
|
||||
);
|
||||
|
||||
return ReferenceNumber;
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* © 2026 Niolla. All rights reserved.
|
||||
*
|
||||
* This file is part of the Niolla software project and is intended for internal use only.
|
||||
* Unauthorized copying, modification, distribution, or disclosure of this file,
|
||||
* via any medium, is strictly prohibited without written permission from Niolla.
|
||||
*
|
||||
* For inquiries, contact: support@niolla.lk
|
||||
*/
|
||||
|
||||
// app/models/upload.model.js
|
||||
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const upload = sequelize.define(
|
||||
"upload",
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
},
|
||||
file_path: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
file_type: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
file_size: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
original_name: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
use_for: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
uploaded_by: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
tableName: "uploads",
|
||||
timestamps: true,
|
||||
},
|
||||
);
|
||||
|
||||
return upload;
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Niolla
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is proprietary and confidential.
|
||||
* Unauthorized copying, modification, distribution, or use
|
||||
* of this file, via any medium, is strictly prohibited.
|
||||
*/
|
||||
|
||||
// app/models/profile.model.js
|
||||
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const Profile = sequelize.define(
|
||||
"Profile",
|
||||
{
|
||||
profile_id: {
|
||||
type: DataTypes.STRING,
|
||||
primaryKey: true,
|
||||
},
|
||||
user_id: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
collate: 'utf8mb4_general_ci'
|
||||
},
|
||||
theme: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
defaultValue: "light",
|
||||
},
|
||||
notificationsEnabled: {
|
||||
type: DataTypes.BOOLEAN,
|
||||
defaultValue: true,
|
||||
},
|
||||
profilePicture_id: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
},
|
||||
backgroundImage_id: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
},
|
||||
dob: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
},
|
||||
phone_number:{
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
}
|
||||
},
|
||||
{
|
||||
tableName: "profiles",
|
||||
timestamps: true,
|
||||
},
|
||||
);
|
||||
|
||||
Profile.associate = (db) => {
|
||||
Profile.belongsTo(db.User, {
|
||||
foreignKey: "user_id",
|
||||
as: "user",
|
||||
});
|
||||
};
|
||||
|
||||
return Profile;
|
||||
};
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Niolla
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is proprietary and confidential.
|
||||
* Unauthorized copying, modification, distribution, or use
|
||||
* of this file, via any medium, is strictly prohibited.
|
||||
*/
|
||||
|
||||
// app/models/User.model.js
|
||||
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const User = sequelize.define(
|
||||
"User",
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.STRING,
|
||||
primaryKey: true,
|
||||
collate: 'utf8mb4_general_ci'
|
||||
},
|
||||
firstName: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
lastName: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
email: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
unique: true
|
||||
},
|
||||
password: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
accountType: {
|
||||
type: DataTypes.ENUM("admin", "management", "team_head", "user"),
|
||||
defaultValue: "user"
|
||||
},
|
||||
role: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
roleID:{
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
department: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true
|
||||
}
|
||||
},
|
||||
{
|
||||
tableName: "users",
|
||||
timestamps: true
|
||||
}
|
||||
);
|
||||
|
||||
User.associate = (db) => {
|
||||
User.hasMany(db.userPermission, {
|
||||
foreignKey: "user_id",
|
||||
as: "userPermissions"
|
||||
});
|
||||
User.hasOne(db.Profile, {
|
||||
foreignKey: "user_id",
|
||||
as: "profile",
|
||||
});
|
||||
};
|
||||
|
||||
return User;
|
||||
};
|
||||
Reference in New Issue
Block a user