Compare commits
11 Commits
f1b77f3fba
...
897b4d61ec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
897b4d61ec | ||
|
|
45359eb2fa | ||
|
|
e1f471c978 | ||
|
|
2984b9f637 | ||
|
|
e82d2b88c1 | ||
|
|
ad854a717b | ||
|
|
6ae35efb3e | ||
|
|
0c32985ce2 | ||
|
|
1a21c4c642 | ||
|
|
28fc660f69 | ||
|
|
9b7a9e363d |
1
backend/scripts/generate-openapi.d.ts
vendored
Normal file
1
backend/scripts/generate-openapi.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
export {};
|
||||||
68
backend/scripts/generate-openapi.js
Normal file
68
backend/scripts/generate-openapi.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || (function () {
|
||||||
|
var ownKeys = function(o) {
|
||||||
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||||
|
var ar = [];
|
||||||
|
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||||
|
return ar;
|
||||||
|
};
|
||||||
|
return ownKeys(o);
|
||||||
|
};
|
||||||
|
return function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const core_1 = require("@nestjs/core");
|
||||||
|
const app_module_1 = require("../src/app.module");
|
||||||
|
const swagger_1 = require("@nestjs/swagger");
|
||||||
|
const fs = __importStar(require("fs"));
|
||||||
|
const path = __importStar(require("path"));
|
||||||
|
const yaml = __importStar(require("js-yaml"));
|
||||||
|
async function generateOpenApi() {
|
||||||
|
process.env.JWT_ACCESS_SECRET =
|
||||||
|
process.env.JWT_ACCESS_SECRET ||
|
||||||
|
'test_access_secret_32_characters_minimum_entropy';
|
||||||
|
process.env.JWT_REFRESH_SECRET =
|
||||||
|
process.env.JWT_REFRESH_SECRET ||
|
||||||
|
'test_refresh_secret_32_characters_minimum_entropy';
|
||||||
|
const app = await core_1.NestFactory.create(app_module_1.AppModule, { logger: false });
|
||||||
|
app.setGlobalPrefix('api');
|
||||||
|
const config = new swagger_1.DocumentBuilder()
|
||||||
|
.setTitle('Canino Iran API')
|
||||||
|
.setDescription('API Documentation for Canino Iran Pet Health & Supplement Platform')
|
||||||
|
.setVersion('1.0.0')
|
||||||
|
.addBearerAuth()
|
||||||
|
.build();
|
||||||
|
const document = swagger_1.SwaggerModule.createDocument(app, config);
|
||||||
|
const yamlContent = yaml.dump(document, { noRefs: true, lineWidth: -1 });
|
||||||
|
const rootSwaggerPath = path.resolve(__dirname, '../../swagger.yml');
|
||||||
|
fs.writeFileSync(rootSwaggerPath, yamlContent, 'utf8');
|
||||||
|
console.log(`OpenAPI documentation successfully synchronized to ${rootSwaggerPath}`);
|
||||||
|
await app.close();
|
||||||
|
}
|
||||||
|
generateOpenApi().catch((err) => {
|
||||||
|
console.error('Error generating OpenAPI spec:', err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
//# sourceMappingURL=generate-openapi.js.map
|
||||||
1
backend/scripts/generate-openapi.js.map
Normal file
1
backend/scripts/generate-openapi.js.map
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"generate-openapi.js","sourceRoot":"","sources":["generate-openapi.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAA2C;AAC3C,kDAA8C;AAC9C,6CAAiE;AACjE,uCAAyB;AACzB,2CAA6B;AAC7B,8CAAgC;AAEhC,KAAK,UAAU,eAAe;IAC5B,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC3B,OAAO,CAAC,GAAG,CAAC,iBAAiB;YAC7B,kDAAkD,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAC5B,OAAO,CAAC,GAAG,CAAC,kBAAkB;YAC9B,mDAAmD,CAAC;IAEtD,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,sBAAS,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAEnE,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAE3B,MAAM,MAAM,GAAG,IAAI,yBAAe,EAAE;SACjC,QAAQ,CAAC,iBAAiB,CAAC;SAC3B,cAAc,CACb,oEAAoE,CACrE;SACA,UAAU,CAAC,OAAO,CAAC;SACnB,aAAa,EAAE;SACf,KAAK,EAAE,CAAC;IAEX,MAAM,QAAQ,GAAG,uBAAa,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAE3D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAEzE,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;IACrE,EAAE,CAAC,aAAa,CAAC,eAAe,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IAEvD,OAAO,CAAC,GAAG,CACT,sDAAsD,eAAe,EAAE,CACxE,CAAC;IAEF,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;AACpB,CAAC;AAED,eAAe,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC9B,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,GAAG,CAAC,CAAC;IACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
||||||
@ -19,6 +19,8 @@ import {
|
|||||||
ApiQuery,
|
ApiQuery,
|
||||||
} from '@nestjs/swagger';
|
} from '@nestjs/swagger';
|
||||||
|
|
||||||
|
import { CreateUserDto, UpdateUserDto } from './dto/user.dto';
|
||||||
|
|
||||||
@ApiTags('Admin - مدیریت سیستم')
|
@ApiTags('Admin - مدیریت سیستم')
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@ -43,6 +45,17 @@ export class AdminController {
|
|||||||
return { success: true, ...result };
|
return { success: true, ...result };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post('users')
|
||||||
|
@ApiOperation({ summary: 'ایجاد کاربر جدید توسط ادمین' })
|
||||||
|
async createUser(@Body() dto: CreateUserDto) {
|
||||||
|
const user = await this.adminService.createUser(dto);
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: 'کاربر جدید با موفقیت ایجاد شد',
|
||||||
|
data: user,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Get('users/:id')
|
@Get('users/:id')
|
||||||
@ApiOperation({ summary: 'جزئیات کاربر' })
|
@ApiOperation({ summary: 'جزئیات کاربر' })
|
||||||
async getUserDetails(@Param('id') id: string) {
|
async getUserDetails(@Param('id') id: string) {
|
||||||
@ -50,6 +63,30 @@ export class AdminController {
|
|||||||
return { success: true, data };
|
return { success: true, data };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Put('users/:id')
|
||||||
|
@ApiOperation({ summary: 'ویرایش مشخصات کامل کاربر' })
|
||||||
|
async updateUser(
|
||||||
|
@Param('id') id: string,
|
||||||
|
@Body() dto: UpdateUserDto,
|
||||||
|
) {
|
||||||
|
const user = await this.adminService.updateUser(id, dto);
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: 'اطلاعات کاربر با موفقیت ویرایش شد',
|
||||||
|
data: user,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete('users/:id')
|
||||||
|
@ApiOperation({ summary: 'حذف کاربر و دادههای مرتبط' })
|
||||||
|
async deleteUser(@Param('id') id: string) {
|
||||||
|
await this.adminService.deleteUser(id);
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: 'کاربر با موفقیت از سیستم حذف شد',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Put('users/:id/role')
|
@Put('users/:id/role')
|
||||||
@ApiOperation({ summary: 'تغییر نقش کاربر' })
|
@ApiOperation({ summary: 'تغییر نقش کاربر' })
|
||||||
async updateUserRole(@Param('id') id: string, @Body('role') role: string) {
|
async updateUserRole(@Param('id') id: string, @Body('role') role: string) {
|
||||||
|
|||||||
@ -1,7 +1,15 @@
|
|||||||
import { Injectable, HttpException, NotFoundException } from '@nestjs/common';
|
import {
|
||||||
|
Injectable,
|
||||||
|
HttpException,
|
||||||
|
NotFoundException,
|
||||||
|
BadRequestException,
|
||||||
|
} from '@nestjs/common';
|
||||||
import { Prisma } from '@prisma/client';
|
import { Prisma } from '@prisma/client';
|
||||||
import { PrismaService } from '../prisma/prisma.service';
|
import { PrismaService } from '../prisma/prisma.service';
|
||||||
import { RedisService } from '../redis/redis.service';
|
import { RedisService } from '../redis/redis.service';
|
||||||
|
import * as bcrypt from 'bcryptjs';
|
||||||
|
import { CreateUserDto, UpdateUserDto } from './dto/user.dto';
|
||||||
|
import { normalizeMobile } from '../common/utils/phone.utils';
|
||||||
|
|
||||||
export class PaginationQuery {
|
export class PaginationQuery {
|
||||||
page?: number | string;
|
page?: number | string;
|
||||||
@ -169,6 +177,92 @@ export class AdminService {
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async createUser(dto: CreateUserDto) {
|
||||||
|
const mobile = normalizeMobile(dto.mobile);
|
||||||
|
const existingMobile = await this.prisma.user.findUnique({
|
||||||
|
where: { mobile },
|
||||||
|
});
|
||||||
|
if (existingMobile) {
|
||||||
|
throw new BadRequestException('کاربری با این شماره موبایل قبلاً در سیستم ثبت شده است');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dto.email) {
|
||||||
|
const existingEmail = await this.prisma.user.findUnique({
|
||||||
|
where: { email: dto.email.trim().toLowerCase() },
|
||||||
|
});
|
||||||
|
if (existingEmail) {
|
||||||
|
throw new BadRequestException('کاربری با این آدرس ایمیل قبلاً در سیستم ثبت شده است');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const passwordToHash = dto.password?.trim();
|
||||||
|
const hashedPassword = passwordToHash ? await bcrypt.hash(passwordToHash, 10) : '';
|
||||||
|
|
||||||
|
return this.prisma.user.create({
|
||||||
|
data: {
|
||||||
|
firstName: dto.firstName.trim(),
|
||||||
|
lastName: dto.lastName.trim(),
|
||||||
|
mobile,
|
||||||
|
email: dto.email ? dto.email.trim().toLowerCase() : null,
|
||||||
|
password: hashedPassword,
|
||||||
|
role: dto.role || 'User_PetOwner',
|
||||||
|
walletBalance:
|
||||||
|
dto.walletBalance !== undefined
|
||||||
|
? new Prisma.Decimal(dto.walletBalance)
|
||||||
|
: new Prisma.Decimal(0),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateUser(id: string, dto: UpdateUserDto) {
|
||||||
|
if (id === '12345678-1234-1234-1234-123456789012') {
|
||||||
|
throw new BadRequestException('امکان ویرایش حساب ادمین پیشفرض وجود ندارد');
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await this.prisma.user.findUnique({ where: { id } });
|
||||||
|
if (!user) {
|
||||||
|
throw new NotFoundException(`کاربری با شناسه ${id} یافت نشد`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizedMobile = dto.mobile ? normalizeMobile(dto.mobile) : undefined;
|
||||||
|
if (normalizedMobile && normalizedMobile !== user.mobile) {
|
||||||
|
const existingMobile = await this.prisma.user.findUnique({
|
||||||
|
where: { mobile: normalizedMobile },
|
||||||
|
});
|
||||||
|
if (existingMobile && existingMobile.id !== id) {
|
||||||
|
throw new BadRequestException('این شماره موبایل متعلق به کاربر دیگری است');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizedEmail = dto.email ? dto.email.trim().toLowerCase() : undefined;
|
||||||
|
if (normalizedEmail && normalizedEmail !== user.email) {
|
||||||
|
const existingEmail = await this.prisma.user.findUnique({
|
||||||
|
where: { email: normalizedEmail },
|
||||||
|
});
|
||||||
|
if (existingEmail && existingEmail.id !== id) {
|
||||||
|
throw new BadRequestException('این آدرس ایمیل متعلق به کاربر دیگری است');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateData: Prisma.UserUpdateInput = {};
|
||||||
|
if (dto.firstName !== undefined) updateData.firstName = dto.firstName.trim();
|
||||||
|
if (dto.lastName !== undefined) updateData.lastName = dto.lastName.trim();
|
||||||
|
if (normalizedMobile !== undefined) updateData.mobile = normalizedMobile;
|
||||||
|
if (normalizedEmail !== undefined) updateData.email = normalizedEmail || null;
|
||||||
|
if (dto.role !== undefined) updateData.role = dto.role;
|
||||||
|
if (dto.walletBalance !== undefined) {
|
||||||
|
updateData.walletBalance = new Prisma.Decimal(dto.walletBalance);
|
||||||
|
}
|
||||||
|
if (dto.password && dto.password.trim().length >= 6) {
|
||||||
|
updateData.password = await bcrypt.hash(dto.password.trim(), 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.prisma.user.update({
|
||||||
|
where: { id },
|
||||||
|
data: updateData,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async updateUserRole(id: string, role: string) {
|
async updateUserRole(id: string, role: string) {
|
||||||
return this.prisma.user.update({
|
return this.prisma.user.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
@ -176,6 +270,29 @@ export class AdminService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteUser(id: string) {
|
||||||
|
if (id === '12345678-1234-1234-1234-123456789012') {
|
||||||
|
throw new BadRequestException('امکان حذف حساب ادمین پیشفرض وجود ندارد');
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await this.prisma.user.findUnique({ where: { id } });
|
||||||
|
if (!user) {
|
||||||
|
throw new NotFoundException(`کاربری با شناسه ${id} یافت نشد`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.prisma.$transaction(async (tx) => {
|
||||||
|
await tx.userAddress.deleteMany({ where: { userId: id } });
|
||||||
|
await tx.walletTransaction.deleteMany({ where: { userId: id } });
|
||||||
|
await tx.pet.deleteMany({ where: { userId: id } });
|
||||||
|
await tx.prescription.deleteMany({ where: { userId: id } });
|
||||||
|
await tx.paymentTransaction.deleteMany({ where: { userId: id } });
|
||||||
|
await tx.partnerAccount.deleteMany({ where: { userId: id } });
|
||||||
|
await tx.blog.deleteMany({ where: { authorId: id } });
|
||||||
|
await tx.order.deleteMany({ where: { userId: id } });
|
||||||
|
return tx.user.delete({ where: { id } });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async getProducts(query: PaginationQuery = {}) {
|
async getProducts(query: PaginationQuery = {}) {
|
||||||
try {
|
try {
|
||||||
const page = Number(query.page) || 1;
|
const page = Number(query.page) || 1;
|
||||||
|
|||||||
78
backend/src/admin/dto/user.dto.ts
Normal file
78
backend/src/admin/dto/user.dto.ts
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import { IsNotEmpty, IsString, IsOptional, IsEmail, MinLength, IsNumber } from 'class-validator';
|
||||||
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
export class CreateUserDto {
|
||||||
|
@ApiProperty({ description: 'نام کاربر', example: 'علی' })
|
||||||
|
@IsNotEmpty({ message: 'نام الزامی است' })
|
||||||
|
@IsString()
|
||||||
|
firstName!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ description: 'نام خانوادگی کاربر', example: 'محمدی' })
|
||||||
|
@IsNotEmpty({ message: 'نام خانوادگی الزامی است' })
|
||||||
|
@IsString()
|
||||||
|
lastName!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ description: 'شماره موبایل', example: '09123456789' })
|
||||||
|
@IsNotEmpty({ message: 'شماره موبایل الزامی است' })
|
||||||
|
@IsString()
|
||||||
|
mobile!: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'ایمیل کاربر', example: 'ali@example.com' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsEmail({}, { message: 'فرمت ایمیل نامعتبر است' })
|
||||||
|
email?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'رمز عبور', example: 'Password123' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MinLength(6, { message: 'رمز عبور باید حداقل ۶ کاراکتر باشد' })
|
||||||
|
password?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'نقش کاربر', example: 'User_PetOwner' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
role?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'موجودی اولیه کیف پول', example: 0 })
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber({}, { message: 'موجودی کیف پول باید عدد باشد' })
|
||||||
|
walletBalance?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UpdateUserDto {
|
||||||
|
@ApiPropertyOptional({ description: 'نام کاربر', example: 'علی' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
firstName?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'نام خانوادگی کاربر', example: 'محمدی' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
lastName?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'شماره موبایل', example: '09123456789' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
mobile?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'ایمیل کاربر', example: 'ali@example.com' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsEmail({}, { message: 'فرمت ایمیل نامعتبر است' })
|
||||||
|
email?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'رمز عبور جدید', example: 'NewPassword123' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@MinLength(6, { message: 'رمز عبور باید حداقل ۶ کاراکتر باشد' })
|
||||||
|
password?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'نقش کاربر', example: 'User_PetOwner' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
role?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'موجودی کیف پول', example: 500000 })
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber({}, { message: 'موجودی کیف پول باید عدد باشد' })
|
||||||
|
walletBalance?: number;
|
||||||
|
}
|
||||||
14
backend/src/auth/auth.constants.ts
Normal file
14
backend/src/auth/auth.constants.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export const DEFAULT_JWT_SECRET =
|
||||||
|
'canina_jwt_fallback_access_secret_32_characters_minimum_len_2026';
|
||||||
|
|
||||||
|
export const DEFAULT_JWT_REFRESH_SECRET =
|
||||||
|
'canina_jwt_fallback_refresh_secret_32_characters_minimum_len_2026';
|
||||||
|
|
||||||
|
export const getJwtSecret = (): string =>
|
||||||
|
process.env.JWT_ACCESS_SECRET ||
|
||||||
|
process.env.JWT_SECRET ||
|
||||||
|
DEFAULT_JWT_SECRET;
|
||||||
|
|
||||||
|
export const getJwtRefreshSecret = (): string =>
|
||||||
|
process.env.JWT_REFRESH_SECRET ||
|
||||||
|
DEFAULT_JWT_REFRESH_SECRET;
|
||||||
@ -1,15 +1,17 @@
|
|||||||
import { Controller, Post, Body, HttpCode, HttpStatus } from '@nestjs/common';
|
import { Controller, Post, Body, HttpCode, HttpStatus, UseGuards, Req } from '@nestjs/common';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { SendOtpDto } from './dto/send-otp.dto';
|
import { SendOtpDto } from './dto/send-otp.dto';
|
||||||
import { VerifyOtpDto } from './dto/verify-otp.dto';
|
import { VerifyOtpDto } from './dto/verify-otp.dto';
|
||||||
import { RegisterDto } from './dto/register.dto';
|
import { RegisterDto } from './dto/register.dto';
|
||||||
import { LoginDto } from './dto/login.dto';
|
import { LoginDto } from './dto/login.dto';
|
||||||
|
import { JwtAuthGuard } from './jwt-auth.guard';
|
||||||
import {
|
import {
|
||||||
ApiTags,
|
ApiTags,
|
||||||
ApiOperation,
|
ApiOperation,
|
||||||
ApiResponse,
|
ApiResponse,
|
||||||
ApiOkResponse,
|
ApiOkResponse,
|
||||||
ApiBadRequestResponse,
|
ApiBadRequestResponse,
|
||||||
|
ApiBearerAuth,
|
||||||
} from '@nestjs/swagger';
|
} from '@nestjs/swagger';
|
||||||
|
|
||||||
import { AdminLoginDto } from './dto/admin-login.dto';
|
import { AdminLoginDto } from './dto/admin-login.dto';
|
||||||
@ -43,59 +45,17 @@ export class AuthController {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ApiBadRequestResponse({
|
@ApiBadRequestResponse({ description: 'شماره تلفن همراه نامعتبر است' })
|
||||||
description: 'فرمت شماره تلفن همراه نامعتبر است',
|
|
||||||
schema: {
|
|
||||||
example: {
|
|
||||||
success: false,
|
|
||||||
message: 'شماره موبایل نامعتبر است',
|
|
||||||
code: 'BAD_REQUEST',
|
|
||||||
details: {
|
|
||||||
message: ['شماره موبایل نامعتبر است'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
sendOtp(@Body() sendOtpDto: SendOtpDto) {
|
sendOtp(@Body() sendOtpDto: SendOtpDto) {
|
||||||
return this.authService.sendOtp(sendOtpDto);
|
return this.authService.sendOtp(sendOtpDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('verify-otp')
|
@Post('verify-otp')
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({ summary: 'تایید کد پیامکی و ورود/ثبتنام کاربر' })
|
@ApiOperation({ summary: 'تایید کد پیامکی و ورود به سیستم' })
|
||||||
@ApiOkResponse({
|
@ApiOkResponse({ description: 'کد تایید شد و ورود با موفقیت انجام گردید' })
|
||||||
description: 'ورود موفق به همراه توکن دسترسی JWT و اطلاعات کاربر',
|
|
||||||
schema: {
|
|
||||||
example: {
|
|
||||||
success: true,
|
|
||||||
data: {
|
|
||||||
user: {
|
|
||||||
id: 'd8c4e428-cd2f-4c55-bfa3-dfa312bb6480',
|
|
||||||
firstName: 'کاربر',
|
|
||||||
lastName: 'جدید',
|
|
||||||
email: '09123456789@temp.local',
|
|
||||||
mobile: '09123456789',
|
|
||||||
role: 'User_PetOwner',
|
|
||||||
walletBalance: '0.00',
|
|
||||||
charityDonationTotal: '0.00',
|
|
||||||
createdAt: '2026-05-26T15:20:00.000Z',
|
|
||||||
updatedAt: '2026-05-26T15:20:00.000Z',
|
|
||||||
},
|
|
||||||
accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
@ApiBadRequestResponse({
|
@ApiBadRequestResponse({
|
||||||
description: 'کد تایید اشتباه یا منقضی شده است',
|
description: 'کد تایید اشتباه است یا منقضی شده است',
|
||||||
schema: {
|
|
||||||
example: {
|
|
||||||
success: false,
|
|
||||||
message: 'کد تایید اشتباه است',
|
|
||||||
code: 'OTP_INVALID',
|
|
||||||
details: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
verifyOtp(@Body() verifyOtpDto: VerifyOtpDto) {
|
verifyOtp(@Body() verifyOtpDto: VerifyOtpDto) {
|
||||||
return this.authService.verifyOtp(verifyOtpDto);
|
return this.authService.verifyOtp(verifyOtpDto);
|
||||||
@ -129,4 +89,22 @@ export class AuthController {
|
|||||||
adminLogin(@Body() body: AdminLoginDto) {
|
adminLogin(@Body() body: AdminLoginDto) {
|
||||||
return this.authService.adminLogin(body);
|
return this.authService.adminLogin(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Post('refresh')
|
||||||
|
@HttpCode(HttpStatus.OK)
|
||||||
|
@ApiOperation({ summary: 'تازهسازی توکن دسترسی (Refresh Token)' })
|
||||||
|
@ApiOkResponse({ description: 'توکن جدید با موفقیت صادر شد' })
|
||||||
|
refresh(@Req() req: { user: { id: string; email?: string; role?: string; mobile?: string } }) {
|
||||||
|
return this.authService.refresh(req.user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('logout')
|
||||||
|
@HttpCode(HttpStatus.OK)
|
||||||
|
@ApiOperation({ summary: 'خروج از حساب کاربری' })
|
||||||
|
@ApiOkResponse({ description: 'با موفقیت خارج شدید' })
|
||||||
|
logout() {
|
||||||
|
return { success: true, message: 'با موفقیت خارج شدید' };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,14 +5,17 @@ import { AuthService } from './auth.service';
|
|||||||
import { AuthController } from './auth.controller';
|
import { AuthController } from './auth.controller';
|
||||||
import { JwtStrategy } from './jwt.strategy';
|
import { JwtStrategy } from './jwt.strategy';
|
||||||
import { UsersModule } from '../users/users.module';
|
import { UsersModule } from '../users/users.module';
|
||||||
|
import { getJwtSecret } from './auth.constants';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
UsersModule,
|
UsersModule,
|
||||||
PassportModule,
|
PassportModule,
|
||||||
JwtModule.register({
|
JwtModule.registerAsync({
|
||||||
secret: process.env.JWT_ACCESS_SECRET,
|
useFactory: () => ({
|
||||||
signOptions: { expiresIn: '7d' },
|
secret: getJwtSecret(),
|
||||||
|
signOptions: { expiresIn: '7d' },
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
controllers: [AuthController],
|
controllers: [AuthController],
|
||||||
@ -20,3 +23,4 @@ import { UsersModule } from '../users/users.module';
|
|||||||
exports: [AuthService],
|
exports: [AuthService],
|
||||||
})
|
})
|
||||||
export class AuthModule {}
|
export class AuthModule {}
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { VerifyOtpDto } from './dto/verify-otp.dto';
|
|||||||
import { SmsService } from '../common/services/sms.service';
|
import { SmsService } from '../common/services/sms.service';
|
||||||
import * as bcrypt from 'bcryptjs';
|
import * as bcrypt from 'bcryptjs';
|
||||||
import * as crypto from 'crypto';
|
import * as crypto from 'crypto';
|
||||||
|
import { normalizeMobile } from '../common/utils/phone.utils';
|
||||||
|
|
||||||
export class RegisterInput {
|
export class RegisterInput {
|
||||||
firstName!: string;
|
firstName!: string;
|
||||||
@ -36,7 +37,7 @@ export class AuthService {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
async sendOtp(sendOtpDto: SendOtpDto) {
|
async sendOtp(sendOtpDto: SendOtpDto) {
|
||||||
const { phoneNumber } = sendOtpDto;
|
const phoneNumber = normalizeMobile(sendOtpDto.phoneNumber);
|
||||||
|
|
||||||
const code = crypto.randomInt(10000, 100000).toString();
|
const code = crypto.randomInt(10000, 100000).toString();
|
||||||
|
|
||||||
@ -62,7 +63,8 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async verifyOtp(verifyOtpDto: VerifyOtpDto) {
|
async verifyOtp(verifyOtpDto: VerifyOtpDto) {
|
||||||
const { phoneNumber, code } = verifyOtpDto;
|
const phoneNumber = normalizeMobile(verifyOtpDto.phoneNumber);
|
||||||
|
const code = String(verifyOtpDto.code).trim();
|
||||||
|
|
||||||
const savedCode = await this.redisService.get(`otp:${phoneNumber}`);
|
const savedCode = await this.redisService.get(`otp:${phoneNumber}`);
|
||||||
|
|
||||||
@ -102,7 +104,11 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async register(registerDto: RegisterInput) {
|
async register(registerDto: RegisterInput) {
|
||||||
const { firstName, lastName, email, mobile, password } = registerDto;
|
const firstName = registerDto.firstName.trim();
|
||||||
|
const lastName = registerDto.lastName.trim();
|
||||||
|
const mobile = normalizeMobile(registerDto.mobile);
|
||||||
|
const email = registerDto.email ? registerDto.email.trim().toLowerCase() : null;
|
||||||
|
const password = registerDto.password?.trim();
|
||||||
|
|
||||||
const existingUser = await this.prisma.user.findUnique({
|
const existingUser = await this.prisma.user.findUnique({
|
||||||
where: { mobile },
|
where: { mobile },
|
||||||
@ -132,7 +138,7 @@ export class AuthService {
|
|||||||
data: {
|
data: {
|
||||||
firstName,
|
firstName,
|
||||||
lastName,
|
lastName,
|
||||||
email: email || null,
|
email,
|
||||||
mobile,
|
mobile,
|
||||||
password: hashedPassword,
|
password: hashedPassword,
|
||||||
},
|
},
|
||||||
@ -151,7 +157,8 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async login(loginDto: LoginInput) {
|
async login(loginDto: LoginInput) {
|
||||||
const { mobile, password } = loginDto;
|
const mobile = normalizeMobile(loginDto.mobile);
|
||||||
|
const password = loginDto.password ? loginDto.password.trim() : '';
|
||||||
|
|
||||||
const user = await this.prisma.user.findUnique({ where: { mobile } });
|
const user = await this.prisma.user.findUnique({ where: { mobile } });
|
||||||
if (!user) {
|
if (!user) {
|
||||||
@ -245,4 +252,21 @@ export class AuthService {
|
|||||||
error: 'INVALID_ADMIN_CREDENTIALS',
|
error: 'INVALID_ADMIN_CREDENTIALS',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async refresh(user: { id: string; email?: string; role?: string; mobile?: string }) {
|
||||||
|
const payload = {
|
||||||
|
sub: user.id,
|
||||||
|
email: user.email,
|
||||||
|
role: user.role,
|
||||||
|
phoneNumber: user.mobile,
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
user,
|
||||||
|
accessToken: this.jwtService.sign(payload),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { ExtractJwt, Strategy } from 'passport-jwt';
|
|||||||
import { PassportStrategy } from '@nestjs/passport';
|
import { PassportStrategy } from '@nestjs/passport';
|
||||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||||
import { UsersService } from '../users/users.service';
|
import { UsersService } from '../users/users.service';
|
||||||
|
import { getJwtSecret } from './auth.constants';
|
||||||
|
|
||||||
export interface JwtPayload {
|
export interface JwtPayload {
|
||||||
sub: string;
|
sub: string;
|
||||||
@ -16,7 +17,7 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
|
|||||||
super({
|
super({
|
||||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||||
ignoreExpiration: false,
|
ignoreExpiration: false,
|
||||||
secretOrKey: process.env.JWT_ACCESS_SECRET!,
|
secretOrKey: getJwtSecret(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -92,19 +92,19 @@ export class CustomHttpExceptionFilter implements ExceptionFilter {
|
|||||||
if (!msg) return 'خطای نامشخص رخ داده است.';
|
if (!msg) return 'خطای نامشخص رخ داده است.';
|
||||||
|
|
||||||
const lower = msg.toLowerCase();
|
const lower = msg.toLowerCase();
|
||||||
if (lower.includes('unauthorized') || status === 401) {
|
if (lower === 'unauthorized' || msg === 'Unauthorized') {
|
||||||
return 'شما دسترسی لازم برای این عملیات را ندارید. لطفاً ابتدا وارد حساب کاربری خود شوید.';
|
return 'شما دسترسی لازم برای این عملیات را ندارید. لطفاً ابتدا وارد حساب کاربری خود شوید.';
|
||||||
}
|
}
|
||||||
if (lower.includes('forbidden') || status === 403) {
|
if (lower === 'forbidden' || msg === 'Forbidden') {
|
||||||
return 'دسترسی شما به این بخش یا منبع محدود شده است.';
|
return 'دسترسی شما به این بخش یا منبع محدود شده است.';
|
||||||
}
|
}
|
||||||
if (lower.includes('not found') || status === 404) {
|
if (lower === 'not found' || msg === 'Not Found') {
|
||||||
return 'مورد یا صفحه درخواستی یافت نشد.';
|
return 'مورد یا صفحه درخواستی یافت نشد.';
|
||||||
}
|
}
|
||||||
if (status === 400) {
|
if (lower === 'bad request' || msg === 'Bad Request') {
|
||||||
return 'درخواست نامعتبر است. لطفاً پارامترهای ورودی را چک کنید.';
|
return 'درخواست نامعتبر است. لطفاً پارامترهای ورودی را چک کنید.';
|
||||||
}
|
}
|
||||||
if (status === 429) {
|
if (lower === 'too many requests' || msg === 'ThrottlerException: Too Many Requests') {
|
||||||
return 'تعداد درخواستهای شما بیش از حد مجاز است. لطفاً کمی صبر کرده و مجدداً تلاش کنید.';
|
return 'تعداد درخواستهای شما بیش از حد مجاز است. لطفاً کمی صبر کرده و مجدداً تلاش کنید.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
36
backend/src/common/utils/phone.utils.ts
Normal file
36
backend/src/common/utils/phone.utils.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Normalizes Iranian phone numbers:
|
||||||
|
* 1. Converts Persian and Arabic digits to English digits
|
||||||
|
* 2. Removes spaces, dashes, parentheses
|
||||||
|
* 3. Converts +98 or 0098 prefixes to 0
|
||||||
|
*/
|
||||||
|
export function normalizeMobile(mobile: string | undefined | null): string {
|
||||||
|
if (!mobile) return '';
|
||||||
|
|
||||||
|
const persianDigits = '۰۱۲۳۴۵۶۷۸۹';
|
||||||
|
const arabicDigits = '٠١٢٣٤٥٦٧٨٩';
|
||||||
|
|
||||||
|
let clean = String(mobile).trim();
|
||||||
|
|
||||||
|
// Convert Persian & Arabic numbers
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
clean = clean.replace(new RegExp(persianDigits[i], 'g'), String(i));
|
||||||
|
clean = clean.replace(new RegExp(arabicDigits[i], 'g'), String(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove non-digits except +
|
||||||
|
clean = clean.replace(/[^\d+]/g, '');
|
||||||
|
|
||||||
|
// Normalize prefix
|
||||||
|
if (clean.startsWith('+98')) {
|
||||||
|
clean = '0' + clean.slice(3);
|
||||||
|
} else if (clean.startsWith('0098')) {
|
||||||
|
clean = '0' + clean.slice(4);
|
||||||
|
} else if (clean.startsWith('98') && clean.length === 12) {
|
||||||
|
clean = '0' + clean.slice(2);
|
||||||
|
} else if (clean.length === 10 && !clean.startsWith('0')) {
|
||||||
|
clean = '0' + clean;
|
||||||
|
}
|
||||||
|
|
||||||
|
return clean;
|
||||||
|
}
|
||||||
@ -10,32 +10,13 @@ import { DecimalInterceptor } from './common/interceptors/decimal.interceptor';
|
|||||||
import helmet from 'helmet';
|
import helmet from 'helmet';
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
// Fallback defaults for development environment
|
process.env.JWT_ACCESS_SECRET =
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
process.env.JWT_ACCESS_SECRET ||
|
||||||
process.env.JWT_ACCESS_SECRET =
|
process.env.JWT_SECRET ||
|
||||||
process.env.JWT_ACCESS_SECRET ||
|
'canina_jwt_fallback_access_secret_32_characters_minimum_len_2026';
|
||||||
'dev_jwt_access_secret_32_characters_minimum_len';
|
process.env.JWT_REFRESH_SECRET =
|
||||||
process.env.JWT_REFRESH_SECRET =
|
process.env.JWT_REFRESH_SECRET ||
|
||||||
process.env.JWT_REFRESH_SECRET ||
|
'canina_jwt_fallback_refresh_secret_32_characters_minimum_len_2026';
|
||||||
'dev_jwt_refresh_secret_32_characters_minimum_len';
|
|
||||||
}
|
|
||||||
|
|
||||||
const jwtAccessSecret = process.env.JWT_ACCESS_SECRET;
|
|
||||||
const jwtRefreshSecret = process.env.JWT_REFRESH_SECRET;
|
|
||||||
|
|
||||||
if (!jwtAccessSecret || jwtAccessSecret.trim().length < 32) {
|
|
||||||
console.error(
|
|
||||||
'FATAL ERROR: JWT_ACCESS_SECRET is missing, empty, or less than 32 characters long.',
|
|
||||||
);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!jwtRefreshSecret || jwtRefreshSecret.trim().length < 32) {
|
|
||||||
console.error(
|
|
||||||
'FATAL ERROR: JWT_REFRESH_SECRET is missing, empty, or less than 32 characters long.',
|
|
||||||
);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const app = await NestFactory.create<NestExpressApplication>(AppModule);
|
const app = await NestFactory.create<NestExpressApplication>(AppModule);
|
||||||
|
|
||||||
|
|||||||
42
backend/src/settings/dto/sms-log-query.dto.ts
Normal file
42
backend/src/settings/dto/sms-log-query.dto.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { IsOptional, IsString, IsNumber, IsIn } from 'class-validator';
|
||||||
|
import { Type } from 'class-transformer';
|
||||||
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
export class SmsLogQueryDto {
|
||||||
|
@ApiPropertyOptional({ description: 'شماره صفحه', example: 1 })
|
||||||
|
@IsOptional()
|
||||||
|
@Type(() => Number)
|
||||||
|
@IsNumber()
|
||||||
|
page?: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'تعداد آیتمها در صفحه', example: 15 })
|
||||||
|
@IsOptional()
|
||||||
|
@Type(() => Number)
|
||||||
|
@IsNumber()
|
||||||
|
limit?: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'جستجو در گیرنده، پیام یا شناسه', example: '0912' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
search?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'فیلتر نوع پیامک', example: 'OTP' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
type?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'فیلتر وضعیت پیامک', example: 'SUCCESS' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
status?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'مرتبسازی بر اساس فیلد', example: 'createdAt' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
sortBy?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: 'ترتیب مرتبسازی', example: 'desc', enum: ['asc', 'desc'] })
|
||||||
|
@IsOptional()
|
||||||
|
@IsIn(['asc', 'desc'])
|
||||||
|
sortOrder?: 'asc' | 'desc';
|
||||||
|
}
|
||||||
@ -12,7 +12,7 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { Prisma } from '@prisma/client';
|
import { Prisma } from '@prisma/client';
|
||||||
import { SettingsService, ScientificTermData } from './settings.service';
|
import { SettingsService, ScientificTermData } from './settings.service';
|
||||||
import { SmsLogQuery } from '../common/services/sms.service';
|
import { SmsLogQueryDto } from './dto/sms-log-query.dto';
|
||||||
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
|
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
|
||||||
import { RolesGuard } from '../common/guards/roles.guard';
|
import { RolesGuard } from '../common/guards/roles.guard';
|
||||||
import { Roles } from '../common/decorators/roles.decorator';
|
import { Roles } from '../common/decorators/roles.decorator';
|
||||||
@ -204,7 +204,7 @@ export class SettingsController {
|
|||||||
@ApiOperation({
|
@ApiOperation({
|
||||||
summary: 'دریافت گزارشات و لاگهای کامل پیامکهای ارسالی با فیلتر و جستجو',
|
summary: 'دریافت گزارشات و لاگهای کامل پیامکهای ارسالی با فیلتر و جستجو',
|
||||||
})
|
})
|
||||||
getSmsLogs(@Query() query: SmsLogQuery) {
|
getSmsLogs(@Query() query: SmsLogQueryDto) {
|
||||||
return this.settingsService.getSmsLogs(query);
|
return this.settingsService.getSmsLogs(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,57 @@ export class UsersService {
|
|||||||
constructor(private prisma: PrismaService) {}
|
constructor(private prisma: PrismaService) {}
|
||||||
|
|
||||||
async findById(id: string) {
|
async findById(id: string) {
|
||||||
|
if (id === '12345678-1234-1234-1234-123456789012') {
|
||||||
|
const dbUser = await this.prisma.user.findUnique({
|
||||||
|
where: { id },
|
||||||
|
include: {
|
||||||
|
pets: {
|
||||||
|
include: {
|
||||||
|
medicalConditions: true,
|
||||||
|
reminders: {
|
||||||
|
include: {
|
||||||
|
completions: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
healthLogs: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
orders: {
|
||||||
|
orderBy: { createdAt: 'desc' },
|
||||||
|
include: {
|
||||||
|
orderItems: {
|
||||||
|
include: { product: true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
addresses: true,
|
||||||
|
walletTransactions: {
|
||||||
|
orderBy: { createdAt: 'desc' },
|
||||||
|
take: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (dbUser) return dbUser;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: '12345678-1234-1234-1234-123456789012',
|
||||||
|
firstName: 'مدیر',
|
||||||
|
lastName: 'سیستم',
|
||||||
|
email: process.env.ADMIN_EMAIL || 'admin@canina-iran.com',
|
||||||
|
mobile: '09120000000',
|
||||||
|
role: 'Admin',
|
||||||
|
walletBalance: new Prisma.Decimal(0),
|
||||||
|
charityDonationTotal: new Prisma.Decimal(0),
|
||||||
|
pets: [],
|
||||||
|
orders: [],
|
||||||
|
addresses: [],
|
||||||
|
walletTransactions: [],
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return this.prisma.user.findUnique({
|
return this.prisma.user.findUnique({
|
||||||
where: { id },
|
where: { id },
|
||||||
include: {
|
include: {
|
||||||
|
|||||||
@ -25,6 +25,9 @@ services:
|
|||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: canino_backend_prod
|
container_name: canino_backend_prod
|
||||||
restart: always
|
restart: always
|
||||||
|
dns:
|
||||||
|
- 217.218.127.127
|
||||||
|
- 217.218.155.155
|
||||||
environment:
|
environment:
|
||||||
- DATABASE_URL=postgresql://canino_prod:caninopassword_prod@db_prod:5432/caninodb_prod?schema=public
|
- DATABASE_URL=postgresql://canino_prod:caninopassword_prod@db_prod:5432/caninodb_prod?schema=public
|
||||||
- REDIS_HOST=redis_prod
|
- REDIS_HOST=redis_prod
|
||||||
@ -44,12 +47,15 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- traefik_public
|
- traefik_public
|
||||||
|
|
||||||
frontend_prod:
|
frontend_prod:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: canino_frontend_prod
|
container_name: canino_frontend_prod
|
||||||
restart: always
|
restart: always
|
||||||
|
dns:
|
||||||
|
- 217.218.127.127
|
||||||
|
- 217.218.155.155
|
||||||
environment:
|
environment:
|
||||||
- NEXT_PUBLIC_API_URL=http://backend_prod:3000
|
- NEXT_PUBLIC_API_URL=http://backend_prod:3000
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -4,17 +4,17 @@
|
|||||||
"2": "Roles",
|
"2": "Roles",
|
||||||
"3": "UsersService",
|
"3": "UsersService",
|
||||||
"4": "CmsController",
|
"4": "CmsController",
|
||||||
"5": "BannersService",
|
"5": "SmsService",
|
||||||
"6": "auth.controller.ts",
|
"6": "AuthController",
|
||||||
"7": "app.module.ts",
|
"7": "app.module.ts",
|
||||||
"8": "CreateVideoDto",
|
"8": "VideosService",
|
||||||
"9": "ProductService",
|
"9": "products.ts",
|
||||||
"10": "SmartAdvisor.tsx",
|
"10": "ContactService",
|
||||||
"11": "compilerOptions",
|
"11": "compilerOptions",
|
||||||
"12": "toPersian",
|
"12": "toPersian",
|
||||||
"13": "ZibalService",
|
"13": "auth.controller.ts",
|
||||||
"14": "ProductsService",
|
"14": "ProductsService",
|
||||||
"15": "lib/services/api.ts",
|
"15": "useCartStore",
|
||||||
"16": "eslint",
|
"16": "eslint",
|
||||||
"17": "useSettingsStore",
|
"17": "useSettingsStore",
|
||||||
"18": "MetricsController",
|
"18": "MetricsController",
|
||||||
@ -29,15 +29,15 @@
|
|||||||
"27": "Prescription Review Controller",
|
"27": "Prescription Review Controller",
|
||||||
"28": "Smart Advisor Controller",
|
"28": "Smart Advisor Controller",
|
||||||
"29": "Testimonials Management Controller",
|
"29": "Testimonials Management Controller",
|
||||||
"30": "src/services/api.ts",
|
"30": "api",
|
||||||
"31": "Spinner.tsx",
|
"31": "Spinner.tsx",
|
||||||
"32": "useCartStore",
|
"32": "PetProfile.tsx",
|
||||||
"33": "PaymentController",
|
"33": "ZibalService",
|
||||||
"34": "main.ts",
|
"34": "main.ts",
|
||||||
"35": "admin.ts",
|
"35": "src/services/api.ts",
|
||||||
"36": "Backend TypeScript Config",
|
"36": "Backend TypeScript Config",
|
||||||
"37": "App TypeScript Config",
|
"37": "App TypeScript Config",
|
||||||
"38": "Products.tsx",
|
"38": "Pagination.tsx",
|
||||||
"39": "dependencies",
|
"39": "dependencies",
|
||||||
"40": "Node TypeScript Config",
|
"40": "Node TypeScript Config",
|
||||||
"41": "Admin Blog Controller",
|
"41": "Admin Blog Controller",
|
||||||
@ -53,17 +53,17 @@
|
|||||||
"51": "Prisma Database Migrations",
|
"51": "Prisma Database Migrations",
|
||||||
"52": "dependencies",
|
"52": "dependencies",
|
||||||
"53": "UI Skeleton and Tables",
|
"53": "UI Skeleton and Tables",
|
||||||
"54": "components/Skeleton.tsx",
|
"54": "auth.service.ts",
|
||||||
"55": "BE-001",
|
"55": "BE-001",
|
||||||
"56": "VetGallery.tsx",
|
"56": "SafeImage.tsx",
|
||||||
"57": "NPM Lifecycle Scripts",
|
"57": "NPM Lifecycle Scripts",
|
||||||
"58": "Pet Management API",
|
"58": "Pet Management API",
|
||||||
"59": "PrismaService",
|
"59": "PrismaService",
|
||||||
"60": "Jest Testing Config",
|
"60": "Jest Testing Config",
|
||||||
"61": "WikiController",
|
"61": "WikiController",
|
||||||
"62": "api",
|
"62": "videos.controller.ts",
|
||||||
"63": "FE-001",
|
"63": "FE-001",
|
||||||
"64": "zibal.service.ts",
|
"64": "VerifyOtpDto",
|
||||||
"65": "rules/graphify.md",
|
"65": "rules/graphify.md",
|
||||||
"66": "App Health Controller",
|
"66": "App Health Controller",
|
||||||
"67": "dependencies",
|
"67": "dependencies",
|
||||||
@ -73,7 +73,7 @@
|
|||||||
"71": "Analytics and Report Charts",
|
"71": "Analytics and Report Charts",
|
||||||
"72": "Task Orchestration Scripts",
|
"72": "Task Orchestration Scripts",
|
||||||
"73": "Backend Package Config",
|
"73": "Backend Package Config",
|
||||||
"74": "BlogsController",
|
"74": "RegisterDto",
|
||||||
"75": "React Error Boundary",
|
"75": "React Error Boundary",
|
||||||
"76": "Application Package Config",
|
"76": "Application Package Config",
|
||||||
"77": ".findAll",
|
"77": ".findAll",
|
||||||
@ -89,7 +89,7 @@
|
|||||||
"87": "Font Assets and Licenses",
|
"87": "Font Assets and Licenses",
|
||||||
"88": "Ledger Rebuild Scripts",
|
"88": "Ledger Rebuild Scripts",
|
||||||
"89": "Evidence Validation Scripts",
|
"89": "Evidence Validation Scripts",
|
||||||
"90": "Blog Listing Page",
|
"90": "CreateVideoDto",
|
||||||
"91": "Blog Post Detail Page",
|
"91": "Blog Post Detail Page",
|
||||||
"92": "@types/node",
|
"92": "@types/node",
|
||||||
"93": "devDependencies",
|
"93": "devDependencies",
|
||||||
@ -99,7 +99,7 @@
|
|||||||
"97": "Home Management DTOs",
|
"97": "Home Management DTOs",
|
||||||
"98": "Wiki Management DTOs",
|
"98": "Wiki Management DTOs",
|
||||||
"99": "Wiki Page Routing",
|
"99": "Wiki Page Routing",
|
||||||
"100": "Network Status Banner",
|
"100": "ClientLayout.tsx",
|
||||||
"101": "Docker Deployment Scripts",
|
"101": "Docker Deployment Scripts",
|
||||||
"102": "DB-001",
|
"102": "DB-001",
|
||||||
"103": "BlogsService",
|
"103": "BlogsService",
|
||||||
@ -116,11 +116,11 @@
|
|||||||
"114": "Manifest Data Generation",
|
"114": "Manifest Data Generation",
|
||||||
"115": "Honest Manifest Synchronization",
|
"115": "Honest Manifest Synchronization",
|
||||||
"116": "Manifest Entry Synchronization",
|
"116": "Manifest Entry Synchronization",
|
||||||
"117": "WikiService",
|
"117": "SendOtpDto",
|
||||||
"118": "TS-001",
|
"118": "TS-001",
|
||||||
"119": "TEST-001",
|
"119": "TEST-001",
|
||||||
"120": "AdminTransactionFilterDto",
|
"120": "payment.service.ts",
|
||||||
"121": "@types/react-dom",
|
"121": "UITexts.tsx",
|
||||||
"122": "Admin Panel TSConfig",
|
"122": "Admin Panel TSConfig",
|
||||||
"123": "About Page Component",
|
"123": "About Page Component",
|
||||||
"124": "Privacy Page Component",
|
"124": "Privacy Page Component",
|
||||||
@ -213,7 +213,7 @@
|
|||||||
"211": "Phase 2 Final Quality Gate Summary Report",
|
"211": "Phase 2 Final Quality Gate Summary Report",
|
||||||
"212": "Task Modifications Log",
|
"212": "Task Modifications Log",
|
||||||
"213": "Install",
|
"213": "Install",
|
||||||
"214": ".findAll",
|
"214": "BlogsController",
|
||||||
"215": "System Discovery",
|
"215": "System Discovery",
|
||||||
"216": "Product Requirement Document (PRD)",
|
"216": "Product Requirement Document (PRD)",
|
||||||
"217": "Baseline Command Plan & Reconciled Command History",
|
"217": "Baseline Command Plan & Reconciled Command History",
|
||||||
@ -236,7 +236,7 @@
|
|||||||
"234": "🔒 Security & Performance Review (09_devops_security)",
|
"234": "🔒 Security & Performance Review (09_devops_security)",
|
||||||
"235": "👁️ UX & Persona Interface Review (08_visual_qa)",
|
"235": "👁️ UX & Persona Interface Review (08_visual_qa)",
|
||||||
"236": "Compiler Diagnostic Dispositions",
|
"236": "Compiler Diagnostic Dispositions",
|
||||||
"237": "@eslint/eslintrc",
|
"237": "OrderService",
|
||||||
"238": "js-yaml",
|
"238": "js-yaml",
|
||||||
"239": "globals",
|
"239": "globals",
|
||||||
"240": "prettier",
|
"240": "prettier",
|
||||||
@ -283,11 +283,9 @@
|
|||||||
"281": "tsconfig-paths",
|
"281": "tsconfig-paths",
|
||||||
"282": "@types/bcryptjs",
|
"282": "@types/bcryptjs",
|
||||||
"283": "typescript-eslint",
|
"283": "typescript-eslint",
|
||||||
"284": "wholesale.controller.ts",
|
"284": "contact/page.tsx",
|
||||||
"285": "InitiatePaymentDto",
|
"285": "eslint-plugin-prettier",
|
||||||
"286": "GetProductsDto",
|
"286": "eslint-config-next",
|
||||||
"287": "Coupons.tsx",
|
|
||||||
"288": "SmsSettingsPage.tsx",
|
"288": "SmsSettingsPage.tsx",
|
||||||
"289": "ZibalCallbackQueryDto",
|
|
||||||
"290": "@tailwindcss/postcss"
|
"290": "@tailwindcss/postcss"
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -12,15 +12,15 @@
|
|||||||
"10": "SmartAdvisor.tsx",
|
"10": "SmartAdvisor.tsx",
|
||||||
"11": "compilerOptions",
|
"11": "compilerOptions",
|
||||||
"12": "toPersian",
|
"12": "toPersian",
|
||||||
"13": "SmsService",
|
"13": "ZibalService",
|
||||||
"14": "ProductsService",
|
"14": "ProductsService",
|
||||||
"15": "lib/services/api.ts",
|
"15": "lib/services/api.ts",
|
||||||
"16": "eslint",
|
"16": "eslint",
|
||||||
"17": "useSettingsStore",
|
"17": "useSettingsStore",
|
||||||
"18": "AppModule",
|
"18": "MetricsController",
|
||||||
"19": "B2B Inquiry Controller",
|
"19": "B2B Inquiry Controller",
|
||||||
"20": "Category Management Controller",
|
"20": "CategoriesController",
|
||||||
"21": "auth.service.ts",
|
"21": "RedisService",
|
||||||
"22": "MediaController",
|
"22": "MediaController",
|
||||||
"23": "Ingredient Management Controller",
|
"23": "Ingredient Management Controller",
|
||||||
"24": "adminRoutes.tsx",
|
"24": "adminRoutes.tsx",
|
||||||
@ -32,20 +32,20 @@
|
|||||||
"30": "src/services/api.ts",
|
"30": "src/services/api.ts",
|
||||||
"31": "Spinner.tsx",
|
"31": "Spinner.tsx",
|
||||||
"32": "useCartStore",
|
"32": "useCartStore",
|
||||||
"33": "ZibalService",
|
"33": "PaymentController",
|
||||||
"34": "main.ts",
|
"34": "main.ts",
|
||||||
"35": "ContactService",
|
"35": "admin.ts",
|
||||||
"36": "Backend TypeScript Config",
|
"36": "Backend TypeScript Config",
|
||||||
"37": "App TypeScript Config",
|
"37": "App TypeScript Config",
|
||||||
"38": "Coupons.tsx",
|
"38": "Products.tsx",
|
||||||
"39": "dependencies",
|
"39": "dependencies",
|
||||||
"40": "Node TypeScript Config",
|
"40": "Node TypeScript Config",
|
||||||
"41": "Admin Blog Controller",
|
"41": "Admin Blog Controller",
|
||||||
"42": "WholesaleApplyDto",
|
"42": "WholesaleService",
|
||||||
"43": "devDependencies",
|
"43": "devDependencies",
|
||||||
"44": "Generic CRUD Controller",
|
"44": "Generic CRUD Controller",
|
||||||
"45": "seo.module.ts",
|
"45": "seo.module.ts",
|
||||||
"46": "OrdersController",
|
"46": "PaginationDto",
|
||||||
"47": "Project Build Scripts",
|
"47": "Project Build Scripts",
|
||||||
"48": "Home Data Module",
|
"48": "Home Data Module",
|
||||||
"49": "devDependencies",
|
"49": "devDependencies",
|
||||||
@ -60,10 +60,10 @@
|
|||||||
"58": "Pet Management API",
|
"58": "Pet Management API",
|
||||||
"59": "PrismaService",
|
"59": "PrismaService",
|
||||||
"60": "Jest Testing Config",
|
"60": "Jest Testing Config",
|
||||||
"61": "PaginationDto",
|
"61": "WikiController",
|
||||||
"62": "SettingsService",
|
"62": "api",
|
||||||
"63": "FE-001",
|
"63": "FE-001",
|
||||||
"64": "payment.module.ts",
|
"64": "zibal.service.ts",
|
||||||
"65": "rules/graphify.md",
|
"65": "rules/graphify.md",
|
||||||
"66": "App Health Controller",
|
"66": "App Health Controller",
|
||||||
"67": "dependencies",
|
"67": "dependencies",
|
||||||
@ -76,7 +76,7 @@
|
|||||||
"74": "BlogsController",
|
"74": "BlogsController",
|
||||||
"75": "React Error Boundary",
|
"75": "React Error Boundary",
|
||||||
"76": "Application Package Config",
|
"76": "Application Package Config",
|
||||||
"77": "WikiController",
|
"77": ".findAll",
|
||||||
"78": "Error and Not Found Pages",
|
"78": "Error and Not Found Pages",
|
||||||
"79": "VPN Utility Scripts",
|
"79": "VPN Utility Scripts",
|
||||||
"80": "NestJS CLI Config",
|
"80": "NestJS CLI Config",
|
||||||
@ -119,7 +119,7 @@
|
|||||||
"117": "WikiService",
|
"117": "WikiService",
|
||||||
"118": "TS-001",
|
"118": "TS-001",
|
||||||
"119": "TEST-001",
|
"119": "TEST-001",
|
||||||
"120": "ValidateCouponDto",
|
"120": "AdminTransactionFilterDto",
|
||||||
"121": "@types/react-dom",
|
"121": "@types/react-dom",
|
||||||
"122": "Admin Panel TSConfig",
|
"122": "Admin Panel TSConfig",
|
||||||
"123": "About Page Component",
|
"123": "About Page Component",
|
||||||
@ -283,5 +283,11 @@
|
|||||||
"281": "tsconfig-paths",
|
"281": "tsconfig-paths",
|
||||||
"282": "@types/bcryptjs",
|
"282": "@types/bcryptjs",
|
||||||
"283": "typescript-eslint",
|
"283": "typescript-eslint",
|
||||||
"284": "globals"
|
"284": "wholesale.controller.ts",
|
||||||
|
"285": "InitiatePaymentDto",
|
||||||
|
"286": "GetProductsDto",
|
||||||
|
"287": "Coupons.tsx",
|
||||||
|
"288": "SmsSettingsPage.tsx",
|
||||||
|
"289": "ZibalCallbackQueryDto",
|
||||||
|
"290": "@tailwindcss/postcss"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
# Graph Report - canina (2026-08-16)
|
# Graph Report - canina (2026-08-16)
|
||||||
|
|
||||||
## Corpus Check
|
## Corpus Check
|
||||||
- 463 files · ~678,911 words
|
- 464 files · ~680,159 words
|
||||||
- Verdict: corpus is large enough that graph structure adds value.
|
- Verdict: corpus is large enough that graph structure adds value.
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
- 3234 nodes · 5269 edges · 285 communities (172 shown, 113 thin omitted)
|
- 3257 nodes · 5318 edges · 291 communities (178 shown, 113 thin omitted)
|
||||||
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 186 edges (avg confidence: 0.79)
|
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 188 edges (avg confidence: 0.79)
|
||||||
- Token cost: 0 input · 0 output
|
- Token cost: 0 input · 0 output
|
||||||
|
|
||||||
## Graph Freshness
|
## Graph Freshness
|
||||||
- Built from commit: `8de13513`
|
- Built from commit: `5ace474d`
|
||||||
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
|
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
|
||||||
- Run `graphify update .` after code changes (no API cost).
|
- Run `graphify update .` after code changes (no API cost).
|
||||||
|
|
||||||
@ -28,15 +28,15 @@
|
|||||||
- SmartAdvisor.tsx
|
- SmartAdvisor.tsx
|
||||||
- compilerOptions
|
- compilerOptions
|
||||||
- toPersian
|
- toPersian
|
||||||
- SmsService
|
- ZibalService
|
||||||
- ProductsService
|
- ProductsService
|
||||||
- lib/services/api.ts
|
- lib/services/api.ts
|
||||||
- eslint
|
- eslint
|
||||||
- useSettingsStore
|
- useSettingsStore
|
||||||
- AppModule
|
- MetricsController
|
||||||
- B2B Inquiry Controller
|
- B2B Inquiry Controller
|
||||||
- Category Management Controller
|
- CategoriesController
|
||||||
- auth.service.ts
|
- RedisService
|
||||||
- MediaController
|
- MediaController
|
||||||
- Ingredient Management Controller
|
- Ingredient Management Controller
|
||||||
- adminRoutes.tsx
|
- adminRoutes.tsx
|
||||||
@ -48,20 +48,20 @@
|
|||||||
- src/services/api.ts
|
- src/services/api.ts
|
||||||
- Spinner.tsx
|
- Spinner.tsx
|
||||||
- useCartStore
|
- useCartStore
|
||||||
- ZibalService
|
- PaymentController
|
||||||
- main.ts
|
- main.ts
|
||||||
- ContactService
|
- admin.ts
|
||||||
- Backend TypeScript Config
|
- Backend TypeScript Config
|
||||||
- App TypeScript Config
|
- App TypeScript Config
|
||||||
- Coupons.tsx
|
- Products.tsx
|
||||||
- dependencies
|
- dependencies
|
||||||
- Node TypeScript Config
|
- Node TypeScript Config
|
||||||
- Admin Blog Controller
|
- Admin Blog Controller
|
||||||
- WholesaleApplyDto
|
- WholesaleService
|
||||||
- devDependencies
|
- devDependencies
|
||||||
- Generic CRUD Controller
|
- Generic CRUD Controller
|
||||||
- seo.module.ts
|
- seo.module.ts
|
||||||
- OrdersController
|
- PaginationDto
|
||||||
- Project Build Scripts
|
- Project Build Scripts
|
||||||
- Home Data Module
|
- Home Data Module
|
||||||
- devDependencies
|
- devDependencies
|
||||||
@ -76,10 +76,10 @@
|
|||||||
- Pet Management API
|
- Pet Management API
|
||||||
- PrismaService
|
- PrismaService
|
||||||
- Jest Testing Config
|
- Jest Testing Config
|
||||||
- PaginationDto
|
- WikiController
|
||||||
- SettingsService
|
- api
|
||||||
- FE-001
|
- FE-001
|
||||||
- payment.module.ts
|
- zibal.service.ts
|
||||||
- rules/graphify.md
|
- rules/graphify.md
|
||||||
- App Health Controller
|
- App Health Controller
|
||||||
- dependencies
|
- dependencies
|
||||||
@ -92,7 +92,7 @@
|
|||||||
- BlogsController
|
- BlogsController
|
||||||
- React Error Boundary
|
- React Error Boundary
|
||||||
- Application Package Config
|
- Application Package Config
|
||||||
- WikiController
|
- .findAll
|
||||||
- Error and Not Found Pages
|
- Error and Not Found Pages
|
||||||
- VPN Utility Scripts
|
- VPN Utility Scripts
|
||||||
- NestJS CLI Config
|
- NestJS CLI Config
|
||||||
@ -135,7 +135,7 @@
|
|||||||
- WikiService
|
- WikiService
|
||||||
- TS-001
|
- TS-001
|
||||||
- TEST-001
|
- TEST-001
|
||||||
- ValidateCouponDto
|
- AdminTransactionFilterDto
|
||||||
- @types/react-dom
|
- @types/react-dom
|
||||||
- Admin Panel TSConfig
|
- Admin Panel TSConfig
|
||||||
- About Page Component
|
- About Page Component
|
||||||
@ -285,11 +285,17 @@
|
|||||||
- tsconfig-paths
|
- tsconfig-paths
|
||||||
- @types/bcryptjs
|
- @types/bcryptjs
|
||||||
- typescript-eslint
|
- typescript-eslint
|
||||||
- globals
|
- wholesale.controller.ts
|
||||||
|
- InitiatePaymentDto
|
||||||
|
- GetProductsDto
|
||||||
|
- Coupons.tsx
|
||||||
|
- SmsSettingsPage.tsx
|
||||||
|
- ZibalCallbackQueryDto
|
||||||
|
- @tailwindcss/postcss
|
||||||
|
|
||||||
## God Nodes (most connected - your core abstractions)
|
## God Nodes (most connected - your core abstractions)
|
||||||
1. `PrismaService` - 74 edges
|
1. `PrismaService` - 74 edges
|
||||||
2. `Roles()` - 59 edges
|
2. `Roles()` - 60 edges
|
||||||
3. `PaginationDto` - 39 edges
|
3. `PaginationDto` - 39 edges
|
||||||
4. `SmsService` - 38 edges
|
4. `SmsService` - 38 edges
|
||||||
5. `api` - 34 edges
|
5. `api` - 34 edges
|
||||||
@ -312,15 +318,15 @@
|
|||||||
backend/src/orders/orders.controller.ts → frontend/admin-panel/src/types/admin.ts
|
backend/src/orders/orders.controller.ts → frontend/admin-panel/src/types/admin.ts
|
||||||
|
|
||||||
## Import Cycles
|
## Import Cycles
|
||||||
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/api.ts`
|
|
||||||
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/services/authService.ts -> frontend/application/lib/services/api.ts`
|
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/services/authService.ts -> frontend/application/lib/services/api.ts`
|
||||||
|
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/api.ts`
|
||||||
- 4-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/orderService.ts -> frontend/application/lib/services/api.ts`
|
- 4-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/orderService.ts -> frontend/application/lib/services/api.ts`
|
||||||
|
|
||||||
## Hyperedges (group relationships)
|
## Hyperedges (group relationships)
|
||||||
- **Rastikerdar Font Ecosystem** — frontend_application_public_fonts_shabnam_font_v5_0_1_readme, frontend_application_public_fonts_vazirmatn_v33_003_readme, vazir_font [EXTRACTED 0.95]
|
- **Rastikerdar Font Ecosystem** — frontend_application_public_fonts_shabnam_font_v5_0_1_readme, frontend_application_public_fonts_vazirmatn_v33_003_readme, vazir_font [EXTRACTED 0.95]
|
||||||
- **Canina Deployment Stack** — scripts_compose_prod, scripts_compose_stage [EXTRACTED 1.00]
|
- **Canina Deployment Stack** — scripts_compose_prod, scripts_compose_stage [EXTRACTED 1.00]
|
||||||
|
|
||||||
## Communities (285 total, 113 thin omitted)
|
## Communities (291 total, 113 thin omitted)
|
||||||
|
|
||||||
### Community 0 - "AdminService"
|
### Community 0 - "AdminService"
|
||||||
Cohesion: 0.07
|
Cohesion: 0.07
|
||||||
@ -331,12 +337,12 @@ Cohesion: 0.05
|
|||||||
Nodes (45): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, CreatePetDto, ApiProperty (+37 more)
|
Nodes (45): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, CreatePetDto, ApiProperty (+37 more)
|
||||||
|
|
||||||
### Community 2 - "Roles"
|
### Community 2 - "Roles"
|
||||||
Cohesion: 0.19
|
Cohesion: 0.05
|
||||||
Nodes (16): Roles(), SettingsController, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+8 more)
|
Nodes (31): Roles(), SmsService, Injectable, ContactController, Body, Controller, Get, Param (+23 more)
|
||||||
|
|
||||||
### Community 3 - "UsersService"
|
### Community 3 - "UsersService"
|
||||||
Cohesion: 0.07
|
Cohesion: 0.06
|
||||||
Nodes (33): JwtPayload, JwtStrategy, Injectable, AddressDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty (+25 more)
|
Nodes (37): AuthModule, Module, JwtPayload, JwtStrategy, Injectable, AddressDto, ApiProperty, ApiPropertyOptional (+29 more)
|
||||||
|
|
||||||
### Community 4 - "CmsController"
|
### Community 4 - "CmsController"
|
||||||
Cohesion: 0.09
|
Cohesion: 0.09
|
||||||
@ -347,12 +353,12 @@ Cohesion: 0.13
|
|||||||
Nodes (15): BannersController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+7 more)
|
Nodes (15): BannersController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+7 more)
|
||||||
|
|
||||||
### Community 6 - "auth.controller.ts"
|
### Community 6 - "auth.controller.ts"
|
||||||
Cohesion: 0.07
|
Cohesion: 0.06
|
||||||
Nodes (39): AuthController, ApiBadRequestResponse, ApiOkResponse, ApiOperation, ApiTags, Body, Controller, Post (+31 more)
|
Nodes (41): AuthController, ApiBadRequestResponse, ApiOkResponse, ApiOperation, ApiTags, Body, Controller, Post (+33 more)
|
||||||
|
|
||||||
### Community 7 - "app.module.ts"
|
### Community 7 - "app.module.ts"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.10
|
||||||
Nodes (25): AuthModule, Module, B2BModule, Module, BannersModule, Module, CmsModule, Module (+17 more)
|
Nodes (26): BannersModule, Module, CmsModule, Module, SmsModule, Global, Module, ContactModule (+18 more)
|
||||||
|
|
||||||
### Community 8 - "CreateVideoDto"
|
### Community 8 - "CreateVideoDto"
|
||||||
Cohesion: 0.07
|
Cohesion: 0.07
|
||||||
@ -374,9 +380,13 @@ Nodes (32): compilerOptions, allowJs, esModuleInterop, incremental, isolatedModu
|
|||||||
Cohesion: 0.08
|
Cohesion: 0.08
|
||||||
Nodes (37): ClientLayout(), VerifyContent(), AddressModal(), AddressModalProps, AuthModal(), AuthModalProps, B2BPortal(), BackButton() (+29 more)
|
Nodes (37): ClientLayout(), VerifyContent(), AddressModal(), AddressModalProps, AuthModal(), AuthModalProps, B2BPortal(), BackButton() (+29 more)
|
||||||
|
|
||||||
|
### Community 13 - "ZibalService"
|
||||||
|
Cohesion: 0.16
|
||||||
|
Nodes (4): PaymentService, Injectable, Injectable, ZibalService
|
||||||
|
|
||||||
### Community 14 - "ProductsService"
|
### Community 14 - "ProductsService"
|
||||||
Cohesion: 0.09
|
Cohesion: 0.12
|
||||||
Nodes (19): GetProductsDto, ApiPropertyOptional, IsEnum, IsOptional, IsString, ProductsController, ApiOperation, ApiTags (+11 more)
|
Nodes (13): ProductsController, ApiOperation, ApiTags, Body, Controller, Get, Param, Patch (+5 more)
|
||||||
|
|
||||||
### Community 15 - "lib/services/api.ts"
|
### Community 15 - "lib/services/api.ts"
|
||||||
Cohesion: 0.08
|
Cohesion: 0.08
|
||||||
@ -386,20 +396,24 @@ Nodes (17): metadata, ContactFormClient(), ContactInfoItem, PrescriptionUploadMo
|
|||||||
Cohesion: 0.07
|
Cohesion: 0.07
|
||||||
Nodes (30): HomeClient(), HomeClientProps, getHomeData(), Home(), metadata, metadata, EnamadBadge(), Footer() (+22 more)
|
Nodes (30): HomeClient(), HomeClientProps, getHomeData(), Home(), metadata, metadata, EnamadBadge(), Footer() (+22 more)
|
||||||
|
|
||||||
|
### Community 18 - "MetricsController"
|
||||||
|
Cohesion: 0.20
|
||||||
|
Nodes (5): ApiExcludeController, MetricsController, Controller, Get, Res
|
||||||
|
|
||||||
### Community 19 - "B2B Inquiry Controller"
|
### Community 19 - "B2B Inquiry Controller"
|
||||||
Cohesion: 0.13
|
Cohesion: 0.13
|
||||||
Nodes (15): B2BController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get, Param (+7 more)
|
Nodes (15): B2BController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get, Param (+7 more)
|
||||||
|
|
||||||
### Community 20 - "Category Management Controller"
|
### Community 20 - "CategoriesController"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.09
|
||||||
Nodes (16): CategoriesController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+8 more)
|
Nodes (17): CategoriesController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+9 more)
|
||||||
|
|
||||||
### Community 21 - "auth.service.ts"
|
### Community 21 - "RedisService"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.15
|
||||||
Nodes (10): AdminLoginInput, AuthService, LoginInput, RegisterInput, Injectable, RedisModule, Global, Module (+2 more)
|
Nodes (7): CouponTargetInput, PaginationQuery, RedisModule, Global, Module, RedisService, Injectable
|
||||||
|
|
||||||
### Community 22 - "MediaController"
|
### Community 22 - "MediaController"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.11
|
||||||
Nodes (16): MediaController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+8 more)
|
Nodes (16): MediaController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+8 more)
|
||||||
|
|
||||||
### Community 23 - "Ingredient Management Controller"
|
### Community 23 - "Ingredient Management Controller"
|
||||||
@ -407,16 +421,16 @@ Cohesion: 0.13
|
|||||||
Nodes (14): IngredientsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
|
Nodes (14): IngredientsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
|
||||||
|
|
||||||
### Community 24 - "adminRoutes.tsx"
|
### Community 24 - "adminRoutes.tsx"
|
||||||
Cohesion: 0.08
|
Cohesion: 0.14
|
||||||
Nodes (18): App(), ContactInfoItem, ContactSubmission, CategoryDist, DashboardData, PatternItem, SmsConfigState, SmsLogItem (+10 more)
|
Nodes (10): App(), ContactInfoItem, ContactSubmission, GROUP_PAGE_MAP, GROUPS, PAGE_TABS, AdminRouteConfig, ContactSubmissions (+2 more)
|
||||||
|
|
||||||
### Community 25 - "admin.module.ts"
|
### Community 25 - "admin.module.ts"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.11
|
||||||
Nodes (14): AdminModule, Module, PetQuery, PetsService, Injectable, ReportsController, ApiBearerAuth, ApiOperation (+6 more)
|
Nodes (13): AdminModule, Module, PetsService, Injectable, ReportsController, ApiBearerAuth, ApiOperation, ApiTags (+5 more)
|
||||||
|
|
||||||
### Community 26 - "ConfirmModal.tsx"
|
### Community 26 - "ConfirmModal.tsx"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.11
|
||||||
Nodes (16): ConfirmModal(), ConfirmModalProps, HeroBanner, VetTestimonial, Pet, fetchVideosList(), Video, Videos() (+8 more)
|
Nodes (12): ConfirmModal(), ConfirmModalProps, HeroBanner, VetTestimonial, Media, WholesaleRequest, ProductItem, WikiTerm (+4 more)
|
||||||
|
|
||||||
### Community 27 - "Prescription Review Controller"
|
### Community 27 - "Prescription Review Controller"
|
||||||
Cohesion: 0.14
|
Cohesion: 0.14
|
||||||
@ -431,28 +445,28 @@ Cohesion: 0.13
|
|||||||
Nodes (14): TestimonialsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
|
Nodes (14): TestimonialsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
|
||||||
|
|
||||||
### Community 30 - "src/services/api.ts"
|
### Community 30 - "src/services/api.ts"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.16
|
||||||
Nodes (27): Layout(), ProtectedRoute(), menuGroups, Sidebar(), SidebarProps, SEARCHABLE_PAGES, Topbar(), TopbarProps (+19 more)
|
Nodes (16): Layout(), ProtectedRoute(), menuGroups, Sidebar(), SidebarProps, SEARCHABLE_PAGES, Topbar(), TopbarProps (+8 more)
|
||||||
|
|
||||||
### Community 31 - "Spinner.tsx"
|
### Community 31 - "Spinner.tsx"
|
||||||
Cohesion: 0.08
|
Cohesion: 0.09
|
||||||
Nodes (23): Media, MediaSelector(), MediaSelectorProps, Spinner(), BlogPost, Category, Category, Product (+15 more)
|
Nodes (20): Media, MediaSelector(), MediaSelectorProps, Spinner(), BlogPost, Category, BannersManager, Blogs (+12 more)
|
||||||
|
|
||||||
### Community 32 - "useCartStore"
|
### Community 32 - "useCartStore"
|
||||||
Cohesion: 0.12
|
Cohesion: 0.12
|
||||||
Nodes (16): metadata, ArchiveProductCard(), ProductCard(), Header(), MENU_ICONS, OrderSuccess(), OrderTracking(), PetProfile() (+8 more)
|
Nodes (16): metadata, ArchiveProductCard(), ProductCard(), Header(), MENU_ICONS, OrderSuccess(), OrderTracking(), PetProfile() (+8 more)
|
||||||
|
|
||||||
### Community 33 - "ZibalService"
|
### Community 33 - "PaymentController"
|
||||||
Cohesion: 0.06
|
Cohesion: 0.19
|
||||||
Nodes (37): AdminTransactionFilterDto, ApiPropertyOptional, IsNumber, IsOptional, IsString, Type, InitiatePaymentDto, InitiateWalletTopupDto (+29 more)
|
Nodes (17): PaymentController, ApiBadRequestResponse, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+9 more)
|
||||||
|
|
||||||
### Community 34 - "main.ts"
|
### Community 34 - "main.ts"
|
||||||
Cohesion: 0.14
|
Cohesion: 0.11
|
||||||
Nodes (9): CustomHttpExceptionFilter, Catch, PrismaExceptionFilter, Catch, DecimalInterceptor, Injectable, ApiErrorResponse, ErrorDetailField (+1 more)
|
Nodes (11): AppModule, Module, CustomHttpExceptionFilter, Catch, PrismaExceptionFilter, Catch, DecimalInterceptor, Injectable (+3 more)
|
||||||
|
|
||||||
### Community 35 - "ContactService"
|
### Community 35 - "admin.ts"
|
||||||
Cohesion: 0.13
|
Cohesion: 0.12
|
||||||
Nodes (11): ContactController, Body, Controller, Get, Param, Post, Put, Query (+3 more)
|
Nodes (13): B2BManager, FinancialSettingsPage, SmartAdvisorManager, SystemSettingsPage, AdminLoginPayload, B2BInquiry, FinancialSettings, PartnerAccount (+5 more)
|
||||||
|
|
||||||
### Community 36 - "Backend TypeScript Config"
|
### Community 36 - "Backend TypeScript Config"
|
||||||
Cohesion: 0.09
|
Cohesion: 0.09
|
||||||
@ -462,9 +476,9 @@ Nodes (22): compilerOptions, allowSyntheticDefaultImports, baseUrl, declaration,
|
|||||||
Cohesion: 0.09
|
Cohesion: 0.09
|
||||||
Nodes (22): compilerOptions, allowImportingTsExtensions, erasableSyntaxOnly, jsx, lib, module, moduleDetection, moduleResolution (+14 more)
|
Nodes (22): compilerOptions, allowImportingTsExtensions, erasableSyntaxOnly, jsx, lib, module, moduleDetection, moduleResolution (+14 more)
|
||||||
|
|
||||||
### Community 38 - "Coupons.tsx"
|
### Community 38 - "Products.tsx"
|
||||||
Cohesion: 0.09
|
Cohesion: 0.13
|
||||||
Nodes (15): Pagination(), PaginationProps, Coupon, CouponFormData, CouponModalProps, CouponTarget, Media, Stats (+7 more)
|
Nodes (11): Pagination(), PaginationProps, Pet, Category, Product, GatewayHealth, Stats, Transaction (+3 more)
|
||||||
|
|
||||||
### Community 39 - "dependencies"
|
### Community 39 - "dependencies"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.10
|
||||||
@ -478,9 +492,9 @@ Nodes (20): compilerOptions, allowImportingTsExtensions, erasableSyntaxOnly, lib
|
|||||||
Cohesion: 0.13
|
Cohesion: 0.13
|
||||||
Nodes (15): BlogsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+7 more)
|
Nodes (15): BlogsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+7 more)
|
||||||
|
|
||||||
### Community 42 - "WholesaleApplyDto"
|
### Community 42 - "WholesaleService"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.14
|
||||||
Nodes (20): ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, WholesaleApplyDto, ApiBearerAuth, ApiOperation (+12 more)
|
Nodes (14): ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get, Param, Post (+6 more)
|
||||||
|
|
||||||
### Community 43 - "devDependencies"
|
### Community 43 - "devDependencies"
|
||||||
Cohesion: 0.13
|
Cohesion: 0.13
|
||||||
@ -494,9 +508,9 @@ Nodes (14): ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, De
|
|||||||
Cohesion: 0.16
|
Cohesion: 0.16
|
||||||
Nodes (10): SeoController, ApiOperation, ApiTags, Controller, Get, Param, SeoModule, Module (+2 more)
|
Nodes (10): SeoController, ApiOperation, ApiTags, Controller, Get, Param, SeoModule, Module (+2 more)
|
||||||
|
|
||||||
### Community 46 - "OrdersController"
|
### Community 46 - "PaginationDto"
|
||||||
Cohesion: 0.13
|
Cohesion: 0.20
|
||||||
Nodes (16): OrdersController, ApiBadRequestResponse, ApiBearerAuth, ApiCreatedResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags (+8 more)
|
Nodes (9): PaginationDto, SortOrder, ApiPropertyOptional, IsEnum, IsOptional, IsString, Type, IsInt (+1 more)
|
||||||
|
|
||||||
### Community 47 - "Project Build Scripts"
|
### Community 47 - "Project Build Scripts"
|
||||||
Cohesion: 0.11
|
Cohesion: 0.11
|
||||||
@ -508,7 +522,7 @@ Nodes (10): HomeController, ApiOkResponse, ApiOperation, ApiTags, Controller, Ge
|
|||||||
|
|
||||||
### Community 49 - "devDependencies"
|
### Community 49 - "devDependencies"
|
||||||
Cohesion: 0.11
|
Cohesion: 0.11
|
||||||
Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, postcss, @tailwindcss/postcss, @types/node (+11 more)
|
Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, globals, postcss, @types/node (+11 more)
|
||||||
|
|
||||||
### Community 50 - "Database Seeding Logic"
|
### Community 50 - "Database Seeding Logic"
|
||||||
Cohesion: 0.17
|
Cohesion: 0.17
|
||||||
@ -548,27 +562,27 @@ Nodes (11): PetsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Cont
|
|||||||
|
|
||||||
### Community 59 - "PrismaService"
|
### Community 59 - "PrismaService"
|
||||||
Cohesion: 0.08
|
Cohesion: 0.08
|
||||||
Nodes (18): ApiExcludeController, CouponTargetInput, PaginationQuery, CategoryQuery, MetricsController, Controller, Get, Res (+10 more)
|
Nodes (19): BlogQuery, PetQuery, WikiQuery, AdminLoginInput, LoginInput, RegisterInput, MeliPayamakPattern, MeliPayamakResponse (+11 more)
|
||||||
|
|
||||||
### Community 60 - "Jest Testing Config"
|
### Community 60 - "Jest Testing Config"
|
||||||
Cohesion: 0.15
|
Cohesion: 0.15
|
||||||
Nodes (13): jest, collectCoverageFrom, coverageDirectory, moduleFileExtensions, rootDir, testEnvironment, testRegex, transform (+5 more)
|
Nodes (13): jest, collectCoverageFrom, coverageDirectory, moduleFileExtensions, rootDir, testEnvironment, testRegex, transform (+5 more)
|
||||||
|
|
||||||
### Community 61 - "PaginationDto"
|
### Community 61 - "WikiController"
|
||||||
Cohesion: 0.13
|
Cohesion: 0.20
|
||||||
Nodes (13): PaginationDto, SortOrder, ApiPropertyOptional, IsEnum, IsOptional, IsString, Type, Module (+5 more)
|
Nodes (7): ApiTags, Controller, WikiController, Module, WikiModule, Injectable, WikiService
|
||||||
|
|
||||||
### Community 62 - "SettingsService"
|
### Community 62 - "api"
|
||||||
Cohesion: 0.11
|
Cohesion: 0.20
|
||||||
Nodes (4): SmsLogQuery, ScientificTermData, SettingsService, Injectable
|
Nodes (8): CategoryDist, DashboardData, fetchVideosList(), Video, Videos(), Dashboard, Videos, api
|
||||||
|
|
||||||
### Community 63 - "FE-001"
|
### Community 63 - "FE-001"
|
||||||
Cohesion: 0.06
|
Cohesion: 0.06
|
||||||
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Architecture Overview & Confirmed Strengths, Category, Completion Statement, Confidence (+23 more)
|
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Architecture Overview & Confirmed Strengths, Category, Completion Statement, Confidence (+23 more)
|
||||||
|
|
||||||
### Community 64 - "payment.module.ts"
|
### Community 64 - "zibal.service.ts"
|
||||||
Cohesion: 0.16
|
Cohesion: 0.16
|
||||||
Nodes (10): SmsModule, Global, Module, ContactModule, Module, PaymentModule, Module, ZibalInquiryResponse (+2 more)
|
Nodes (9): GatewayHealthResult, IPaymentGateway, PaymentInquiryResult, PaymentRequestOptions, PaymentRequestResult, PaymentVerifyResult, ZibalInquiryResponse, ZibalRequestResponse (+1 more)
|
||||||
|
|
||||||
### Community 66 - "App Health Controller"
|
### Community 66 - "App Health Controller"
|
||||||
Cohesion: 0.29
|
Cohesion: 0.29
|
||||||
@ -579,8 +593,8 @@ Cohesion: 0.12
|
|||||||
Nodes (17): dependencies, axios, lucide-react, motion, next, react, react-dom, sonner (+9 more)
|
Nodes (17): dependencies, axios, lucide-react, motion, next, react, react-dom, sonner (+9 more)
|
||||||
|
|
||||||
### Community 68 - "OrdersService"
|
### Community 68 - "OrdersService"
|
||||||
Cohesion: 0.12
|
Cohesion: 0.06
|
||||||
Nodes (15): CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional (+7 more)
|
Nodes (35): CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional (+27 more)
|
||||||
|
|
||||||
### Community 69 - "Integrity Validation Scripts"
|
### Community 69 - "Integrity Validation Scripts"
|
||||||
Cohesion: 0.20
|
Cohesion: 0.20
|
||||||
@ -614,9 +628,9 @@ Nodes (3): ErrorBoundary, Props, State
|
|||||||
Cohesion: 0.22
|
Cohesion: 0.22
|
||||||
Nodes (8): name, private, scripts, build, dev, lint, start, version
|
Nodes (8): name, private, scripts, build, dev, lint, start, version
|
||||||
|
|
||||||
### Community 77 - "WikiController"
|
### Community 77 - ".findAll"
|
||||||
Cohesion: 0.21
|
Cohesion: 0.32
|
||||||
Nodes (9): ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags, Controller, Get, Param, Query (+1 more)
|
Nodes (6): ApiNotFoundResponse, ApiOkResponse, ApiOperation, Get, Param, Query
|
||||||
|
|
||||||
### Community 79 - "VPN Utility Scripts"
|
### Community 79 - "VPN Utility Scripts"
|
||||||
Cohesion: 0.62
|
Cohesion: 0.62
|
||||||
@ -682,18 +696,10 @@ Nodes (3): COMPOSE_DOCKER_CLI_BUILD, DOCKER_BUILDKIT, deploy.sh script
|
|||||||
Cohesion: 0.06
|
Cohesion: 0.06
|
||||||
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Category, Completion Statement, Confidence, Database and Data Integrity Audit Report (+23 more)
|
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Category, Completion Statement, Confidence, Database and Data Integrity Audit Report (+23 more)
|
||||||
|
|
||||||
### Community 103 - "BlogsService"
|
|
||||||
Cohesion: 0.22
|
|
||||||
Nodes (3): BlogQuery, BlogsService, Injectable
|
|
||||||
|
|
||||||
### Community 109 - "Auth Architecture and Planning"
|
### Community 109 - "Auth Architecture and Planning"
|
||||||
Cohesion: 0.67
|
Cohesion: 0.67
|
||||||
Nodes (3): ADR-AUTH-001: Admin Panel Authentication Architecture & Token Management, Master Task Backlog (Phase 3.3), Phase 3 Master Execution Plan
|
Nodes (3): ADR-AUTH-001: Admin Panel Authentication Architecture & Token Management, Master Task Backlog (Phase 3.3), Phase 3 Master Execution Plan
|
||||||
|
|
||||||
### Community 117 - "WikiService"
|
|
||||||
Cohesion: 0.22
|
|
||||||
Nodes (3): Injectable, WikiQuery, WikiService
|
|
||||||
|
|
||||||
### Community 118 - "TS-001"
|
### Community 118 - "TS-001"
|
||||||
Cohesion: 0.06
|
Cohesion: 0.06
|
||||||
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Category, Completion Statement, Confidence, Dependencies (+23 more)
|
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Category, Completion Statement, Confidence, Dependencies (+23 more)
|
||||||
@ -702,9 +708,9 @@ Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternati
|
|||||||
Cohesion: 0.06
|
Cohesion: 0.06
|
||||||
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Category, Completion Statement, Confidence, Dependencies (+23 more)
|
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Category, Completion Statement, Confidence, Dependencies (+23 more)
|
||||||
|
|
||||||
### Community 120 - "ValidateCouponDto"
|
### Community 120 - "AdminTransactionFilterDto"
|
||||||
Cohesion: 0.50
|
Cohesion: 0.22
|
||||||
Nodes (4): IsNotEmpty, IsNumber, IsString, ValidateCouponDto
|
Nodes (7): AdminTransactionFilterDto, ApiPropertyOptional, IsNumber, IsOptional, IsString, Type, IsIn
|
||||||
|
|
||||||
### Community 126 - "Typography and Font Assets"
|
### Community 126 - "Typography and Font Assets"
|
||||||
Cohesion: 0.67
|
Cohesion: 0.67
|
||||||
@ -723,8 +729,8 @@ Cohesion: 0.07
|
|||||||
Nodes (26): For /graphify add and --watch, For /graphify query, For the commit hook and native CLAUDE.md integration, For --update and --cluster-only, /graphify, Honesty Rules, Interpreter guard for subcommands, Part A - Structural extraction for code files (+18 more)
|
Nodes (26): For /graphify add and --watch, For /graphify query, For the commit hook and native CLAUDE.md integration, For --update and --cluster-only, /graphify, Honesty Rules, Interpreter guard for subcommands, Part A - Structural extraction for code files (+18 more)
|
||||||
|
|
||||||
### Community 130 - "JwtAuthGuard"
|
### Community 130 - "JwtAuthGuard"
|
||||||
Cohesion: 0.18
|
Cohesion: 0.15
|
||||||
Nodes (7): JwtAuthGuard, Injectable, ROLES_KEY, RequestWithUser, RolesGuard, Injectable, UserReqPayload
|
Nodes (9): JwtAuthGuard, Injectable, B2BModule, Module, ROLES_KEY, RequestWithUser, RolesGuard, Injectable (+1 more)
|
||||||
|
|
||||||
### Community 131 - "راهنمای تست سیستم (Software Testing)"
|
### Community 131 - "راهنمای تست سیستم (Software Testing)"
|
||||||
Cohesion: 0.07
|
Cohesion: 0.07
|
||||||
@ -954,25 +960,49 @@ Nodes (3): Expanding the ESLint configuration, React Compiler, React + TypeScrip
|
|||||||
Cohesion: 0.50
|
Cohesion: 0.50
|
||||||
Nodes (3): Deploy on Vercel, Getting Started, Learn More
|
Nodes (3): Deploy on Vercel, Getting Started, Learn More
|
||||||
|
|
||||||
|
### Community 284 - "wholesale.controller.ts"
|
||||||
|
Cohesion: 0.31
|
||||||
|
Nodes (6): ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, WholesaleApplyDto
|
||||||
|
|
||||||
|
### Community 285 - "InitiatePaymentDto"
|
||||||
|
Cohesion: 0.43
|
||||||
|
Nodes (7): InitiatePaymentDto, InitiateWalletTopupDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString
|
||||||
|
|
||||||
|
### Community 286 - "GetProductsDto"
|
||||||
|
Cohesion: 0.29
|
||||||
|
Nodes (6): GetProductsDto, ApiPropertyOptional, IsEnum, IsOptional, IsString, Query
|
||||||
|
|
||||||
|
### Community 287 - "Coupons.tsx"
|
||||||
|
Cohesion: 0.25
|
||||||
|
Nodes (5): Coupon, CouponFormData, CouponModalProps, CouponTarget, Coupons
|
||||||
|
|
||||||
|
### Community 288 - "SmsSettingsPage.tsx"
|
||||||
|
Cohesion: 0.29
|
||||||
|
Nodes (5): PatternItem, SmsConfigState, SmsLogItem, SmsLogStats, SmsSettingsPage
|
||||||
|
|
||||||
|
### Community 289 - "ZibalCallbackQueryDto"
|
||||||
|
Cohesion: 0.40
|
||||||
|
Nodes (4): ApiPropertyOptional, IsOptional, IsString, ZibalCallbackQueryDto
|
||||||
|
|
||||||
## Knowledge Gaps
|
## Knowledge Gaps
|
||||||
- **1179 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1174 more)
|
- **1181 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1176 more)
|
||||||
These have ≤1 connection - possible missing edges or undocumented components.
|
These have ≤1 connection - possible missing edges or undocumented components.
|
||||||
- **113 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
|
- **113 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
|
||||||
|
|
||||||
## Suggested Questions
|
## Suggested Questions
|
||||||
_Questions this graph is uniquely positioned to answer:_
|
_Questions this graph is uniquely positioned to answer:_
|
||||||
|
|
||||||
- **Why does `ApiResponse` connect `src/services/api.ts` to `pets/pets.controller.ts`, `UsersService`, `auth.controller.ts`, `BlogsController`, `WikiController`, `OrdersController`, `ProductsService`, `Home Data Module`?**
|
- **Why does `ApiResponse` connect `src/services/api.ts` to `pets/pets.controller.ts`, `UsersService`, `OrdersService`, `admin.ts`, `auth.controller.ts`, `BlogsController`, `ProductsService`, `Home Data Module`, `WikiController`?**
|
||||||
_High betweenness centrality (0.039) - this node is a cross-community bridge._
|
_High betweenness centrality (0.039) - this node is a cross-community bridge._
|
||||||
- **Why does `Roles()` connect `Roles` to `ZibalService`, `JwtAuthGuard`, `ContactService`, `CmsController`, `BannersService`, `WholesaleApplyDto`, `ProductsService`, `B2B Inquiry Controller`, `Ingredient Management Controller`, `Prescription Review Controller`, `Smart Advisor Controller`, `Testimonials Management Controller`, `SettingsService`?**
|
- **Why does `Roles()` connect `Roles` to `PaymentController`, `JwtAuthGuard`, `CmsController`, `BannersService`, `WholesaleService`, `ProductsService`, `B2B Inquiry Controller`, `wholesale.controller.ts`, `Ingredient Management Controller`, `Prescription Review Controller`, `Smart Advisor Controller`, `Testimonials Management Controller`?**
|
||||||
_High betweenness centrality (0.037) - this node is a cross-community bridge._
|
_High betweenness centrality (0.029) - this node is a cross-community bridge._
|
||||||
- **Why does `JwtAuthGuard` connect `JwtAuthGuard` to `AdminService`, `pets/pets.controller.ts`, `UsersService`, `CmsController`, `OrdersService`, `CreateVideoDto`, `MediaController`, `admin.module.ts`, `SettingsService`?**
|
- **Why does `PrismaService` connect `PrismaService` to `pets/pets.controller.ts`, `JwtAuthGuard`, `Roles`, `CmsController`, `BannersService`, `UsersService`, `app.module.ts`, `CreateVideoDto`, `ZibalService`, `ProductsService`, `MetricsController`, `B2B Inquiry Controller`, `CategoriesController`, `RedisService`, `MediaController`, `Ingredient Management Controller`, `admin.module.ts`, `Prescription Review Controller`, `Smart Advisor Controller`, `Testimonials Management Controller`, `wholesale.controller.ts`, `WholesaleService`, `seo.module.ts`, `Home Data Module`, `WikiController`, `zibal.service.ts`, `OrdersService`, `BlogsController`, `BlogsService`, `WikiService`?**
|
||||||
_High betweenness centrality (0.022) - this node is a cross-community bridge._
|
_High betweenness centrality (0.025) - this node is a cross-community bridge._
|
||||||
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
|
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
|
||||||
_1179 weakly-connected nodes found - possible documentation gaps or missing edges._
|
_1181 weakly-connected nodes found - possible documentation gaps or missing edges._
|
||||||
- **Should `AdminService` be split into smaller, more focused modules?**
|
- **Should `AdminService` be split into smaller, more focused modules?**
|
||||||
_Cohesion score 0.06841046277665996 - nodes in this community are weakly interconnected._
|
_Cohesion score 0.06690140845070422 - nodes in this community are weakly interconnected._
|
||||||
- **Should `pets/pets.controller.ts` be split into smaller, more focused modules?**
|
- **Should `pets/pets.controller.ts` be split into smaller, more focused modules?**
|
||||||
_Cohesion score 0.053923541247484906 - nodes in this community are weakly interconnected._
|
_Cohesion score 0.0528169014084507 - nodes in this community are weakly interconnected._
|
||||||
- **Should `UsersService` be split into smaller, more focused modules?**
|
- **Should `Roles` be split into smaller, more focused modules?**
|
||||||
_Cohesion score 0.06766917293233082 - nodes in this community are weakly interconnected._
|
_Cohesion score 0.051446321102698506 - nodes in this community are weakly interconnected._
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,16 +1,16 @@
|
|||||||
# Graph Report - canina (2026-08-16)
|
# Graph Report - canina (2026-08-16)
|
||||||
|
|
||||||
## Corpus Check
|
## Corpus Check
|
||||||
- 464 files · ~680,159 words
|
- 467 files · ~685,071 words
|
||||||
- Verdict: corpus is large enough that graph structure adds value.
|
- Verdict: corpus is large enough that graph structure adds value.
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
- 3257 nodes · 5318 edges · 291 communities (178 shown, 113 thin omitted)
|
- 3274 nodes · 5352 edges · 289 communities (175 shown, 114 thin omitted)
|
||||||
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 188 edges (avg confidence: 0.79)
|
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 189 edges (avg confidence: 0.79)
|
||||||
- Token cost: 0 input · 0 output
|
- Token cost: 0 input · 0 output
|
||||||
|
|
||||||
## Graph Freshness
|
## Graph Freshness
|
||||||
- Built from commit: `5ace474d`
|
- Built from commit: `5c13dd2f`
|
||||||
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
|
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
|
||||||
- Run `graphify update .` after code changes (no API cost).
|
- Run `graphify update .` after code changes (no API cost).
|
||||||
|
|
||||||
@ -20,17 +20,17 @@
|
|||||||
- Roles
|
- Roles
|
||||||
- UsersService
|
- UsersService
|
||||||
- CmsController
|
- CmsController
|
||||||
- BannersService
|
- SmsService
|
||||||
- auth.controller.ts
|
- AuthController
|
||||||
- app.module.ts
|
- app.module.ts
|
||||||
- CreateVideoDto
|
- VideosService
|
||||||
- ProductService
|
- products.ts
|
||||||
- SmartAdvisor.tsx
|
- ContactService
|
||||||
- compilerOptions
|
- compilerOptions
|
||||||
- toPersian
|
- toPersian
|
||||||
- ZibalService
|
- auth.controller.ts
|
||||||
- ProductsService
|
- ProductsService
|
||||||
- lib/services/api.ts
|
- useCartStore
|
||||||
- eslint
|
- eslint
|
||||||
- useSettingsStore
|
- useSettingsStore
|
||||||
- MetricsController
|
- MetricsController
|
||||||
@ -45,15 +45,15 @@
|
|||||||
- Prescription Review Controller
|
- Prescription Review Controller
|
||||||
- Smart Advisor Controller
|
- Smart Advisor Controller
|
||||||
- Testimonials Management Controller
|
- Testimonials Management Controller
|
||||||
- src/services/api.ts
|
- api
|
||||||
- Spinner.tsx
|
- Spinner.tsx
|
||||||
- useCartStore
|
- PetProfile.tsx
|
||||||
- PaymentController
|
- ZibalService
|
||||||
- main.ts
|
- main.ts
|
||||||
- admin.ts
|
- src/services/api.ts
|
||||||
- Backend TypeScript Config
|
- Backend TypeScript Config
|
||||||
- App TypeScript Config
|
- App TypeScript Config
|
||||||
- Products.tsx
|
- Pagination.tsx
|
||||||
- dependencies
|
- dependencies
|
||||||
- Node TypeScript Config
|
- Node TypeScript Config
|
||||||
- Admin Blog Controller
|
- Admin Blog Controller
|
||||||
@ -69,17 +69,17 @@
|
|||||||
- Prisma Database Migrations
|
- Prisma Database Migrations
|
||||||
- dependencies
|
- dependencies
|
||||||
- UI Skeleton and Tables
|
- UI Skeleton and Tables
|
||||||
- components/Skeleton.tsx
|
- auth.service.ts
|
||||||
- BE-001
|
- BE-001
|
||||||
- VetGallery.tsx
|
- SafeImage.tsx
|
||||||
- NPM Lifecycle Scripts
|
- NPM Lifecycle Scripts
|
||||||
- Pet Management API
|
- Pet Management API
|
||||||
- PrismaService
|
- PrismaService
|
||||||
- Jest Testing Config
|
- Jest Testing Config
|
||||||
- WikiController
|
- WikiController
|
||||||
- api
|
- videos.controller.ts
|
||||||
- FE-001
|
- FE-001
|
||||||
- zibal.service.ts
|
- VerifyOtpDto
|
||||||
- rules/graphify.md
|
- rules/graphify.md
|
||||||
- App Health Controller
|
- App Health Controller
|
||||||
- dependencies
|
- dependencies
|
||||||
@ -89,7 +89,7 @@
|
|||||||
- Analytics and Report Charts
|
- Analytics and Report Charts
|
||||||
- Task Orchestration Scripts
|
- Task Orchestration Scripts
|
||||||
- Backend Package Config
|
- Backend Package Config
|
||||||
- BlogsController
|
- RegisterDto
|
||||||
- React Error Boundary
|
- React Error Boundary
|
||||||
- Application Package Config
|
- Application Package Config
|
||||||
- .findAll
|
- .findAll
|
||||||
@ -105,7 +105,7 @@
|
|||||||
- Font Assets and Licenses
|
- Font Assets and Licenses
|
||||||
- Ledger Rebuild Scripts
|
- Ledger Rebuild Scripts
|
||||||
- Evidence Validation Scripts
|
- Evidence Validation Scripts
|
||||||
- Blog Listing Page
|
- CreateVideoDto
|
||||||
- Blog Post Detail Page
|
- Blog Post Detail Page
|
||||||
- @types/node
|
- @types/node
|
||||||
- devDependencies
|
- devDependencies
|
||||||
@ -115,7 +115,7 @@
|
|||||||
- Home Management DTOs
|
- Home Management DTOs
|
||||||
- Wiki Management DTOs
|
- Wiki Management DTOs
|
||||||
- Wiki Page Routing
|
- Wiki Page Routing
|
||||||
- Network Status Banner
|
- ClientLayout.tsx
|
||||||
- Docker Deployment Scripts
|
- Docker Deployment Scripts
|
||||||
- DB-001
|
- DB-001
|
||||||
- BlogsService
|
- BlogsService
|
||||||
@ -132,11 +132,11 @@
|
|||||||
- Manifest Data Generation
|
- Manifest Data Generation
|
||||||
- Honest Manifest Synchronization
|
- Honest Manifest Synchronization
|
||||||
- Manifest Entry Synchronization
|
- Manifest Entry Synchronization
|
||||||
- WikiService
|
- SendOtpDto
|
||||||
- TS-001
|
- TS-001
|
||||||
- TEST-001
|
- TEST-001
|
||||||
- AdminTransactionFilterDto
|
- payment.service.ts
|
||||||
- @types/react-dom
|
- UITexts.tsx
|
||||||
- Admin Panel TSConfig
|
- Admin Panel TSConfig
|
||||||
- About Page Component
|
- About Page Component
|
||||||
- Privacy Page Component
|
- Privacy Page Component
|
||||||
@ -222,7 +222,7 @@
|
|||||||
- Phase 2 Final Quality Gate Summary Report
|
- Phase 2 Final Quality Gate Summary Report
|
||||||
- Task Modifications Log
|
- Task Modifications Log
|
||||||
- Install
|
- Install
|
||||||
- .findAll
|
- BlogsController
|
||||||
- System Discovery
|
- System Discovery
|
||||||
- Product Requirement Document (PRD)
|
- Product Requirement Document (PRD)
|
||||||
- Baseline Command Plan & Reconciled Command History
|
- Baseline Command Plan & Reconciled Command History
|
||||||
@ -245,7 +245,7 @@
|
|||||||
- 🔒 Security & Performance Review (09_devops_security)
|
- 🔒 Security & Performance Review (09_devops_security)
|
||||||
- 👁️ UX & Persona Interface Review (08_visual_qa)
|
- 👁️ UX & Persona Interface Review (08_visual_qa)
|
||||||
- Compiler Diagnostic Dispositions
|
- Compiler Diagnostic Dispositions
|
||||||
- @eslint/eslintrc
|
- OrderService
|
||||||
- js-yaml
|
- js-yaml
|
||||||
- globals
|
- globals
|
||||||
- prettier
|
- prettier
|
||||||
@ -285,12 +285,10 @@
|
|||||||
- tsconfig-paths
|
- tsconfig-paths
|
||||||
- @types/bcryptjs
|
- @types/bcryptjs
|
||||||
- typescript-eslint
|
- typescript-eslint
|
||||||
- wholesale.controller.ts
|
- contact/page.tsx
|
||||||
- InitiatePaymentDto
|
- eslint-plugin-prettier
|
||||||
- GetProductsDto
|
- eslint-config-next
|
||||||
- Coupons.tsx
|
|
||||||
- SmsSettingsPage.tsx
|
- SmsSettingsPage.tsx
|
||||||
- ZibalCallbackQueryDto
|
|
||||||
- @tailwindcss/postcss
|
- @tailwindcss/postcss
|
||||||
|
|
||||||
## God Nodes (most connected - your core abstractions)
|
## God Nodes (most connected - your core abstractions)
|
||||||
@ -326,78 +324,74 @@
|
|||||||
- **Rastikerdar Font Ecosystem** — frontend_application_public_fonts_shabnam_font_v5_0_1_readme, frontend_application_public_fonts_vazirmatn_v33_003_readme, vazir_font [EXTRACTED 0.95]
|
- **Rastikerdar Font Ecosystem** — frontend_application_public_fonts_shabnam_font_v5_0_1_readme, frontend_application_public_fonts_vazirmatn_v33_003_readme, vazir_font [EXTRACTED 0.95]
|
||||||
- **Canina Deployment Stack** — scripts_compose_prod, scripts_compose_stage [EXTRACTED 1.00]
|
- **Canina Deployment Stack** — scripts_compose_prod, scripts_compose_stage [EXTRACTED 1.00]
|
||||||
|
|
||||||
## Communities (291 total, 113 thin omitted)
|
## Communities (289 total, 114 thin omitted)
|
||||||
|
|
||||||
### Community 0 - "AdminService"
|
### Community 0 - "AdminService"
|
||||||
Cohesion: 0.07
|
Cohesion: 0.06
|
||||||
Nodes (22): AdminController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+14 more)
|
Nodes (24): AdminController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+16 more)
|
||||||
|
|
||||||
### Community 1 - "pets/pets.controller.ts"
|
### Community 1 - "pets/pets.controller.ts"
|
||||||
Cohesion: 0.05
|
Cohesion: 0.05
|
||||||
Nodes (45): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, CreatePetDto, ApiProperty (+37 more)
|
Nodes (45): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, CreatePetDto, ApiProperty (+37 more)
|
||||||
|
|
||||||
### Community 2 - "Roles"
|
### Community 2 - "Roles"
|
||||||
Cohesion: 0.05
|
Cohesion: 0.06
|
||||||
Nodes (31): Roles(), SmsService, Injectable, ContactController, Body, Controller, Get, Param (+23 more)
|
Nodes (33): BannersController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+25 more)
|
||||||
|
|
||||||
### Community 3 - "UsersService"
|
### Community 3 - "UsersService"
|
||||||
Cohesion: 0.06
|
Cohesion: 0.06
|
||||||
Nodes (37): AuthModule, Module, JwtPayload, JwtStrategy, Injectable, AddressDto, ApiProperty, ApiPropertyOptional (+29 more)
|
Nodes (36): JwtPayload, JwtStrategy, Injectable, AddressDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty (+28 more)
|
||||||
|
|
||||||
### Community 4 - "CmsController"
|
### Community 4 - "CmsController"
|
||||||
Cohesion: 0.09
|
Cohesion: 0.09
|
||||||
Nodes (24): CmsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+16 more)
|
Nodes (24): CmsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+16 more)
|
||||||
|
|
||||||
### Community 5 - "BannersService"
|
### Community 6 - "AuthController"
|
||||||
Cohesion: 0.13
|
Cohesion: 0.36
|
||||||
Nodes (15): BannersController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+7 more)
|
Nodes (9): AuthController, ApiBadRequestResponse, ApiOkResponse, ApiOperation, ApiTags, Body, Controller, Post (+1 more)
|
||||||
|
|
||||||
### Community 6 - "auth.controller.ts"
|
|
||||||
Cohesion: 0.06
|
|
||||||
Nodes (41): AuthController, ApiBadRequestResponse, ApiOkResponse, ApiOperation, ApiTags, Body, Controller, Post (+33 more)
|
|
||||||
|
|
||||||
### Community 7 - "app.module.ts"
|
### Community 7 - "app.module.ts"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.09
|
||||||
Nodes (26): BannersModule, Module, CmsModule, Module, SmsModule, Global, Module, ContactModule (+18 more)
|
Nodes (28): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+20 more)
|
||||||
|
|
||||||
### Community 8 - "CreateVideoDto"
|
### Community 8 - "VideosService"
|
||||||
Cohesion: 0.07
|
Cohesion: 0.12
|
||||||
Nodes (31): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, UpdateVideoDto (+23 more)
|
Nodes (16): ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete, Get (+8 more)
|
||||||
|
|
||||||
### Community 9 - "ProductService"
|
### Community 9 - "products.ts"
|
||||||
Cohesion: 0.07
|
Cohesion: 0.06
|
||||||
Nodes (30): CatalogClient(), metadata, metadata, metadata, ArchivePage(), CATEGORY_MAP, ICON_MAP, BlogPost (+22 more)
|
Nodes (30): Blog(), getBlogs(), metadata, CatalogClient(), metadata, metadata, metadata, BlogPage() (+22 more)
|
||||||
|
|
||||||
### Community 10 - "SmartAdvisor.tsx"
|
### Community 10 - "ContactService"
|
||||||
Cohesion: 0.32
|
Cohesion: 0.13
|
||||||
Nodes (6): CURRENT_SYMPTOMS, MEDICAL_HISTORIES, SmartAdvisor(), SmartAdvisorProps, UIState, useUIStore
|
Nodes (11): ContactController, Body, Controller, Get, Param, Post, Put, Query (+3 more)
|
||||||
|
|
||||||
### Community 11 - "compilerOptions"
|
### Community 11 - "compilerOptions"
|
||||||
Cohesion: 0.06
|
Cohesion: 0.06
|
||||||
Nodes (32): compilerOptions, allowJs, esModuleInterop, incremental, isolatedModules, jsx, lib, module (+24 more)
|
Nodes (32): compilerOptions, allowJs, esModuleInterop, incremental, isolatedModules, jsx, lib, module (+24 more)
|
||||||
|
|
||||||
### Community 12 - "toPersian"
|
### Community 12 - "toPersian"
|
||||||
Cohesion: 0.08
|
Cohesion: 0.12
|
||||||
Nodes (37): ClientLayout(), VerifyContent(), AddressModal(), AddressModalProps, AuthModal(), AuthModalProps, B2BPortal(), BackButton() (+29 more)
|
Nodes (24): AddressModal(), AddressModalProps, BackButton(), BackButtonProps, CheckoutPage(), DeleteConfirmModal(), DeleteConfirmModalProps, HeaderButton() (+16 more)
|
||||||
|
|
||||||
### Community 13 - "ZibalService"
|
### Community 13 - "auth.controller.ts"
|
||||||
Cohesion: 0.16
|
Cohesion: 0.16
|
||||||
Nodes (4): PaymentService, Injectable, Injectable, ZibalService
|
Nodes (11): AdminLoginDto, ApiProperty, IsEmail, IsNotEmpty, IsString, MinLength, LoginDto, ApiProperty (+3 more)
|
||||||
|
|
||||||
### Community 14 - "ProductsService"
|
### Community 14 - "ProductsService"
|
||||||
Cohesion: 0.12
|
Cohesion: 0.09
|
||||||
Nodes (13): ProductsController, ApiOperation, ApiTags, Body, Controller, Get, Param, Patch (+5 more)
|
Nodes (19): GetProductsDto, ApiPropertyOptional, IsEnum, IsOptional, IsString, ProductsController, ApiOperation, ApiTags (+11 more)
|
||||||
|
|
||||||
### Community 15 - "lib/services/api.ts"
|
### Community 15 - "useCartStore"
|
||||||
Cohesion: 0.08
|
Cohesion: 0.08
|
||||||
Nodes (17): metadata, ContactFormClient(), ContactInfoItem, PrescriptionUploadModal(), PrescriptionUploadModalProps, api, ApiErrorPayload, ApiErr (+9 more)
|
Nodes (31): VerifyContent(), AuthModal(), AuthModalProps, B2BPortal(), CartDrawer(), ContactInfoItem, Header(), MENU_ICONS (+23 more)
|
||||||
|
|
||||||
### Community 17 - "useSettingsStore"
|
### Community 17 - "useSettingsStore"
|
||||||
Cohesion: 0.07
|
Cohesion: 0.09
|
||||||
Nodes (30): HomeClient(), HomeClientProps, getHomeData(), Home(), metadata, metadata, EnamadBadge(), Footer() (+22 more)
|
Nodes (31): HomeClient(), HomeClientProps, getHomeData(), Home(), metadata, metadata, EnamadBadge(), Hero() (+23 more)
|
||||||
|
|
||||||
### Community 18 - "MetricsController"
|
### Community 18 - "MetricsController"
|
||||||
Cohesion: 0.20
|
Cohesion: 0.29
|
||||||
Nodes (5): ApiExcludeController, MetricsController, Controller, Get, Res
|
Nodes (5): ApiExcludeController, MetricsController, Controller, Get, Res
|
||||||
|
|
||||||
### Community 19 - "B2B Inquiry Controller"
|
### Community 19 - "B2B Inquiry Controller"
|
||||||
@ -409,8 +403,8 @@ Cohesion: 0.09
|
|||||||
Nodes (17): CategoriesController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+9 more)
|
Nodes (17): CategoriesController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+9 more)
|
||||||
|
|
||||||
### Community 21 - "RedisService"
|
### Community 21 - "RedisService"
|
||||||
Cohesion: 0.15
|
Cohesion: 0.11
|
||||||
Nodes (7): CouponTargetInput, PaginationQuery, RedisModule, Global, Module, RedisService, Injectable
|
Nodes (7): AppModule, Module, RedisModule, Global, Module, RedisService, Injectable
|
||||||
|
|
||||||
### Community 22 - "MediaController"
|
### Community 22 - "MediaController"
|
||||||
Cohesion: 0.11
|
Cohesion: 0.11
|
||||||
@ -421,16 +415,16 @@ Cohesion: 0.13
|
|||||||
Nodes (14): IngredientsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
|
Nodes (14): IngredientsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
|
||||||
|
|
||||||
### Community 24 - "adminRoutes.tsx"
|
### Community 24 - "adminRoutes.tsx"
|
||||||
Cohesion: 0.14
|
Cohesion: 0.12
|
||||||
Nodes (10): App(), ContactInfoItem, ContactSubmission, GROUP_PAGE_MAP, GROUPS, PAGE_TABS, AdminRouteConfig, ContactSubmissions (+2 more)
|
Nodes (11): App(), ContactInfoItem, ContactSubmission, CategoryDist, DashboardData, AdminRouteConfig, ContactSubmissions, Dashboard (+3 more)
|
||||||
|
|
||||||
### Community 25 - "admin.module.ts"
|
### Community 25 - "admin.module.ts"
|
||||||
Cohesion: 0.11
|
Cohesion: 0.10
|
||||||
Nodes (13): AdminModule, Module, PetsService, Injectable, ReportsController, ApiBearerAuth, ApiOperation, ApiTags (+5 more)
|
Nodes (14): AdminModule, Module, PetQuery, PetsService, Injectable, ReportsController, ApiBearerAuth, ApiOperation (+6 more)
|
||||||
|
|
||||||
### Community 26 - "ConfirmModal.tsx"
|
### Community 26 - "ConfirmModal.tsx"
|
||||||
Cohesion: 0.11
|
Cohesion: 0.08
|
||||||
Nodes (12): ConfirmModal(), ConfirmModalProps, HeroBanner, VetTestimonial, Media, WholesaleRequest, ProductItem, WikiTerm (+4 more)
|
Nodes (19): ConfirmModal(), ConfirmModalProps, HeroBanner, VetTestimonial, Coupon, CouponFormData, CouponModalProps, CouponTarget (+11 more)
|
||||||
|
|
||||||
### Community 27 - "Prescription Review Controller"
|
### Community 27 - "Prescription Review Controller"
|
||||||
Cohesion: 0.14
|
Cohesion: 0.14
|
||||||
@ -444,29 +438,29 @@ Nodes (14): SmartAdvisorController, ApiBearerAuth, ApiOperation, ApiTags, Body,
|
|||||||
Cohesion: 0.13
|
Cohesion: 0.13
|
||||||
Nodes (14): TestimonialsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
|
Nodes (14): TestimonialsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
|
||||||
|
|
||||||
### Community 30 - "src/services/api.ts"
|
### Community 30 - "api"
|
||||||
Cohesion: 0.16
|
Cohesion: 0.24
|
||||||
Nodes (16): Layout(), ProtectedRoute(), menuGroups, Sidebar(), SidebarProps, SEARCHABLE_PAGES, Topbar(), TopbarProps (+8 more)
|
Nodes (8): Layout(), menuGroups, Sidebar(), SidebarProps, SEARCHABLE_PAGES, Topbar(), TopbarProps, api
|
||||||
|
|
||||||
### Community 31 - "Spinner.tsx"
|
### Community 31 - "Spinner.tsx"
|
||||||
Cohesion: 0.09
|
Cohesion: 0.09
|
||||||
Nodes (20): Media, MediaSelector(), MediaSelectorProps, Spinner(), BlogPost, Category, BannersManager, Blogs (+12 more)
|
Nodes (20): Media, MediaSelector(), MediaSelectorProps, Spinner(), BlogPost, Category, BannersManager, Blogs (+12 more)
|
||||||
|
|
||||||
### Community 32 - "useCartStore"
|
### Community 32 - "PetProfile.tsx"
|
||||||
Cohesion: 0.12
|
Cohesion: 0.08
|
||||||
Nodes (16): metadata, ArchiveProductCard(), ProductCard(), Header(), MENU_ICONS, OrderSuccess(), OrderTracking(), PetProfile() (+8 more)
|
Nodes (27): metadata, ArchivePage(), ArchiveProductCard(), CATEGORY_MAP, ICON_MAP, FeaturedProducts(), ProductCard(), OrderSuccess() (+19 more)
|
||||||
|
|
||||||
### Community 33 - "PaymentController"
|
### Community 33 - "ZibalService"
|
||||||
Cohesion: 0.19
|
Cohesion: 0.05
|
||||||
Nodes (17): PaymentController, ApiBadRequestResponse, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+9 more)
|
Nodes (41): InitiatePaymentDto, InitiateWalletTopupDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, ApiPropertyOptional (+33 more)
|
||||||
|
|
||||||
### Community 34 - "main.ts"
|
### Community 34 - "main.ts"
|
||||||
Cohesion: 0.11
|
Cohesion: 0.14
|
||||||
Nodes (11): AppModule, Module, CustomHttpExceptionFilter, Catch, PrismaExceptionFilter, Catch, DecimalInterceptor, Injectable (+3 more)
|
Nodes (9): CustomHttpExceptionFilter, Catch, PrismaExceptionFilter, Catch, DecimalInterceptor, Injectable, ApiErrorResponse, ErrorDetailField (+1 more)
|
||||||
|
|
||||||
### Community 35 - "admin.ts"
|
### Community 35 - "src/services/api.ts"
|
||||||
Cohesion: 0.12
|
Cohesion: 0.12
|
||||||
Nodes (13): B2BManager, FinancialSettingsPage, SmartAdvisorManager, SystemSettingsPage, AdminLoginPayload, B2BInquiry, FinancialSettings, PartnerAccount (+5 more)
|
Nodes (20): ProtectedRoute(), Login(), B2BManager, FinancialSettingsPage, SmartAdvisorManager, ApiErrorPayload, failedQueue, useAdminAuthStore (+12 more)
|
||||||
|
|
||||||
### Community 36 - "Backend TypeScript Config"
|
### Community 36 - "Backend TypeScript Config"
|
||||||
Cohesion: 0.09
|
Cohesion: 0.09
|
||||||
@ -476,9 +470,9 @@ Nodes (22): compilerOptions, allowSyntheticDefaultImports, baseUrl, declaration,
|
|||||||
Cohesion: 0.09
|
Cohesion: 0.09
|
||||||
Nodes (22): compilerOptions, allowImportingTsExtensions, erasableSyntaxOnly, jsx, lib, module, moduleDetection, moduleResolution (+14 more)
|
Nodes (22): compilerOptions, allowImportingTsExtensions, erasableSyntaxOnly, jsx, lib, module, moduleDetection, moduleResolution (+14 more)
|
||||||
|
|
||||||
### Community 38 - "Products.tsx"
|
### Community 38 - "Pagination.tsx"
|
||||||
Cohesion: 0.13
|
Cohesion: 0.11
|
||||||
Nodes (11): Pagination(), PaginationProps, Pet, Category, Product, GatewayHealth, Stats, Transaction (+3 more)
|
Nodes (13): Pagination(), PaginationProps, Media, Pet, GatewayHealth, Stats, Transaction, ProductItem (+5 more)
|
||||||
|
|
||||||
### Community 39 - "dependencies"
|
### Community 39 - "dependencies"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.10
|
||||||
@ -498,7 +492,7 @@ Nodes (14): ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get, Param,
|
|||||||
|
|
||||||
### Community 43 - "devDependencies"
|
### Community 43 - "devDependencies"
|
||||||
Cohesion: 0.13
|
Cohesion: 0.13
|
||||||
Nodes (15): eslint-config-next, devDependencies, eslint, eslint-config-next, jsdom, tailwindcss, @tailwindcss/postcss, @types/node (+7 more)
|
Nodes (15): devDependencies, eslint, jsdom, tailwindcss, @tailwindcss/postcss, @types/node, @types/react-dom, @vitejs/plugin-react (+7 more)
|
||||||
|
|
||||||
### Community 44 - "Generic CRUD Controller"
|
### Community 44 - "Generic CRUD Controller"
|
||||||
Cohesion: 0.13
|
Cohesion: 0.13
|
||||||
@ -509,8 +503,8 @@ Cohesion: 0.16
|
|||||||
Nodes (10): SeoController, ApiOperation, ApiTags, Controller, Get, Param, SeoModule, Module (+2 more)
|
Nodes (10): SeoController, ApiOperation, ApiTags, Controller, Get, Param, SeoModule, Module (+2 more)
|
||||||
|
|
||||||
### Community 46 - "PaginationDto"
|
### Community 46 - "PaginationDto"
|
||||||
Cohesion: 0.20
|
Cohesion: 0.14
|
||||||
Nodes (9): PaginationDto, SortOrder, ApiPropertyOptional, IsEnum, IsOptional, IsString, Type, IsInt (+1 more)
|
Nodes (13): BlogsModule, Module, BlogsService, Injectable, PaginationDto, SortOrder, ApiPropertyOptional, IsEnum (+5 more)
|
||||||
|
|
||||||
### Community 47 - "Project Build Scripts"
|
### Community 47 - "Project Build Scripts"
|
||||||
Cohesion: 0.11
|
Cohesion: 0.11
|
||||||
@ -540,17 +534,17 @@ Nodes (21): dependencies, axios, lucide-react, react, react-dom, react-hot-toast
|
|||||||
Cohesion: 0.18
|
Cohesion: 0.18
|
||||||
Nodes (11): Skeleton(), Order, OrderItem, Orders(), statusStyles, toPersianDigits(), UserRecord, Orders (+3 more)
|
Nodes (11): Skeleton(), Order, OrderItem, Orders(), statusStyles, toPersianDigits(), UserRecord, Orders (+3 more)
|
||||||
|
|
||||||
### Community 54 - "components/Skeleton.tsx"
|
### Community 54 - "auth.service.ts"
|
||||||
Cohesion: 0.33
|
Cohesion: 0.16
|
||||||
Nodes (4): OrderRowSkeleton(), PetProfileSkeleton(), Skeleton(), SkeletonProps
|
Nodes (7): AuthModule, Module, AdminLoginInput, AuthService, LoginInput, RegisterInput, Injectable
|
||||||
|
|
||||||
### Community 55 - "BE-001"
|
### Community 55 - "BE-001"
|
||||||
Cohesion: 0.06
|
Cohesion: 0.06
|
||||||
Nodes (32): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, BE-001, Category, Completion Statement, Confidence (+24 more)
|
Nodes (32): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, BE-001, Category, Completion Statement, Confidence (+24 more)
|
||||||
|
|
||||||
### Community 56 - "VetGallery.tsx"
|
### Community 56 - "SafeImage.tsx"
|
||||||
Cohesion: 0.22
|
Cohesion: 0.17
|
||||||
Nodes (8): DisplayVideoItem, FALLBACK_VIDEOS, TestimonialItem, VetGallery(), FALLBACK_VIDEOS, VideosPage(), Video, videoService
|
Nodes (10): ProductDetailModalProps, SafeImage(), SafeImageProps, DisplayVideoItem, FALLBACK_VIDEOS, TestimonialItem, FALLBACK_VIDEOS, VideosPage() (+2 more)
|
||||||
|
|
||||||
### Community 57 - "NPM Lifecycle Scripts"
|
### Community 57 - "NPM Lifecycle Scripts"
|
||||||
Cohesion: 0.14
|
Cohesion: 0.14
|
||||||
@ -561,8 +555,8 @@ Cohesion: 0.15
|
|||||||
Nodes (11): PetsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Controller, Delete, Get (+3 more)
|
Nodes (11): PetsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Controller, Delete, Get (+3 more)
|
||||||
|
|
||||||
### Community 59 - "PrismaService"
|
### Community 59 - "PrismaService"
|
||||||
Cohesion: 0.08
|
Cohesion: 0.06
|
||||||
Nodes (19): BlogQuery, PetQuery, WikiQuery, AdminLoginInput, LoginInput, RegisterInput, MeliPayamakPattern, MeliPayamakResponse (+11 more)
|
Nodes (21): BlogQuery, Injectable, WikiQuery, WikiService, MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions, SmsConfig (+13 more)
|
||||||
|
|
||||||
### Community 60 - "Jest Testing Config"
|
### Community 60 - "Jest Testing Config"
|
||||||
Cohesion: 0.15
|
Cohesion: 0.15
|
||||||
@ -572,17 +566,17 @@ Nodes (13): jest, collectCoverageFrom, coverageDirectory, moduleFileExtensions,
|
|||||||
Cohesion: 0.20
|
Cohesion: 0.20
|
||||||
Nodes (7): ApiTags, Controller, WikiController, Module, WikiModule, Injectable, WikiService
|
Nodes (7): ApiTags, Controller, WikiController, Module, WikiModule, Injectable, WikiService
|
||||||
|
|
||||||
### Community 62 - "api"
|
### Community 62 - "videos.controller.ts"
|
||||||
Cohesion: 0.20
|
Cohesion: 0.22
|
||||||
Nodes (8): CategoryDist, DashboardData, fetchVideosList(), Video, Videos(), Dashboard, Videos, api
|
Nodes (7): GetVideosQueryDto, ApiPropertyOptional, IsBoolean, IsOptional, Module, VideosModule, Transform
|
||||||
|
|
||||||
### Community 63 - "FE-001"
|
### Community 63 - "FE-001"
|
||||||
Cohesion: 0.06
|
Cohesion: 0.06
|
||||||
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Architecture Overview & Confirmed Strengths, Category, Completion Statement, Confidence (+23 more)
|
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Architecture Overview & Confirmed Strengths, Category, Completion Statement, Confidence (+23 more)
|
||||||
|
|
||||||
### Community 64 - "zibal.service.ts"
|
### Community 64 - "VerifyOtpDto"
|
||||||
Cohesion: 0.16
|
Cohesion: 0.22
|
||||||
Nodes (9): GatewayHealthResult, IPaymentGateway, PaymentInquiryResult, PaymentRequestOptions, PaymentRequestResult, PaymentVerifyResult, ZibalInquiryResponse, ZibalRequestResponse (+1 more)
|
Nodes (6): ApiProperty, IsNotEmpty, IsString, Matches, VerifyOtpDto, Length
|
||||||
|
|
||||||
### Community 66 - "App Health Controller"
|
### Community 66 - "App Health Controller"
|
||||||
Cohesion: 0.29
|
Cohesion: 0.29
|
||||||
@ -616,9 +610,9 @@ Nodes (8): cmd_next_task(), cmd_progress(), cmd_reset(), cmd_status(), cmd_unblo
|
|||||||
Cohesion: 0.22
|
Cohesion: 0.22
|
||||||
Nodes (8): author, description, license, name, prisma, seed, private, version
|
Nodes (8): author, description, license, name, prisma, seed, private, version
|
||||||
|
|
||||||
### Community 74 - "BlogsController"
|
### Community 74 - "RegisterDto"
|
||||||
Cohesion: 0.20
|
Cohesion: 0.22
|
||||||
Nodes (7): BlogsController, ApiTags, Controller, BlogsModule, Module, BlogsService, Injectable
|
Nodes (8): RegisterDto, ApiProperty, ApiPropertyOptional, IsEmail, IsNotEmpty, IsOptional, IsString, MinLength
|
||||||
|
|
||||||
### Community 75 - "React Error Boundary"
|
### Community 75 - "React Error Boundary"
|
||||||
Cohesion: 0.22
|
Cohesion: 0.22
|
||||||
@ -672,9 +666,9 @@ Nodes (4): evidenceList, ledger, mandatoryMap, mandatoryScope
|
|||||||
Cohesion: 0.40
|
Cohesion: 0.40
|
||||||
Nodes (4): activeFiles, errors, validationOutput, warnings
|
Nodes (4): activeFiles, errors, validationOutput, warnings
|
||||||
|
|
||||||
### Community 90 - "Blog Listing Page"
|
### Community 90 - "CreateVideoDto"
|
||||||
Cohesion: 0.50
|
Cohesion: 0.25
|
||||||
Nodes (4): Blog(), getBlogs(), metadata, BlogPage()
|
Nodes (8): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, UpdateVideoDto
|
||||||
|
|
||||||
### Community 91 - "Blog Post Detail Page"
|
### Community 91 - "Blog Post Detail Page"
|
||||||
Cohesion: 0.60
|
Cohesion: 0.60
|
||||||
@ -682,12 +676,16 @@ Nodes (4): BlogPostPage(), generateMetadata(), getBlog(), revalidate
|
|||||||
|
|
||||||
### Community 93 - "devDependencies"
|
### Community 93 - "devDependencies"
|
||||||
Cohesion: 0.22
|
Cohesion: 0.22
|
||||||
Nodes (9): devDependencies, eslint-plugin-prettier, @types/passport-jwt, @types/supertest, typescript, typescript, eslint-plugin-prettier, @types/passport-jwt (+1 more)
|
Nodes (9): devDependencies, @eslint/eslintrc, @types/passport-jwt, @types/supertest, typescript, typescript, @eslint/eslintrc, @types/passport-jwt (+1 more)
|
||||||
|
|
||||||
### Community 99 - "Wiki Page Routing"
|
### Community 99 - "Wiki Page Routing"
|
||||||
Cohesion: 0.83
|
Cohesion: 0.83
|
||||||
Nodes (3): generateMetadata(), getWikiTerm(), WikiTermPage()
|
Nodes (3): generateMetadata(), getWikiTerm(), WikiTermPage()
|
||||||
|
|
||||||
|
### Community 100 - "ClientLayout.tsx"
|
||||||
|
Cohesion: 0.17
|
||||||
|
Nodes (8): ClientLayout(), Footer(), LoginModal(), LoginModalProps, MaintenancePage(), NetworkBanner(), useNetworkStatus(), NavigationTarget
|
||||||
|
|
||||||
### Community 101 - "Docker Deployment Scripts"
|
### Community 101 - "Docker Deployment Scripts"
|
||||||
Cohesion: 0.50
|
Cohesion: 0.50
|
||||||
Nodes (3): COMPOSE_DOCKER_CLI_BUILD, DOCKER_BUILDKIT, deploy.sh script
|
Nodes (3): COMPOSE_DOCKER_CLI_BUILD, DOCKER_BUILDKIT, deploy.sh script
|
||||||
@ -700,6 +698,10 @@ Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternati
|
|||||||
Cohesion: 0.67
|
Cohesion: 0.67
|
||||||
Nodes (3): ADR-AUTH-001: Admin Panel Authentication Architecture & Token Management, Master Task Backlog (Phase 3.3), Phase 3 Master Execution Plan
|
Nodes (3): ADR-AUTH-001: Admin Panel Authentication Architecture & Token Management, Master Task Backlog (Phase 3.3), Phase 3 Master Execution Plan
|
||||||
|
|
||||||
|
### Community 117 - "SendOtpDto"
|
||||||
|
Cohesion: 0.25
|
||||||
|
Nodes (5): SendOtpDto, ApiProperty, IsNotEmpty, IsString, Matches
|
||||||
|
|
||||||
### Community 118 - "TS-001"
|
### Community 118 - "TS-001"
|
||||||
Cohesion: 0.06
|
Cohesion: 0.06
|
||||||
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Category, Completion Statement, Confidence, Dependencies (+23 more)
|
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Category, Completion Statement, Confidence, Dependencies (+23 more)
|
||||||
@ -708,9 +710,13 @@ Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternati
|
|||||||
Cohesion: 0.06
|
Cohesion: 0.06
|
||||||
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Category, Completion Statement, Confidence, Dependencies (+23 more)
|
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Category, Completion Statement, Confidence, Dependencies (+23 more)
|
||||||
|
|
||||||
### Community 120 - "AdminTransactionFilterDto"
|
### Community 120 - "payment.service.ts"
|
||||||
Cohesion: 0.22
|
Cohesion: 0.22
|
||||||
Nodes (7): AdminTransactionFilterDto, ApiPropertyOptional, IsNumber, IsOptional, IsString, Type, IsIn
|
Nodes (8): AdminTransactionFilterDto, ApiPropertyOptional, IsNumber, IsOptional, IsString, Type, ClientMetadata, IsIn
|
||||||
|
|
||||||
|
### Community 121 - "UITexts.tsx"
|
||||||
|
Cohesion: 0.33
|
||||||
|
Nodes (4): GROUP_PAGE_MAP, GROUPS, PAGE_TABS, UITexts
|
||||||
|
|
||||||
### Community 126 - "Typography and Font Assets"
|
### Community 126 - "Typography and Font Assets"
|
||||||
Cohesion: 0.67
|
Cohesion: 0.67
|
||||||
@ -729,8 +735,8 @@ Cohesion: 0.07
|
|||||||
Nodes (26): For /graphify add and --watch, For /graphify query, For the commit hook and native CLAUDE.md integration, For --update and --cluster-only, /graphify, Honesty Rules, Interpreter guard for subcommands, Part A - Structural extraction for code files (+18 more)
|
Nodes (26): For /graphify add and --watch, For /graphify query, For the commit hook and native CLAUDE.md integration, For --update and --cluster-only, /graphify, Honesty Rules, Interpreter guard for subcommands, Part A - Structural extraction for code files (+18 more)
|
||||||
|
|
||||||
### Community 130 - "JwtAuthGuard"
|
### Community 130 - "JwtAuthGuard"
|
||||||
Cohesion: 0.15
|
Cohesion: 0.19
|
||||||
Nodes (9): JwtAuthGuard, Injectable, B2BModule, Module, ROLES_KEY, RequestWithUser, RolesGuard, Injectable (+1 more)
|
Nodes (7): JwtAuthGuard, Injectable, ROLES_KEY, RequestWithUser, RolesGuard, Injectable, UserReqPayload
|
||||||
|
|
||||||
### Community 131 - "راهنمای تست سیستم (Software Testing)"
|
### Community 131 - "راهنمای تست سیستم (Software Testing)"
|
||||||
Cohesion: 0.07
|
Cohesion: 0.07
|
||||||
@ -880,9 +886,9 @@ Nodes (8): 1. `TASK-AUTH-001`, 2. `TASK-FIN-001`, 3. `DECISION-002`, 4. `TASK-VE
|
|||||||
Cohesion: 0.22
|
Cohesion: 0.22
|
||||||
Nodes (8): Arch Linux, bower, Install, npm, Shabnam Font, yarn, طریقه استفاده در صفحات وب:, نمونه متن Sample:
|
Nodes (8): Arch Linux, bower, Install, npm, Shabnam Font, yarn, طریقه استفاده در صفحات وب:, نمونه متن Sample:
|
||||||
|
|
||||||
### Community 214 - ".findAll"
|
### Community 214 - "BlogsController"
|
||||||
Cohesion: 0.32
|
Cohesion: 0.21
|
||||||
Nodes (6): ApiNotFoundResponse, ApiOkResponse, ApiOperation, Get, Param, Query
|
Nodes (9): BlogsController, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags, Controller, Get, Param (+1 more)
|
||||||
|
|
||||||
### Community 215 - "System Discovery"
|
### Community 215 - "System Discovery"
|
||||||
Cohesion: 0.25
|
Cohesion: 0.25
|
||||||
@ -960,49 +966,29 @@ Nodes (3): Expanding the ESLint configuration, React Compiler, React + TypeScrip
|
|||||||
Cohesion: 0.50
|
Cohesion: 0.50
|
||||||
Nodes (3): Deploy on Vercel, Getting Started, Learn More
|
Nodes (3): Deploy on Vercel, Getting Started, Learn More
|
||||||
|
|
||||||
### Community 284 - "wholesale.controller.ts"
|
|
||||||
Cohesion: 0.31
|
|
||||||
Nodes (6): ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, WholesaleApplyDto
|
|
||||||
|
|
||||||
### Community 285 - "InitiatePaymentDto"
|
|
||||||
Cohesion: 0.43
|
|
||||||
Nodes (7): InitiatePaymentDto, InitiateWalletTopupDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString
|
|
||||||
|
|
||||||
### Community 286 - "GetProductsDto"
|
|
||||||
Cohesion: 0.29
|
|
||||||
Nodes (6): GetProductsDto, ApiPropertyOptional, IsEnum, IsOptional, IsString, Query
|
|
||||||
|
|
||||||
### Community 287 - "Coupons.tsx"
|
|
||||||
Cohesion: 0.25
|
|
||||||
Nodes (5): Coupon, CouponFormData, CouponModalProps, CouponTarget, Coupons
|
|
||||||
|
|
||||||
### Community 288 - "SmsSettingsPage.tsx"
|
### Community 288 - "SmsSettingsPage.tsx"
|
||||||
Cohesion: 0.29
|
Cohesion: 0.29
|
||||||
Nodes (5): PatternItem, SmsConfigState, SmsLogItem, SmsLogStats, SmsSettingsPage
|
Nodes (5): PatternItem, SmsConfigState, SmsLogItem, SmsLogStats, SmsSettingsPage
|
||||||
|
|
||||||
### Community 289 - "ZibalCallbackQueryDto"
|
|
||||||
Cohesion: 0.40
|
|
||||||
Nodes (4): ApiPropertyOptional, IsOptional, IsString, ZibalCallbackQueryDto
|
|
||||||
|
|
||||||
## Knowledge Gaps
|
## Knowledge Gaps
|
||||||
- **1181 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1176 more)
|
- **1182 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1177 more)
|
||||||
These have ≤1 connection - possible missing edges or undocumented components.
|
These have ≤1 connection - possible missing edges or undocumented components.
|
||||||
- **113 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
|
- **114 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
|
||||||
|
|
||||||
## Suggested Questions
|
## Suggested Questions
|
||||||
_Questions this graph is uniquely positioned to answer:_
|
_Questions this graph is uniquely positioned to answer:_
|
||||||
|
|
||||||
- **Why does `ApiResponse` connect `src/services/api.ts` to `pets/pets.controller.ts`, `UsersService`, `OrdersService`, `admin.ts`, `auth.controller.ts`, `BlogsController`, `ProductsService`, `Home Data Module`, `WikiController`?**
|
- **Why does `ApiResponse` connect `src/services/api.ts` to `pets/pets.controller.ts`, `UsersService`, `OrdersService`, `AuthController`, `ProductsService`, `Home Data Module`, `BlogsController`, `WikiController`?**
|
||||||
_High betweenness centrality (0.039) - this node is a cross-community bridge._
|
_High betweenness centrality (0.041) - this node is a cross-community bridge._
|
||||||
- **Why does `Roles()` connect `Roles` to `PaymentController`, `JwtAuthGuard`, `CmsController`, `BannersService`, `WholesaleService`, `ProductsService`, `B2B Inquiry Controller`, `wholesale.controller.ts`, `Ingredient Management Controller`, `Prescription Review Controller`, `Smart Advisor Controller`, `Testimonials Management Controller`?**
|
- **Why does `Roles()` connect `Roles` to `ZibalService`, `JwtAuthGuard`, `CmsController`, `ContactService`, `WholesaleService`, `ProductsService`, `B2B Inquiry Controller`, `Ingredient Management Controller`, `Prescription Review Controller`, `Smart Advisor Controller`, `Testimonials Management Controller`?**
|
||||||
_High betweenness centrality (0.029) - this node is a cross-community bridge._
|
_High betweenness centrality (0.034) - this node is a cross-community bridge._
|
||||||
- **Why does `PrismaService` connect `PrismaService` to `pets/pets.controller.ts`, `JwtAuthGuard`, `Roles`, `CmsController`, `BannersService`, `UsersService`, `app.module.ts`, `CreateVideoDto`, `ZibalService`, `ProductsService`, `MetricsController`, `B2B Inquiry Controller`, `CategoriesController`, `RedisService`, `MediaController`, `Ingredient Management Controller`, `admin.module.ts`, `Prescription Review Controller`, `Smart Advisor Controller`, `Testimonials Management Controller`, `wholesale.controller.ts`, `WholesaleService`, `seo.module.ts`, `Home Data Module`, `WikiController`, `zibal.service.ts`, `OrdersService`, `BlogsController`, `BlogsService`, `WikiService`?**
|
- **Why does `PaginationDto` connect `PaginationDto` to `AdminService`, `pets/pets.controller.ts`, `JwtAuthGuard`, `OrdersService`, `Admin Blog Controller`, `Generic CRUD Controller`, `.findAll`, `ProductsService`, `CategoriesController`, `BlogsController`, `admin.module.ts`, `Pet Management API`, `WikiController`, `videos.controller.ts`?**
|
||||||
_High betweenness centrality (0.025) - this node is a cross-community bridge._
|
_High betweenness centrality (0.024) - this node is a cross-community bridge._
|
||||||
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
|
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
|
||||||
_1181 weakly-connected nodes found - possible documentation gaps or missing edges._
|
_1182 weakly-connected nodes found - possible documentation gaps or missing edges._
|
||||||
- **Should `AdminService` be split into smaller, more focused modules?**
|
- **Should `AdminService` be split into smaller, more focused modules?**
|
||||||
_Cohesion score 0.06690140845070422 - nodes in this community are weakly interconnected._
|
_Cohesion score 0.06414414414414414 - nodes in this community are weakly interconnected._
|
||||||
- **Should `pets/pets.controller.ts` be split into smaller, more focused modules?**
|
- **Should `pets/pets.controller.ts` be split into smaller, more focused modules?**
|
||||||
_Cohesion score 0.0528169014084507 - nodes in this community are weakly interconnected._
|
_Cohesion score 0.0528169014084507 - nodes in this community are weakly interconnected._
|
||||||
- **Should `Roles` be split into smaller, more focused modules?**
|
- **Should `Roles` be split into smaller, more focused modules?**
|
||||||
_Cohesion score 0.051446321102698506 - nodes in this community are weakly interconnected._
|
_Cohesion score 0.06347340581839553 - nodes in this community are weakly interconnected._
|
||||||
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
|||||||
|
{"nodes": [{"id": "$graphify-root$_agents_rules_graphify_md", "label": "graphify.md", "file_type": "document", "source_file": ".agents/rules/graphify.md", "source_location": "L1"}, {"id": "$graphify-root$_agents_rules_graphify_graphify", "label": "graphify", "file_type": "document", "source_file": ".agents/rules/graphify.md", "source_location": "L6"}], "edges": [{"source": "$graphify-root$_agents_rules_graphify_md", "target": "$graphify-root$_agents_rules_graphify_graphify", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".agents/rules/graphify.md", "source_location": "L6", "weight": 1.0}], "input_tokens": 0, "output_tokens": 0}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
{"nodes": [{"id": "$graphify-root$_claude_md", "label": "CLAUDE.md", "file_type": "document", "source_file": "CLAUDE.md", "source_location": "L1"}, {"id": "$graphify-root$_claude_graphify", "label": "graphify", "file_type": "document", "source_file": "CLAUDE.md", "source_location": "L1"}], "edges": [{"source": "$graphify-root$_claude_md", "target": "$graphify-root$_claude_graphify", "relation": "contains", "confidence": "EXTRACTED", "source_file": "CLAUDE.md", "source_location": "L1", "weight": 1.0}], "input_tokens": 0, "output_tokens": 0}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
{"nodes": [{"id": "$graphify-root$_antigravity_instructions_md", "label": "instructions.md", "file_type": "document", "source_file": ".antigravity/instructions.md", "source_location": "L1"}, {"id": "$graphify-root$_antigravity_instructions_graphify", "label": "graphify", "file_type": "document", "source_file": ".antigravity/instructions.md", "source_location": "L1"}], "edges": [{"source": "$graphify-root$_antigravity_instructions_md", "target": "$graphify-root$_antigravity_instructions_graphify", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".antigravity/instructions.md", "source_location": "L1", "weight": 1.0}], "input_tokens": 0, "output_tokens": 0}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
{"nodes": [{"id": "$graphify-root$_agents_workflows_graphify_md", "label": "graphify.md", "file_type": "document", "source_file": ".agents/workflows/graphify.md", "source_location": "L1"}, {"id": "$graphify-root$_agents_workflows_graphify_workflow_graphify", "label": "Workflow: graphify", "file_type": "document", "source_file": ".agents/workflows/graphify.md", "source_location": "L6"}], "edges": [{"source": "$graphify-root$_agents_workflows_graphify_md", "target": "$graphify-root$_agents_workflows_graphify_workflow_graphify", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".agents/workflows/graphify.md", "source_location": "L6", "weight": 1.0}], "input_tokens": 0, "output_tokens": 0}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
{"nodes": [{"id": "$graphify-root$_claude_claude_md", "label": "CLAUDE.md", "file_type": "document", "source_file": ".claude/CLAUDE.md", "source_location": "L1"}, {"id": "$graphify-root$_claude_claude_graphify", "label": "graphify", "file_type": "document", "source_file": ".claude/CLAUDE.md", "source_location": "L1"}], "edges": [{"source": "$graphify-root$_claude_claude_md", "target": "$graphify-root$_claude_claude_graphify", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".claude/CLAUDE.md", "source_location": "L1", "weight": 1.0}], "input_tokens": 0, "output_tokens": 0}
|
||||||
2
graphify-out/cache/stat-index.json
vendored
2
graphify-out/cache/stat-index.json
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -27,6 +27,9 @@ services:
|
|||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: canino_backend_stage
|
container_name: canino_backend_stage
|
||||||
restart: always
|
restart: always
|
||||||
|
dns:
|
||||||
|
- 217.218.127.127
|
||||||
|
- 217.218.155.155
|
||||||
environment:
|
environment:
|
||||||
- DATABASE_URL=postgresql://canino_stage:caninopassword_stage@db_stage:5432/caninodb_stage?schema=public
|
- DATABASE_URL=postgresql://canino_stage:caninopassword_stage@db_stage:5432/caninodb_stage?schema=public
|
||||||
- REDIS_HOST=redis_stage
|
- REDIS_HOST=redis_stage
|
||||||
@ -56,6 +59,9 @@ services:
|
|||||||
VITE_API_URL: "https://stageapi.canina.ir"
|
VITE_API_URL: "https://stageapi.canina.ir"
|
||||||
container_name: canino_frontend_stage
|
container_name: canino_frontend_stage
|
||||||
restart: always
|
restart: always
|
||||||
|
dns:
|
||||||
|
- 217.218.127.127
|
||||||
|
- 217.218.155.155
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
- "traefik.http.routers.canina-stage.rule=Host(`stage.canina.ir`) || Host(`stageadmin.canina.ir`)"
|
- "traefik.http.routers.canina-stage.rule=Host(`stage.canina.ir`) || Host(`stageadmin.canina.ir`)"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user