fix(types,lint): resolve all TypeScript type check and eslint errors across backend and sms suite

This commit is contained in:
parsa aghaei 2026-08-16 12:00:49 +03:30
parent d8c6aa8d8e
commit 8de1351349
19 changed files with 11299 additions and 8849 deletions

View File

@ -29,6 +29,8 @@ import { PrescriptionsModule } from './prescriptions/prescriptions.module';
import { B2BModule } from './b2b/b2b.module';
import { PaymentModule } from './payment/payment.module';
import { Request, Response, NextFunction } from 'express';
@Module({
imports: [
SmsModule,
@ -77,15 +79,18 @@ export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply((req: any, res: any, next: () => void) => {
.apply((req: Request, res: Response, next: NextFunction) => {
MetricsController.incrementRequestCount();
const url: string = req.originalUrl || req.url || '';
const method: string = req.method || '';
// Exclude options, admin panel requests, static assets, and health metrics from visit counter
const isAdminPath = url.includes('/admin') || url.includes('/api/admin');
const isStaticAsset = url.match(/\.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?|map)$/i);
const isAdminPath =
url.includes('/admin') || url.includes('/api/admin');
const isStaticAsset = url.match(
/\.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?|map)$/i,
);
const isIgnoredMethod = method === 'OPTIONS' || method === 'HEAD';
if (!isAdminPath && !isStaticAsset && !isIgnoredMethod) {

View File

@ -49,7 +49,8 @@ export class AuthService {
// Remove OTP from Redis if SMS failed to avoid phantom codes
await this.redisService.del(`otp:${phoneNumber}`);
throw new BadRequestException({
message: 'ارسال پیامک با خطا مواجه شد. لطفاً چند لحظه دیگر دوباره تلاش کنید.',
message:
'ارسال پیامک با خطا مواجه شد. لطفاً چند لحظه دیگر دوباره تلاش کنید.',
error: 'SMS_DELIVERY_FAILED',
});
}

View File

@ -31,7 +31,7 @@ export interface MeliPayamakPattern {
assignedTo?: string[];
}
export interface SmsLogQuery {
export class SmsLogQuery {
page?: number;
limit?: number;
search?: string;
@ -41,7 +41,7 @@ export interface SmsLogQuery {
sortOrder?: 'asc' | 'desc';
}
interface MeliPayamakResponse {
export interface MeliPayamakResponse {
Value?: number;
RetStatus?: number;
StrRetStatus?: string;
@ -61,18 +61,44 @@ export class SmsService {
const setting = await this.prisma.setting.findFirst({
where: { category: 'sms' },
});
const dbConfig = (setting?.value as Record<string, any>) || {};
const dbConfig = (setting?.value as Record<string, unknown>) || {};
return {
enabled: dbConfig.enabled !== undefined ? Boolean(dbConfig.enabled) : true,
username: dbConfig.username || process.env.MELIPAYAMAK_USERNAME || '9364100228',
password: dbConfig.password || process.env.MELIPAYAMAK_PASSWORD || '',
fromNumber: dbConfig.fromNumber || process.env.MELIPAYAMAK_FROM_NUMBER || '',
otpBodyId: Number(dbConfig.otpBodyId || process.env.MELIPAYAMAK_OTP_BODY_ID || '508079'),
orderBodyId: Number(dbConfig.orderBodyId || process.env.MELIPAYAMAK_ORDER_BODY_ID || '508081'),
shippingBodyId: Number(dbConfig.shippingBodyId || process.env.MELIPAYAMAK_SHIPPING_BODY_ID || '508082'),
b2bBodyId: Number(dbConfig.b2bBodyId || process.env.MELIPAYAMAK_B2B_BODY_ID || '508083'),
petCareBodyId: Number(dbConfig.petCareBodyId || process.env.MELIPAYAMAK_PET_CARE_BODY_ID || '0'),
enabled:
dbConfig.enabled !== undefined ? Boolean(dbConfig.enabled) : true,
username:
typeof dbConfig.username === 'string' && dbConfig.username
? dbConfig.username
: process.env.MELIPAYAMAK_USERNAME || '9364100228',
password:
typeof dbConfig.password === 'string' && dbConfig.password
? dbConfig.password
: process.env.MELIPAYAMAK_PASSWORD || '',
fromNumber:
typeof dbConfig.fromNumber === 'string' && dbConfig.fromNumber
? dbConfig.fromNumber
: process.env.MELIPAYAMAK_FROM_NUMBER || '',
otpBodyId: Number(
dbConfig.otpBodyId || process.env.MELIPAYAMAK_OTP_BODY_ID || '508079',
),
orderBodyId: Number(
dbConfig.orderBodyId ||
process.env.MELIPAYAMAK_ORDER_BODY_ID ||
'508081',
),
shippingBodyId: Number(
dbConfig.shippingBodyId ||
process.env.MELIPAYAMAK_SHIPPING_BODY_ID ||
'508082',
),
b2bBodyId: Number(
dbConfig.b2bBodyId || process.env.MELIPAYAMAK_B2B_BODY_ID || '508083',
),
petCareBodyId: Number(
dbConfig.petCareBodyId ||
process.env.MELIPAYAMAK_PET_CARE_BODY_ID ||
'0',
),
};
} catch {
return {
@ -82,7 +108,9 @@ export class SmsService {
fromNumber: process.env.MELIPAYAMAK_FROM_NUMBER || '',
otpBodyId: Number(process.env.MELIPAYAMAK_OTP_BODY_ID || '508079'),
orderBodyId: Number(process.env.MELIPAYAMAK_ORDER_BODY_ID || '508081'),
shippingBodyId: Number(process.env.MELIPAYAMAK_SHIPPING_BODY_ID || '508082'),
shippingBodyId: Number(
process.env.MELIPAYAMAK_SHIPPING_BODY_ID || '508082',
),
b2bBodyId: Number(process.env.MELIPAYAMAK_B2B_BODY_ID || '508083'),
petCareBodyId: Number(process.env.MELIPAYAMAK_PET_CARE_BODY_ID || '0'),
};
@ -92,9 +120,14 @@ export class SmsService {
/**
* Helper HTTP POST request to Payamak-Panel ASMX endpoints
*/
private async postAsmx(endpoint: string, params: Record<string, string | number>): Promise<string> {
private async postAsmx(
endpoint: string,
params: Record<string, string | number>,
): Promise<string> {
const postData = Object.entries(params)
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)
.map(
([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`,
)
.join('&');
return new Promise((resolve, reject) => {
@ -109,12 +142,12 @@ export class SmsService {
},
(res) => {
let data = '';
res.on('data', (chunk) => (data += chunk));
res.on('data', (chunk: Buffer | string) => (data += String(chunk)));
res.on('end', () => resolve(data));
},
);
req.on('error', (err) => reject(err));
req.on('error', (err: Error) => reject(err));
req.write(postData);
req.end();
});
@ -132,7 +165,7 @@ export class SmsService {
status: string;
recId?: string;
errorMessage?: string;
}) {
}): Promise<void> {
try {
await this.prisma.smsLog.create({
data: {
@ -146,8 +179,9 @@ export class SmsService {
errorMessage: entry.errorMessage || null,
},
});
} catch (err: any) {
this.logger.error(`[SMS Log Save Failed]: ${err.message}`);
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
this.logger.error(`[SMS Log Save Failed]: ${msg}`);
}
}
@ -239,8 +273,14 @@ export class SmsService {
if (idMatch) {
const id = parseInt(idMatch[1], 10);
const title = (titleMatch ? titleMatch[1] : '').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');
const body = (bodyMatch ? bodyMatch[1] : '').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');
const title = (titleMatch ? titleMatch[1] : '')
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&amp;/g, '&');
const body = (bodyMatch ? bodyMatch[1] : '')
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&amp;/g, '&');
const status = statusMatch ? parseInt(statusMatch[1], 10) : 0;
let statusText = 'در انتظار تایید';
@ -268,8 +308,11 @@ export class SmsService {
password: config.password,
});
remotePatterns = this.parsePatternsXml(rawXml);
} catch (err: any) {
this.logger.warn(`[SMS Patterns] Remote fetch failed: ${err.message}. Using stored patterns.`);
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
this.logger.warn(
`[SMS Patterns] Remote fetch failed: ${msg}. Using stored patterns.`,
);
}
}
@ -277,17 +320,46 @@ export class SmsService {
const storedSetting = await this.prisma.setting.findFirst({
where: { category: 'sms_patterns' },
});
const localPatterns: MeliPayamakPattern[] = (storedSetting?.value as any) || [];
const localPatterns: MeliPayamakPattern[] = Array.isArray(
storedSetting?.value,
)
? (storedSetting.value as unknown as MeliPayamakPattern[])
: [];
// Merge remote and local (remote takes precedence on ID match)
const map = new Map<number, MeliPayamakPattern>();
// Add configured system patterns by default if map is empty
const defaultConfigs: Array<{ id: number; title: string; body: string; assigned: string }> = [
{ id: config.otpBodyId, title: 'کد تایید ورود و ثبت‌نام (OTP)', body: 'کد ورود به کانینا: {0}', assigned: 'otp' },
{ id: config.orderBodyId, title: 'تایید و ثبت فاکتور سفارش', body: 'سفارش شما به شماره {0} با مبلغ {1} ثبت گردید.', assigned: 'order' },
{ id: config.shippingBodyId, title: 'ارسال کد رهگیری پستی', body: 'مرسوله سفارش {0} با کد رهگیری پستی {1} ارسال شد.', assigned: 'shipping' },
{ id: config.b2bBodyId, title: 'اطلاع‌رسانی درخواست B2B', body: 'همکار گرامی {0} درخواست شما دریافت شد.', assigned: 'b2b' },
const defaultConfigs: Array<{
id: number;
title: string;
body: string;
assigned: string;
}> = [
{
id: config.otpBodyId,
title: 'کد تایید ورود و ثبت‌نام (OTP)',
body: 'کد ورود به کانینا: {0}',
assigned: 'otp',
},
{
id: config.orderBodyId,
title: 'تایید و ثبت فاکتور سفارش',
body: 'سفارش شما به شماره {0} با مبلغ {1} ثبت گردید.',
assigned: 'order',
},
{
id: config.shippingBodyId,
title: 'ارسال کد رهگیری پستی',
body: 'مرسوله سفارش {0} با کد رهگیری پستی {1} ارسال شد.',
assigned: 'shipping',
},
{
id: config.b2bBodyId,
title: 'اطلاع‌رسانی درخواست B2B',
body: 'همکار گرامی {0} درخواست شما دریافت شد.',
assigned: 'b2b',
},
];
for (const d of defaultConfigs) {
@ -304,7 +376,7 @@ export class SmsService {
}
for (const lp of localPatterns) {
if (lp.id) map.set(lp.id, { ...lp });
if (lp && lp.id) map.set(lp.id, { ...lp });
}
for (const rp of remotePatterns) {
@ -332,7 +404,11 @@ export class SmsService {
/**
* Add a new pattern to MeliPayamak
*/
async addPattern(title: string, body: string, blackListId: number = 0): Promise<{ success: boolean; bodyId?: number; message: string }> {
async addPattern(
title: string,
body: string,
blackListId: number = 0,
): Promise<{ success: boolean; bodyId?: number; message: string }> {
const config = await this.getSmsConfig();
if (!config.username || !config.password) {
@ -351,7 +427,8 @@ export class SmsService {
blackListId,
});
const match = rawXml.match(/<int.*?>(-?\d+)<\/int>/i) || rawXml.match(/>(-?\d+)</);
const match =
rawXml.match(/<int.*?>(-?\d+)<\/int>/i) || rawXml.match(/>(-?\d+)</);
const code = match ? parseInt(match[1], 10) : 0;
if (code > 0) {
@ -369,13 +446,23 @@ export class SmsService {
message: `الگو با موفقیت ثبت شد و شناسه اختصاصی ${code} دریافت گردید. (وضعیت: در انتظار تایید ناظر)`,
};
} else if (code === 0) {
return { success: false, message: 'نام کاربری یا کلمه عبور ملی پیامک اشتباه است.' };
return {
success: false,
message: 'نام کاربری یا کلمه عبور ملی پیامک اشتباه است.',
};
} else if (code === -2) {
return { success: false, message: 'شناسه لیست سیاه ویژه اشتباه است.' };
return {
success: false,
message: 'شناسه لیست سیاه ویژه اشتباه است.',
};
} else {
return { success: false, message: `خطا در ثبت پترن با کد پاسخ: ${code}` };
return {
success: false,
message: `خطا در ثبت پترن با کد پاسخ: ${code}`,
};
}
} catch (err: any) {
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
const generatedId = Math.floor(500000 + Math.random() * 90000);
await this.saveLocalPattern({
id: generatedId,
@ -388,7 +475,7 @@ export class SmsService {
return {
success: true,
bodyId: generatedId,
message: `الگو به صورت محلی با شناسه موقت ${generatedId} ذخیره شد (${err.message}).`,
message: `الگو به صورت محلی با شناسه موقت ${generatedId} ذخیره شد (${msg}).`,
};
}
}
@ -396,7 +483,10 @@ export class SmsService {
/**
* Edit an existing pattern in MeliPayamak
*/
async editPattern(bodyId: number, body: string): Promise<{ success: boolean; message: string }> {
async editPattern(
bodyId: number,
body: string,
): Promise<{ success: boolean; message: string }> {
const config = await this.getSmsConfig();
if (!config.username || !config.password) {
@ -414,29 +504,36 @@ export class SmsService {
body,
});
const match = rawXml.match(/<int.*?>(-?\d+)<\/int>/i) || rawXml.match(/>(-?\d+)</);
const match =
rawXml.match(/<int.*?>(-?\d+)<\/int>/i) || rawXml.match(/>(-?\d+)</);
const code = match ? parseInt(match[1], 10) : 0;
if (code === 1) {
await this.updateLocalPattern(bodyId, body);
return {
success: true,
message: 'ویرایش الگو با موفقیت انجام شد و منتظر تایید مجدد ناظر می‌باشد.',
message:
'ویرایش الگو با موفقیت انجام شد و منتظر تایید مجدد ناظر می‌باشد.',
};
} else if (code === -1) {
await this.updateLocalPattern(bodyId, body);
return {
success: true,
message: 'متن الگو در سیستم بروز شد (توجه: فقط الگوهای در وضعیت نیاز به ویرایش در وب‌سرویس اصلاح می‌شوند).',
message:
'متن الگو در سیستم بروز شد (توجه: فقط الگوهای در وضعیت نیاز به ویرایش در وب‌سرویس اصلاح می‌شوند).',
};
} else {
return { success: false, message: `خطا در ویرایش الگو با کد پاسخ: ${code}` };
return {
success: false,
message: `خطا در ویرایش الگو با کد پاسخ: ${code}`,
};
}
} catch (err: any) {
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
await this.updateLocalPattern(bodyId, body);
return {
success: true,
message: `متن الگو در دیتابیس داخلی بروز شد (${err.message}).`,
message: `متن الگو در دیتابیس داخلی بروز شد (${msg}).`,
};
}
}
@ -446,16 +543,26 @@ export class SmsService {
const setting = await this.prisma.setting.findFirst({
where: { category: 'sms_patterns' },
});
const list: MeliPayamakPattern[] = (setting?.value as any) || [];
const list: MeliPayamakPattern[] = Array.isArray(setting?.value)
? (setting.value as unknown as MeliPayamakPattern[])
: [];
const updated = [pattern, ...list.filter((p) => p.id !== pattern.id)];
await this.prisma.setting.upsert({
where: { key: 'sms_patterns_config' },
update: { category: 'sms_patterns', value: updated as any },
create: { key: 'sms_patterns_config', category: 'sms_patterns', value: updated as any },
update: {
category: 'sms_patterns',
value: updated as unknown as Prisma.InputJsonValue,
},
create: {
key: 'sms_patterns_config',
category: 'sms_patterns',
value: updated as unknown as Prisma.InputJsonValue,
},
});
} catch (err: any) {
this.logger.error(`Failed to save local pattern: ${err.message}`);
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
this.logger.error(`Failed to save local pattern: ${msg}`);
}
}
@ -464,16 +571,35 @@ export class SmsService {
const setting = await this.prisma.setting.findFirst({
where: { category: 'sms_patterns' },
});
const list: MeliPayamakPattern[] = (setting?.value as any) || [];
const updated = list.map((p) => (p.id === bodyId ? { ...p, body: newBody, status: 0, statusText: 'در انتظار تایید' } : p));
const list: MeliPayamakPattern[] = Array.isArray(setting?.value)
? (setting.value as unknown as MeliPayamakPattern[])
: [];
const updated = list.map((p) =>
p.id === bodyId
? {
...p,
body: newBody,
status: 0,
statusText: 'در انتظار تایید',
}
: p,
);
await this.prisma.setting.upsert({
where: { key: 'sms_patterns_config' },
update: { category: 'sms_patterns', value: updated as any },
create: { key: 'sms_patterns_config', category: 'sms_patterns', value: updated as any },
update: {
category: 'sms_patterns',
value: updated as unknown as Prisma.InputJsonValue,
},
create: {
key: 'sms_patterns_config',
category: 'sms_patterns',
value: updated as unknown as Prisma.InputJsonValue,
},
});
} catch (err: any) {
this.logger.error(`Failed to update local pattern: ${err.message}`);
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
this.logger.error(`Failed to update local pattern: ${msg}`);
}
}
@ -531,64 +657,73 @@ export class SmsService {
},
(res) => {
let data = '';
res.on('data', (chunk) => (data += chunk));
res.on('end', async () => {
try {
const json = JSON.parse(data) as MeliPayamakResponse;
const val = json.Value ?? 0;
if (json && (val > 15 || json.RetStatus === 1)) {
this.logger.log(
`[SMS Sent] Pattern SMS ${options.bodyId} dispatched to ${options.to} (RecId: ${val})`,
);
await this.recordLog({
receptor: options.to,
type: msgType,
patternId: options.bodyId,
args: options.args,
status: 'SUCCESS',
recId: String(val),
});
resolve(true);
} else {
const errMsg = `خطای درگاه ملی پیامک با کد بازگشتی: ${val}`;
this.logger.error(`[SMS Error] Failed sending to ${options.to}. Code: ${val}`);
res.on('data', (chunk: Buffer | string) => (data += String(chunk)));
res.on('end', () => {
void (async () => {
try {
const json = JSON.parse(data) as MeliPayamakResponse;
const val = json.Value ?? 0;
if (json && (val > 15 || json.RetStatus === 1)) {
this.logger.log(
`[SMS Sent] Pattern SMS ${options.bodyId} dispatched to ${options.to} (RecId: ${val})`,
);
await this.recordLog({
receptor: options.to,
type: msgType,
patternId: options.bodyId,
args: options.args,
status: 'SUCCESS',
recId: String(val),
});
resolve(true);
} else {
const errMsg = `خطای درگاه ملی پیامک با کد بازگشتی: ${val}`;
this.logger.error(
`[SMS Error] Failed sending to ${options.to}. Code: ${val}`,
);
await this.recordLog({
receptor: options.to,
type: msgType,
patternId: options.bodyId,
args: options.args,
status: 'FAILED',
recId: String(val),
errorMessage: errMsg,
});
resolve(false);
}
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
await this.recordLog({
receptor: options.to,
type: msgType,
patternId: options.bodyId,
args: options.args,
status: 'FAILED',
recId: String(val),
errorMessage: errMsg,
errorMessage: `خطای پارس پاسخ سرور: ${data || msg}`,
});
resolve(false);
}
} catch (err: any) {
await this.recordLog({
receptor: options.to,
type: msgType,
patternId: options.bodyId,
args: options.args,
status: 'FAILED',
errorMessage: `خطای پارس پاسخ سرور: ${data || err.message}`,
});
resolve(false);
}
})();
});
},
);
req.on('error', async (err) => {
this.logger.error(`[SMS Exception] MeliPayamak HTTP Error: ${err.message}`);
await this.recordLog({
receptor: options.to,
type: msgType,
patternId: options.bodyId,
args: options.args,
status: 'FAILED',
errorMessage: `خطای شبکه: ${err.message}`,
});
resolve(false);
req.on('error', (err: Error) => {
void (async () => {
this.logger.error(
`[SMS Exception] MeliPayamak HTTP Error: ${err.message}`,
);
await this.recordLog({
receptor: options.to,
type: msgType,
patternId: options.bodyId,
args: options.args,
status: 'FAILED',
errorMessage: `خطای شبکه: ${err.message}`,
});
resolve(false);
})();
});
req.write(payload);
@ -599,7 +734,15 @@ export class SmsService {
/**
* Test SMS Dispatch from Admin Panel
*/
async testSms(targetPhone: string, testPatternId?: number, testArgs?: string[]): Promise<{ success: boolean; message: string; rawResponse?: any }> {
async testSms(
targetPhone: string,
testPatternId?: number,
testArgs?: string[],
): Promise<{
success: boolean;
message: string;
rawResponse?: MeliPayamakResponse;
}> {
const config = await this.getSmsConfig();
if (!config.username || !config.password) {
@ -638,69 +781,74 @@ export class SmsService {
},
(res) => {
let data = '';
res.on('data', (chunk) => (data += chunk));
res.on('end', async () => {
try {
const json = JSON.parse(data) as MeliPayamakResponse;
const val = json.Value ?? 0;
if (json && (val > 15 || json.RetStatus === 1)) {
await this.recordLog({
receptor: targetPhone,
type: 'TEST',
patternId: bodyId,
args,
status: 'SUCCESS',
recId: String(val),
});
resolve({
success: true,
message: `پیامک تستی پترن با موفقیت ارسال شد (شناسه پیگیری ملی پیامک: ${val})`,
rawResponse: json,
});
} else {
const errMsg = `خطای درگاه ملی پیامک: کد پاسخ بازگشتی ${val}`;
res.on('data', (chunk: Buffer | string) => (data += String(chunk)));
res.on('end', () => {
void (async () => {
try {
const json = JSON.parse(data) as MeliPayamakResponse;
const val = json.Value ?? 0;
if (json && (val > 15 || json.RetStatus === 1)) {
await this.recordLog({
receptor: targetPhone,
type: 'TEST',
patternId: bodyId,
args,
status: 'SUCCESS',
recId: String(val),
});
resolve({
success: true,
message: `پیامک تستی پترن با موفقیت ارسال شد (شناسه پیگیری ملی پیامک: ${val})`,
rawResponse: json,
});
} else {
const errMsg = `خطای درگاه ملی پیامک: کد پاسخ بازگشتی ${val}`;
await this.recordLog({
receptor: targetPhone,
type: 'TEST',
patternId: bodyId,
args,
status: 'FAILED',
recId: String(val),
errorMessage: errMsg,
});
resolve({
success: false,
message: errMsg,
rawResponse: json,
});
}
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
const errMsg = `پاسخ نامعتبر از سرور ملی پیامک: ${data || msg}`;
await this.recordLog({
receptor: targetPhone,
type: 'TEST',
patternId: bodyId,
args,
status: 'FAILED',
recId: String(val),
errorMessage: errMsg,
});
resolve({
success: false,
message: errMsg,
rawResponse: json,
});
resolve({ success: false, message: errMsg });
}
} catch (err: any) {
const errMsg = `پاسخ نامعتبر از سرور ملی پیامک: ${data || err.message}`;
await this.recordLog({
receptor: targetPhone,
type: 'TEST',
patternId: bodyId,
args,
status: 'FAILED',
errorMessage: errMsg,
});
resolve({ success: false, message: errMsg });
}
})();
});
},
);
req.on('error', async (err) => {
const errMsg = `خطای برقراری ارتباط با وب‌سرویس ملی پیامک: ${err.message}`;
await this.recordLog({
receptor: targetPhone,
type: 'TEST',
patternId: bodyId,
args,
status: 'FAILED',
errorMessage: errMsg,
});
resolve({ success: false, message: errMsg });
req.on('error', (err: Error) => {
void (async () => {
const errMsg = `خطای برقراری ارتباط با وب‌سرویس ملی پیامک: ${err.message}`;
await this.recordLog({
receptor: targetPhone,
type: 'TEST',
patternId: bodyId,
args,
status: 'FAILED',
errorMessage: errMsg,
});
resolve({ success: false, message: errMsg });
})();
});
req.write(payload);

View File

@ -23,7 +23,6 @@ import {
ApiTags,
ApiOperation,
ApiBearerAuth,
ApiResponse,
ApiOkResponse,
ApiBadRequestResponse,
} from '@nestjs/swagger';
@ -52,7 +51,9 @@ export class PaymentController {
},
},
})
@ApiBadRequestResponse({ description: 'خطا در ایجاد تراکنش یا نامعتبر بودن سفارش' })
@ApiBadRequestResponse({
description: 'خطا در ایجاد تراکنش یا نامعتبر بودن سفارش',
})
async initiateOrderPayment(
@Req() req: { user: { id: string } },
@Body() body: InitiatePaymentDto,
@ -91,7 +92,9 @@ export class PaymentController {
}
@Get('zibal/callback')
@ApiOperation({ summary: 'دریافت کال‌بک بازگشت از درگاه زیبال و تایید تراکنش' })
@ApiOperation({
summary: 'دریافت کال‌بک بازگشت از درگاه زیبال و تایید تراکنش',
})
async handleZibalCallback(
@Query() query: ZibalCallbackQueryDto,
@Res() res: Response,
@ -130,9 +133,10 @@ export class PaymentController {
});
return res.redirect(`${frontendUrl}/payment/verify?${params.toString()}`);
} catch (err: any) {
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : 'خطا در پردازش پرداخت';
return res.redirect(
`${frontendUrl}/payment/verify?success=0&trackId=${trackId}&message=${encodeURIComponent(err.message || 'خطا در پردازش پرداخت')}`,
`${frontendUrl}/payment/verify?success=0&trackId=${trackId}&message=${encodeURIComponent(msg)}`,
);
}
}
@ -149,7 +153,9 @@ export class PaymentController {
const orderId = body.orderId;
if (!trackId) {
return res.status(HttpStatus.BAD_REQUEST).json({ success: false, message: 'trackId is required' });
return res
.status(HttpStatus.BAD_REQUEST)
.json({ success: false, message: 'trackId is required' });
}
const result = await this.paymentService.verifyAndProcess(

View File

@ -46,7 +46,9 @@ export class PaymentService {
const amountRials = Math.round(amountTomans * 10);
if (amountRials < 1000) {
throw new BadRequestException('مبلغ سفارش کمتر از حداقل مجاز درگاه بانکی (۱,۰۰۰ ریال) است');
throw new BadRequestException(
'مبلغ سفارش کمتر از حداقل مجاز درگاه بانکی (۱,۰۰۰ ریال) است',
);
}
const frontendUrl = await this.zibalService.getFrontendUrl();
@ -111,9 +113,11 @@ export class PaymentService {
orderId: order.id,
amount: amountTomans,
};
} catch (err: any) {
this.logger.error(`Error requesting payment from Zibal: ${err.message}`, err.stack);
throw new BadRequestException(err.message || 'خطا در اتصال به درگاه پرداخت');
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
const stack = err instanceof Error ? err.stack : undefined;
this.logger.error(`Error requesting payment from Zibal: ${msg}`, stack);
throw new BadRequestException(msg || 'خطا در اتصال به درگاه پرداخت');
}
}
@ -189,9 +193,10 @@ export class PaymentService {
paymentUrl: this.zibalService.getStartUrl(trackId),
amount: amountTomans,
};
} catch (err: any) {
this.logger.error(`Error requesting wallet topup from Zibal: ${err.message}`);
throw new BadRequestException(err.message || 'خطا در ارتباط با درگاه بانکی');
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
this.logger.error(`Error requesting wallet topup from Zibal: ${msg}`);
throw new BadRequestException(msg || 'خطا در ارتباط با درگاه بانکی');
}
}
@ -226,7 +231,10 @@ export class PaymentService {
orderBy: { createdAt: 'desc' },
include: {
order: {
include: { user: true, orderItems: { include: { product: true } } },
include: {
user: true,
orderItems: { include: { product: true } },
},
},
user: true,
},
@ -255,7 +263,9 @@ export class PaymentService {
// If user cancelled or Zibal signaled failure at the gate
if (successParam === '0' || statusParam === '3') {
const statusMessage = this.zibalService.getStatusMessage(statusParam || 3);
const statusMessage = this.zibalService.getStatusMessage(
statusParam || 3,
);
await this.prisma.paymentTransaction.update({
where: { id: transaction.id },
data: {
@ -301,9 +311,13 @@ export class PaymentService {
}
// SUCCESSFUL PAYMENT!
const refNumber = verifyRes.refNumber ? String(verifyRes.refNumber) : undefined;
const refNumber = verifyRes.refNumber
? String(verifyRes.refNumber)
: undefined;
const cardNumber = verifyRes.cardNumber || undefined;
const paidDate = verifyRes.paidAt ? new Date(verifyRes.paidAt) : new Date();
const paidDate = verifyRes.paidAt
? new Date(verifyRes.paidAt)
: new Date();
await this.prisma.$transaction(async (tx) => {
// 1. Mark transaction as VERIFIED
@ -330,7 +344,10 @@ export class PaymentService {
});
// If charity donation was made, update user's total charity
if (transaction.order && Number(transaction.order.charityDonation) > 0) {
if (
transaction.order &&
Number(transaction.order.charityDonation) > 0
) {
await tx.user.update({
where: { id: transaction.userId },
data: {
@ -369,8 +386,11 @@ export class PaymentService {
// Send SMS notification if order payment
if (transaction.type === 'ORDER' && transaction.order?.user?.mobile) {
const mobile = transaction.order.user.mobile;
const trackingNum = transaction.order.trackingNumber || transaction.order.id;
const formattedAmount = Number(transaction.amount).toLocaleString('fa-IR');
const trackingNum =
transaction.order.trackingNumber || transaction.order.id;
const formattedAmount = Number(transaction.amount).toLocaleString(
'fa-IR',
);
this.smsService
.sendOrderConfirmation(mobile, trackingNum, formattedAmount)
@ -390,13 +410,15 @@ export class PaymentService {
type: transaction.type,
message: 'پرداخت با موفقیت انجام شد',
};
} catch (err: any) {
this.logger.error(`Error during verify: ${err.message}`, err.stack);
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
const stack = err instanceof Error ? err.stack : undefined;
this.logger.error(`Error during verify: ${msg}`, stack);
return {
success: false,
status: 'ERROR',
trackId,
message: err.message || 'خطا در فرایند تایید تراکنش',
message: msg || 'خطا در فرایند تایید تراکنش',
orderId: transaction.orderId,
};
}

View File

@ -115,8 +115,12 @@ export class ZibalService {
if (!response.ok) {
const errorText = await response.text();
this.logger.error(`Zibal request HTTP error ${response.status}: ${errorText}`);
throw new Error(`خطا در اتصال به درگاه زیبال: کد وضعیت ${response.status}`);
this.logger.error(
`Zibal request HTTP error ${response.status}: ${errorText}`,
);
throw new Error(
`خطا در اتصال به درگاه زیبال: کد وضعیت ${response.status}`,
);
}
const data = (await response.json()) as ZibalRequestResponse;
@ -142,7 +146,9 @@ export class ZibalService {
trackId: String(trackId),
};
this.logger.log(`Verifying payment on Zibal for trackId=${trackId}, merchant=${merchant}`);
this.logger.log(
`Verifying payment on Zibal for trackId=${trackId}, merchant=${merchant}`,
);
const response = await fetch(`${this.baseUrl}/v1/verify`, {
method: 'POST',
@ -154,8 +160,12 @@ export class ZibalService {
if (!response.ok) {
const errorText = await response.text();
this.logger.error(`Zibal verify HTTP error ${response.status}: ${errorText}`);
throw new Error(`خطا در تایید تراکنش درگاه زیبال: کد وضعیت ${response.status}`);
this.logger.error(
`Zibal verify HTTP error ${response.status}: ${errorText}`,
);
throw new Error(
`خطا در تایید تراکنش درگاه زیبال: کد وضعیت ${response.status}`,
);
}
const data = (await response.json()) as ZibalVerifyResponse;
@ -166,7 +176,9 @@ export class ZibalService {
/**
* 4. Inquiry Payment (استعلام وضعیت تراکنش)
*/
async inquiryPayment(trackId: string | number): Promise<ZibalInquiryResponse> {
async inquiryPayment(
trackId: string | number,
): Promise<ZibalInquiryResponse> {
const merchant = await this.getMerchant();
const payload = {
@ -186,8 +198,12 @@ export class ZibalService {
if (!response.ok) {
const errorText = await response.text();
this.logger.error(`Zibal inquiry HTTP error ${response.status}: ${errorText}`);
throw new Error(`خطا در استعلام تراکنش زیبال: کد وضعیت ${response.status}`);
this.logger.error(
`Zibal inquiry HTTP error ${response.status}: ${errorText}`,
);
throw new Error(
`خطا در استعلام تراکنش زیبال: کد وضعیت ${response.status}`,
);
}
const data = (await response.json()) as ZibalInquiryResponse;

View File

@ -12,6 +12,7 @@ import {
} from '@nestjs/common';
import { Prisma } from '@prisma/client';
import { SettingsService, ScientificTermData } from './settings.service';
import { SmsLogQuery } from '../common/services/sms.service';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { RolesGuard } from '../common/guards/roles.guard';
import { Roles } from '../common/decorators/roles.decorator';
@ -164,7 +165,9 @@ export class SettingsController {
@Roles('Admin')
@ApiBearerAuth()
@Get('sms/patterns')
@ApiOperation({ summary: 'دریافت لیست تمامی پترن‌های تعریف شده در ملی پیامک' })
@ApiOperation({
summary: 'دریافت لیست تمامی پترن‌های تعریف شده در ملی پیامک',
})
getPatterns() {
return this.settingsService.getPatterns();
}
@ -186,11 +189,10 @@ export class SettingsController {
@Roles('Admin')
@ApiBearerAuth()
@Put('sms/patterns/:bodyId')
@ApiOperation({ summary: 'ویرایش الگوی رد شده یا در حال ویرایش در ملی پیامک' })
editPattern(
@Param('bodyId') bodyId: string,
@Body('body') body: string,
) {
@ApiOperation({
summary: 'ویرایش الگوی رد شده یا در حال ویرایش در ملی پیامک',
})
editPattern(@Param('bodyId') bodyId: string, @Body('body') body: string) {
return this.settingsService.editPattern(Number(bodyId), body);
}
@ -199,8 +201,10 @@ export class SettingsController {
@Roles('Admin')
@ApiBearerAuth()
@Get('sms/logs')
@ApiOperation({ summary: 'دریافت گزارشات و لاگ‌های کامل پیامک‌های ارسالی با فیلتر و جستجو' })
getSmsLogs(@Query() query: any) {
@ApiOperation({
summary: 'دریافت گزارشات و لاگ‌های کامل پیامک‌های ارسالی با فیلتر و جستجو',
})
getSmsLogs(@Query() query: SmsLogQuery) {
return this.settingsService.getSmsLogs(query);
}
@ -222,5 +226,3 @@ export class SettingsController {
return this.settingsService.clearAllSmsLogs();
}
}

View File

@ -1,7 +1,7 @@
import { Injectable } from '@nestjs/common';
import { Prisma } from '@prisma/client';
import { PrismaService } from '../prisma/prisma.service';
import { SmsService } from '../common/services/sms.service';
import { SmsService, SmsLogQuery } from '../common/services/sms.service';
export class ScientificTermData {
term?: string;
@ -116,7 +116,7 @@ export class SettingsService {
return this.smsService.editPattern(bodyId, body);
}
async getSmsLogs(query: any) {
async getSmsLogs(query: SmsLogQuery) {
return this.smsService.getSmsLogs(query);
}
@ -128,4 +128,3 @@ export class SettingsService {
return this.smsService.clearAllSmsLogs();
}
}

View File

@ -1,31 +1,31 @@
{
"0": "AdminService",
"1": "pets/pets.controller.ts",
"1": "PetsController",
"2": "Roles",
"3": "UsersService",
"4": "CmsController",
"5": ".create",
"6": "auth.controller.ts",
"5": "BannersService",
"6": "auth.service.ts",
"7": "app.module.ts",
"8": "CreateVideoDto",
"9": "ProductService",
"10": "SmartAdvisor.tsx",
"11": "compilerOptions",
"12": "toPersian",
"13": "Products.tsx",
"13": "pets/pets.controller.ts",
"14": "ProductsService",
"15": "lib/services/api.ts",
"16": "devDependencies",
"17": "useSettingsStore",
"18": "AppModule",
"18": "MetricsController",
"19": "B2B Inquiry Controller",
"20": "Category Management Controller",
"21": "auth.service.ts",
"21": "RedisService",
"22": "MediaController",
"23": "Ingredient Management Controller",
"24": "adminRoutes.tsx",
"25": "admin.module.ts",
"26": "SmsService",
"26": "api",
"27": "Prescription Review Controller",
"28": "Smart Advisor Controller",
"29": "Testimonials Management Controller",
@ -34,7 +34,7 @@
"32": "useCartStore",
"33": "ZibalService",
"34": "main.ts",
"35": "ContactService",
"35": "payment.controller.ts",
"36": "Backend TypeScript Config",
"37": "App TypeScript Config",
"38": "ConfirmModal.tsx",
@ -61,9 +61,9 @@
"59": "PrismaService",
"60": "Jest Testing Config",
"61": "PaginationDto",
"62": "BlogsController",
"62": "WikiController",
"63": "FE-001",
"64": "WikiService",
"64": "PetsService",
"65": "rules/graphify.md",
"66": "App Health Controller",
"67": "dependencies",
@ -73,10 +73,10 @@
"71": "Analytics and Report Charts",
"72": "Task Orchestration Scripts",
"73": "Backend Package Config",
"74": "CreateOrderDto",
"74": "CreateHealthLogDto",
"75": "React Error Boundary",
"76": "Application Package Config",
"77": "WikiController",
"77": ".findAll",
"78": "Error and Not Found Pages",
"79": "VPN Utility Scripts",
"80": "NestJS CLI Config",
@ -102,7 +102,7 @@
"100": "Network Status Banner",
"101": "Docker Deployment Scripts",
"102": "DB-001",
"103": ".adminLogin",
"103": "CreateReminderDto",
"104": "Database Migration Scripts",
"105": "Scientific Terms Schema",
"106": "Blog Data Seeding",
@ -116,7 +116,7 @@
"114": "Manifest Data Generation",
"115": "Honest Manifest Synchronization",
"116": "Manifest Entry Synchronization",
"117": "AuthController",
"117": "Videos.tsx",
"118": "TS-001",
"119": "TEST-001",
"120": "@tailwindcss/postcss",
@ -129,14 +129,14 @@
"127": "DEVOPS-001",
"128": "DOC-001",
"129": "What You Must Do When Invoked",
"130": "JwtAuthGuard",
"130": "RolesGuard",
"131": "راهنمای تست سیستم (Software Testing)",
"132": "Role & Core Objective",
"133": "Required Review Group Closures",
"134": "Operational Rules & Boundaries",
"135": "Operational Rules & Boundaries",
"136": "🏢 AI Software Agency — Master Orchestration Protocol v3",
"137": "BlogsService",
"137": "@nestjs/cli",
"138": "Operational Rules & Boundaries",
"139": "Operational Rules & Boundaries",
"140": "Bcrypt Type Definitions",
@ -213,7 +213,7 @@
"211": "Phase 2 Final Quality Gate Summary Report",
"212": "Task Modifications Log",
"213": "Install",
"214": ".findAll",
"214": "BlogsController",
"215": "System Discovery",
"216": "Product Requirement Document (PRD)",
"217": "Baseline Command Plan & Reconciled Command History",
@ -264,15 +264,7 @@
"262": "application/CLAUDE.md",
"263": "application/public/fonts/sahel-font-v3.4.0/CHANGELOG.md",
"264": "tailwindcss",
"265": "AuthService",
"266": "RegisterDto",
"267": "GetProductsDto",
"268": "WholesaleApplyDto",
"269": "AdminLoginDto",
"270": "VerifyOtpDto",
"271": "App.tsx",
"272": "ValidateCouponDto",
"273": "AGENTS.md",
"274": "eslint-config-prettier",
"275": "globals"
"265": "typescript-eslint",
"268": "wholesale.controller.ts",
"273": "AGENTS.md"
}

File diff suppressed because one or more lines are too long

View File

@ -1,10 +1,10 @@
{
"0": "AdminService",
"1": "Pet Management Controller",
"2": "SettingsController",
"1": "pets/pets.controller.ts",
"2": "Roles",
"3": "UsersService",
"4": "CMS Content Management",
"5": "OrdersService",
"4": "CmsController",
"5": ".create",
"6": "auth.controller.ts",
"7": "app.module.ts",
"8": "CreateVideoDto",
@ -12,7 +12,7 @@
"10": "SmartAdvisor.tsx",
"11": "compilerOptions",
"12": "toPersian",
"13": "Media and Blog UI Components",
"13": "Products.tsx",
"14": "ProductsService",
"15": "lib/services/api.ts",
"16": "devDependencies",
@ -20,28 +20,28 @@
"18": "AppModule",
"19": "B2B Inquiry Controller",
"20": "Category Management Controller",
"21": "Banner Management Controller",
"22": "Media Upload Controller",
"21": "auth.service.ts",
"22": "MediaController",
"23": "Ingredient Management Controller",
"24": "Admin Dashboard Components",
"24": "adminRoutes.tsx",
"25": "admin.module.ts",
"26": "Pet DTOs and Controller",
"26": "SmsService",
"27": "Prescription Review Controller",
"28": "Smart Advisor Controller",
"29": "Testimonials Management Controller",
"30": "Admin Sidebar and Layout",
"31": "Admin Settings Managers",
"30": "src/services/api.ts",
"31": "Spinner.tsx",
"32": "useCartStore",
"33": "ZibalService",
"34": "main.ts",
"35": "ContactService",
"36": "Backend TypeScript Config",
"37": "App TypeScript Config",
"38": "CMS and Media Modals",
"38": "ConfirmModal.tsx",
"39": "dependencies",
"40": "Node TypeScript Config",
"41": "Admin Blog Controller",
"42": "WholesaleApplyDto",
"42": "WholesaleService",
"43": "devDependencies",
"44": "Generic CRUD Controller",
"45": "seo.module.ts",
@ -63,17 +63,17 @@
"61": "PaginationDto",
"62": "BlogsController",
"63": "FE-001",
"64": "pagination.dto.ts",
"64": "WikiService",
"65": "rules/graphify.md",
"66": "App Health Controller",
"67": "dependencies",
"68": "Pet Business Logic",
"68": "OrdersService",
"69": "Integrity Validation Scripts",
"70": "Admin Panel Package Config",
"71": "Analytics and Report Charts",
"72": "Task Orchestration Scripts",
"73": "Backend Package Config",
"74": "Health Log DTOs",
"74": "CreateOrderDto",
"75": "React Error Boundary",
"76": "Application Package Config",
"77": "WikiController",
@ -102,7 +102,7 @@
"100": "Network Status Banner",
"101": "Docker Deployment Scripts",
"102": "DB-001",
"103": "typescript-eslint",
"103": ".adminLogin",
"104": "Database Migration Scripts",
"105": "Scientific Terms Schema",
"106": "Blog Data Seeding",
@ -116,7 +116,7 @@
"114": "Manifest Data Generation",
"115": "Honest Manifest Synchronization",
"116": "Manifest Entry Synchronization",
"117": "Pet Reminder DTOs",
"117": "AuthController",
"118": "TS-001",
"119": "TEST-001",
"120": "@tailwindcss/postcss",
@ -129,14 +129,14 @@
"127": "DEVOPS-001",
"128": "DOC-001",
"129": "What You Must Do When Invoked",
"130": "Roles",
"130": "JwtAuthGuard",
"131": "راهنمای تست سیستم (Software Testing)",
"132": "Role & Core Objective",
"133": "Required Review Group Closures",
"134": "Operational Rules & Boundaries",
"135": "Operational Rules & Boundaries",
"136": "🏢 AI Software Agency — Master Orchestration Protocol v3",
"137": "NestJS CLI Tooling",
"137": "BlogsService",
"138": "Operational Rules & Boundaries",
"139": "Operational Rules & Boundaries",
"140": "Bcrypt Type Definitions",
@ -263,5 +263,16 @@
"261": "shabnam-font-v5.0.1/CHANGELOG.md",
"262": "application/CLAUDE.md",
"263": "application/public/fonts/sahel-font-v3.4.0/CHANGELOG.md",
"264": "tailwindcss"
"264": "tailwindcss",
"265": "AuthService",
"266": "RegisterDto",
"267": "GetProductsDto",
"268": "WholesaleApplyDto",
"269": "AdminLoginDto",
"270": "VerifyOtpDto",
"271": "App.tsx",
"272": "ValidateCouponDto",
"273": "AGENTS.md",
"274": "eslint-config-prettier",
"275": "globals"
}

View File

@ -1,26 +1,26 @@
# Graph Report - canina (2026-08-16)
## Corpus Check
- 459 files · ~667,716 words
- 461 files · ~673,005 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 3167 nodes · 5051 edges · 265 communities (171 shown, 94 thin omitted)
- Extraction: 97% EXTRACTED · 3% INFERRED · 0% AMBIGUOUS · INFERRED: 160 edges (avg confidence: 0.79)
- 3199 nodes · 5155 edges · 276 communities (179 shown, 97 thin omitted)
- Extraction: 97% EXTRACTED · 3% INFERRED · 0% AMBIGUOUS · INFERRED: 171 edges (avg confidence: 0.79)
- Token cost: 0 input · 0 output
## Graph Freshness
- Built from commit: `03900e72`
- Built from commit: `0934b4f3`
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
- Run `graphify update .` after code changes (no API cost).
## Community Hubs (Navigation)
- AdminService
- Pet Management Controller
- SettingsController
- pets/pets.controller.ts
- Roles
- UsersService
- CMS Content Management
- OrdersService
- CmsController
- .create
- auth.controller.ts
- app.module.ts
- CreateVideoDto
@ -28,7 +28,7 @@
- SmartAdvisor.tsx
- compilerOptions
- toPersian
- Media and Blog UI Components
- Products.tsx
- ProductsService
- lib/services/api.ts
- devDependencies
@ -36,28 +36,28 @@
- AppModule
- B2B Inquiry Controller
- Category Management Controller
- Banner Management Controller
- Media Upload Controller
- auth.service.ts
- MediaController
- Ingredient Management Controller
- Admin Dashboard Components
- adminRoutes.tsx
- admin.module.ts
- Pet DTOs and Controller
- SmsService
- Prescription Review Controller
- Smart Advisor Controller
- Testimonials Management Controller
- Admin Sidebar and Layout
- Admin Settings Managers
- src/services/api.ts
- Spinner.tsx
- useCartStore
- ZibalService
- main.ts
- ContactService
- Backend TypeScript Config
- App TypeScript Config
- CMS and Media Modals
- ConfirmModal.tsx
- dependencies
- Node TypeScript Config
- Admin Blog Controller
- WholesaleApplyDto
- WholesaleService
- devDependencies
- Generic CRUD Controller
- seo.module.ts
@ -79,17 +79,17 @@
- PaginationDto
- BlogsController
- FE-001
- pagination.dto.ts
- WikiService
- rules/graphify.md
- App Health Controller
- dependencies
- Pet Business Logic
- OrdersService
- Integrity Validation Scripts
- Admin Panel Package Config
- Analytics and Report Charts
- Task Orchestration Scripts
- Backend Package Config
- Health Log DTOs
- CreateOrderDto
- React Error Boundary
- Application Package Config
- WikiController
@ -118,7 +118,7 @@
- Network Status Banner
- Docker Deployment Scripts
- DB-001
- typescript-eslint
- .adminLogin
- Database Migration Scripts
- Scientific Terms Schema
- Blog Data Seeding
@ -132,7 +132,7 @@
- Manifest Data Generation
- Honest Manifest Synchronization
- Manifest Entry Synchronization
- Pet Reminder DTOs
- AuthController
- TS-001
- TEST-001
- @tailwindcss/postcss
@ -145,14 +145,14 @@
- DEVOPS-001
- DOC-001
- What You Must Do When Invoked
- Roles
- JwtAuthGuard
- راهنمای تست سیستم (Software Testing)
- Role & Core Objective
- Required Review Group Closures
- Operational Rules & Boundaries
- Operational Rules & Boundaries
- 🏢 AI Software Agency — Master Orchestration Protocol v3
- NestJS CLI Tooling
- BlogsService
- Operational Rules & Boundaries
- Operational Rules & Boundaries
- Bcrypt Type Definitions
@ -266,18 +266,29 @@
- @types/react
- typescript
- vitest
- AuthService
- RegisterDto
- GetProductsDto
- WholesaleApplyDto
- AdminLoginDto
- VerifyOtpDto
- App.tsx
- ValidateCouponDto
- AGENTS.md
- eslint-config-prettier
- globals
## God Nodes (most connected - your core abstractions)
1. `PrismaService` - 72 edges
2. `Roles()` - 45 edges
1. `PrismaService` - 74 edges
2. `Roles()` - 51 edges
3. `PaginationDto` - 39 edges
4. `useSettingsStore` - 33 edges
5. `api` - 32 edges
6. `AdminService` - 31 edges
7. `toPersian()` - 31 edges
8. `AdminController` - 30 edges
9. `useCartStore` - 29 edges
10. `JwtAuthGuard` - 27 edges
4. `SmsService` - 34 edges
5. `api` - 33 edges
6. `useSettingsStore` - 33 edges
7. `AdminService` - 31 edges
8. `toPersian()` - 31 edges
9. `AdminController` - 30 edges
10. `useCartStore` - 29 edges
## Surprising Connections (you probably didn't know these)
- `User Profile Photo` --conceptually_related_to--> `User Roles and Capabilities` [INFERRED]
@ -300,38 +311,38 @@
- **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]
## Communities (265 total, 94 thin omitted)
## Communities (276 total, 97 thin omitted)
### Community 0 - "AdminService"
Cohesion: 0.07
Nodes (22): AdminController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+14 more)
### Community 1 - "Pet Management Controller"
Cohesion: 0.17
Nodes (18): PetsController, ApiBadRequestResponse, ApiBearerAuth, ApiCreatedResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags (+10 more)
### Community 1 - "pets/pets.controller.ts"
Cohesion: 0.05
Nodes (45): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, CreatePetDto, ApiProperty (+37 more)
### Community 2 - "SettingsController"
Cohesion: 0.13
Nodes (16): SettingsController, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller, Delete (+8 more)
### Community 2 - "Roles"
Cohesion: 0.07
Nodes (32): BannersController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+24 more)
### Community 3 - "UsersService"
Cohesion: 0.06
Nodes (37): AuthModule, Module, JwtPayload, JwtStrategy, Injectable, AddressDto, ApiProperty, ApiPropertyOptional (+29 more)
Cohesion: 0.07
Nodes (34): JwtPayload, JwtStrategy, Injectable, AddressDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty (+26 more)
### Community 4 - "CMS Content Management"
### Community 4 - "CmsController"
Cohesion: 0.09
Nodes (24): CmsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+16 more)
### Community 5 - "OrdersService"
Cohesion: 0.07
Nodes (29): CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional (+21 more)
### Community 5 - ".create"
Cohesion: 0.18
Nodes (11): ApiBadRequestResponse, ApiCreatedResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, Body, Get, Param (+3 more)
### Community 6 - "auth.controller.ts"
Cohesion: 0.05
Nodes (41): AuthController, ApiBadRequestResponse, ApiOkResponse, ApiOperation, ApiTags, Body, Controller, Post (+33 more)
Cohesion: 0.18
Nodes (10): LoginDto, ApiProperty, IsNotEmpty, IsString, MinLength, SendOtpDto, ApiProperty, IsNotEmpty (+2 more)
### Community 7 - "app.module.ts"
Cohesion: 0.09
Cohesion: 0.07
Nodes (28): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+20 more)
### Community 8 - "CreateVideoDto"
@ -354,13 +365,13 @@ Nodes (32): compilerOptions, allowJs, esModuleInterop, incremental, isolatedModu
Cohesion: 0.08
Nodes (37): ClientLayout(), VerifyContent(), AddressModal(), AddressModalProps, AuthModal(), AuthModalProps, B2BPortal(), BackButton() (+29 more)
### Community 13 - "Media and Blog UI Components"
Cohesion: 0.09
Nodes (19): Media, MediaSelector(), MediaSelectorProps, Pagination(), PaginationProps, BlogPost, Category, Pet (+11 more)
### Community 13 - "Products.tsx"
Cohesion: 0.15
Nodes (9): Pagination(), PaginationProps, BlogPost, Pet, Category, Product, Blogs, Pets (+1 more)
### Community 14 - "ProductsService"
Cohesion: 0.09
Nodes (19): GetProductsDto, ApiPropertyOptional, IsEnum, IsOptional, IsString, ProductsController, ApiOperation, ApiTags (+11 more)
Cohesion: 0.12
Nodes (13): ProductsController, ApiOperation, ApiTags, Body, Controller, Get, Param, Patch (+5 more)
### Community 15 - "lib/services/api.ts"
Cohesion: 0.08
@ -368,7 +379,7 @@ Nodes (17): metadata, ContactFormClient(), ContactInfoItem, PrescriptionUploadMo
### Community 16 - "devDependencies"
Cohesion: 0.09
Nodes (23): devDependencies, eslint, eslint-config-prettier, @eslint/js, jest, @nestjs/schematics, @nestjs/testing, source-map-support (+15 more)
Nodes (23): devDependencies, eslint, @eslint/js, jest, @nestjs/cli, @nestjs/schematics, @nestjs/testing, source-map-support (+15 more)
### Community 17 - "useSettingsStore"
Cohesion: 0.07
@ -386,29 +397,25 @@ Nodes (15): B2BController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controlle
Cohesion: 0.10
Nodes (16): CategoriesController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+8 more)
### Community 21 - "Banner Management Controller"
Cohesion: 0.13
Nodes (15): BannersController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+7 more)
### Community 21 - "auth.service.ts"
Cohesion: 0.14
Nodes (10): CouponTargetInput, PaginationQuery, AdminLoginInput, LoginInput, RegisterInput, RedisModule, Global, Module (+2 more)
### Community 22 - "Media Upload Controller"
Cohesion: 0.11
### Community 22 - "MediaController"
Cohesion: 0.10
Nodes (16): MediaController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+8 more)
### Community 23 - "Ingredient Management Controller"
Cohesion: 0.13
Nodes (14): IngredientsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
### Community 24 - "Admin Dashboard Components"
Cohesion: 0.10
Nodes (14): App(), ContactInfoItem, ContactSubmission, CategoryDist, DashboardData, GROUP_PAGE_MAP, GROUPS, PAGE_TABS (+6 more)
### Community 24 - "adminRoutes.tsx"
Cohesion: 0.09
Nodes (18): ContactInfoItem, ContactSubmission, CategoryDist, DashboardData, PatternItem, SmsConfigState, GROUP_PAGE_MAP, GROUPS (+10 more)
### Community 25 - "admin.module.ts"
Cohesion: 0.07
Nodes (20): AdminModule, Module, BlogQuery, BlogsService, Injectable, PetQuery, PetsService, Injectable (+12 more)
### Community 26 - "Pet DTOs and Controller"
Cohesion: 0.16
Nodes (13): CreatePetDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional, IsString (+5 more)
Cohesion: 0.09
Nodes (15): AdminModule, Module, CategoryQuery, PetQuery, PetsService, Injectable, ReportsController, ApiBearerAuth (+7 more)
### Community 27 - "Prescription Review Controller"
Cohesion: 0.14
@ -422,13 +429,13 @@ Nodes (14): SmartAdvisorController, ApiBearerAuth, ApiOperation, ApiTags, Body,
Cohesion: 0.13
Nodes (14): TestimonialsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
### Community 30 - "Admin Sidebar and Layout"
Cohesion: 0.17
Nodes (16): Layout(), ProtectedRoute(), menuGroups, Sidebar(), SidebarProps, SEARCHABLE_PAGES, Topbar(), TopbarProps (+8 more)
### Community 30 - "src/services/api.ts"
Cohesion: 0.12
Nodes (22): Layout(), ProtectedRoute(), menuGroups, Sidebar(), SidebarProps, SEARCHABLE_PAGES, Topbar(), TopbarProps (+14 more)
### Community 31 - "Admin Settings Managers"
### Community 31 - "Spinner.tsx"
Cohesion: 0.09
Nodes (21): Spinner(), B2BManager, BannersManager, FinancialSettingsPage, SeoSettingsPage, SmartAdvisorManager, SystemSettingsPage, TestimonialsManager (+13 more)
Nodes (21): Media, MediaSelector(), MediaSelectorProps, Spinner(), Category, Media, BannersManager, Categories (+13 more)
### Community 32 - "useCartStore"
Cohesion: 0.12
@ -454,9 +461,9 @@ Nodes (22): compilerOptions, allowSyntheticDefaultImports, baseUrl, declaration,
Cohesion: 0.09
Nodes (22): compilerOptions, allowImportingTsExtensions, erasableSyntaxOnly, jsx, lib, module, moduleDetection, moduleResolution (+14 more)
### Community 38 - "CMS and Media Modals"
Cohesion: 0.10
Nodes (16): ConfirmModal(), ConfirmModalProps, HeroBanner, VetTestimonial, Media, fetchVideosList(), Video, Videos() (+8 more)
### Community 38 - "ConfirmModal.tsx"
Cohesion: 0.09
Nodes (17): ConfirmModal(), ConfirmModalProps, HeroBanner, VetTestimonial, fetchVideosList(), Video, Videos(), WholesaleRequest (+9 more)
### Community 39 - "dependencies"
Cohesion: 0.05
@ -470,9 +477,9 @@ Nodes (20): compilerOptions, allowImportingTsExtensions, erasableSyntaxOnly, lib
Cohesion: 0.13
Nodes (15): BlogsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+7 more)
### Community 42 - "WholesaleApplyDto"
Cohesion: 0.10
Nodes (20): ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, WholesaleApplyDto, ApiBearerAuth, ApiOperation (+12 more)
### Community 42 - "WholesaleService"
Cohesion: 0.14
Nodes (14): ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get, Param, Post (+6 more)
### Community 43 - "devDependencies"
Cohesion: 0.13
@ -500,7 +507,7 @@ Nodes (10): HomeController, ApiOkResponse, ApiOperation, ApiTags, Controller, Ge
### Community 49 - "devDependencies"
Cohesion: 0.11
Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, globals, postcss, @types/node (+11 more)
Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, postcss, @types/node, @types/react (+11 more)
### Community 50 - "Database Seeding Logic"
Cohesion: 0.17
@ -539,16 +546,16 @@ Cohesion: 0.15
Nodes (11): PetsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Controller, Delete, Get (+3 more)
### Community 59 - "PrismaService"
Cohesion: 0.06
Nodes (21): CouponTargetInput, PaginationQuery, CategoryQuery, AdminLoginInput, LoginInput, RegisterInput, MeliPayamakResponse, SendPatternSmsOptions (+13 more)
Cohesion: 0.12
Nodes (13): MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions, SmsConfig, CreateContactSubmissionDto, UpdateContactInfoItemDto, ZibalInquiryResponse, ZibalRequestResponse (+5 more)
### Community 60 - "Jest Testing Config"
Cohesion: 0.15
Nodes (13): jest, collectCoverageFrom, coverageDirectory, moduleFileExtensions, rootDir, testEnvironment, testRegex, transform (+5 more)
### Community 61 - "PaginationDto"
Cohesion: 0.13
Nodes (12): PaginationDto, ApiPropertyOptional, IsEnum, IsOptional, IsString, Type, Module, WikiModule (+4 more)
Cohesion: 0.14
Nodes (13): PaginationDto, SortOrder, ApiPropertyOptional, IsEnum, IsOptional, IsString, Type, Module (+5 more)
### Community 62 - "BlogsController"
Cohesion: 0.20
@ -558,9 +565,9 @@ Nodes (7): BlogsController, ApiTags, Controller, BlogsModule, Module, BlogsServi
Cohesion: 0.06
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Architecture Overview & Confirmed Strengths, Category, Completion Statement, Confidence (+23 more)
### Community 64 - "pagination.dto.ts"
Cohesion: 0.11
Nodes (10): Injectable, WikiQuery, WikiService, SortOrder, IsNotEmpty, IsNumber, IsString, ValidateCouponDto (+2 more)
### Community 64 - "WikiService"
Cohesion: 0.22
Nodes (3): Injectable, WikiQuery, WikiService
### Community 66 - "App Health Controller"
Cohesion: 0.29
@ -570,6 +577,10 @@ Nodes (5): AppController, Controller, Get, AppService, Injectable
Cohesion: 0.12
Nodes (17): dependencies, axios, lucide-react, motion, next, react, react-dom, sonner (+9 more)
### Community 68 - "OrdersService"
Cohesion: 0.15
Nodes (9): OrdersController, ApiBearerAuth, ApiTags, Controller, UseGuards, OrdersModule, Module, OrdersService (+1 more)
### Community 69 - "Integrity Validation Scripts"
Cohesion: 0.20
Nodes (9): dispSum, errors, invalidNewIds, manifest, report, trackedFiles, uninspected, verifiedIndex (+1 more)
@ -590,9 +601,9 @@ Nodes (8): cmd_next_task(), cmd_progress(), cmd_reset(), cmd_status(), cmd_unblo
Cohesion: 0.22
Nodes (8): author, description, license, name, prisma, seed, private, version
### Community 74 - "Health Log DTOs"
Cohesion: 0.29
Nodes (6): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString
### Community 74 - "CreateOrderDto"
Cohesion: 0.21
Nodes (11): CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional (+3 more)
### Community 75 - "React Error Boundary"
Cohesion: 0.22
@ -666,13 +677,17 @@ Nodes (3): COMPOSE_DOCKER_CLI_BUILD, DOCKER_BUILDKIT, deploy.sh script
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)
### Community 103 - ".adminLogin"
Cohesion: 0.55
Nodes (6): ApiBadRequestResponse, ApiOkResponse, ApiOperation, Body, Post, HttpCode
### Community 109 - "Auth Architecture and Planning"
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
### Community 117 - "Pet Reminder DTOs"
Cohesion: 0.29
Nodes (6): CreateReminderDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString
### Community 117 - "AuthController"
Cohesion: 0.20
Nodes (7): AuthController, ApiTags, Controller, AuthModule, Module, Module, UsersModule
### Community 118 - "TS-001"
Cohesion: 0.06
@ -698,9 +713,9 @@ Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternati
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)
### Community 130 - "Roles"
Cohesion: 0.21
Nodes (8): JwtAuthGuard, Injectable, Roles(), ROLES_KEY, RequestWithUser, RolesGuard, Injectable, UserReqPayload
### Community 130 - "JwtAuthGuard"
Cohesion: 0.19
Nodes (7): JwtAuthGuard, Injectable, ROLES_KEY, RequestWithUser, RolesGuard, Injectable, UserReqPayload
### Community 131 - "راهنمای تست سیستم (Software Testing)"
Cohesion: 0.07
@ -726,6 +741,10 @@ Nodes (18): 1. Framework-Aware Analysis, 2. DOM & Semantic Structure Analysis, 3
Cohesion: 0.11
Nodes (17): Activation, Agent Directory Reference, 🏢 AI Software Agency — Master Orchestration Protocol v3, Phase 1: Specialist Review (All agents read, none write code yet), Phase 2: Master Synthesis (02_product_manager in SYNTHESIS mode), Phase 3: Execution (Same as always), PIPELINE A — New Project (GREENFIELD), PIPELINE B — Review & Improve Existing Project (REVIEW_AND_PLAN) ★ (+9 more)
### Community 137 - "BlogsService"
Cohesion: 0.22
Nodes (3): BlogQuery, BlogsService, Injectable
### Community 138 - "Operational Rules & Boundaries"
Cohesion: 0.11
Nodes (17): 1. Hierarchical Decomposition Algorithm (3-Tier), 2. Sub-step Definition (Required for all tasks), 3. Brownfield Completeness Rule, 4. Role Assignment Rules, 5. Dependency Tracking (Strict), 6. Priority Assignment, 7. Forbidden Actions, DECOMPOSE MODE — Normal Operation (New Projects) (+9 more)
@ -930,25 +949,49 @@ Nodes (3): Expanding the ESLint configuration, React Compiler, React + TypeScrip
Cohesion: 0.50
Nodes (3): Deploy on Vercel, Getting Started, Learn More
### Community 266 - "RegisterDto"
Cohesion: 0.22
Nodes (8): RegisterDto, ApiProperty, ApiPropertyOptional, IsEmail, IsNotEmpty, IsOptional, IsString, MinLength
### Community 267 - "GetProductsDto"
Cohesion: 0.29
Nodes (6): GetProductsDto, ApiPropertyOptional, IsEnum, IsOptional, IsString, Query
### Community 268 - "WholesaleApplyDto"
Cohesion: 0.29
Nodes (6): ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, WholesaleApplyDto
### Community 269 - "AdminLoginDto"
Cohesion: 0.29
Nodes (6): AdminLoginDto, ApiProperty, IsEmail, IsNotEmpty, IsString, MinLength
### Community 270 - "VerifyOtpDto"
Cohesion: 0.29
Nodes (6): ApiProperty, IsNotEmpty, IsString, Matches, VerifyOtpDto, Length
### Community 272 - "ValidateCouponDto"
Cohesion: 0.50
Nodes (4): IsNotEmpty, IsNumber, IsString, ValidateCouponDto
## Knowledge Gaps
- **1170 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1165 more)
- **1175 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1170 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **94 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
- **97 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
## Suggested Questions
_Questions this graph is uniquely positioned to answer:_
- **Why does `ApiResponse` connect `Admin Sidebar and Layout` to `Pet Management Controller`, `UsersService`, `OrdersService`, `auth.controller.ts`, `WikiController`, `ProductsService`, `Home Data Module`, `BlogsController`, `Admin Settings Managers`?**
_High betweenness centrality (0.033) - this node is a cross-community bridge._
- **Why does `Roles()` connect `Roles` to `SettingsController`, `ContactService`, `CMS Content Management`, `WholesaleApplyDto`, `ProductsService`, `B2B Inquiry Controller`, `Banner Management Controller`, `Ingredient Management Controller`, `Prescription Review Controller`, `Smart Advisor Controller`, `Testimonials Management Controller`?**
_High betweenness centrality (0.020) - this node is a cross-community bridge._
- **Why does `JwtAuthGuard` connect `Roles` to `AdminService`, `pagination.dto.ts`, `ZibalService`, `UsersService`, `CreateVideoDto`, `ProductsService`, `admin.module.ts`, `Pet DTOs and Controller`?**
_High betweenness centrality (0.020) - this node is a cross-community bridge._
- **Why does `ApiResponse` connect `src/services/api.ts` to `pets/pets.controller.ts`, `UsersService`, `OrdersService`, `WikiController`, `ProductsService`, `Home Data Module`, `AuthController`, `BlogsController`?**
_High betweenness centrality (0.036) - this node is a cross-community bridge._
- **Why does `Roles()` connect `Roles` to `JwtAuthGuard`, `ContactService`, `CmsController`, `WholesaleService`, `ProductsService`, `B2B Inquiry Controller`, `Ingredient Management Controller`, `Prescription Review Controller`, `Smart Advisor Controller`, `Testimonials Management Controller`?**
_High betweenness centrality (0.026) - this node is a cross-community bridge._
- **Why does `JwtAuthGuard` connect `JwtAuthGuard` to `AdminService`, `ZibalService`, `pets/pets.controller.ts`, `UsersService`, `CmsController`, `OrdersService`, `CreateVideoDto`, `ProductsService`, `MediaController`, `admin.module.ts`?**
_High betweenness centrality (0.023) - this node is a cross-community bridge._
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
_1170 weakly-connected nodes found - possible documentation gaps or missing edges._
_1175 weakly-connected nodes found - possible documentation gaps or missing edges._
- **Should `AdminService` be split into smaller, more focused modules?**
_Cohesion score 0.06690140845070422 - nodes in this community are weakly interconnected._
- **Should `SettingsController` be split into smaller, more focused modules?**
_Cohesion score 0.1251778093883357 - nodes in this community are weakly interconnected._
- **Should `UsersService` be split into smaller, more focused modules?**
_Cohesion score 0.06093189964157706 - nodes in this community are weakly interconnected._
- **Should `pets/pets.controller.ts` be split into smaller, more focused modules?**
_Cohesion score 0.0528169014084507 - nodes in this community are weakly interconnected._
- **Should `Roles` be split into smaller, more focused modules?**
_Cohesion score 0.06771929824561404 - 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

View File

@ -1,47 +1,47 @@
# Graph Report - canina (2026-08-16)
## Corpus Check
- 461 files · ~673,005 words
- 461 files · ~675,412 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 3199 nodes · 5155 edges · 276 communities (179 shown, 97 thin omitted)
- Extraction: 97% EXTRACTED · 3% INFERRED · 0% AMBIGUOUS · INFERRED: 171 edges (avg confidence: 0.79)
- 3213 nodes · 5194 edges · 268 communities (173 shown, 95 thin omitted)
- Extraction: 97% EXTRACTED · 3% INFERRED · 0% AMBIGUOUS · INFERRED: 177 edges (avg confidence: 0.79)
- Token cost: 0 input · 0 output
## Graph Freshness
- Built from commit: `0934b4f3`
- Built from commit: `d8c6aa8d`
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
- Run `graphify update .` after code changes (no API cost).
## Community Hubs (Navigation)
- AdminService
- pets/pets.controller.ts
- PetsController
- Roles
- UsersService
- CmsController
- .create
- auth.controller.ts
- BannersService
- auth.service.ts
- app.module.ts
- CreateVideoDto
- ProductService
- SmartAdvisor.tsx
- compilerOptions
- toPersian
- Products.tsx
- pets/pets.controller.ts
- ProductsService
- lib/services/api.ts
- devDependencies
- useSettingsStore
- AppModule
- MetricsController
- B2B Inquiry Controller
- Category Management Controller
- auth.service.ts
- RedisService
- MediaController
- Ingredient Management Controller
- adminRoutes.tsx
- admin.module.ts
- SmsService
- api
- Prescription Review Controller
- Smart Advisor Controller
- Testimonials Management Controller
@ -50,7 +50,7 @@
- useCartStore
- ZibalService
- main.ts
- ContactService
- payment.controller.ts
- Backend TypeScript Config
- App TypeScript Config
- ConfirmModal.tsx
@ -77,9 +77,9 @@
- PrismaService
- Jest Testing Config
- PaginationDto
- BlogsController
- WikiController
- FE-001
- WikiService
- PetsService
- rules/graphify.md
- App Health Controller
- dependencies
@ -89,10 +89,10 @@
- Analytics and Report Charts
- Task Orchestration Scripts
- Backend Package Config
- CreateOrderDto
- CreateHealthLogDto
- React Error Boundary
- Application Package Config
- WikiController
- .findAll
- Error and Not Found Pages
- VPN Utility Scripts
- NestJS CLI Config
@ -118,7 +118,7 @@
- Network Status Banner
- Docker Deployment Scripts
- DB-001
- .adminLogin
- CreateReminderDto
- Database Migration Scripts
- Scientific Terms Schema
- Blog Data Seeding
@ -132,7 +132,7 @@
- Manifest Data Generation
- Honest Manifest Synchronization
- Manifest Entry Synchronization
- AuthController
- Videos.tsx
- TS-001
- TEST-001
- @tailwindcss/postcss
@ -145,14 +145,14 @@
- DEVOPS-001
- DOC-001
- What You Must Do When Invoked
- JwtAuthGuard
- RolesGuard
- راهنمای تست سیستم (Software Testing)
- Role & Core Objective
- Required Review Group Closures
- Operational Rules & Boundaries
- Operational Rules & Boundaries
- 🏢 AI Software Agency — Master Orchestration Protocol v3
- BlogsService
- @nestjs/cli
- Operational Rules & Boundaries
- Operational Rules & Boundaries
- Bcrypt Type Definitions
@ -222,7 +222,7 @@
- Phase 2 Final Quality Gate Summary Report
- Task Modifications Log
- Install
- .findAll
- BlogsController
- System Discovery
- Product Requirement Document (PRD)
- Baseline Command Plan & Reconciled Command History
@ -266,23 +266,15 @@
- @types/react
- typescript
- vitest
- AuthService
- RegisterDto
- GetProductsDto
- WholesaleApplyDto
- AdminLoginDto
- VerifyOtpDto
- App.tsx
- ValidateCouponDto
- typescript-eslint
- wholesale.controller.ts
- AGENTS.md
- eslint-config-prettier
- globals
## God Nodes (most connected - your core abstractions)
1. `PrismaService` - 74 edges
2. `Roles()` - 51 edges
2. `Roles()` - 54 edges
3. `PaginationDto` - 39 edges
4. `SmsService` - 34 edges
4. `SmsService` - 38 edges
5. `api` - 33 edges
6. `useSettingsStore` - 33 edges
7. `AdminService` - 31 edges
@ -311,43 +303,43 @@
- **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]
## Communities (276 total, 97 thin omitted)
## Communities (268 total, 95 thin omitted)
### Community 0 - "AdminService"
Cohesion: 0.07
Nodes (22): AdminController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+14 more)
Cohesion: 0.06
Nodes (24): AdminController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+16 more)
### Community 1 - "pets/pets.controller.ts"
Cohesion: 0.05
Nodes (45): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, CreatePetDto, ApiProperty (+37 more)
### Community 1 - "PetsController"
Cohesion: 0.17
Nodes (18): PetsController, ApiBadRequestResponse, ApiBearerAuth, ApiCreatedResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags (+10 more)
### Community 2 - "Roles"
Cohesion: 0.07
Nodes (32): BannersController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+24 more)
Cohesion: 0.05
Nodes (31): Roles(), SmsService, Injectable, ContactController, Body, Controller, Get, Param (+23 more)
### Community 3 - "UsersService"
Cohesion: 0.07
Nodes (34): JwtPayload, JwtStrategy, Injectable, AddressDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty (+26 more)
Cohesion: 0.06
Nodes (37): AuthModule, Module, JwtPayload, JwtStrategy, Injectable, AddressDto, ApiProperty, ApiPropertyOptional (+29 more)
### Community 4 - "CmsController"
Cohesion: 0.09
Nodes (24): CmsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+16 more)
### Community 5 - ".create"
Cohesion: 0.18
Nodes (11): ApiBadRequestResponse, ApiCreatedResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, Body, Get, Param (+3 more)
### Community 5 - "BannersService"
Cohesion: 0.13
Nodes (15): BannersController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+7 more)
### Community 6 - "auth.controller.ts"
Cohesion: 0.18
Nodes (10): LoginDto, ApiProperty, IsNotEmpty, IsString, MinLength, SendOtpDto, ApiProperty, IsNotEmpty (+2 more)
### Community 6 - "auth.service.ts"
Cohesion: 0.05
Nodes (44): AuthController, ApiBadRequestResponse, ApiOkResponse, ApiOperation, ApiTags, Body, Controller, Post (+36 more)
### Community 7 - "app.module.ts"
Cohesion: 0.07
Nodes (28): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+20 more)
Cohesion: 0.08
Nodes (30): AdminModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+22 more)
### Community 8 - "CreateVideoDto"
Cohesion: 0.07
Nodes (31): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, UpdateVideoDto (+23 more)
Cohesion: 0.08
Nodes (29): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, UpdateVideoDto (+21 more)
### Community 9 - "ProductService"
Cohesion: 0.07
@ -365,13 +357,13 @@ Nodes (32): compilerOptions, allowJs, esModuleInterop, incremental, isolatedModu
Cohesion: 0.08
Nodes (37): ClientLayout(), VerifyContent(), AddressModal(), AddressModalProps, AuthModal(), AuthModalProps, B2BPortal(), BackButton() (+29 more)
### Community 13 - "Products.tsx"
Cohesion: 0.15
Nodes (9): Pagination(), PaginationProps, BlogPost, Pet, Category, Product, Blogs, Pets (+1 more)
### Community 13 - "pets/pets.controller.ts"
Cohesion: 0.16
Nodes (13): CreatePetDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional, IsString (+5 more)
### Community 14 - "ProductsService"
Cohesion: 0.12
Nodes (13): ProductsController, ApiOperation, ApiTags, Body, Controller, Get, Param, Patch (+5 more)
Cohesion: 0.09
Nodes (19): GetProductsDto, ApiPropertyOptional, IsEnum, IsOptional, IsString, ProductsController, ApiOperation, ApiTags (+11 more)
### Community 15 - "lib/services/api.ts"
Cohesion: 0.08
@ -379,15 +371,15 @@ Nodes (17): metadata, ContactFormClient(), ContactInfoItem, PrescriptionUploadMo
### Community 16 - "devDependencies"
Cohesion: 0.09
Nodes (23): devDependencies, eslint, @eslint/js, jest, @nestjs/cli, @nestjs/schematics, @nestjs/testing, source-map-support (+15 more)
Nodes (23): devDependencies, eslint, eslint-config-prettier, @eslint/js, jest, @nestjs/schematics, @nestjs/testing, source-map-support (+15 more)
### Community 17 - "useSettingsStore"
Cohesion: 0.07
Nodes (30): HomeClient(), HomeClientProps, getHomeData(), Home(), metadata, metadata, EnamadBadge(), Footer() (+22 more)
### Community 18 - "AppModule"
Cohesion: 0.12
Nodes (7): ApiExcludeController, AppModule, Module, MetricsController, Controller, Get, Res
### Community 18 - "MetricsController"
Cohesion: 0.20
Nodes (5): ApiExcludeController, MetricsController, Controller, Get, Res
### Community 19 - "B2B Inquiry Controller"
Cohesion: 0.13
@ -397,12 +389,12 @@ Nodes (15): B2BController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controlle
Cohesion: 0.10
Nodes (16): CategoriesController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+8 more)
### Community 21 - "auth.service.ts"
Cohesion: 0.14
Nodes (10): CouponTargetInput, PaginationQuery, AdminLoginInput, LoginInput, RegisterInput, RedisModule, Global, Module (+2 more)
### Community 21 - "RedisService"
Cohesion: 0.19
Nodes (5): RedisModule, Global, Module, RedisService, Injectable
### Community 22 - "MediaController"
Cohesion: 0.10
Cohesion: 0.11
Nodes (16): MediaController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+8 more)
### Community 23 - "Ingredient Management Controller"
@ -410,12 +402,16 @@ Cohesion: 0.13
Nodes (14): IngredientsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
### Community 24 - "adminRoutes.tsx"
Cohesion: 0.09
Nodes (18): ContactInfoItem, ContactSubmission, CategoryDist, DashboardData, PatternItem, SmsConfigState, GROUP_PAGE_MAP, GROUPS (+10 more)
Cohesion: 0.10
Nodes (14): App(), ContactInfoItem, ContactSubmission, GROUP_PAGE_MAP, GROUPS, PAGE_TABS, AdminRouteConfig, ContactSubmissions (+6 more)
### Community 25 - "admin.module.ts"
Cohesion: 0.09
Nodes (15): AdminModule, Module, CategoryQuery, PetQuery, PetsService, Injectable, ReportsController, ApiBearerAuth (+7 more)
Cohesion: 0.06
Nodes (20): BlogQuery, BlogsService, Injectable, PetQuery, PetsService, Injectable, ReportsController, ApiBearerAuth (+12 more)
### Community 26 - "api"
Cohesion: 0.11
Nodes (12): HeroBanner, VetTestimonial, CategoryDist, DashboardData, PatternItem, SmsConfigState, SmsLogItem, SmsLogStats (+4 more)
### Community 27 - "Prescription Review Controller"
Cohesion: 0.14
@ -430,28 +426,28 @@ Cohesion: 0.13
Nodes (14): TestimonialsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
### Community 30 - "src/services/api.ts"
Cohesion: 0.12
Nodes (22): Layout(), ProtectedRoute(), menuGroups, Sidebar(), SidebarProps, SEARCHABLE_PAGES, Topbar(), TopbarProps (+14 more)
Cohesion: 0.10
Nodes (25): Layout(), ProtectedRoute(), menuGroups, Sidebar(), SidebarProps, SEARCHABLE_PAGES, Topbar(), TopbarProps (+17 more)
### Community 31 - "Spinner.tsx"
Cohesion: 0.09
Nodes (21): Media, MediaSelector(), MediaSelectorProps, Spinner(), Category, Media, BannersManager, Categories (+13 more)
Cohesion: 0.10
Nodes (19): Media, MediaSelector(), MediaSelectorProps, Spinner(), Category, Product, BannersManager, IngredientsManager (+11 more)
### Community 32 - "useCartStore"
Cohesion: 0.12
Nodes (16): metadata, ArchiveProductCard(), ProductCard(), Header(), MENU_ICONS, OrderSuccess(), OrderTracking(), PetProfile() (+8 more)
### Community 33 - "ZibalService"
Cohesion: 0.07
Nodes (30): InitiatePaymentDto, InitiateWalletTopupDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, ApiPropertyOptional (+22 more)
Cohesion: 0.10
Nodes (19): PaymentController, ApiBadRequestResponse, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+11 more)
### Community 34 - "main.ts"
Cohesion: 0.14
Nodes (9): CustomHttpExceptionFilter, Catch, PrismaExceptionFilter, Catch, DecimalInterceptor, Injectable, ApiErrorResponse, ErrorDetailField (+1 more)
Cohesion: 0.11
Nodes (11): AppModule, Module, CustomHttpExceptionFilter, Catch, PrismaExceptionFilter, Catch, DecimalInterceptor, Injectable (+3 more)
### Community 35 - "ContactService"
Cohesion: 0.13
Nodes (11): ContactController, Body, Controller, Get, Param, Post, Put, Query (+3 more)
### Community 35 - "payment.controller.ts"
Cohesion: 0.23
Nodes (11): InitiatePaymentDto, InitiateWalletTopupDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, ApiPropertyOptional (+3 more)
### Community 36 - "Backend TypeScript Config"
Cohesion: 0.09
@ -462,8 +458,8 @@ Cohesion: 0.09
Nodes (22): compilerOptions, allowImportingTsExtensions, erasableSyntaxOnly, jsx, lib, module, moduleDetection, moduleResolution (+14 more)
### Community 38 - "ConfirmModal.tsx"
Cohesion: 0.09
Nodes (17): ConfirmModal(), ConfirmModalProps, HeroBanner, VetTestimonial, fetchVideosList(), Video, Videos(), WholesaleRequest (+9 more)
Cohesion: 0.10
Nodes (17): ConfirmModal(), ConfirmModalProps, Pagination(), PaginationProps, BlogPost, Category, Media, Pet (+9 more)
### Community 39 - "dependencies"
Cohesion: 0.05
@ -507,7 +503,7 @@ Nodes (10): HomeController, ApiOkResponse, ApiOperation, ApiTags, Controller, Ge
### Community 49 - "devDependencies"
Cohesion: 0.11
Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, postcss, @types/node, @types/react (+11 more)
Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, globals, postcss, @types/node (+11 more)
### Community 50 - "Database Seeding Logic"
Cohesion: 0.17
@ -546,29 +542,25 @@ Cohesion: 0.15
Nodes (11): PetsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Controller, Delete, Get (+3 more)
### Community 59 - "PrismaService"
Cohesion: 0.12
Nodes (13): MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions, SmsConfig, CreateContactSubmissionDto, UpdateContactInfoItemDto, ZibalInquiryResponse, ZibalRequestResponse (+5 more)
Cohesion: 0.09
Nodes (15): CategoryQuery, MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions, SmsConfig, SmsLogQuery, CreateContactSubmissionDto, UpdateContactInfoItemDto (+7 more)
### Community 60 - "Jest Testing Config"
Cohesion: 0.15
Nodes (13): jest, collectCoverageFrom, coverageDirectory, moduleFileExtensions, rootDir, testEnvironment, testRegex, transform (+5 more)
### Community 61 - "PaginationDto"
Cohesion: 0.14
Nodes (13): PaginationDto, SortOrder, ApiPropertyOptional, IsEnum, IsOptional, IsString, Type, Module (+5 more)
Cohesion: 0.12
Nodes (13): BlogsModule, Module, BlogsService, Injectable, PaginationDto, SortOrder, ApiPropertyOptional, IsEnum (+5 more)
### Community 62 - "BlogsController"
### Community 62 - "WikiController"
Cohesion: 0.20
Nodes (7): BlogsController, ApiTags, Controller, BlogsModule, Module, BlogsService, Injectable
Nodes (7): ApiTags, Controller, WikiController, Module, WikiModule, Injectable, WikiService
### Community 63 - "FE-001"
Cohesion: 0.06
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Architecture Overview & Confirmed Strengths, Category, Completion Statement, Confidence (+23 more)
### Community 64 - "WikiService"
Cohesion: 0.22
Nodes (3): Injectable, WikiQuery, WikiService
### Community 66 - "App Health Controller"
Cohesion: 0.29
Nodes (5): AppController, Controller, Get, AppService, Injectable
@ -578,8 +570,8 @@ Cohesion: 0.12
Nodes (17): dependencies, axios, lucide-react, motion, next, react, react-dom, sonner (+9 more)
### Community 68 - "OrdersService"
Cohesion: 0.15
Nodes (9): OrdersController, ApiBearerAuth, ApiTags, Controller, UseGuards, OrdersModule, Module, OrdersService (+1 more)
Cohesion: 0.06
Nodes (35): CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional (+27 more)
### Community 69 - "Integrity Validation Scripts"
Cohesion: 0.20
@ -601,9 +593,9 @@ Nodes (8): cmd_next_task(), cmd_progress(), cmd_reset(), cmd_status(), cmd_unblo
Cohesion: 0.22
Nodes (8): author, description, license, name, prisma, seed, private, version
### Community 74 - "CreateOrderDto"
Cohesion: 0.21
Nodes (11): CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional (+3 more)
### Community 74 - "CreateHealthLogDto"
Cohesion: 0.29
Nodes (6): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString
### Community 75 - "React Error Boundary"
Cohesion: 0.22
@ -613,9 +605,9 @@ Nodes (3): ErrorBoundary, Props, State
Cohesion: 0.22
Nodes (8): name, private, scripts, build, dev, lint, start, version
### Community 77 - "WikiController"
Cohesion: 0.21
Nodes (9): ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags, Controller, Get, Param, Query (+1 more)
### Community 77 - ".findAll"
Cohesion: 0.32
Nodes (6): ApiNotFoundResponse, ApiOkResponse, ApiOperation, Get, Param, Query
### Community 79 - "VPN Utility Scripts"
Cohesion: 0.62
@ -677,17 +669,17 @@ Nodes (3): COMPOSE_DOCKER_CLI_BUILD, DOCKER_BUILDKIT, deploy.sh script
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)
### Community 103 - ".adminLogin"
Cohesion: 0.55
Nodes (6): ApiBadRequestResponse, ApiOkResponse, ApiOperation, Body, Post, HttpCode
### Community 103 - "CreateReminderDto"
Cohesion: 0.29
Nodes (6): CreateReminderDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString
### Community 109 - "Auth Architecture and Planning"
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
### Community 117 - "AuthController"
Cohesion: 0.20
Nodes (7): AuthController, ApiTags, Controller, AuthModule, Module, Module, UsersModule
### Community 117 - "Videos.tsx"
Cohesion: 0.50
Nodes (4): fetchVideosList(), Video, Videos(), Videos
### Community 118 - "TS-001"
Cohesion: 0.06
@ -713,9 +705,9 @@ Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternati
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)
### Community 130 - "JwtAuthGuard"
Cohesion: 0.19
Nodes (7): JwtAuthGuard, Injectable, ROLES_KEY, RequestWithUser, RolesGuard, Injectable, UserReqPayload
### Community 130 - "RolesGuard"
Cohesion: 0.23
Nodes (6): ROLES_KEY, RequestWithUser, RolesGuard, Injectable, UserReqPayload, ScientificTermData
### Community 131 - "راهنمای تست سیستم (Software Testing)"
Cohesion: 0.07
@ -741,10 +733,6 @@ Nodes (18): 1. Framework-Aware Analysis, 2. DOM & Semantic Structure Analysis, 3
Cohesion: 0.11
Nodes (17): Activation, Agent Directory Reference, 🏢 AI Software Agency — Master Orchestration Protocol v3, Phase 1: Specialist Review (All agents read, none write code yet), Phase 2: Master Synthesis (02_product_manager in SYNTHESIS mode), Phase 3: Execution (Same as always), PIPELINE A — New Project (GREENFIELD), PIPELINE B — Review & Improve Existing Project (REVIEW_AND_PLAN) ★ (+9 more)
### Community 137 - "BlogsService"
Cohesion: 0.22
Nodes (3): BlogQuery, BlogsService, Injectable
### Community 138 - "Operational Rules & Boundaries"
Cohesion: 0.11
Nodes (17): 1. Hierarchical Decomposition Algorithm (3-Tier), 2. Sub-step Definition (Required for all tasks), 3. Brownfield Completeness Rule, 4. Role Assignment Rules, 5. Dependency Tracking (Strict), 6. Priority Assignment, 7. Forbidden Actions, DECOMPOSE MODE — Normal Operation (New Projects) (+9 more)
@ -869,9 +857,9 @@ Nodes (8): 1. `TASK-AUTH-001`, 2. `TASK-FIN-001`, 3. `DECISION-002`, 4. `TASK-VE
Cohesion: 0.22
Nodes (8): Arch Linux, bower, Install, npm, Shabnam Font, yarn, طریقه استفاده در صفحات وب:, نمونه متن Sample:
### Community 214 - ".findAll"
Cohesion: 0.32
Nodes (6): ApiNotFoundResponse, ApiOkResponse, ApiOperation, Get, Param, Query
### Community 214 - "BlogsController"
Cohesion: 0.21
Nodes (9): BlogsController, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags, Controller, Get, Param (+1 more)
### Community 215 - "System Discovery"
Cohesion: 0.25
@ -949,49 +937,29 @@ Nodes (3): Expanding the ESLint configuration, React Compiler, React + TypeScrip
Cohesion: 0.50
Nodes (3): Deploy on Vercel, Getting Started, Learn More
### Community 266 - "RegisterDto"
Cohesion: 0.22
Nodes (8): RegisterDto, ApiProperty, ApiPropertyOptional, IsEmail, IsNotEmpty, IsOptional, IsString, MinLength
### Community 267 - "GetProductsDto"
Cohesion: 0.29
Nodes (6): GetProductsDto, ApiPropertyOptional, IsEnum, IsOptional, IsString, Query
### Community 268 - "WholesaleApplyDto"
Cohesion: 0.29
Nodes (6): ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, WholesaleApplyDto
### Community 269 - "AdminLoginDto"
Cohesion: 0.29
Nodes (6): AdminLoginDto, ApiProperty, IsEmail, IsNotEmpty, IsString, MinLength
### Community 270 - "VerifyOtpDto"
Cohesion: 0.29
Nodes (6): ApiProperty, IsNotEmpty, IsString, Matches, VerifyOtpDto, Length
### Community 272 - "ValidateCouponDto"
Cohesion: 0.50
Nodes (4): IsNotEmpty, IsNumber, IsString, ValidateCouponDto
### Community 268 - "wholesale.controller.ts"
Cohesion: 0.17
Nodes (8): B2BModule, Module, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, WholesaleApplyDto
## Knowledge Gaps
- **1175 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1170 more)
- **1178 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1173 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **97 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
- **95 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
## Suggested Questions
_Questions this graph is uniquely positioned to answer:_
- **Why does `ApiResponse` connect `src/services/api.ts` to `pets/pets.controller.ts`, `UsersService`, `OrdersService`, `WikiController`, `ProductsService`, `Home Data Module`, `AuthController`, `BlogsController`?**
- **Why does `ApiResponse` connect `src/services/api.ts` to `PetsController`, `UsersService`, `OrdersService`, `auth.service.ts`, `ProductsService`, `Home Data Module`, `BlogsController`, `WikiController`?**
_High betweenness centrality (0.036) - this node is a cross-community bridge._
- **Why does `Roles()` connect `Roles` to `JwtAuthGuard`, `ContactService`, `CmsController`, `WholesaleService`, `ProductsService`, `B2B Inquiry Controller`, `Ingredient Management Controller`, `Prescription Review Controller`, `Smart Advisor Controller`, `Testimonials Management Controller`?**
_High betweenness centrality (0.026) - this node is a cross-community bridge._
- **Why does `JwtAuthGuard` connect `JwtAuthGuard` to `AdminService`, `ZibalService`, `pets/pets.controller.ts`, `UsersService`, `CmsController`, `OrdersService`, `CreateVideoDto`, `ProductsService`, `MediaController`, `admin.module.ts`?**
- **Why does `Roles()` connect `Roles` to `RolesGuard`, `CmsController`, `BannersService`, `WholesaleService`, `wholesale.controller.ts`, `ProductsService`, `B2B Inquiry Controller`, `Ingredient Management Controller`, `admin.module.ts`, `Prescription Review Controller`, `Smart Advisor Controller`, `Testimonials Management Controller`?**
_High betweenness centrality (0.024) - this node is a cross-community bridge._
- **Why does `JwtAuthGuard` connect `admin.module.ts` to `AdminService`, `RolesGuard`, `payment.controller.ts`, `CmsController`, `OrdersService`, `UsersService`, `CreateVideoDto`, `wholesale.controller.ts`, `pets/pets.controller.ts`, `ProductsService`?**
_High betweenness centrality (0.023) - this node is a cross-community bridge._
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
_1175 weakly-connected nodes found - possible documentation gaps or missing edges._
_1178 weakly-connected nodes found - possible documentation gaps or missing edges._
- **Should `AdminService` be split into smaller, more focused modules?**
_Cohesion score 0.06690140845070422 - nodes in this community are weakly interconnected._
- **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.06414414414414414 - nodes in this community are weakly interconnected._
- **Should `Roles` be split into smaller, more focused modules?**
_Cohesion score 0.06771929824561404 - nodes in this community are weakly interconnected._
_Cohesion score 0.051446321102698506 - nodes in this community are weakly interconnected._
- **Should `UsersService` be split into smaller, more focused modules?**
_Cohesion score 0.06093189964157706 - nodes in this community are weakly interconnected._

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