Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c82cc654f0 | |||
| c956bc0deb | |||
| 0e8e0cba2e | |||
| 3a84740d9a | |||
| cb77a55281 | |||
| 11445f0a07 | |||
| c2a861041f | |||
| 50d9fb2274 | |||
| 2768611a7c | |||
| b1a02d6b0d | |||
| 8b901e4d02 | |||
| 43b4f05894 | |||
| 7bef7d414a | |||
| 30dba5ae37 |
+11
-7
@@ -2,10 +2,14 @@
|
||||
FROM node:22-alpine AS base
|
||||
|
||||
ENV TZ=Asia/Tehran
|
||||
# Use the public npm registry to avoid paid/unstable mirror outages.
|
||||
ENV NPM_CONFIG_REGISTRY=https://package-mirror.liara.ir/repository/npm
|
||||
|
||||
# Runflare build hosts cannot reach registry.npmjs.org; use their npm mirror.
|
||||
# RUN npm install -g pnpm@9.15.9 --registry=https://mirror-npm.runflare.com
|
||||
RUN npm install -g pnpm@9.15.9
|
||||
# Change Alpine repo
|
||||
RUN sed -i 's|https://dl-cdn.alpinelinux.org/alpine|https://mirror.de.velop.ir/alpine|g' /etc/apk/repositories
|
||||
|
||||
# Install pnpm globally (uses NPM_CONFIG_REGISTRY mirror above).
|
||||
RUN npm install -g pnpm@9.15.9 --registry=https://package-mirror.liara.ir/repository/npm
|
||||
|
||||
# Stage 2: Install all dependencies (including dev)
|
||||
FROM base AS deps
|
||||
@@ -15,9 +19,9 @@ COPY package.json pnpm-lock.yaml ./
|
||||
# @nestjs/cli and typescript are required for the build step.
|
||||
ENV NODE_ENV=development
|
||||
# RUN pnpm install --frozen-lockfile --loglevel info \
|
||||
# --registry=https://mirror-npm.runflare.com
|
||||
# --registry=https://package-mirror.liara.ir/repository/npm
|
||||
|
||||
RUN pnpm install --frozen-lockfile --loglevel info
|
||||
RUN pnpm install --frozen-lockfile --loglevel info --registry=https://package-mirror.liara.ir/repository/npm
|
||||
|
||||
|
||||
# Stage 3: Build
|
||||
@@ -32,8 +36,8 @@ FROM base AS prod-deps
|
||||
WORKDIR /temp-deps
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
# RUN pnpm install --prod --frozen-lockfile --loglevel info \
|
||||
# --registry=https://mirror-npm.runflare.com
|
||||
RUN pnpm install --prod --frozen-lockfile --loglevel info
|
||||
# --registry=https://package-mirror.liara.ir/repository/npm
|
||||
RUN pnpm install --prod --frozen-lockfile --loglevel info --registry=https://package-mirror.liara.ir/repository/npm
|
||||
|
||||
|
||||
# Stage 5: Runner
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AddTitleToPermission1784465631499 implements MigrationInterface {
|
||||
name = "AddTitleToPermission1784465631499";
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "permission" ADD "title" character varying(150)`);
|
||||
await queryRunner.query(`UPDATE "permission" SET "title" = "name"::text WHERE "title" IS NULL`);
|
||||
await queryRunner.query(`ALTER TABLE "permission" ALTER COLUMN "title" SET NOT NULL`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "permission" DROP COLUMN "title"`);
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,46 @@ import { DataSource } from "typeorm";
|
||||
import { PermissionEnum } from "../../src/modules/users/enums/permission.enum";
|
||||
import { RoleEnum } from "../../src/modules/users/enums/role.enum";
|
||||
|
||||
const permissionTitles: Record<PermissionEnum, string> = {
|
||||
[PermissionEnum.SERVICES]: "سرویسها",
|
||||
[PermissionEnum.CUSTOMERS]: "مشتریان",
|
||||
[PermissionEnum.AGENTS]: "نمایندگان",
|
||||
[PermissionEnum.DEVELOPERS]: "توسعهدهندگان",
|
||||
[PermissionEnum.INVOICES]: "صورتحسابها",
|
||||
[PermissionEnum.TRANSACTIONS]: "تراکنشها",
|
||||
[PermissionEnum.DISCOUNTS]: "تخفیفها",
|
||||
[PermissionEnum.ADMINS]: "ادمینها",
|
||||
[PermissionEnum.TICKETS]: "تیکتها",
|
||||
[PermissionEnum.CRITICISMS]: "انتقادات",
|
||||
[PermissionEnum.CONTACTS_US]: "تماس با ما",
|
||||
[PermissionEnum.ADVERTISEMENTS]: "تبلیغات",
|
||||
[PermissionEnum.ANNOUNCEMENTS]: "اطلاعیهها",
|
||||
[PermissionEnum.BLOGS]: "بلاگها",
|
||||
[PermissionEnum.LEARNINGS]: "آموزشها",
|
||||
[PermissionEnum.LOGS]: "لاگها",
|
||||
[PermissionEnum.SETTINGS]: "تنظیمات",
|
||||
[PermissionEnum.BANK_ACCOUNTS]: "حسابهای بانکی",
|
||||
[PermissionEnum.PAYMENTS]: "پرداختها",
|
||||
[PermissionEnum.MANAGE_SSO_CLIENTS]: "مدیریت کلاینتهای SSO",
|
||||
[PermissionEnum.SUPPORT_PLAN]: "پلن پشتیبانی",
|
||||
[PermissionEnum.DMENU]: "دیمنو",
|
||||
[PermissionEnum.DKALA]: "دیکالا",
|
||||
[PermissionEnum.DPAGE]: "دیپیج",
|
||||
[PermissionEnum.DMAIL]: "دیمیل",
|
||||
[PermissionEnum.RESELLER]: "نمایندگی فروش",
|
||||
[PermissionEnum.WORKSPACE]: "فضای کار",
|
||||
[PermissionEnum.VIEW_ALL_WORKSPACES]: "مشاهده همه فضاهای کار",
|
||||
[PermissionEnum.PROJECT]: "پروژه",
|
||||
[PermissionEnum.VIEW_ALL_PROJECTS]: "مشاهده همه پروژهها",
|
||||
[PermissionEnum.TASK]: "وظیفه",
|
||||
[PermissionEnum.TASK_PHASE]: "فاز وظیفه",
|
||||
};
|
||||
|
||||
// Define permissions
|
||||
const permissions = Object.values(PermissionEnum).map((perm) => ({ name: perm }));
|
||||
const permissions = Object.values(PermissionEnum).map((perm) => ({
|
||||
name: perm,
|
||||
title: permissionTitles[perm],
|
||||
}));
|
||||
|
||||
// Define roles with their default permissions
|
||||
const rolesWithPermissions: { name: RoleEnum; permissions: PermissionEnum[] }[] = [
|
||||
@@ -23,8 +61,8 @@ const rolesWithPermissions: { name: RoleEnum; permissions: PermissionEnum[] }[]
|
||||
|
||||
export const seedPermissionsAndRoles = async (dataSource: DataSource, logger: Logger) => {
|
||||
try {
|
||||
const permissionRepo = dataSource.getRepository('Permission');
|
||||
const roleRepo = dataSource.getRepository('Role');
|
||||
const permissionRepo = dataSource.getRepository("Permission");
|
||||
const roleRepo = dataSource.getRepository("Role");
|
||||
|
||||
// Seed Permissions
|
||||
logger.log("Seeding Permissions...");
|
||||
@@ -33,6 +71,9 @@ export const seedPermissionsAndRoles = async (dataSource: DataSource, logger: Lo
|
||||
if (!existingPerm) {
|
||||
const newPerm = permissionRepo.create(perm);
|
||||
await permissionRepo.save(newPerm);
|
||||
} else if (!existingPerm.title || existingPerm.title !== perm.title) {
|
||||
existingPerm.title = perm.title;
|
||||
await permissionRepo.save(existingPerm);
|
||||
}
|
||||
}
|
||||
logger.log("Permissions seeded successfully");
|
||||
|
||||
@@ -444,6 +444,46 @@ export class RestaurantService {
|
||||
}
|
||||
}
|
||||
|
||||
async finishChargeRequest(invoiceId: string) {
|
||||
this.logger.log(`Finishing charge request for invoice ${invoiceId}`);
|
||||
try {
|
||||
const url = `${this.config.baseUrl}/super-admin/restaurants/charge-request/finish`;
|
||||
const { data } = await firstValueFrom(
|
||||
this.httpService
|
||||
.post(url, { invoiceId }, {
|
||||
headers: this.getHeaders(),
|
||||
})
|
||||
.pipe(
|
||||
catchError((err: AxiosError) => {
|
||||
this.logger.error(
|
||||
`Failed to finish charge request for invoice ${invoiceId}: ${err.message}`,
|
||||
err.stack,
|
||||
);
|
||||
return throwError(() => err);
|
||||
}),
|
||||
),
|
||||
);
|
||||
this.logger.log(`Successfully finished charge request for invoice ${invoiceId}`);
|
||||
return data;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof AxiosError && error.response) {
|
||||
this.logger.error(
|
||||
`External API error finishing charge request for invoice ${invoiceId} (status ${error.response.status}):`,
|
||||
error.response.data,
|
||||
);
|
||||
const errorResponse = {
|
||||
...error.response.data,
|
||||
message: error.response.data.error?.message || error.message,
|
||||
};
|
||||
throw new HttpException(errorResponse, error.response.status);
|
||||
}
|
||||
this.logger.error(
|
||||
`Error finishing charge request for invoice ${invoiceId}: ${error instanceof Error ? error.message : "Unknown error"}`,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async directLogin(userSubscriptionId: string, userId: string) {
|
||||
try {
|
||||
// 1. Get userSubscription by id
|
||||
|
||||
@@ -948,9 +948,13 @@ export class InvoicesService {
|
||||
await this.addNotifyForWalletDeduction(invoice, user, userWallet, WalletMessage.SUPPORT_PLAN_WALLET_TRANSFER);
|
||||
//
|
||||
} else if (invoice.isExternal) {
|
||||
if (invoice.items[0]?.name == 'purchase_design') {
|
||||
if (invoice.items[0]?.name == 'dmenu_wallet_charge') {
|
||||
this.restaurantService.finishChargeRequest(invoice.id);
|
||||
} else if (invoice.items[0]?.name == 'purchase_plan') {
|
||||
this.dpageService.finishPurchaseDesign(invoice.externalBusinessId!, invoice.id)
|
||||
} else if (invoice.items[0]?.name == 'purchase_new_catalogue') {
|
||||
}
|
||||
|
||||
else if (invoice.items[0]?.name == 'purchase_new_catalogue') {
|
||||
// call dpage api
|
||||
const businessId = invoice.externalBusinessId
|
||||
if (!businessId) {
|
||||
|
||||
@@ -9,6 +9,9 @@ export class Permission extends BaseEntity {
|
||||
@Column({ type: "enum", enum: PermissionEnum, nullable: false, unique: true })
|
||||
name: PermissionEnum;
|
||||
|
||||
@Column({ type: "varchar", length: 150, nullable: false })
|
||||
title: string;
|
||||
|
||||
@ManyToMany(() => Role, (role) => role.permissions)
|
||||
roles: Role[];
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ export class AdminsService {
|
||||
/************************************************************ */
|
||||
|
||||
async getPermissions() {
|
||||
const permissions = await this.permissionsRepository.find({ select: { id: true, name: true } });
|
||||
const permissions = await this.permissionsRepository.find({ select: { id: true, name: true, title: true } });
|
||||
return {
|
||||
permissions,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user