chore: add crude for admin
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
node_modules
|
||||
dist
|
||||
.eslintrc.js
|
||||
.prettierrc.js
|
||||
commitlint.config.ts
|
||||
@@ -1,98 +0,0 @@
|
||||
module.exports = {
|
||||
parser: "@typescript-eslint/parser",
|
||||
plugins: ["@typescript-eslint", "prettier", "import"],
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:prettier/recommended",
|
||||
"plugin:import/recommended",
|
||||
"plugin:import/typescript",
|
||||
"prettier",
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2022,
|
||||
sourceType: "module",
|
||||
tsconfigRootDir: __dirname,
|
||||
project: "./tsconfig.json",
|
||||
},
|
||||
env: {
|
||||
es6: true,
|
||||
node: true,
|
||||
},
|
||||
rules: {
|
||||
// turn on errors for missing imports
|
||||
"sort-imports": [
|
||||
"error",
|
||||
{
|
||||
ignoreCase: false,
|
||||
ignoreDeclarationSort: true,
|
||||
ignoreMemberSort: false,
|
||||
memberSyntaxSortOrder: ["none", "all", "multiple", "single"],
|
||||
allowSeparatedGroups: true,
|
||||
},
|
||||
],
|
||||
"import/no-unresolved": "error",
|
||||
"import/order": [
|
||||
"error",
|
||||
{
|
||||
groups: ["builtin", "external", "internal", ["sibling", "parent"], "index", "unknown"],
|
||||
"newlines-between": "always",
|
||||
alphabetize: {
|
||||
/* sort in ascending order. Options: ["ignore", "asc", "desc"] */
|
||||
order: "asc",
|
||||
/* ignore case. Options: [true, false] */
|
||||
caseInsensitive: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
// JavaScript Rules
|
||||
"no-var": "error",
|
||||
"prefer-const": "error",
|
||||
"no-multi-spaces": "error",
|
||||
"space-in-parens": "error",
|
||||
"no-multiple-empty-lines": ["error", { max: 1, maxEOF: 0 }],
|
||||
semi: ["error", "always"],
|
||||
|
||||
// Best Practices
|
||||
"no-async-promise-executor": "warn",
|
||||
"no-control-regex": "warn",
|
||||
"no-empty": ["warn", { allowEmptyCatch: true }],
|
||||
"no-extra-semi": "warn",
|
||||
"no-prototype-builtins": "warn",
|
||||
"no-regex-spaces": "warn",
|
||||
"prefer-rest-params": "warn",
|
||||
"prefer-spread": "warn",
|
||||
|
||||
// TypeScript-Specific Rules
|
||||
"@typescript-eslint/ban-ts-comment": "warn",
|
||||
"@typescript-eslint/no-explicit-any": "warn",
|
||||
"@typescript-eslint/no-loss-of-precision": "warn",
|
||||
"@typescript-eslint/no-misused-new": "warn",
|
||||
"@typescript-eslint/no-namespace": "warn",
|
||||
"@typescript-eslint/no-this-alias": "warn",
|
||||
"@typescript-eslint/no-unnecessary-type-constraint": "warn",
|
||||
"@typescript-eslint/no-unsafe-declaration-merging": "warn",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_",
|
||||
caughtErrorsIgnorePattern: "^_",
|
||||
ignoreRestSiblings: true,
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-var-requires": "warn",
|
||||
"@typescript-eslint/triple-slash-reference": "warn",
|
||||
|
||||
// "@typescript-eslint/explicit-function-return-type": [
|
||||
// "warn",
|
||||
// {
|
||||
// allowExpressions: true,
|
||||
// allowTypedFunctionExpressions: true,
|
||||
// },
|
||||
// ],
|
||||
// "@typescript-eslint/no-inferrable-types": "warn",
|
||||
// "@typescript-eslint/no-non-null-assertion": "warn",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,130 @@
|
||||
import eslint from "@eslint/js";
|
||||
import tseslint from "typescript-eslint";
|
||||
import eslintPluginPrettier from "eslint-plugin-prettier";
|
||||
import eslintPluginImport from "eslint-plugin-import";
|
||||
import globals from "globals";
|
||||
import prettierConfig from "eslint-config-prettier";
|
||||
|
||||
export default tseslint.config(
|
||||
{
|
||||
ignores: [
|
||||
"dist/**",
|
||||
"node_modules/**",
|
||||
"jest.config.js",
|
||||
"coverage/**",
|
||||
"database/migrations/**",
|
||||
"pnpm-lock.yaml",
|
||||
".prettierrc.js",
|
||||
"commitlint.config.ts",
|
||||
"eslint.config.mjs",
|
||||
],
|
||||
},
|
||||
eslint.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
prettierConfig,
|
||||
// Base configuration for all TypeScript files
|
||||
{
|
||||
files: ["**/*.ts"],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.node,
|
||||
...globals.jest,
|
||||
},
|
||||
ecmaVersion: 2022,
|
||||
sourceType: "module",
|
||||
parser: tseslint.parser,
|
||||
parserOptions: {
|
||||
projectService: true,
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
"@typescript-eslint": tseslint.plugin,
|
||||
prettier: eslintPluginPrettier,
|
||||
import: eslintPluginImport,
|
||||
},
|
||||
rules: {
|
||||
// Import rules
|
||||
"sort-imports": [
|
||||
"error",
|
||||
{
|
||||
ignoreCase: false,
|
||||
ignoreDeclarationSort: true,
|
||||
ignoreMemberSort: false,
|
||||
memberSyntaxSortOrder: ["none", "all", "multiple", "single"],
|
||||
allowSeparatedGroups: true,
|
||||
},
|
||||
],
|
||||
"import/order": [
|
||||
"error",
|
||||
{
|
||||
groups: ["builtin", "external", "internal", ["sibling", "parent"], "index", "unknown"],
|
||||
"newlines-between": "always",
|
||||
alphabetize: {
|
||||
order: "asc",
|
||||
caseInsensitive: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
// JavaScript Rules
|
||||
"no-var": "error",
|
||||
"prefer-const": "error",
|
||||
"no-multi-spaces": "error",
|
||||
"space-in-parens": "error",
|
||||
"no-multiple-empty-lines": ["error", { max: 1, maxEOF: 0 }],
|
||||
semi: ["error", "always"],
|
||||
|
||||
// Best Practices
|
||||
"no-async-promise-executor": "warn",
|
||||
"no-control-regex": "warn",
|
||||
"no-empty": ["warn", { allowEmptyCatch: true }],
|
||||
"no-extra-semi": "warn",
|
||||
"no-prototype-builtins": "warn",
|
||||
"no-regex-spaces": "warn",
|
||||
"prefer-rest-params": "warn",
|
||||
"prefer-spread": "warn",
|
||||
|
||||
// TypeScript-Specific Rules that don't need type information
|
||||
"@typescript-eslint/ban-ts-comment": "warn",
|
||||
"@typescript-eslint/no-explicit-any": "warn",
|
||||
"@typescript-eslint/no-loss-of-precision": "warn",
|
||||
"@typescript-eslint/no-misused-new": "warn",
|
||||
"@typescript-eslint/no-namespace": "warn",
|
||||
"@typescript-eslint/no-this-alias": "warn",
|
||||
"@typescript-eslint/no-unnecessary-type-constraint": "warn",
|
||||
"@typescript-eslint/no-unsafe-declaration-merging": "warn",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_",
|
||||
caughtErrorsIgnorePattern: "^_",
|
||||
ignoreRestSiblings: true,
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-var-requires": "warn",
|
||||
"@typescript-eslint/triple-slash-reference": "warn",
|
||||
},
|
||||
},
|
||||
// Additional configuration for type-checked files - disabled for now
|
||||
{
|
||||
files: ["**/*.ts"],
|
||||
// Disable type-aware linting until we can configure it properly
|
||||
rules: {
|
||||
"@typescript-eslint/await-thenable": "off",
|
||||
"@typescript-eslint/no-floating-promises": "off",
|
||||
"@typescript-eslint/no-misused-promises": "off",
|
||||
"@typescript-eslint/no-unnecessary-type-assertion": "off",
|
||||
"@typescript-eslint/no-unsafe-argument": "off",
|
||||
"@typescript-eslint/no-unsafe-assignment": "off",
|
||||
"@typescript-eslint/no-unsafe-call": "off",
|
||||
"@typescript-eslint/no-unsafe-member-access": "off",
|
||||
"@typescript-eslint/no-unsafe-return": "off",
|
||||
"@typescript-eslint/require-await": "off",
|
||||
"@typescript-eslint/restrict-plus-operands": "off",
|
||||
"@typescript-eslint/restrict-template-expressions": "off",
|
||||
"@typescript-eslint/unbound-method": "off",
|
||||
},
|
||||
},
|
||||
);
|
||||
+44
-40
@@ -12,7 +12,8 @@
|
||||
"start:dev": "nest start --watch",
|
||||
"start:debug": "nest start --debug --watch",
|
||||
"start": "NODE_ENV=production node --trace-warnings dist/main",
|
||||
"lint:fix": "eslint . --ext .ts --fix",
|
||||
"lint": "eslint . --fix",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"test:cov": "jest --coverage",
|
||||
@@ -29,76 +30,79 @@
|
||||
"prepare": "husky || true"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.735.0",
|
||||
"@fastify/static": "^7.0.4",
|
||||
"@keyv/redis": "^4.2.0",
|
||||
"@aws-sdk/client-s3": "^3.787.0",
|
||||
"@fastify/static": "^8.1.1",
|
||||
"@keyv/redis": "^4.3.4",
|
||||
"@nest-lab/fastify-multer": "^1.3.0",
|
||||
"@nest-lab/throttler-storage-redis": "^1.0.0",
|
||||
"@nest-lab/throttler-storage-redis": "^1.1.0",
|
||||
"@nestjs-modules/mailer": "^2.0.2",
|
||||
"@nestjs/axios": "^4.0.0",
|
||||
"@nestjs/bullmq": "^11.0.2",
|
||||
"@nestjs/cache-manager": "^3.0.0",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^4.0.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
"@nestjs/cache-manager": "^3.0.1",
|
||||
"@nestjs/common": "^11.0.20",
|
||||
"@nestjs/config": "^4.0.2",
|
||||
"@nestjs/core": "^11.0.20",
|
||||
"@nestjs/jwt": "^11.0.0",
|
||||
"@nestjs/passport": "^11.0.4",
|
||||
"@nestjs/platform-fastify": "^10.4.15",
|
||||
"@nestjs/swagger": "^8.1.1",
|
||||
"@nestjs/throttler": "^6.3.0",
|
||||
"@nestjs/typeorm": "^10.0.2",
|
||||
"@nestjs/passport": "^11.0.5",
|
||||
"@nestjs/platform-fastify": "^11.0.20",
|
||||
"@nestjs/swagger": "^11.1.5",
|
||||
"@nestjs/throttler": "^6.4.0",
|
||||
"@nestjs/typeorm": "^11.0.0",
|
||||
"@types/bcrypt": "^5.0.2",
|
||||
"aws-sdk": "^2.1692.0",
|
||||
"axios": "^1.7.9",
|
||||
"axios": "^1.8.4",
|
||||
"bcrypt": "^5.1.1",
|
||||
"bullmq": "^5.40.0",
|
||||
"cache-manager": "^6.3.2",
|
||||
"bullmq": "^5.49.2",
|
||||
"cache-manager": "^6.4.2",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"decimal.js": "^10.5.0",
|
||||
"dotenv": "^16.4.7",
|
||||
"fastify": "^5.2.1",
|
||||
"dotenv": "^16.5.0",
|
||||
"fastify": "^5.3.2",
|
||||
"handlebars": "^4.7.8",
|
||||
"nestjs-telegraf": "^2.8.1",
|
||||
"nodemailer": "^6.9.16",
|
||||
"nodemailer": "^6.10.1",
|
||||
"passport-jwt": "^4.0.1",
|
||||
"pg": "^8.13.1",
|
||||
"pg": "^8.14.1",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.1",
|
||||
"rxjs": "^7.8.2",
|
||||
"slugify": "^1.6.6",
|
||||
"telegraf": "^4.16.3",
|
||||
"typeorm": "^0.3.20"
|
||||
"typeorm": "^0.3.22"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^19.6.1",
|
||||
"@commitlint/config-conventional": "^19.6.0",
|
||||
"@nestjs/cli": "^10.4.9",
|
||||
"@nestjs/schematics": "^10.2.3",
|
||||
"@nestjs/testing": "^10.4.15",
|
||||
"@commitlint/cli": "^19.8.0",
|
||||
"@commitlint/config-conventional": "^19.8.0",
|
||||
"@nestjs/cli": "^11.0.6",
|
||||
"@nestjs/schematics": "^11.0.5",
|
||||
"@nestjs/testing": "^11.0.20",
|
||||
"@types/bcrypt": "^5.0.2",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/node": "^20.17.14",
|
||||
"@types/node": "^20.17.30",
|
||||
"@types/nodemailer": "^6.4.17",
|
||||
"@types/passport-jwt": "^4.0.1",
|
||||
"@types/supertest": "^6.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^8.21.0",
|
||||
"@typescript-eslint/parser": "^8.21.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"@types/supertest": "^6.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "^8.31.0",
|
||||
"@typescript-eslint/parser": "^8.31.0",
|
||||
"eslint": "^9.25.0",
|
||||
"eslint-config-prettier": "^10.1.2",
|
||||
"eslint-import-resolver-typescript": "^3.10.1",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-prettier": "^5.2.3",
|
||||
"eslint-plugin-prettier": "^5.2.6",
|
||||
"globals": "^16.0.0",
|
||||
"husky": "^9.1.7",
|
||||
"jest": "^29.7.0",
|
||||
"lint-staged": "^15.4.1",
|
||||
"prettier": "^3.4.2",
|
||||
"lint-staged": "^15.5.1",
|
||||
"prettier": "^3.5.3",
|
||||
"source-map-support": "^0.5.21",
|
||||
"supertest": "^7.0.0",
|
||||
"ts-jest": "^29.2.5",
|
||||
"supertest": "^7.1.0",
|
||||
"ts-jest": "^29.3.2",
|
||||
"ts-loader": "^9.5.2",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
"typescript": "^5.7.3"
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.31.0"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
|
||||
Generated
+2620
-2169
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -7,13 +7,13 @@ import { ConfigModule } from "@nestjs/config";
|
||||
import { ThrottlerModule } from "@nestjs/throttler";
|
||||
import { TypeOrmModule } from "@nestjs/typeorm";
|
||||
import { MailerModule } from "@nestjs-modules/mailer";
|
||||
import { TelegrafModule } from "nestjs-telegraf";
|
||||
// import { TelegrafModule } from "nestjs-telegraf";
|
||||
|
||||
import { bullMqConfig } from "./configs/bullmq.config";
|
||||
import { cacheConfig } from "./configs/cache.config";
|
||||
import { mailerConfig } from "./configs/mailer.config";
|
||||
import { rateLimitConfig } from "./configs/rateLimit.config";
|
||||
import { telegrafConfig } from "./configs/telegraf.config";
|
||||
// import { telegrafConfig } from "./configs/telegraf.config";
|
||||
import { databaseConfigs } from "./configs/typeorm.config";
|
||||
import { HTTPLogger } from "./core/middlewares/logger.middleware";
|
||||
import { AddressModule } from "./modules/address/address.module";
|
||||
@@ -42,7 +42,7 @@ import { WalletsModule } from "./modules/wallets/wallets.module";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TelegrafModule.forRootAsync(telegrafConfig()),
|
||||
// TelegrafModule.forRootAsync(telegrafConfig()),
|
||||
MailerModule.forRootAsync(mailerConfig()),
|
||||
BullModule.forRootAsync(bullMqConfig()),
|
||||
ThrottlerModule.forRootAsync(rateLimitConfig()),
|
||||
|
||||
@@ -29,7 +29,6 @@ export const enum AuthMessage {
|
||||
PHONE_EXISTS = "شماره تلفن قبلا ثبت شده است",
|
||||
ADMIN_CREATED = "ادمین با موفقیت ایجاد شد",
|
||||
PERM_NOT_FOUND = "دسترسی یافت نشد",
|
||||
ADMIN_NOT_FOUND = "ادمین یافت نشد",
|
||||
INVALID_PASS_FORMAT = "فرمت رمز عبور صحیح نیست",
|
||||
PHONE_NOT_EMPTY = "شماره تلفن نمیتواند خالی باشد",
|
||||
PASSWORD_FORMAT_INVALID = "رمز عبور باید به صورت رشته باشد",
|
||||
@@ -61,6 +60,7 @@ export const enum AuthMessage {
|
||||
LOGOUT_SUCCESS = "خروج با موفقیت انجام شد",
|
||||
CURRENT_PASSWORD_INVALID = "رمز عبور فعلی نامعتبر است",
|
||||
TOKEN_EXPIRED_OR_INVALID = "توکن منقضی شده یا نامعتبر است",
|
||||
ACCESS_DENIED = "دسترسی شما محدود شده است",
|
||||
}
|
||||
|
||||
export const enum UserMessage {
|
||||
@@ -105,6 +105,7 @@ export const enum UserMessage {
|
||||
ADMIN_ID_REQUIRED = "شناسه ادمین مورد نیاز است",
|
||||
INVALID_ADMIN_ID = "شناسه ادمین نامعتبر است",
|
||||
ADMIN_ID_SHOULD_BE_UUID = "شناسه ادمین باید یک UUID باشد",
|
||||
ADMIN_NOT_FOUND = "ادمین یافت نشد",
|
||||
}
|
||||
|
||||
export const enum CommonMessage {
|
||||
@@ -593,6 +594,9 @@ export const enum AdminMessage {
|
||||
ROLE_NAME_LENGTH = "نام نقش باید بین ۳ تا ۱۵۰ کاراکتر باشد",
|
||||
ROLE_EXIST = "نقش با این نام قبلا ثبت شده است",
|
||||
ROLE_CREATED = "نقش با موفقیت ایجاد شد",
|
||||
ADMIN_UPDATED = "مدیر با موفقیت به روز رسانی شد",
|
||||
ADMIN_NOT_FOUND = "مدیری با این شناسه یافت نشد",
|
||||
ADMIN_DELETED = "مدیر با موفقیت حذف شد",
|
||||
}
|
||||
export const enum AdsMessage {
|
||||
TITLE_REQUIRED = "عنوان الزامی است",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
import { ValueTransformer } from "typeorm";
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ export class HttpExceptionFilter implements ExceptionFilter {
|
||||
});
|
||||
}
|
||||
|
||||
private extractMessage(response: string | object): string | string[] {
|
||||
private extractMessage(response: string | Record<string, any>): string | string[] {
|
||||
if (typeof response === "string") {
|
||||
return [response];
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ async function bootstrap() {
|
||||
|
||||
app.enableCors({
|
||||
origin: true,
|
||||
methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
|
||||
credentials: true,
|
||||
optionsSuccessStatus: 204,
|
||||
});
|
||||
|
||||
@@ -113,6 +113,8 @@ export class AuthService {
|
||||
const isAdmin = this.checkUserIsAdmin(user.roles);
|
||||
if (!isAdmin) throw new BadRequestException(AuthMessage.NOT_ADMIN);
|
||||
|
||||
if (user.deletedAt) throw new BadRequestException(AuthMessage.ACCESS_DENIED);
|
||||
|
||||
const tokens = await this.tokensService.generateTokens(user);
|
||||
|
||||
return {
|
||||
@@ -191,6 +193,7 @@ export class AuthService {
|
||||
const isUserAdmin = this.checkUserIsAdmin(user.roles);
|
||||
|
||||
if (!isUserAdmin) throw new BadRequestException(AuthMessage.NOT_ADMIN);
|
||||
if (user.deletedAt) throw new BadRequestException(AuthMessage.ACCESS_DENIED);
|
||||
|
||||
const tokens = await this.tokensService.generateTokens(user);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { IsBoolean, IsNotEmpty, IsString, IsUrl, MaxLength } from "class-validat
|
||||
|
||||
import { BlogMessage } from "../../../common/enums/message.enum";
|
||||
|
||||
export class CreateCategoryDto {
|
||||
export class CreateBlogCategoryDto {
|
||||
@IsNotEmpty({ message: BlogMessage.TITLE_REQUIRED })
|
||||
@IsString({ message: BlogMessage.TITLE_STRING })
|
||||
@MaxLength(100, { message: BlogMessage.TITLE_MAX_LENGTH })
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { PartialType } from "@nestjs/swagger";
|
||||
|
||||
import { CreateCategoryDto } from "./create-category.dto";
|
||||
import { CreateBlogCategoryDto } from "./create-category.dto";
|
||||
|
||||
export class UpdateCategoryDto extends PartialType(CreateCategoryDto) {}
|
||||
export class UpdateBlogCategoryDto extends PartialType(CreateBlogCategoryDto) {}
|
||||
|
||||
@@ -11,12 +11,12 @@ import { ParamDto } from "../../../common/DTO/param.dto";
|
||||
import { CategoryListSearchQueryDto } from "../../danak-services/DTO/category-search-query.dto";
|
||||
import { PermissionEnum } from "../../users/enums/permission.enum";
|
||||
import { CreateBlogDto } from "../DTO/create-blog.dto";
|
||||
import { CreateCategoryDto } from "../DTO/create-category.dto";
|
||||
import { CreateBlogCategoryDto } from "../DTO/create-category.dto";
|
||||
import { CreateCommentDto } from "../DTO/create-comment.dto";
|
||||
import { BlogSlugDto } from "../DTO/get-blog-by-slug.dto";
|
||||
import { BlogListSearchQueryDto, BlogSearchQueryDto } from "../DTO/search-blog-query.dto";
|
||||
import { UpdateBlogDto } from "../DTO/update-blog.dto";
|
||||
import { UpdateCategoryDto } from "../DTO/update-category.dto";
|
||||
import { UpdateBlogCategoryDto } from "../DTO/update-category.dto";
|
||||
import { UpdateCommentStatusDto } from "../DTO/update-comment-status.dto";
|
||||
import { BlogsService } from "../providers/blogs.service";
|
||||
|
||||
@@ -165,7 +165,7 @@ export class BlogsController {
|
||||
@Post("categories")
|
||||
@AdminRoute()
|
||||
@PermissionsDec(PermissionEnum.BLOGS)
|
||||
createCategory(@Body() createCategoryDto: CreateCategoryDto) {
|
||||
createCategory(@Body() createCategoryDto: CreateBlogCategoryDto) {
|
||||
return this.blogsService.createCategory(createCategoryDto);
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ export class BlogsController {
|
||||
@Patch("categories/:id")
|
||||
@AdminRoute()
|
||||
@PermissionsDec(PermissionEnum.BLOGS)
|
||||
updateCategory(@Param() paramDto: ParamDto, @Body() updateCategoryDto: UpdateCategoryDto) {
|
||||
updateCategory(@Param() paramDto: ParamDto, @Body() updateCategoryDto: UpdateBlogCategoryDto) {
|
||||
return this.blogsService.updateCategory(paramDto.id, updateCategoryDto);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ import { BlogMessage, CommonMessage } from "../../../common/enums/message.enum";
|
||||
import { CategoryListSearchQueryDto } from "../../danak-services/DTO/category-search-query.dto";
|
||||
import { UsersService } from "../../users/providers/users.service";
|
||||
import { CreateBlogDto } from "../DTO/create-blog.dto";
|
||||
import { CreateCategoryDto } from "../DTO/create-category.dto";
|
||||
import { CreateBlogCategoryDto } from "../DTO/create-category.dto";
|
||||
import { CreateCommentDto } from "../DTO/create-comment.dto";
|
||||
import { BlogListSearchQueryDto, BlogSearchQueryDto } from "../DTO/search-blog-query.dto";
|
||||
import { UpdateBlogDto } from "../DTO/update-blog.dto";
|
||||
import { UpdateCategoryDto } from "../DTO/update-category.dto";
|
||||
import { UpdateBlogCategoryDto } from "../DTO/update-category.dto";
|
||||
import { UpdateCommentStatusDto } from "../DTO/update-comment-status.dto";
|
||||
import { CommentStatus } from "../enums/comment-status.enum";
|
||||
import { BlogCategoriesRepository } from "../repositories/blog-categories.repository";
|
||||
@@ -25,7 +25,7 @@ export class BlogsService {
|
||||
) {}
|
||||
|
||||
//*********************************** */
|
||||
async createCategory(createCategoryDto: CreateCategoryDto) {
|
||||
async createCategory(createCategoryDto: CreateBlogCategoryDto) {
|
||||
const existingCategory = await this.blogCategoriesRepository.findOneBy({ title: createCategoryDto.title });
|
||||
if (existingCategory) throw new BadRequestException(BlogMessage.CATEGORY_ALREADY_EXISTS);
|
||||
|
||||
@@ -38,7 +38,7 @@ export class BlogsService {
|
||||
}
|
||||
//*********************************** */
|
||||
|
||||
async updateCategory(id: string, updateCategoryDto: UpdateCategoryDto) {
|
||||
async updateCategory(id: string, updateCategoryDto: UpdateBlogCategoryDto) {
|
||||
const category = await this.findCategoryById(id);
|
||||
|
||||
if (updateCategoryDto.title) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { IsNull, Repository } from "typeorm";
|
||||
|
||||
import { CategoryListSearchQueryDto } from "../../danak-services/DTO/category-search-query.dto";
|
||||
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
||||
import { CreateCategoryDto } from "../DTO/create-category.dto";
|
||||
import { CreateBlogCategoryDto } from "../DTO/create-category.dto";
|
||||
import { BlogCategory } from "../entities/blog-category.entity";
|
||||
|
||||
@Injectable()
|
||||
@@ -44,7 +44,7 @@ export class BlogCategoriesRepository extends Repository<BlogCategory> {
|
||||
return query.getManyAndCount();
|
||||
}
|
||||
|
||||
async createCategory(createBlogCategoryDto: CreateCategoryDto) {
|
||||
async createCategory(createBlogCategoryDto: CreateBlogCategoryDto) {
|
||||
const { title, description, iconUrl, isActive } = createBlogCategoryDto;
|
||||
|
||||
const blogCategory = this.create({ title, description, iconUrl, isActive });
|
||||
|
||||
@@ -3,7 +3,7 @@ import { IsBoolean, IsInt, IsNotEmpty, IsOptional, IsString, IsUUID, IsUrl, Leng
|
||||
|
||||
import { CategoryMessage } from "../../../common/enums/message.enum";
|
||||
|
||||
export class CreateCategoryDto {
|
||||
export class CreateDanakServiceCategoryDto {
|
||||
@IsNotEmpty({ message: CategoryMessage.TITLE_REQUIRED })
|
||||
@IsString({ message: CategoryMessage.TITLE_STRING })
|
||||
@Length(3, 50, { message: CategoryMessage.TITLE_LENGTH })
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { PartialType } from "@nestjs/swagger";
|
||||
|
||||
import { CreateCategoryDto } from "./create-category.dto";
|
||||
import { CreateDanakServiceCategoryDto } from "./create-category.dto";
|
||||
|
||||
export class UpdateCategoryDto extends PartialType(CreateCategoryDto) {}
|
||||
export class UpdateDanakServiceCategoryDto extends PartialType(CreateDanakServiceCategoryDto) {}
|
||||
|
||||
@@ -3,11 +3,11 @@ import { ApiOperation, ApiTags } from "@nestjs/swagger";
|
||||
|
||||
import { AddReviewDto } from "./DTO/add-review.dto";
|
||||
import { CategoryListSearchQueryDto, CategorySearchQueryDto } from "./DTO/category-search-query.dto";
|
||||
import { CreateCategoryDto } from "./DTO/create-category.dto";
|
||||
import { CreateDanakServiceCategoryDto } from "./DTO/create-category.dto";
|
||||
import { CreateServiceDto } from "./DTO/create-service.dto";
|
||||
import { DanakServiceReviewQueryDto } from "./DTO/danak-service-review-query.dto";
|
||||
import { DanakServicesGlobalSearchDto, DanakServicesQueryDto, DanakServicesSearchQueryDto } from "./DTO/danak-services-search-query.dto";
|
||||
import { UpdateCategoryDto } from "./DTO/update-category.dto";
|
||||
import { UpdateDanakServiceCategoryDto } from "./DTO/update-category.dto";
|
||||
import { UpdateReviewStatusDto } from "./DTO/update-review-status.dto";
|
||||
import { UpdateServiceDto } from "./DTO/update-service.dto";
|
||||
import { DanakServicesService } from "./providers/danak-services.service";
|
||||
@@ -28,7 +28,7 @@ export class DanakServicesController {
|
||||
@PermissionsDec(PermissionEnum.SERVICES)
|
||||
@ApiOperation({ summary: "Create a new service category => admin route" })
|
||||
@Post("categories")
|
||||
createCategory(@Body() createDto: CreateCategoryDto) {
|
||||
createCategory(@Body() createDto: CreateDanakServiceCategoryDto) {
|
||||
return this.danakServicesService.createCategory(createDto);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ export class DanakServicesController {
|
||||
@PermissionsDec(PermissionEnum.SERVICES)
|
||||
@ApiOperation({ summary: "update category by id => admin route" })
|
||||
@Patch("categories/:id")
|
||||
updateCategory(@Param() paramDto: ParamDto, @Body() updateDto: UpdateCategoryDto) {
|
||||
updateCategory(@Param() paramDto: ParamDto, @Body() updateDto: UpdateDanakServiceCategoryDto) {
|
||||
return this.danakServicesService.updateCategory(paramDto.id, updateDto);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,11 +7,11 @@ import { SubscriptionStatus } from "../../subscriptions/enums/subscription-statu
|
||||
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
||||
import { AddReviewDto } from "../DTO/add-review.dto";
|
||||
import { CategoryListSearchQueryDto, CategorySearchQueryDto } from "../DTO/category-search-query.dto";
|
||||
import { CreateCategoryDto } from "../DTO/create-category.dto";
|
||||
import { CreateDanakServiceCategoryDto } from "../DTO/create-category.dto";
|
||||
import { CreateServiceDto } from "../DTO/create-service.dto";
|
||||
import { DanakServiceReviewQueryDto } from "../DTO/danak-service-review-query.dto";
|
||||
import { DanakServicesGlobalSearchDto, DanakServicesQueryDto, DanakServicesSearchQueryDto } from "../DTO/danak-services-search-query.dto";
|
||||
import { UpdateCategoryDto } from "../DTO/update-category.dto";
|
||||
import { UpdateDanakServiceCategoryDto } from "../DTO/update-category.dto";
|
||||
import { UpdateReviewStatusDto } from "../DTO/update-review-status.dto";
|
||||
import { UpdateServiceDto } from "../DTO/update-service.dto";
|
||||
import { DanakServiceCategory } from "../entities/danak-service-category.entity";
|
||||
@@ -34,7 +34,7 @@ export class DanakServicesService {
|
||||
) {}
|
||||
/******************************************** */
|
||||
|
||||
async createCategory(createDto: CreateCategoryDto) {
|
||||
async createCategory(createDto: CreateDanakServiceCategoryDto) {
|
||||
const queryRunner = this.dataSource.createQueryRunner();
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
@@ -98,7 +98,7 @@ export class DanakServicesService {
|
||||
|
||||
/******************************************** */
|
||||
|
||||
async updateCategory(categoryId: string, updateDto: UpdateCategoryDto) {
|
||||
async updateCategory(categoryId: string, updateDto: UpdateDanakServiceCategoryDto) {
|
||||
const queryRunner = this.dataSource.createQueryRunner();
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
import { Column, Entity, ManyToOne } from "typeorm";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
import { Column, Entity, ManyToOne } from "typeorm";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
import { Column, Entity, ManyToOne, OneToMany } from "typeorm";
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { InjectQueue } from "@nestjs/bullmq";
|
||||
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
import { Queue } from "bullmq";
|
||||
import dayjs from "dayjs";
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
import Decimal from "decimal.js";
|
||||
import { Between, DataSource, QueryRunner } from "typeorm";
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { InjectQueue, Processor } from "@nestjs/bullmq";
|
||||
import { Job, Queue } from "bullmq";
|
||||
import dayjs from "dayjs";
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
import Decimal from "decimal.js";
|
||||
import { DataSource, QueryRunner } from "typeorm";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
import { Column, Entity, ManyToOne, OneToMany } from "typeorm";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
import { Column, Entity, ManyToOne, OneToMany } from "typeorm";
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
//------------------ process payment -------------------------
|
||||
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
|
||||
export interface IProcessPaymentParams {
|
||||
|
||||
@@ -3,7 +3,6 @@ import { BadRequestException, HttpException, HttpStatus, Injectable, InternalSer
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
import { Queue } from "bullmq";
|
||||
import dayjs from "dayjs";
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
import Decimal from "decimal.js";
|
||||
import { FastifyReply } from "fastify";
|
||||
import { DataSource, Not, QueryRunner } from "typeorm";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
import { Column, Entity, ManyToOne } from "typeorm";
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { randomBytes } from "node:crypto";
|
||||
|
||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
import Decimal from "decimal.js";
|
||||
import { QueryRunner } from "typeorm";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
import { Column, DeleteDateColumn, Entity, Index, ManyToOne, OneToMany } from "typeorm";
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||
import dayjs from "dayjs";
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
import Decimal from "decimal.js";
|
||||
import { DataSource, In, Not, QueryRunner } from "typeorm";
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { PartialType } from "@nestjs/swagger";
|
||||
|
||||
import { CreateAdminDto } from "./create-admin.dto";
|
||||
|
||||
export class UpdateAdminDto extends PartialType(CreateAdminDto) {}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Exclude } from "class-transformer";
|
||||
import { Column, Entity, JoinTable, ManyToMany, OneToMany, OneToOne } from "typeorm";
|
||||
import { Column, DeleteDateColumn, Entity, JoinTable, ManyToMany, OneToMany, OneToOne } from "typeorm";
|
||||
|
||||
import { LegalUser } from "./legal-user.entity";
|
||||
import { RealUser } from "./real-user.entity";
|
||||
@@ -63,6 +63,9 @@ export class User extends BaseEntity {
|
||||
@Column({ type: "enum", enum: FinancialType, nullable: true, default: null })
|
||||
financialType: FinancialType | null;
|
||||
|
||||
@DeleteDateColumn({ nullable: true })
|
||||
deletedAt?: Date;
|
||||
|
||||
//-----------------------------------------
|
||||
|
||||
@ManyToMany(() => Role, (role) => role.users)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||
import slugify from "slugify";
|
||||
import { In } from "typeorm";
|
||||
import { DataSource, In, Not } from "typeorm";
|
||||
|
||||
import { AdminMessage, AdsMessage, UserMessage } from "../../../common/enums/message.enum";
|
||||
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
||||
@@ -9,6 +9,7 @@ import { CreateAdminDto } from "../DTO/create-admin.dto";
|
||||
import { CreateRoleDto } from "../DTO/create-role.dto";
|
||||
import { SearchAdminQueryDto } from "../DTO/search-admins-query.dto";
|
||||
import { SearchRolesQueryDto } from "../DTO/search-roles.dto";
|
||||
import { UpdateAdminDto } from "../DTO/update-admin.dto";
|
||||
import { PermissionsRepository } from "../repositories/permissions.repository";
|
||||
import { RoleRepository } from "../repositories/roles.repository";
|
||||
import { UserRepository } from "../repositories/users.repository";
|
||||
@@ -20,33 +21,127 @@ export class AdminsService {
|
||||
private readonly rolesRepository: RoleRepository,
|
||||
private readonly permissionsRepository: PermissionsRepository,
|
||||
private readonly passwordService: PasswordService,
|
||||
private readonly dataSource: DataSource,
|
||||
) {}
|
||||
|
||||
async createAdmin(createDto: CreateAdminDto) {
|
||||
const existEmail = await this.userRepository.findOneBy({ email: createDto.email });
|
||||
if (existEmail) throw new BadRequestException(UserMessage.EMAIL_EXIST);
|
||||
const queryRunner = this.dataSource.createQueryRunner();
|
||||
|
||||
const existPhone = await this.userRepository.findOneBy({ phone: createDto.phone });
|
||||
if (existPhone) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
||||
try {
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
|
||||
const role = await this.rolesRepository.findOne({ where: { id: createDto.roleId }, relations: { permissions: true } });
|
||||
if (!role) throw new BadRequestException(AdsMessage.ROLE_NOT_FOUND);
|
||||
const existEmail = await queryRunner.manager.findOneBy(this.userRepository.target, { email: createDto.email });
|
||||
if (existEmail) throw new BadRequestException(UserMessage.EMAIL_EXIST);
|
||||
|
||||
await this.rolesRepository.save(role);
|
||||
const existPhone = await queryRunner.manager.findOneBy(this.userRepository.target, { phone: createDto.phone });
|
||||
if (existPhone) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
||||
|
||||
if (createDto.password !== createDto.repeatPassword) throw new BadRequestException(AdminMessage.PASSWORD_NOT_MATCH);
|
||||
const role = await queryRunner.manager.findOne(this.rolesRepository.target, {
|
||||
where: { id: createDto.roleId },
|
||||
relations: { permissions: true },
|
||||
});
|
||||
if (!role) throw new BadRequestException(AdsMessage.ROLE_NOT_FOUND);
|
||||
|
||||
const hashedPassword = await this.passwordService.hashPassword(createDto.password);
|
||||
if (createDto.password !== createDto.repeatPassword) throw new BadRequestException(AdminMessage.PASSWORD_NOT_MATCH);
|
||||
|
||||
const userName = slugify(`${createDto.firstName} ${Date.now().toString().slice(-5)}`, { lower: true, trim: true });
|
||||
const hashedPassword = await this.passwordService.hashPassword(createDto.password);
|
||||
const userName = slugify(`${createDto.firstName} ${Date.now().toString().slice(-5)}`, { lower: true, trim: true });
|
||||
|
||||
const adminUser = this.userRepository.create({ ...createDto, roles: [role], password: hashedPassword, userName });
|
||||
await this.userRepository.save(adminUser);
|
||||
await queryRunner.manager.save(this.rolesRepository.target, role);
|
||||
|
||||
const adminUser = queryRunner.manager.create(this.userRepository.target, {
|
||||
...createDto,
|
||||
roles: [role],
|
||||
password: hashedPassword,
|
||||
userName,
|
||||
});
|
||||
|
||||
await queryRunner.manager.save(this.userRepository.target, adminUser);
|
||||
await queryRunner.commitTransaction();
|
||||
|
||||
return {
|
||||
message: AdminMessage.ADMIN_CREATED,
|
||||
adminUser,
|
||||
};
|
||||
} catch (error) {
|
||||
await queryRunner.rollbackTransaction();
|
||||
throw error;
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
}
|
||||
}
|
||||
/************************************************************ */
|
||||
|
||||
async updateAdmin(id: string, updateDto: UpdateAdminDto) {
|
||||
const queryRunner = this.dataSource.createQueryRunner();
|
||||
|
||||
try {
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
|
||||
const admin = await queryRunner.manager.findOne(this.userRepository.target, {
|
||||
where: { id, roles: { isAdmin: true } },
|
||||
relations: { roles: true },
|
||||
});
|
||||
if (!admin) throw new BadRequestException(UserMessage.ADMIN_NOT_FOUND);
|
||||
|
||||
if (updateDto.email && updateDto.email !== admin.email) {
|
||||
const existEmail = await queryRunner.manager.findOneBy(this.userRepository.target, { email: updateDto.email, id: Not(id) });
|
||||
if (existEmail) throw new BadRequestException(UserMessage.EMAIL_EXIST);
|
||||
}
|
||||
|
||||
if (updateDto.phone && updateDto.phone !== admin.phone) {
|
||||
const existPhone = await queryRunner.manager.findOneBy(this.userRepository.target, { phone: updateDto.phone, id: Not(id) });
|
||||
if (existPhone) throw new BadRequestException(UserMessage.PHONE_EXIST);
|
||||
}
|
||||
|
||||
if (updateDto.roleId) {
|
||||
const role = await queryRunner.manager.findOne(this.rolesRepository.target, {
|
||||
where: { id: updateDto.roleId },
|
||||
relations: { permissions: true },
|
||||
});
|
||||
if (!role) throw new BadRequestException(AdsMessage.ROLE_NOT_FOUND);
|
||||
|
||||
await queryRunner.manager.save(this.rolesRepository.target, role);
|
||||
|
||||
admin.roles = [role];
|
||||
|
||||
await queryRunner.manager.save(this.userRepository.target, admin);
|
||||
}
|
||||
|
||||
if (updateDto.password) {
|
||||
if (updateDto.password !== updateDto.repeatPassword) throw new BadRequestException(AdminMessage.PASSWORD_NOT_MATCH);
|
||||
|
||||
admin.password = await this.passwordService.hashPassword(updateDto.password);
|
||||
}
|
||||
|
||||
await queryRunner.manager.save(this.userRepository.target, { ...admin, ...updateDto, password: admin.password });
|
||||
|
||||
await queryRunner.commitTransaction();
|
||||
|
||||
return {
|
||||
message: AdminMessage.ADMIN_UPDATED,
|
||||
};
|
||||
} catch (error) {
|
||||
await queryRunner.rollbackTransaction();
|
||||
throw error;
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
}
|
||||
}
|
||||
/************************************************************ */
|
||||
|
||||
async deleteAdmin(id: string) {
|
||||
const admin = await this.userRepository.findOne({ where: { id, roles: { isAdmin: true } } });
|
||||
if (!admin) throw new BadRequestException(AdminMessage.ADMIN_NOT_FOUND);
|
||||
|
||||
await this.userRepository.softDelete(id);
|
||||
return {
|
||||
message: AdminMessage.ADMIN_CREATED,
|
||||
adminUser,
|
||||
message: AdminMessage.ADMIN_DELETED,
|
||||
};
|
||||
}
|
||||
|
||||
/************************************************************ */
|
||||
|
||||
async createRole(createDto: CreateRoleDto) {
|
||||
@@ -78,6 +173,13 @@ export class AdminsService {
|
||||
|
||||
/************************************************************ */
|
||||
|
||||
async getAdminById(id: string) {
|
||||
const admin = await this.userRepository.findOne({ where: { id, roles: { isAdmin: true } }, relations: { roles: true } });
|
||||
if (!admin) throw new BadRequestException(AdminMessage.ADMIN_NOT_FOUND);
|
||||
return { admin };
|
||||
}
|
||||
/************************************************************ */
|
||||
|
||||
async getPermissions() {
|
||||
const permissions = await this.permissionsRepository.find({ select: { id: true, name: true } });
|
||||
return {
|
||||
|
||||
@@ -117,7 +117,8 @@ export class UserRepository extends Repository<User> {
|
||||
// .addSelect(["role.id", "role.name"])
|
||||
.where("role.isAdmin = :isAdmin", { isAdmin: true })
|
||||
.leftJoinAndSelect("user.groups", "groups")
|
||||
.leftJoinAndSelect("role.permissions", "permissions");
|
||||
.leftJoinAndSelect("role.permissions", "permissions")
|
||||
.andWhere("user.deletedAt IS NULL");
|
||||
// .where("permissions.name IN (:...adminPermissions)", {
|
||||
// adminPermissions: [PermissionEnum.ADMINS],
|
||||
// });
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Body, Controller, Get, HttpCode, HttpStatus, Param, Patch, Post, Query, Res } from "@nestjs/common";
|
||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Patch, Post, Query, Res } from "@nestjs/common";
|
||||
import { ApiOperation, ApiTags } from "@nestjs/swagger";
|
||||
import { FastifyReply } from "fastify";
|
||||
|
||||
@@ -12,6 +12,7 @@ import { CreateRoleDto } from "./DTO/create-role.dto";
|
||||
import { SearchAdminQueryDto } from "./DTO/search-admins-query.dto";
|
||||
import { SearchCustomersDto } from "./DTO/search-customers.dto";
|
||||
import { SearchRolesQueryDto } from "./DTO/search-roles.dto";
|
||||
import { UpdateAdminDto } from "./DTO/update-admin.dto";
|
||||
import { UpdateCustomerDto } from "./DTO/update-customer.dto";
|
||||
import { UpdateProfileDto } from "./DTO/update-profile.dto";
|
||||
import { CreateUserGroupDto } from "./DTO/user-group.dto";
|
||||
@@ -183,6 +184,30 @@ export class UsersController {
|
||||
return this.adminsService.getAdmins(queryDto);
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "get admin by id ==> admin route" })
|
||||
@AuthGuards()
|
||||
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
||||
@Get("admins/:id")
|
||||
getAdminById(@Param() paramDto: ParamDto) {
|
||||
return this.adminsService.getAdminById(paramDto.id);
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "update admin ==> admin route" })
|
||||
@AuthGuards()
|
||||
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
||||
@Patch("admins/:id")
|
||||
updateAdmin(@Param() paramDto: ParamDto, @Body() updateDto: UpdateAdminDto) {
|
||||
return this.adminsService.updateAdmin(paramDto.id, updateDto);
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "delete admin ==> admin route" })
|
||||
@AuthGuards()
|
||||
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
||||
@Delete("admins/:id")
|
||||
deleteAdmin(@Param() paramDto: ParamDto) {
|
||||
return this.adminsService.deleteAdmin(paramDto.id);
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "create admin ==> admin route" })
|
||||
@AuthGuards()
|
||||
@PermissionsDec(PermissionEnum.ADMINS, PermissionEnum.CUSTOMERS)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
import { Column, Entity, ManyToOne } from "typeorm";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
import { Column, Entity, JoinColumn, OneToMany, OneToOne } from "typeorm";
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
import Decimal from "decimal.js";
|
||||
import { QueryRunner } from "typeorm";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user