fix(blog): resolve 404 and 500 error on blog post slug navigation
Some checks failed
Deploy Canina / deploy (push) Has been cancelled

This commit is contained in:
parsa aghaei 2026-08-25 10:21:50 +03:30
parent 1ddfb0a823
commit 088f8e20bb
19 changed files with 145201 additions and 5346 deletions

View File

@ -137,10 +137,28 @@ export class BlogsService {
return { mode: 'newest', blogs: newestBlogs }; return { mode: 'newest', blogs: newestBlogs };
} }
async findOneBySlug(slug: string) { async findOneBySlug(rawSlug: string) {
const now = new Date(); if (!rawSlug) {
const blog = await this.prisma.blog.findUnique({ throw new NotFoundException('مقاله یافت نشد');
where: { slug }, }
let decodedSlug = rawSlug;
try {
decodedSlug = decodeURIComponent(rawSlug);
} catch {
decodedSlug = rawSlug;
}
const isUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(decodedSlug);
const blog = await this.prisma.blog.findFirst({
where: {
OR: [
{ slug: decodedSlug },
{ slug: rawSlug },
...(isUuid ? [{ id: decodedSlug }] : []),
],
},
include: { include: {
author: { author: {
select: { firstName: true, lastName: true }, select: { firstName: true, lastName: true },
@ -161,68 +179,90 @@ export class BlogsService {
throw new NotFoundException('مقاله یافت نشد'); throw new NotFoundException('مقاله یافت نشد');
} }
// Fetch related products if any // Fetch related products safely
let relatedProducts: any[] = []; let relatedProducts: any[] = [];
if (blog.relatedProductIds && blog.relatedProductIds.length > 0) { if (blog.relatedProductIds && Array.isArray(blog.relatedProductIds) && blog.relatedProductIds.length > 0) {
relatedProducts = await this.prisma.product.findMany({ const validProductUuids = blog.relatedProductIds.filter(
where: { id: { in: blog.relatedProductIds } }, (id) => typeof id === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id)
select: { );
id: true, if (validProductUuids.length > 0) {
nameFa: true, try {
slug: true, relatedProducts = await this.prisma.product.findMany({
priceValue: true, where: { id: { in: validProductUuids } },
priceDisplay: true, select: {
imageUrl: true, id: true,
categorySlug: true, nameFa: true,
unit: true, slug: true,
}, priceValue: true,
}); priceDisplay: true,
imageUrl: true,
categorySlug: true,
unit: true,
},
});
} catch (err) {
console.warn('[BlogsService] Error fetching related products:', err);
}
}
} }
// Fetch related blogs if any or fallback to same category // Fetch related blogs safely
let relatedBlogs: any[] = []; let relatedBlogs: any[] = [];
if (blog.relatedBlogIds && blog.relatedBlogIds.length > 0) { if (blog.relatedBlogIds && Array.isArray(blog.relatedBlogIds) && blog.relatedBlogIds.length > 0) {
relatedBlogs = await this.prisma.blog.findMany({ const validBlogUuids = blog.relatedBlogIds.filter(
where: { (id) => typeof id === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id)
id: { in: blog.relatedBlogIds }, );
isPublished: true, if (validBlogUuids.length > 0) {
status: 'PUBLISHED', try {
}, relatedBlogs = await this.prisma.blog.findMany({
select: { where: {
id: true, id: { in: validBlogUuids },
title: true, isPublished: true,
slug: true, status: 'PUBLISHED',
imageUrl: true, },
readingTime: true, select: {
publishedAt: true, id: true,
createdAt: true, title: true,
category: { select: { name: true, slug: true } }, slug: true,
}, imageUrl: true,
}); readingTime: true,
publishedAt: true,
createdAt: true,
category: { select: { name: true, slug: true } },
},
});
} catch (err) {
console.warn('[BlogsService] Error fetching related blogs:', err);
}
}
} else if (blog.categoryId) { } else if (blog.categoryId) {
relatedBlogs = await this.prisma.blog.findMany({ try {
where: { relatedBlogs = await this.prisma.blog.findMany({
categoryId: blog.categoryId, where: {
id: { not: blog.id }, categoryId: blog.categoryId,
isPublished: true, id: { not: blog.id },
status: 'PUBLISHED', isPublished: true,
}, status: 'PUBLISHED',
take: 3, },
select: { take: 3,
id: true, select: {
title: true, id: true,
slug: true, title: true,
imageUrl: true, slug: true,
readingTime: true, imageUrl: true,
publishedAt: true, readingTime: true,
createdAt: true, publishedAt: true,
category: { select: { name: true, slug: true } }, createdAt: true,
}, category: { select: { name: true, slug: true } },
}); },
});
} catch (err) {
console.warn('[BlogsService] Error fetching fallback related blogs:', err);
}
} }
// Increment view count asynchronously // Increment view count asynchronously
await this.prisma.blog this.prisma.blog
.update({ .update({
where: { id: blog.id }, where: { id: blog.id },
data: { viewCount: { increment: 1 } }, data: { viewCount: { increment: 1 } },
@ -231,7 +271,7 @@ export class BlogsService {
return { return {
...blog, ...blog,
viewCount: blog.viewCount + 1, viewCount: (blog.viewCount || 0) + 1,
relatedProducts, relatedProducts,
relatedBlogs, relatedBlogs,
}; };

View File

@ -10,16 +10,37 @@ import {
Sparkles, Sparkles,
ShoppingBag, ShoppingBag,
ArrowLeft, ArrowLeft,
Heart,
Send, Send,
Eye, Eye,
} from "lucide-react"; } from "lucide-react";
import Link from 'next/link'; import Link from 'next/link';
import Image from 'next/image'; import { notFound } from 'next/navigation';
import type { Metadata } from 'next'; import type { Metadata } from 'next';
import SafeImage from "../../../components/SafeImage";
import { getSeoConfig, formatPageTitle } from "../../../lib/seo"; import { getSeoConfig, formatPageTitle } from "../../../lib/seo";
function safeIso(val: any, fallback?: string): string | undefined {
if (!val) return fallback;
try {
const d = new Date(val);
return isNaN(d.getTime()) ? fallback : d.toISOString();
} catch {
return fallback;
}
}
function safeLocalDate(val: any): string {
if (!val) return '';
try {
const d = new Date(val);
return isNaN(d.getTime()) ? '' : d.toLocaleDateString('fa-IR');
} catch {
return '';
}
}
async function getBlog(rawSlug: string) { async function getBlog(rawSlug: string) {
if (!rawSlug) return null;
try { try {
const slug = decodeURIComponent(rawSlug); const slug = decodeURIComponent(rawSlug);
const apiUrl = process.env.INTERNAL_API_URL || process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4001/api'; const apiUrl = process.env.INTERNAL_API_URL || process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4001/api';
@ -31,7 +52,7 @@ async function getBlog(rawSlug: string) {
}, },
}); });
if (!res.ok) { if (!res.ok) {
console.error(`[Blog] Failed to fetch blog ${slug}: ${res.status}`); console.warn(`[Blog] Failed to fetch blog ${slug}: ${res.status}`);
return null; return null;
} }
const b = await res.json(); const b = await res.json();
@ -58,7 +79,7 @@ export async function generateMetadata({ params }: { params: Promise<{ slug: str
const rawSiteUrl = process.env.NEXT_PUBLIC_SITE_URL || config.canonicalBaseUrl || 'https://canina.ir'; const rawSiteUrl = process.env.NEXT_PUBLIC_SITE_URL || config.canonicalBaseUrl || 'https://canina.ir';
const siteUrl = rawSiteUrl.replace(/\/+$/, ''); const siteUrl = rawSiteUrl.replace(/\/+$/, '');
const metaTitle = blog.metaTitle || blog.title; const metaTitle = blog.metaTitle || blog.title || 'مقاله آموزشی و تخصصی کنینا';
const title = formatPageTitle(metaTitle, config.brandNameFa, config.titleSeparator, config.titlePosition, false); const title = formatPageTitle(metaTitle, config.brandNameFa, config.titleSeparator, config.titlePosition, false);
const description = const description =
blog.metaDescription || blog.metaDescription ||
@ -74,8 +95,8 @@ export async function generateMetadata({ params }: { params: Promise<{ slug: str
? `${blog.author.firstName || ''} ${blog.author.lastName || ''}`.trim() || 'نویسنده کنینا' ? `${blog.author.firstName || ''} ${blog.author.lastName || ''}`.trim() || 'نویسنده کنینا'
: 'نویسنده و پژوهشگر کنینا'; : 'نویسنده و پژوهشگر کنینا';
const publishedTime = blog.publishedAt ? new Date(blog.publishedAt).toISOString() : blog.createdAt ? new Date(blog.createdAt).toISOString() : undefined; const publishedTime = safeIso(blog.publishedAt) || safeIso(blog.createdAt);
const modifiedTime = blog.updatedAt ? new Date(blog.updatedAt).toISOString() : publishedTime; const modifiedTime = safeIso(blog.updatedAt) || publishedTime;
const keywordsList = blog.focusKeywords const keywordsList = blog.focusKeywords
? blog.focusKeywords.split(',').map((k: string) => k.trim()) ? blog.focusKeywords.split(',').map((k: string) => k.trim())
@ -109,7 +130,7 @@ export async function generateMetadata({ params }: { params: Promise<{ slug: str
url: ogImageUrl, url: ogImageUrl,
width: 1200, width: 1200,
height: 630, height: 630,
alt: blog.imageAlt || blog.title, alt: blog.imageAlt || blog.title || title,
}, },
], ],
url: canonicalUrl, url: canonicalUrl,
@ -118,7 +139,7 @@ export async function generateMetadata({ params }: { params: Promise<{ slug: str
publishedTime, publishedTime,
modifiedTime, modifiedTime,
authors: [authorName], authors: [authorName],
tags: blog.tags?.map((t: any) => t.name) || [], tags: blog.tags?.map((t: any) => typeof t === 'string' ? t : t?.name).filter(Boolean) || [],
}, },
twitter: { twitter: {
card: "summary_large_image", card: "summary_large_image",
@ -135,46 +156,23 @@ export default async function BlogPostPage({ params }: { params: Promise<{ slug:
const config = await getSeoConfig(); const config = await getSeoConfig();
if (!blog) { if (!blog) {
return ( notFound();
<div className="min-h-[60vh] flex flex-col items-center justify-center font-vazir text-center px-4" dir="rtl">
<div className="w-16 h-16 rounded-3xl bg-red-100 text-red-600 flex items-center justify-center mb-4">
<MessageSquare className="w-8 h-8" />
</div>
<h1 className="text-2xl sm:text-3xl font-black text-medical-gray-900 mb-2">مقاله مورد نظر یافت نشد</h1>
<p className="text-sm text-medical-gray-500 mb-6">احتمالاً این مقاله حذف یا به آدرس دیگری منتقل شده است.</p>
<Link
href="/blog"
className="px-6 py-3 rounded-2xl bg-canina-blue text-white text-xs font-black flex items-center gap-2 hover:bg-canina-blue/90 shadow-md"
>
<ChevronRight className="w-4 h-4" />
<span>بازگشت به مجله سلامت</span>
</Link>
</div>
);
} }
const rawSiteUrl = process.env.NEXT_PUBLIC_SITE_URL || config.canonicalBaseUrl || 'https://canina.ir'; const rawSiteUrl = process.env.NEXT_PUBLIC_SITE_URL || config.canonicalBaseUrl || 'https://canina.ir';
const siteUrl = rawSiteUrl.replace(/\/+$/, ''); const siteUrl = rawSiteUrl.replace(/\/+$/, '');
const authorName = blog.author const authorName = blog.author
? `${blog.author.firstName || ''} ${blog.author.lastName || ''}`.trim() || 'نویسنده کنینا' ? `${blog.author.firstName || ''} ${blog.author.lastName || ''}`.trim() || 'نویسنده کنینا'
: 'نویسنده و پژوهشگر کنینا'; : 'نویسنده و پژوهشگر کنینا';
const publishedDate = blog.publishedAt const publishedDate = safeLocalDate(blog.publishedAt) || safeLocalDate(blog.createdAt);
? new Date(blog.publishedAt).toLocaleDateString('fa-IR')
: blog.createdAt
? new Date(blog.createdAt).toLocaleDateString('fa-IR')
: '';
const canonicalUrl = blog.canonicalUrl const canonicalUrl = blog.canonicalUrl
? blog.canonicalUrl.replace(/\/+$/, '') ? blog.canonicalUrl.replace(/\/+$/, '')
: `${siteUrl}/blog/${slug}`; : `${siteUrl}/blog/${slug}`;
const publishedIso = blog.publishedAt const publishedIso = safeIso(blog.publishedAt) || safeIso(blog.createdAt) || new Date().toISOString();
? new Date(blog.publishedAt).toISOString() const modifiedIso = safeIso(blog.updatedAt) || publishedIso;
: blog.createdAt
? new Date(blog.createdAt).toISOString()
: new Date().toISOString();
const modifiedIso = blog.updatedAt ? new Date(blog.updatedAt).toISOString() : publishedIso;
// JSON-LD Structured Data Schema (BlogPosting & BreadcrumbList) // JSON-LD Structured Data Schema (BlogPosting & BreadcrumbList)
const schemaType = blog.schemaType || 'BlogPosting'; const schemaType = blog.schemaType || 'BlogPosting';
@ -216,7 +214,7 @@ export default async function BlogPostPage({ params }: { params: Promise<{ slug:
}, },
}, },
articleSection: blog.category?.name || 'دانشنامه سلامت حیوانات', articleSection: blog.category?.name || 'دانشنامه سلامت حیوانات',
keywords: blog.focusKeywords || blog.tags?.map((t: any) => t.name).join(', ') || undefined, keywords: blog.focusKeywords || (Array.isArray(blog.tags) ? blog.tags.map((t: any) => typeof t === 'string' ? t : t?.name).filter(Boolean).join(', ') : undefined),
}; };
const breadcrumbJsonLd = { const breadcrumbJsonLd = {
@ -261,9 +259,9 @@ export default async function BlogPostPage({ params }: { params: Promise<{ slug:
], ],
}; };
const relatedProducts = blog.relatedProducts || []; const relatedProducts = Array.isArray(blog.relatedProducts) ? blog.relatedProducts : [];
const relatedBlogs = blog.relatedBlogs || []; const relatedBlogs = Array.isArray(blog.relatedBlogs) ? blog.relatedBlogs : [];
const comments = blog.comments || []; const comments = Array.isArray(blog.comments) ? blog.comments : [];
return ( return (
<div className="min-h-screen bg-medical-gray-50 pt-8 pb-24 px-4 font-vazir" dir="rtl"> <div className="min-h-screen bg-medical-gray-50 pt-8 pb-24 px-4 font-vazir" dir="rtl">
@ -302,14 +300,13 @@ export default async function BlogPostPage({ params }: { params: Promise<{ slug:
{/* Featured Image */} {/* Featured Image */}
{blog.imageUrl && ( {blog.imageUrl && (
<div className="aspect-video w-full overflow-hidden rounded-[2rem] relative mb-8 shadow-sm"> <div className="aspect-video w-full overflow-hidden rounded-[2rem] relative mb-8 shadow-sm">
<Image <SafeImage
src={blog.imageUrl} src={blog.imageUrl}
alt={blog.imageAlt || blog.title} alt={blog.imageAlt || blog.title}
fill
priority priority
sizes="(max-width: 1024px) 100vw, 800px" sizes="(max-width: 1024px) 100vw, 800px"
className="w-full h-full object-cover" className="w-full h-full"
unoptimized imgClassName="w-full h-full object-cover"
/> />
{blog.imageCaption && ( {blog.imageCaption && (
<div className="absolute bottom-0 inset-x-0 bg-black/60 backdrop-blur-sm text-white text-xs font-medium py-2 px-4 text-center"> <div className="absolute bottom-0 inset-x-0 bg-black/60 backdrop-blur-sm text-white text-xs font-medium py-2 px-4 text-center">
@ -326,10 +323,12 @@ export default async function BlogPostPage({ params }: { params: Promise<{ slug:
{blog.category.name} {blog.category.name}
</span> </span>
)} )}
<div className="flex items-center gap-1"> {publishedDate && (
<Calendar className="w-3.5 h-3.5 text-canina-blue" /> <div className="flex items-center gap-1">
<span>{publishedDate}</span> <Calendar className="w-3.5 h-3.5 text-canina-blue" />
</div> <span>{publishedDate}</span>
</div>
)}
<div className="flex items-center gap-1"> <div className="flex items-center gap-1">
<Clock className="w-3.5 h-3.5 text-canina-blue" /> <Clock className="w-3.5 h-3.5 text-canina-blue" />
<span>{blog.readingTime || 4} دقیقه مطالعه</span> <span>{blog.readingTime || 4} دقیقه مطالعه</span>
@ -359,21 +358,26 @@ export default async function BlogPostPage({ params }: { params: Promise<{ slug:
/> />
{/* Tags Chip Footer */} {/* Tags Chip Footer */}
{blog.tags && blog.tags.length > 0 && ( {Array.isArray(blog.tags) && blog.tags.length > 0 && (
<div className="pt-8 mt-10 border-t border-medical-gray-100 flex flex-wrap items-center gap-2"> <div className="pt-8 mt-10 border-t border-medical-gray-100 flex flex-wrap items-center gap-2">
<span className="text-xs font-bold text-medical-gray-400 flex items-center gap-1"> <span className="text-xs font-bold text-medical-gray-400 flex items-center gap-1">
<Tag className="w-3.5 h-3.5" /> <Tag className="w-3.5 h-3.5" />
برچسبهای مرتبط: برچسبهای مرتبط:
</span> </span>
{blog.tags.map((tag: any) => ( {blog.tags.map((tag: any, idx: number) => {
<Link const tagName = typeof tag === 'string' ? tag : tag?.name || '';
key={tag.id} const tagId = tag?.id || idx;
href={`/blog?tag=${encodeURIComponent(tag.name)}`} if (!tagName) return null;
className="px-3 py-1 bg-purple-50 text-purple-700 hover:bg-purple-100 border border-purple-200 rounded-xl text-xs font-bold transition-colors" return (
> <Link
#{tag.name} key={tagId}
</Link> href={`/blog?tag=${encodeURIComponent(tagName)}`}
))} className="px-3 py-1 bg-purple-50 text-purple-700 hover:bg-purple-100 border border-purple-200 rounded-xl text-xs font-bold transition-colors"
>
#{tagName}
</Link>
);
})}
</div> </div>
)} )}
@ -393,11 +397,13 @@ export default async function BlogPostPage({ params }: { params: Promise<{ slug:
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<button <button
onClick={() => { onClick={() => {
if (navigator.share) { if (typeof window !== 'undefined') {
navigator.share({ title: blog.title, url: window.location.href }); if (navigator.share) {
} else { navigator.share({ title: blog.title, url: window.location.href });
navigator.clipboard.writeText(window.location.href); } else {
alert('لینک مقاله در کلیپ‌بورد کپی شد'); navigator.clipboard.writeText(window.location.href);
alert('لینک مقاله در کلیپ‌بورد کپی شد');
}
} }
}} }}
className="p-3 bg-white rounded-2xl hover:bg-canina-blue hover:text-white transition-all text-medical-gray-600 border border-medical-gray-200 shadow-xs cursor-pointer flex items-center gap-1.5 text-xs font-bold" className="p-3 bg-white rounded-2xl hover:bg-canina-blue hover:text-white transition-all text-medical-gray-600 border border-medical-gray-200 shadow-xs cursor-pointer flex items-center gap-1.5 text-xs font-bold"
@ -467,7 +473,7 @@ export default async function BlogPostPage({ params }: { params: Promise<{ slug:
<div className="flex items-center justify-between text-xs font-bold"> <div className="flex items-center justify-between text-xs font-bold">
<span className="text-medical-gray-900">{c.authorName}</span> <span className="text-medical-gray-900">{c.authorName}</span>
<span className="text-medical-gray-400 text-[10px]"> <span className="text-medical-gray-400 text-[10px]">
{c.createdAt ? new Date(c.createdAt).toLocaleDateString('fa-IR') : ''} {safeLocalDate(c.createdAt)}
</span> </span>
</div> </div>
<p className="text-xs text-medical-gray-600 leading-relaxed">{c.content}</p> <p className="text-xs text-medical-gray-600 leading-relaxed">{c.content}</p>
@ -503,12 +509,11 @@ export default async function BlogPostPage({ params }: { params: Promise<{ slug:
className="bg-white/10 hover:bg-white/20 border border-white/20 p-3.5 rounded-2xl flex items-center gap-3 transition-all group" className="bg-white/10 hover:bg-white/20 border border-white/20 p-3.5 rounded-2xl flex items-center gap-3 transition-all group"
> >
<div className="w-14 h-14 bg-white rounded-xl p-1.5 shrink-0 overflow-hidden relative group-hover:scale-105 transition-transform"> <div className="w-14 h-14 bg-white rounded-xl p-1.5 shrink-0 overflow-hidden relative group-hover:scale-105 transition-transform">
<Image <SafeImage
src={p.images?.[0]?.url || p.imageUrl || '/assets/images/product-placeholder.png'} src={p.imageUrl || (Array.isArray(p.images) && p.images[0]) || '/assets/images/product-placeholder.png'}
alt={p.nameFa} alt={p.nameFa}
fill className="w-full h-full"
className="w-full h-full object-contain" imgClassName="w-full h-full object-contain"
unoptimized
/> />
</div> </div>
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
@ -536,16 +541,15 @@ export default async function BlogPostPage({ params }: { params: Promise<{ slug:
{relatedBlogs.map((item: any) => ( {relatedBlogs.map((item: any) => (
<Link <Link
key={item.id} key={item.id}
href={`/blog/${item.slug}`} href={`/blog/${encodeURIComponent(item.slug || item.id)}`}
className="flex items-center gap-3 group" className="flex items-center gap-3 group"
> >
<div className="w-16 h-14 rounded-2xl overflow-hidden shrink-0 relative bg-medical-gray-100"> <div className="w-16 h-14 rounded-2xl overflow-hidden shrink-0 relative bg-medical-gray-100">
<Image <SafeImage
src={item.imageUrl || '/assets/images/blog-placeholder.png'} src={item.imageUrl || '/assets/images/blog-placeholder.png'}
alt={item.title} alt={item.title}
fill className="w-full h-full"
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500" imgClassName="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500"
unoptimized
/> />
</div> </div>
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
@ -585,4 +589,3 @@ export default async function BlogPostPage({ params }: { params: Promise<{ slug:
</div> </div>
); );
} }

View File

@ -239,7 +239,7 @@ export default function BlogPage({
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
className="bg-white rounded-[3.5rem] overflow-hidden border border-medical-gray-200 shadow-2xl flex flex-col lg:flex-row cursor-pointer group hover:border-canina-blue/30 transition-all" className="bg-white rounded-[3.5rem] overflow-hidden border border-medical-gray-200 shadow-2xl flex flex-col lg:flex-row cursor-pointer group hover:border-canina-blue/30 transition-all"
onClick={() => router.push(`/blog/${featuredPost.slug}`)} onClick={() => router.push(`/blog/${encodeURIComponent(featuredPost.slug || featuredPost.id)}`)}
> >
<div className="lg:w-1/2 aspect-video lg:aspect-auto relative overflow-hidden bg-medical-gray-100"> <div className="lg:w-1/2 aspect-video lg:aspect-auto relative overflow-hidden bg-medical-gray-100">
<SafeImage <SafeImage
@ -308,7 +308,7 @@ export default function BlogPage({
viewport={{ once: true }} viewport={{ once: true }}
transition={{ delay: idx * 0.05 }} transition={{ delay: idx * 0.05 }}
className="bg-white rounded-[2.5rem] overflow-hidden border border-medical-gray-200 shadow-lg group hover:shadow-2xl hover:border-canina-blue/30 transition-all cursor-pointer flex flex-col justify-between" className="bg-white rounded-[2.5rem] overflow-hidden border border-medical-gray-200 shadow-lg group hover:shadow-2xl hover:border-canina-blue/30 transition-all cursor-pointer flex flex-col justify-between"
onClick={() => router.push(`/blog/${post.slug}`)} onClick={() => router.push(`/blog/${encodeURIComponent(post.slug || post.id)}`)}
> >
<div> <div>
<div className="aspect-[16/10] overflow-hidden relative bg-medical-gray-100"> <div className="aspect-[16/10] overflow-hidden relative bg-medical-gray-100">

View File

@ -113,6 +113,8 @@ export default function BlogPreviewSection() {
const formattedDate = new Date(blog.createdAt).toLocaleDateString("fa-IR"); const formattedDate = new Date(blog.createdAt).toLocaleDateString("fa-IR");
const blogHref = `/blog/${encodeURIComponent(blog.slug || blog.id)}`;
return ( return (
<motion.article <motion.article
key={blog.id || idx} key={blog.id || idx}
@ -122,7 +124,7 @@ export default function BlogPreviewSection() {
transition={{ delay: idx * 0.1 }} transition={{ delay: idx * 0.1 }}
className="bg-medical-gray-50/60 rounded-[2rem] border border-medical-gray-100 overflow-hidden hover:shadow-lg hover:-translate-y-1 transition-all flex flex-col group" className="bg-medical-gray-50/60 rounded-[2rem] border border-medical-gray-100 overflow-hidden hover:shadow-lg hover:-translate-y-1 transition-all flex flex-col group"
> >
<Link href={`/blog/${blog.slug}`} className="block relative aspect-video w-full overflow-hidden bg-medical-gray-100"> <Link href={blogHref} className="block relative aspect-video w-full overflow-hidden bg-medical-gray-100">
<SafeImage <SafeImage
src={image} src={image}
alt={blog.title} alt={blog.title}
@ -149,7 +151,7 @@ export default function BlogPreviewSection() {
</span> </span>
</div> </div>
<Link href={`/blog/${blog.slug}`}> <Link href={blogHref}>
<h3 className="text-lg font-black text-medical-gray-900 group-hover:text-canina-blue transition-colors line-clamp-2 leading-snug"> <h3 className="text-lg font-black text-medical-gray-900 group-hover:text-canina-blue transition-colors line-clamp-2 leading-snug">
{blog.title} {blog.title}
</h3> </h3>
@ -161,7 +163,7 @@ export default function BlogPreviewSection() {
{authorName} {authorName}
</span> </span>
<Link <Link
href={`/blog/${blog.slug}`} href={blogHref}
className="text-xs font-black text-canina-blue group-hover:underline flex items-center gap-1" className="text-xs font-black text-canina-blue group-hover:underline flex items-center gap-1"
> >
{getText("blog_preview_read_article", "خواندن مقاله")} {getText("blog_preview_read_article", "خواندن مقاله")}

View File

@ -1,22 +1,22 @@
{ {
"0": "Roles", "0": "Roles",
"1": "app.module.ts", "1": "app.module.ts",
"2": "SettingsController", "2": "SmsService",
"3": "ProductService", "3": "ProductService",
"4": "SafeImage.tsx", "4": "SafeImage.tsx",
"5": "CmsController", "5": "CmsController",
"6": "tickets.controller.ts", "6": "tickets.controller.ts",
"7": "PaginationDto", "7": "pets/pets.controller.ts",
"8": "ReportsController", "8": "ReportsController",
"9": "devDependencies", "9": "devDependencies",
"10": "ReviewsController", "10": "ReviewsController",
"11": "Spinner.tsx", "11": "Spinner.tsx",
"12": "useCartStore", "12": "PetProfile.tsx",
"13": "app-audit-verification.e2e-spec.js", "13": "app-audit-verification.e2e-spec.js",
"14": "lib/services/api.ts", "14": "lib/services/api.ts",
"15": "src/services/api.ts", "15": "src/services/api.ts",
"16": "DoctorQueryDto", "16": "DoctorQueryDto",
"17": "RedisService", "17": "admin.service.ts",
"18": "JwtAuthGuard", "18": "JwtAuthGuard",
"19": "ProductsService", "19": "ProductsService",
"20": "CreateVideoDto", "20": "CreateVideoDto",
@ -59,15 +59,15 @@
"57": "Role & Core Objective", "57": "Role & Core Objective",
"58": "ContactService", "58": "ContactService",
"59": "compilerOptions", "59": "compilerOptions",
"60": "admin.service.ts", "60": "admin.controller.ts",
"61": "CreateEBankCheckoutDto", "61": "CreateEBankCheckoutDto",
"62": "api", "62": "api",
"63": "dependencies", "63": "dependencies",
"64": "compilerOptions", "64": "compilerOptions",
"65": "AdminTransactionFilterDto", "65": "AdminTransactionFilterDto",
"66": "AdminQueryDto", "66": "AdminQueryDto",
"67": "admin.module.ts", "67": "PaginationDto",
"68": "BlogsController", "68": "20260526145407_init/migration.sql",
"69": "Required Review Group Closures", "69": "Required Review Group Closures",
"70": "compilerOptions", "70": "compilerOptions",
"71": "getPageMetadata", "71": "getPageMetadata",
@ -84,7 +84,7 @@
"82": "scripts", "82": "scripts",
"83": "dependencies", "83": "dependencies",
"84": "Role & Core Objective", "84": "Role & Core Objective",
"85": "SettingsService", "85": "PetsController",
"86": "zibal.service.ts", "86": "zibal.service.ts",
"87": "dependencies", "87": "dependencies",
"88": "useSettingsStore", "88": "useSettingsStore",
@ -94,11 +94,11 @@
"92": "OrdersService", "92": "OrdersService",
"93": "ProductPage.tsx", "93": "ProductPage.tsx",
"94": "Phase 3.1 — Human Review Preparation and Master Backlog Critique", "94": "Phase 3.1 — Human Review Preparation and Master Backlog Critique",
"95": "getSeoConfig", "95": "blog/[slug]/page.tsx",
"96": "compilerOptions", "96": "compilerOptions",
"97": "prisma", "97": "prisma",
"98": "scripts", "98": "scripts",
"99": "HomeController", "99": "BlogsController",
"100": "Deep Audit Summary Report", "100": "Deep Audit Summary Report",
"101": "Operational Rules & Boundaries", "101": "Operational Rules & Boundaries",
"102": "jest", "102": "jest",
@ -121,19 +121,19 @@
"119": "compilerOptions", "119": "compilerOptions",
"120": "compilerOptions", "120": "compilerOptions",
"121": "backend/README.md", "121": "backend/README.md",
"122": "SmsService", "122": "auth.module.ts",
"123": "BlogsService", "123": "BlogsService",
"124": "Repository Map", "124": "Repository Map",
"125": "validate_integrity.js", "125": "validate_integrity.js",
"126": "admin-panel/package.json", "126": "admin-panel/package.json",
"127": "Sahel-Font", "127": "Sahel-Font",
"128": "AdminService", "128": "AdminController",
"129": "videos.controller.ts", "129": "videos.controller.ts",
"130": "Sahel-Font", "130": "Sahel-Font",
"131": "Role & Core Objective", "131": "Role & Core Objective",
"132": "orchestrate.py", "132": "orchestrate.py",
"133": "backend/package.json", "133": "backend/package.json",
"134": "Get", "134": "CreateReviewDto",
"135": "graphify reference: extra exports and benchmark", "135": "graphify reference: extra exports and benchmark",
"136": "Phase 2 Final Quality Gate Summary Report", "136": "Phase 2 Final Quality Gate Summary Report",
"137": "Task Modifications Log", "137": "Task Modifications Log",
@ -144,10 +144,10 @@
"142": "start-dev.js", "142": "start-dev.js",
"143": "generate-openapi.js", "143": "generate-openapi.js",
"144": "@testing-library/react", "144": "@testing-library/react",
"145": "app/page.tsx", "145": "ProductDto",
"146": "System Discovery", "146": "System Discovery",
"147": "RevalidationService", "147": "ReviewsService",
"148": "AdminController", "148": "Body",
"149": "SmsSettingsPage.tsx", "149": "SmsSettingsPage.tsx",
"150": "Product Requirement Document (PRD)", "150": "Product Requirement Document (PRD)",
"151": "AuthService", "151": "AuthService",
@ -183,8 +183,8 @@
"181": "⚙️ Backend Technical Review (05_dev_backend)", "181": "⚙️ Backend Technical Review (05_dev_backend)",
"182": "🎨 Frontend & Admin Panel Technical Review (06_dev_frontend)", "182": "🎨 Frontend & Admin Panel Technical Review (06_dev_frontend)",
"183": "🚀 SEO & Content Strategy Review (12_seo_content)", "183": "🚀 SEO & Content Strategy Review (12_seo_content)",
"184": "eslint-config-next", "184": "MetricsController",
"185": "ApiResponse", "185": "WikiController",
"186": "seed-ui-texts.ts", "186": "seed-ui-texts.ts",
"187": "seed-wiki.ts", "187": "seed-wiki.ts",
"188": "update-blog.dto.ts", "188": "update-blog.dto.ts",
@ -196,6 +196,8 @@
"194": "Raw Finding Verification & Disposition Report", "194": "Raw Finding Verification & Disposition Report",
"195": "React + TypeScript + Vite", "195": "React + TypeScript + Vite",
"196": "Select.tsx", "196": "Select.tsx",
"197": "AuthService",
"198": "users.service.ts",
"199": "auth.service.ts", "199": "auth.service.ts",
"200": "application/README.md", "200": "application/README.md",
"201": "deploy.sh", "201": "deploy.sh",
@ -228,13 +230,16 @@
"228": "rules/graphify.md", "228": "rules/graphify.md",
"229": ".agents/workflows/graphify.md", "229": ".agents/workflows/graphify.md",
"230": "instructions.md", "230": "instructions.md",
"231": "catalog/page.tsx",
"232": "ts-loader", "232": "ts-loader",
"233": "ts-node", "233": "ts-node",
"234": "20260526160916_add_ui_texts_and_scientific_terms/migration.sql",
"235": "source-map-support", "235": "source-map-support",
"236": "@types/bcrypt", "236": "@types/bcrypt",
"237": "ts-jest", "237": "ts-jest",
"238": "tsconfig-paths", "238": "tsconfig-paths",
"239": "RegisterDto", "239": "RegisterDto",
"240": "eslint",
"241": "blog.entity.ts", "241": "blog.entity.ts",
"242": "home.entity.ts", "242": "home.entity.ts",
"243": "wiki.entity.ts", "243": "wiki.entity.ts",
@ -259,6 +264,7 @@
"262": "User Logout API", "262": "User Logout API",
"263": "generate-openapi.d.ts", "263": "generate-openapi.d.ts",
"264": "InitiatePaymentDto", "264": "InitiatePaymentDto",
"265": "@testing-library/jest-dom",
"267": "@types/js-yaml", "267": "@types/js-yaml",
"268": "@types/multer", "268": "@types/multer",
"269": "eslint-plugin-react-hooks", "269": "eslint-plugin-react-hooks",
@ -290,27 +296,21 @@
"295": "eslint-plugin-react-refresh", "295": "eslint-plugin-react-refresh",
"296": "tailwindcss", "296": "tailwindcss",
"297": "ZibalEBankService", "297": "ZibalEBankService",
"298": ".initiateOrderPayment", "298": "ZibalCallbackQueryDto",
"299": "@tailwindcss/postcss", "299": "@tailwindcss/postcss",
"300": "typescript", "300": "typescript",
"301": "app.e2e-spec.js",
"302": "typescript-eslint", "302": "typescript-eslint",
"304": "SmsLogQueryDto",
"305": "@types/react", "305": "@types/react",
"306": "globals", "306": "globals",
"307": "SendOtpDto",
"308": "vitest", "308": "vitest",
"309": "axios", "309": "axios",
"310": "tailwindcss", "310": "tailwindcss",
"311": "track/page.tsx", "311": "track/page.tsx",
"312": ".addComment",
"313": "MenuManager.tsx", "313": "MenuManager.tsx",
"314": "layout.tsx", "314": "layout.tsx",
"315": "typescript", "315": "typescript",
"316": "trust-seals/page.tsx",
"317": "revalidate/route.ts", "317": "revalidate/route.ts",
"318": "MaskableField.tsx", "318": "MaskableField.tsx",
"319": ".getDashboardStats", "319": "AdminService",
"330": "@types/passport-jwt", "330": "@types/passport-jwt"
"331": "@types/supertest"
} }

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,316 @@
{
"0": "Roles",
"1": "app.module.ts",
"2": "SettingsController",
"3": "ProductService",
"4": "SafeImage.tsx",
"5": "CmsController",
"6": "tickets.controller.ts",
"7": "PaginationDto",
"8": "ReportsController",
"9": "devDependencies",
"10": "ReviewsController",
"11": "Spinner.tsx",
"12": "useCartStore",
"13": "app-audit-verification.e2e-spec.js",
"14": "lib/services/api.ts",
"15": "src/services/api.ts",
"16": "DoctorQueryDto",
"17": "RedisService",
"18": "JwtAuthGuard",
"19": "ProductsService",
"20": "CreateVideoDto",
"21": "@types/react-dom",
"22": "UserDashboard.tsx",
"23": "MenuService",
"24": "BE-001",
"25": "FE-001",
"26": "ADM-001",
"27": "DB-001",
"28": "TS-001",
"29": "TEST-001",
"30": "DEVOPS-001",
"31": "DOC-001",
"32": "adminRoutes.tsx",
"33": "WholesaleApplyDto",
"34": "B2BService",
"35": "AuthController",
"36": "FaqService",
"37": "راهنمای تست سیستم (Software Testing)",
"38": "Button.tsx",
"39": "CategoriesController",
"40": "MediaController",
"41": "What You Must Do When Invoked",
"42": "SslController",
"43": "BannersService",
"44": "TestimonialsService",
"45": "What You Must Do When Invoked",
"46": "ApiOperation",
"47": "IngredientsService",
"48": "Reports.tsx",
"49": "devDependencies",
"50": "devDependencies",
"51": "BlogsController",
"52": "PrescriptionsService",
"53": "SmartAdvisorService",
"54": "UsersService",
"55": "UITexts.tsx",
"56": "Orders.tsx",
"57": "Role & Core Objective",
"58": "ContactService",
"59": "compilerOptions",
"60": "admin.service.ts",
"61": "CreateEBankCheckoutDto",
"62": "api",
"63": "dependencies",
"64": "compilerOptions",
"65": "AdminTransactionFilterDto",
"66": "AdminQueryDto",
"67": "admin.module.ts",
"68": "BlogsController",
"69": "Required Review Group Closures",
"70": "compilerOptions",
"71": "getPageMetadata",
"72": "Operational Rules & Boundaries",
"73": "Operational Rules & Boundaries",
"74": "WikiController",
"75": "PetsController",
"76": "PaymentService",
"77": "seo.module.ts",
"78": "route.ts",
"79": "🏢 AI Software Agency — Master Orchestration Protocol v3",
"80": "Operational Rules & Boundaries",
"81": "Operational Rules & Boundaries",
"82": "scripts",
"83": "dependencies",
"84": "Role & Core Objective",
"85": "SettingsService",
"86": "zibal.service.ts",
"87": "dependencies",
"88": "useSettingsStore",
"89": "seed-products.ts",
"90": "HomeClient.tsx",
"91": "Reconciled Audit Roles & Assignments",
"92": "OrdersService",
"93": "ProductPage.tsx",
"94": "Phase 3.1 — Human Review Preparation and Master Backlog Critique",
"95": "getSeoConfig",
"96": "compilerOptions",
"97": "prisma",
"98": "scripts",
"99": "HomeController",
"100": "Deep Audit Summary Report",
"101": "Operational Rules & Boundaries",
"102": "jest",
"103": "Comprehensive Change Log",
"104": "Coupons.tsx",
"105": "Operational Rules & Boundaries",
"106": "auth.controller.ts",
"107": "shop/page.tsx",
"108": "PrismaService",
"109": "1. Summary of Integrity Repairs Performed",
"110": "Operational Rules & Boundaries",
"111": "Operational Rules & Boundaries",
"112": "Operational Rules & Boundaries",
"113": "reviews.controller.ts",
"114": "AppService",
"115": "seo.ts",
"116": "Vazirmatn Changelog",
"117": "Vazirmatn Font فونت وزیرمتن",
"118": "Operational Rules & Boundaries",
"119": "compilerOptions",
"120": "compilerOptions",
"121": "backend/README.md",
"122": "SmsService",
"123": "BlogsService",
"124": "Repository Map",
"125": "validate_integrity.js",
"126": "admin-panel/package.json",
"127": "Sahel-Font",
"128": "AdminService",
"129": "videos.controller.ts",
"130": "Sahel-Font",
"131": "Role & Core Objective",
"132": "orchestrate.py",
"133": "backend/package.json",
"134": "Get",
"135": "graphify reference: extra exports and benchmark",
"136": "Phase 2 Final Quality Gate Summary Report",
"137": "Task Modifications Log",
"138": "Install",
"139": "RouteErrorBoundary",
"140": "ErrorBoundary",
"141": "application/package.json",
"142": "start-dev.js",
"143": "generate-openapi.js",
"144": "@testing-library/react",
"145": "app/page.tsx",
"146": "System Discovery",
"147": "RevalidationService",
"148": "AdminController",
"149": "SmsSettingsPage.tsx",
"150": "Product Requirement Document (PRD)",
"151": "AuthService",
"152": "@nestjs/cli",
"153": "exclude",
"154": "Baseline Command Plan & Reconciled Command History",
"155": "Blogs.tsx",
"156": "contact/page.tsx",
"157": "ErrorPages.tsx",
"158": "@types/bcryptjs",
"159": "with-vpn.sh",
"160": "Architecture Specification",
"161": "Project Health Audit Report",
"162": "nest-cli.json",
"163": "graphify reference: query, path, explain",
"164": "Open Questions",
"165": "Final Phase 2 Audit Closure Report",
"166": "open-browsers.js",
"167": "📝 Active Agent Working Scratchpad",
"168": "🔍 Code Health Audit Review (01_auditor)",
"169": "paginated-response.schema.ts",
"170": "Vazirmatn Font README",
"171": "Omitted File Inspection Report",
"172": "Phase 3.2 / 3.3 — Implementation Readiness & Architectural Finalization Report",
"173": "Phase 3 Audit Traceability Matrix",
"174": "rebuild_honest_ledger.js",
"175": "validate_evidence_grade.js",
"176": "@types/node",
"177": "blog/page.tsx",
"178": "typescript",
"179": "BlogsService",
"180": "API Contract Specification",
"181": "⚙️ Backend Technical Review (05_dev_backend)",
"182": "🎨 Frontend & Admin Panel Technical Review (06_dev_frontend)",
"183": "🚀 SEO & Content Strategy Review (12_seo_content)",
"184": "eslint-config-next",
"185": "ApiResponse",
"186": "seed-ui-texts.ts",
"187": "seed-wiki.ts",
"188": "update-blog.dto.ts",
"189": "update-home.dto.ts",
"190": "update-wiki.dto.ts",
"191": "graphify reference: add a URL and watch a folder",
"192": "graphify reference: commit hook and native CLAUDE.md integration",
"193": "graphify reference: incremental update and cluster-only",
"194": "Raw Finding Verification & Disposition Report",
"195": "React + TypeScript + Vite",
"196": "Select.tsx",
"199": "auth.service.ts",
"200": "application/README.md",
"201": "deploy.sh",
"202": "🔒 Security & Performance Review (09_devops_security)",
"203": "👁️ UX & Persona Interface Review (08_visual_qa)",
"204": "supertest",
"205": "prisma/scientificTerms.ts",
"206": "seed-blogs.ts",
"207": "seed-custom.ts",
"208": "graphify reference: GitHub clone and cross-repo merge",
"209": "graphify reference: transcribe video and audio",
"210": "Compiler Diagnostic Dispositions",
"211": "Master Task Backlog (Phase 3.3)",
"212": "build_manifest.js",
"213": "generate_classification.js",
"214": "generate_evidence.js",
"215": "generate_ledger.js",
"216": "generate_manifest.js",
"217": "sync_honest_manifest.js",
"218": "sync_manifest.js",
"219": "FormField.tsx",
"220": "Input.tsx",
"221": "Textarea.tsx",
"222": "admin-panel/tsconfig.json",
"223": "@eslint/js",
"224": "jest",
"225": "next.config.ts",
"226": "Shabnam Font README",
"227": "AGENTS.md",
"228": "rules/graphify.md",
"229": ".agents/workflows/graphify.md",
"230": "instructions.md",
"232": "ts-loader",
"233": "ts-node",
"235": "source-map-support",
"236": "@types/bcrypt",
"237": "ts-jest",
"238": "tsconfig-paths",
"239": "RegisterDto",
"241": "blog.entity.ts",
"242": "home.entity.ts",
"243": "wiki.entity.ts",
"244": "User Profile Photo",
"245": "CLAUDE.md",
"246": ".claude/CLAUDE.md",
"247": "extraction-spec.md",
"248": "Products Table",
"249": "Users Table",
"250": "Architectural Audit Findings",
"251": "Cross Boundary Dependencies & Backend Architecture Specification",
"252": "Next.js Agent Rules & Brand Guidelines",
"253": "robots.ts",
"254": "application/eslint.config.mjs",
"255": "postcss.config.mjs",
"256": "vitest.setup.ts",
"257": "backup_db.sh",
"258": "start.sh",
"259": "reviews/README.md",
"260": "backend/eslint.config.mjs",
"261": "User Login API",
"262": "User Logout API",
"263": "generate-openapi.d.ts",
"264": "InitiatePaymentDto",
"267": "@types/js-yaml",
"268": "@types/multer",
"269": "eslint-plugin-react-hooks",
"270": "app-audit-verification.e2e-spec.d.ts",
"271": "app.e2e-spec.d.ts",
"272": "Canina Pharma GmbH",
"273": "Pets Table",
"274": "Canina Iran Project Introduction",
"275": "Developer Standards and Architecture",
"276": "Frontend & Admin Architecture Route Map Specification",
"277": "Project Backlog and Tasks",
"278": "eslint.config.js",
"279": "postcss.config.js",
"280": "admin-panel/public/fonts/sahel-font-v3.4.0/CHANGELOG.md",
"281": "shabnam-font-v5.0.1/CHANGELOG.md",
"282": "tailwind.config.js",
"283": "vite.config.ts",
"284": "application/CLAUDE.md",
"285": "application/public/fonts/sahel-font-v3.4.0/CHANGELOG.md",
"286": "Sahel Font Sample",
"287": "Shabnam Font Changelog",
"288": "Vazirmatn Changelog",
"289": "vitest.config.ts",
"290": "Sahel Font Variable Sample",
"291": "Shabnam Font Sample",
"292": "Production Docker Compose",
"293": "Staging Docker Compose",
"294": "ZibalService",
"295": "eslint-plugin-react-refresh",
"296": "tailwindcss",
"297": "ZibalEBankService",
"298": ".initiateOrderPayment",
"299": "@tailwindcss/postcss",
"300": "typescript",
"301": "app.e2e-spec.js",
"302": "typescript-eslint",
"304": "SmsLogQueryDto",
"305": "@types/react",
"306": "globals",
"307": "SendOtpDto",
"308": "vitest",
"309": "axios",
"310": "tailwindcss",
"311": "track/page.tsx",
"312": ".addComment",
"313": "MenuManager.tsx",
"314": "layout.tsx",
"315": "typescript",
"316": "trust-seals/page.tsx",
"317": "revalidate/route.ts",
"318": "MaskableField.tsx",
"319": ".getDashboardStats",
"330": "@types/passport-jwt",
"331": "@types/supertest"
}

View File

@ -0,0 +1 @@
{"output_tokens": 7105}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +1,38 @@
# Graph Report - canina (2026-08-24) # Graph Report - canina (2026-08-25)
## Corpus Check ## Corpus Check
- 552 files · ~1,314,021 words - 552 files · ~1,314,184 words
- Verdict: corpus is large enough that graph structure adds value. - Verdict: corpus is large enough that graph structure adds value.
## Summary ## Summary
- 3987 nodes · 7191 edges · 314 communities (209 shown, 105 thin omitted) - 4007 nodes · 7228 edges · 314 communities (207 shown, 107 thin omitted)
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 281 edges (avg confidence: 0.79) - Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 281 edges (avg confidence: 0.79)
- Token cost: 0 input · 0 output - Token cost: 0 input · 0 output
## Graph Freshness ## Graph Freshness
- Built from commit: `fe6a9006` - Built from commit: `1ddfb0a8`
- 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).
## Community Hubs (Navigation) ## Community Hubs (Navigation)
- Roles - Roles
- app.module.ts - app.module.ts
- SettingsController - SmsService
- ProductService - ProductService
- SafeImage.tsx - SafeImage.tsx
- CmsController - CmsController
- tickets.controller.ts - tickets.controller.ts
- PaginationDto - pets/pets.controller.ts
- ReportsController - ReportsController
- devDependencies - devDependencies
- ReviewsController - ReviewsController
- Spinner.tsx - Spinner.tsx
- useCartStore - PetProfile.tsx
- app-audit-verification.e2e-spec.js - app-audit-verification.e2e-spec.js
- lib/services/api.ts - lib/services/api.ts
- src/services/api.ts - src/services/api.ts
- DoctorQueryDto - DoctorQueryDto
- RedisService - admin.service.ts
- JwtAuthGuard - JwtAuthGuard
- ProductsService - ProductsService
- CreateVideoDto - CreateVideoDto
@ -75,15 +75,15 @@
- Role & Core Objective - Role & Core Objective
- ContactService - ContactService
- compilerOptions - compilerOptions
- admin.service.ts - admin.controller.ts
- CreateEBankCheckoutDto - CreateEBankCheckoutDto
- api - api
- dependencies - dependencies
- compilerOptions - compilerOptions
- AdminTransactionFilterDto - AdminTransactionFilterDto
- AdminQueryDto - AdminQueryDto
- admin.module.ts - PaginationDto
- BlogsController - 20260526145407_init/migration.sql
- Required Review Group Closures - Required Review Group Closures
- compilerOptions - compilerOptions
- getPageMetadata - getPageMetadata
@ -100,7 +100,7 @@
- scripts - scripts
- dependencies - dependencies
- Role & Core Objective - Role & Core Objective
- SettingsService - PetsController
- zibal.service.ts - zibal.service.ts
- dependencies - dependencies
- useSettingsStore - useSettingsStore
@ -110,11 +110,11 @@
- OrdersService - OrdersService
- ProductPage.tsx - ProductPage.tsx
- Phase 3.1 — Human Review Preparation and Master Backlog Critique - Phase 3.1 — Human Review Preparation and Master Backlog Critique
- getSeoConfig - blog/[slug]/page.tsx
- compilerOptions - compilerOptions
- prisma - prisma
- scripts - scripts
- HomeController - BlogsController
- Deep Audit Summary Report - Deep Audit Summary Report
- Operational Rules & Boundaries - Operational Rules & Boundaries
- jest - jest
@ -137,19 +137,19 @@
- compilerOptions - compilerOptions
- compilerOptions - compilerOptions
- backend/README.md - backend/README.md
- SmsService - auth.module.ts
- BlogsService - BlogsService
- Repository Map - Repository Map
- validate_integrity.js - validate_integrity.js
- admin-panel/package.json - admin-panel/package.json
- Sahel-Font - Sahel-Font
- AdminService - AdminController
- videos.controller.ts - videos.controller.ts
- Sahel-Font - Sahel-Font
- Role & Core Objective - Role & Core Objective
- orchestrate.py - orchestrate.py
- backend/package.json - backend/package.json
- Get - CreateReviewDto
- graphify reference: extra exports and benchmark - graphify reference: extra exports and benchmark
- Phase 2 Final Quality Gate Summary Report - Phase 2 Final Quality Gate Summary Report
- Task Modifications Log - Task Modifications Log
@ -160,10 +160,10 @@
- start-dev.js - start-dev.js
- generate-openapi.js - generate-openapi.js
- @testing-library/react - @testing-library/react
- app/page.tsx - ProductDto
- System Discovery - System Discovery
- RevalidationService - ReviewsService
- AdminController - Body
- SmsSettingsPage.tsx - SmsSettingsPage.tsx
- Product Requirement Document (PRD) - Product Requirement Document (PRD)
- AuthService - AuthService
@ -199,8 +199,8 @@
- ⚙️ Backend Technical Review (05_dev_backend) - ⚙️ Backend Technical Review (05_dev_backend)
- 🎨 Frontend & Admin Panel Technical Review (06_dev_frontend) - 🎨 Frontend & Admin Panel Technical Review (06_dev_frontend)
- 🚀 SEO & Content Strategy Review (12_seo_content) - 🚀 SEO & Content Strategy Review (12_seo_content)
- eslint-config-next - MetricsController
- ApiResponse - WikiController
- seed-ui-texts.ts - seed-ui-texts.ts
- seed-wiki.ts - seed-wiki.ts
- update-blog.dto.ts - update-blog.dto.ts
@ -212,6 +212,8 @@
- Raw Finding Verification & Disposition Report - Raw Finding Verification & Disposition Report
- React + TypeScript + Vite - React + TypeScript + Vite
- Select.tsx - Select.tsx
- AuthService
- users.service.ts
- auth.service.ts - auth.service.ts
- application/README.md - application/README.md
- deploy.sh - deploy.sh
@ -244,13 +246,16 @@
- rules/graphify.md - rules/graphify.md
- .agents/workflows/graphify.md - .agents/workflows/graphify.md
- instructions.md - instructions.md
- catalog/page.tsx
- ts-loader - ts-loader
- ts-node - ts-node
- 20260526160916_add_ui_texts_and_scientific_terms/migration.sql
- source-map-support - source-map-support
- @types/bcrypt - @types/bcrypt
- ts-jest - ts-jest
- tsconfig-paths - tsconfig-paths
- RegisterDto - RegisterDto
- eslint
- blog.entity.ts - blog.entity.ts
- home.entity.ts - home.entity.ts
- wiki.entity.ts - wiki.entity.ts
@ -271,6 +276,7 @@
- User Login API - User Login API
- User Logout API - User Logout API
- InitiatePaymentDto - InitiatePaymentDto
- @testing-library/jest-dom
- @types/js-yaml - @types/js-yaml
- @types/multer - @types/multer
- eslint-plugin-react-hooks - eslint-plugin-react-hooks
@ -291,26 +297,21 @@
- eslint-plugin-react-refresh - eslint-plugin-react-refresh
- tailwindcss - tailwindcss
- ZibalEBankService - ZibalEBankService
- .initiateOrderPayment - ZibalCallbackQueryDto
- @tailwindcss/postcss - @tailwindcss/postcss
- typescript - typescript
- app.e2e-spec.js
- typescript-eslint - typescript-eslint
- SmsLogQueryDto
- @types/react - @types/react
- globals - globals
- SendOtpDto
- vitest - vitest
- track/page.tsx - track/page.tsx
- .addComment
- MenuManager.tsx - MenuManager.tsx
- layout.tsx - layout.tsx
- typescript - typescript
- trust-seals/page.tsx
- revalidate/route.ts - revalidate/route.ts
- MaskableField.tsx - MaskableField.tsx
- AdminService
- @types/passport-jwt - @types/passport-jwt
- @types/supertest
## God Nodes (most connected - your core abstractions) ## God Nodes (most connected - your core abstractions)
1. `Roles()` - 106 edges 1. `Roles()` - 106 edges
@ -329,39 +330,39 @@
docs/02-user-guide.md → backend/uploads/1781288429353-508765350.jpg docs/02-user-guide.md → backend/uploads/1781288429353-508765350.jpg
- `AuthController` --references--> `ApiResponse` [EXTRACTED] - `AuthController` --references--> `ApiResponse` [EXTRACTED]
backend/src/auth/auth.controller.ts → frontend/admin-panel/src/types/admin.ts backend/src/auth/auth.controller.ts → frontend/admin-panel/src/types/admin.ts
- `BlogsController` --references--> `ApiResponse` [EXTRACTED]
backend/src/blogs/blogs.controller.ts → frontend/admin-panel/src/types/admin.ts
- `HomeController` --references--> `ApiResponse` [EXTRACTED]
backend/src/home/home.controller.ts → frontend/admin-panel/src/types/admin.ts
- `OrdersController` --references--> `ApiResponse` [EXTRACTED] - `OrdersController` --references--> `ApiResponse` [EXTRACTED]
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
- `PetsController` --references--> `ApiResponse` [EXTRACTED]
backend/src/pets/pets.controller.ts → frontend/admin-panel/src/types/admin.ts
- `ProductsController` --references--> `ApiResponse` [EXTRACTED]
backend/src/products/products.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/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` - 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`
## Communities (314 total, 105 thin omitted) ## Communities (314 total, 107 thin omitted)
### Community 0 - "Roles" ### Community 0 - "Roles"
Cohesion: 0.24 Cohesion: 0.18
Nodes (13): Roles(), PaymentController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get (+5 more) Nodes (19): Roles(), PaymentController, ApiBadRequestResponse, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body (+11 more)
### Community 1 - "app.module.ts" ### Community 1 - "app.module.ts"
Cohesion: 0.07 Cohesion: 0.06
Nodes (34): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+26 more) Nodes (34): AdminModule, Module, CmsModule, Module, SmsModule, Global, Module, ContactModule (+26 more)
### Community 2 - "SettingsController" ### Community 2 - "SmsService"
Cohesion: 0.23 Cohesion: 0.06
Nodes (12): SettingsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Param (+4 more) Nodes (26): SmsService, Injectable, SmsLogQueryDto, ApiPropertyOptional, IsIn, IsNumber, IsOptional, IsString (+18 more)
### Community 3 - "ProductService" ### Community 3 - "ProductService"
Cohesion: 0.06 Cohesion: 0.06
Nodes (33): dynamic, revalidate, DEFAULT_CATEGORIES, dynamic, revalidate, dynamic, revalidate, BlogCategory (+25 more) Nodes (37): dynamic, revalidate, DEFAULT_CATEGORIES, dynamic, revalidate, dynamic, revalidate, ArchiveProductCard() (+29 more)
### Community 4 - "SafeImage.tsx" ### Community 4 - "SafeImage.tsx"
Cohesion: 0.12 Cohesion: 0.08
Nodes (16): OrderDetailsModalProps, PLAYBACK_RATES, PodcastPlayerModal(), PodcastPlayerModalProps, VideoModalPlayer, SafeImage(), SafeImageProps, DisplayVideoItem (+8 more) Nodes (22): BlogPost, BlogPreviewSection(), ProductDetailModalProps, OrderDetailsModalProps, PLAYBACK_RATES, PodcastPlayerModal(), PodcastPlayerModalProps, VideoModalPlayer (+14 more)
### Community 5 - "CmsController" ### Community 5 - "CmsController"
Cohesion: 0.09 Cohesion: 0.09
@ -371,37 +372,37 @@ Nodes (24): CmsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controlle
Cohesion: 0.09 Cohesion: 0.09
Nodes (31): AdminUpdateTicketDto, CreateTicketDto, ReplyTicketDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString (+23 more) Nodes (31): AdminUpdateTicketDto, CreateTicketDto, ReplyTicketDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString (+23 more)
### Community 7 - "PaginationDto" ### Community 7 - "pets/pets.controller.ts"
Cohesion: 0.09 Cohesion: 0.12
Nodes (20): BlogFilterDto, PaginationDto, SortOrder, ApiPropertyOptional, IsEnum, IsInt, IsOptional, IsString (+12 more) Nodes (15): CreatePetDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional, IsString (+7 more)
### Community 8 - "ReportsController" ### Community 8 - "ReportsController"
Cohesion: 0.17 Cohesion: 0.16
Nodes (9): ReportsController, ApiBearerAuth, ApiOperation, ApiTags, Controller, Get, UseGuards, ReportsService (+1 more) Nodes (9): ReportsController, ApiBearerAuth, ApiOperation, ApiTags, Controller, Get, UseGuards, ReportsService (+1 more)
### Community 9 - "devDependencies" ### Community 9 - "devDependencies"
Cohesion: 0.09 Cohesion: 0.09
Nodes (23): devDependencies, eslint, eslint-config-prettier, @eslint/eslintrc, eslint-plugin-prettier, @nestjs/schematics, @nestjs/testing, prettier (+15 more) Nodes (23): devDependencies, eslint-config-prettier, @eslint/eslintrc, eslint-plugin-prettier, @nestjs/schematics, @nestjs/testing, prettier, @types/compression (+15 more)
### Community 10 - "ReviewsController" ### Community 10 - "ReviewsController"
Cohesion: 0.14 Cohesion: 0.20
Nodes (14): ReviewsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more) Nodes (11): ReviewsController, ApiBearerAuth, ApiOperation, ApiTags, Controller, Delete, Get, Param (+3 more)
### Community 11 - "Spinner.tsx" ### Community 11 - "Spinner.tsx"
Cohesion: 0.09 Cohesion: 0.09
Nodes (30): ConfirmModal(), ConfirmModalProps, getFileType(), Media, MediaSelector(), MediaSelectorProps, maxWidthClasses, Modal() (+22 more) Nodes (30): ConfirmModal(), ConfirmModalProps, getFileType(), Media, MediaSelector(), MediaSelectorProps, maxWidthClasses, Modal() (+22 more)
### Community 12 - "useCartStore" ### Community 12 - "PetProfile.tsx"
Cohesion: 0.11 Cohesion: 0.11
Nodes (26): ArchiveProductCard(), B2BPortal(), CheckoutPage(), FeaturedProducts(), ProductCard(), Header(), MENU_ICONS, OrderSuccess() (+18 more) Nodes (20): FeaturedProducts(), ProductCard(), OrderSuccess(), SearchResultsPage(), OrderRowSkeleton(), PetProfileSkeleton(), ProductCardSkeleton(), Skeleton() (+12 more)
### Community 13 - "app-audit-verification.e2e-spec.js" ### Community 13 - "app-audit-verification.e2e-spec.js"
Cohesion: 0.07 Cohesion: 0.07
Nodes (22): AppModule, Module, CustomHttpExceptionFilter, Catch, PrismaExceptionFilter, Catch, DecimalInterceptor, Injectable (+14 more) Nodes (22): AppModule, Module, CustomHttpExceptionFilter, Catch, PrismaExceptionFilter, Catch, DecimalInterceptor, Injectable (+14 more)
### Community 14 - "lib/services/api.ts" ### Community 14 - "lib/services/api.ts"
Cohesion: 0.06 Cohesion: 0.08
Nodes (26): LoginModal, ContactInfoItem, LoginModal(), LoginModalProps, Testimonial, TestimonialsSection(), api, ApiErrorPayload (+18 more) Nodes (29): LoginModal, VerifyContent(), B2BPortal(), CartDrawer(), ContactInfoItem, Header(), LoginModal(), LoginModalProps (+21 more)
### Community 15 - "src/services/api.ts" ### Community 15 - "src/services/api.ts"
Cohesion: 0.09 Cohesion: 0.09
@ -411,13 +412,13 @@ Nodes (25): ProtectedRoute(), Login(), B2BManager, SeoSettingsPage, SmartAdvisor
Cohesion: 0.09 Cohesion: 0.09
Nodes (24): DoctorsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+16 more) Nodes (24): DoctorsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+16 more)
### Community 17 - "RedisService" ### Community 17 - "admin.service.ts"
Cohesion: 0.10 Cohesion: 0.11
Nodes (10): ApiExcludeController, MetricsController, Controller, Get, Res, RedisModule, Global, Module (+2 more) Nodes (11): CouponTargetInput, PaginationQuery, RevalidationModule, Global, Module, RedisModule, Global, Module (+3 more)
### Community 18 - "JwtAuthGuard" ### Community 18 - "JwtAuthGuard"
Cohesion: 0.16 Cohesion: 0.21
Nodes (8): JwtAuthGuard, Injectable, B2BWholesaleOrderItem, ROLES_KEY, RequestWithUser, RolesGuard, Injectable, UserReqPayload Nodes (7): JwtAuthGuard, Injectable, ROLES_KEY, RequestWithUser, RolesGuard, Injectable, UserReqPayload
### Community 19 - "ProductsService" ### Community 19 - "ProductsService"
Cohesion: 0.10 Cohesion: 0.10
@ -429,7 +430,7 @@ Nodes (24): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEm
### Community 22 - "UserDashboard.tsx" ### Community 22 - "UserDashboard.tsx"
Cohesion: 0.10 Cohesion: 0.10
Nodes (26): VerifyContent(), AddressModal(), AddressModalProps, BackButton(), BackButtonProps, BlogPost, BlogPreviewSection(), DeleteConfirmModal() (+18 more) Nodes (30): AddressModal(), AddressModalProps, AuthModal(), AuthModalProps, extractOtpFromText(), BackButton(), BackButtonProps, CheckoutPage() (+22 more)
### Community 23 - "MenuService" ### Community 23 - "MenuService"
Cohesion: 0.12 Cohesion: 0.12
@ -523,10 +524,6 @@ Nodes (14): TestimonialsController, ApiBearerAuth, ApiOperation, ApiTags, Body,
Cohesion: 0.07 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 46 - "ApiOperation"
Cohesion: 0.15
Nodes (3): ApiOperation, Body, Put
### Community 47 - "IngredientsService" ### Community 47 - "IngredientsService"
Cohesion: 0.13 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)
@ -541,7 +538,7 @@ Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, glo
### Community 50 - "devDependencies" ### Community 50 - "devDependencies"
Cohesion: 0.13 Cohesion: 0.13
Nodes (15): devDependencies, eslint, jsdom, tailwindcss, @tailwindcss/postcss, @testing-library/jest-dom, @types/node, @vitejs/plugin-react (+7 more) Nodes (15): eslint-config-next, devDependencies, eslint, eslint-config-next, jsdom, tailwindcss, @tailwindcss/postcss, @types/node (+7 more)
### Community 51 - "BlogsController" ### Community 51 - "BlogsController"
Cohesion: 0.14 Cohesion: 0.14
@ -556,8 +553,8 @@ Cohesion: 0.13
Nodes (14): SmartAdvisorController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more) Nodes (14): SmartAdvisorController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
### Community 54 - "UsersService" ### Community 54 - "UsersService"
Cohesion: 0.06 Cohesion: 0.08
Nodes (41): DEFAULT_JWT_REFRESH_SECRET, DEFAULT_JWT_SECRET, getJwtSecret(), AuthModule, Module, JwtPayload, JwtStrategy, Injectable (+33 more) Nodes (31): AddressDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, ApiPropertyOptional (+23 more)
### Community 55 - "UITexts.tsx" ### Community 55 - "UITexts.tsx"
Cohesion: 0.09 Cohesion: 0.09
@ -579,9 +576,9 @@ Nodes (11): ContactController, Body, Controller, Get, Param, Post, Put, Query (+
Cohesion: 0.06 Cohesion: 0.06
Nodes (30): compilerOptions, allowSyntheticDefaultImports, baseUrl, declaration, emitDecoratorMetadata, esModuleInterop, experimentalDecorators, forceConsistentCasingInFileNames (+22 more) Nodes (30): compilerOptions, allowSyntheticDefaultImports, baseUrl, declaration, emitDecoratorMetadata, esModuleInterop, experimentalDecorators, forceConsistentCasingInFileNames (+22 more)
### Community 60 - "admin.service.ts" ### Community 60 - "admin.controller.ts"
Cohesion: 0.13 Cohesion: 0.21
Nodes (21): CouponInput, CouponTargetInput, PaginationQuery, ProductDto, ApiPropertyOptional, IsArray, IsBoolean, IsNumber (+13 more) Nodes (10): CreateUserDto, ApiProperty, ApiPropertyOptional, IsEmail, IsNotEmpty, IsNumber, IsOptional, IsString (+2 more)
### Community 61 - "CreateEBankCheckoutDto" ### Community 61 - "CreateEBankCheckoutDto"
Cohesion: 0.22 Cohesion: 0.22
@ -607,13 +604,13 @@ Nodes (7): AdminTransactionFilterDto, ApiPropertyOptional, IsIn, IsNumber, IsOpt
Cohesion: 0.18 Cohesion: 0.18
Nodes (7): ApiQuery, Get, Query, AdminQueryDto, ApiPropertyOptional, IsOptional, IsString Nodes (7): ApiQuery, Get, Query, AdminQueryDto, ApiPropertyOptional, IsOptional, IsString
### Community 67 - "admin.module.ts" ### Community 67 - "PaginationDto"
Cohesion: 0.06 Cohesion: 0.07
Nodes (21): AdminModule, Module, MediaService, Injectable, PetsController, ApiBearerAuth, ApiOperation, ApiQuery (+13 more) Nodes (19): CategoryQuery, MediaService, Injectable, PetQuery, PetsService, Injectable, SslCertInfo, Injectable (+11 more)
### Community 68 - "BlogsController" ### Community 68 - "20260526145407_init/migration.sql"
Cohesion: 0.23 Cohesion: 0.27
Nodes (9): BlogsController, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags, Controller, Get, Param (+1 more) Nodes (14): "coupons", "health_logs", "order_items", "orders", "pet_medical_conditions", "pets", "product_ingredients", "product_symptoms" (+6 more)
### Community 69 - "Required Review Group Closures" ### Community 69 - "Required Review Group Closures"
Cohesion: 0.10 Cohesion: 0.10
@ -625,7 +622,7 @@ Nodes (23): compilerOptions, allowImportingTsExtensions, erasableSyntaxOnly, jsx
### Community 71 - "getPageMetadata" ### Community 71 - "getPageMetadata"
Cohesion: 0.11 Cohesion: 0.11
Nodes (9): generateMetadata(), generateMetadata(), generateMetadata(), generateMetadata(), generateMetadata(), generateMetadata(), generateMetadata(), SearchResultsPage() (+1 more) Nodes (9): generateMetadata(), generateMetadata(), generateMetadata(), generateMetadata(), generateMetadata(), generateMetadata(), generateMetadata(), generateMetadata() (+1 more)
### Community 72 - "Operational Rules & Boundaries" ### Community 72 - "Operational Rules & Boundaries"
Cohesion: 0.11 Cohesion: 0.11
@ -640,8 +637,8 @@ Cohesion: 0.13
Nodes (14): ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete, Get (+6 more) Nodes (14): ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete, Get (+6 more)
### Community 75 - "PetsController" ### Community 75 - "PetsController"
Cohesion: 0.05 Cohesion: 0.08
Nodes (47): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, CreatePetDto, ApiProperty (+39 more) Nodes (32): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, CreateReminderDto, ApiProperty (+24 more)
### Community 77 - "seo.module.ts" ### Community 77 - "seo.module.ts"
Cohesion: 0.16 Cohesion: 0.16
@ -675,6 +672,10 @@ Nodes (21): dependencies, axios, lucide-react, react, react-dom, react-hot-toast
Cohesion: 0.12 Cohesion: 0.12
Nodes (16): 1. Active Secret Scanning (All Modified Files), 2. Docker Container Verification (if Dockerfile exists), 3. CI/CD Basic Check (if `.github/workflows/` exists), 4. Failure Routing Protocol, 5. Forbidden Actions, ENFORCE MODE — Normal Operation, Expected JSON Output Schema, Operational Rules & Boundaries (+8 more) Nodes (16): 1. Active Secret Scanning (All Modified Files), 2. Docker Container Verification (if Dockerfile exists), 3. CI/CD Basic Check (if `.github/workflows/` exists), 4. Failure Routing Protocol, 5. Forbidden Actions, ENFORCE MODE — Normal Operation, Expected JSON Output Schema, Operational Rules & Boundaries (+8 more)
### Community 85 - "PetsController"
Cohesion: 0.15
Nodes (11): PetsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Controller, Delete, Get (+3 more)
### Community 86 - "zibal.service.ts" ### Community 86 - "zibal.service.ts"
Cohesion: 0.16 Cohesion: 0.16
Nodes (9): GatewayHealthResult, IPaymentGateway, PaymentInquiryResult, PaymentRequestOptions, PaymentRequestResult, PaymentVerifyResult, ZibalInquiryResponse, ZibalRequestResponse (+1 more) Nodes (9): GatewayHealthResult, IPaymentGateway, PaymentInquiryResult, PaymentRequestOptions, PaymentRequestResult, PaymentVerifyResult, ZibalInquiryResponse, ZibalRequestResponse (+1 more)
@ -684,36 +685,36 @@ 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 88 - "useSettingsStore" ### Community 88 - "useSettingsStore"
Cohesion: 0.09 Cohesion: 0.11
Nodes (29): AuthModal, B2BPortal, CartDrawer, ClientLayout(), AuthModal(), AuthModalProps, extractOtpFromText(), BrandLogo() (+21 more) Nodes (21): AuthModal, B2BPortal, CartDrawer, ClientLayout(), BrandLogo(), BrandLogoProps, EnamadBadge(), FAQItem (+13 more)
### Community 89 - "seed-products.ts" ### Community 89 - "seed-products.ts"
Cohesion: 0.17 Cohesion: 0.17
Nodes (12): prisma, main(), prisma, determineSuitableFor(), findOrCreateCategory(), getProductImageUrl(), main(), parseSize() (+4 more) Nodes (12): prisma, main(), prisma, determineSuitableFor(), findOrCreateCategory(), getProductImageUrl(), main(), parseSize() (+4 more)
### Community 90 - "HomeClient.tsx" ### Community 90 - "HomeClient.tsx"
Cohesion: 0.15 Cohesion: 0.14
Nodes (16): HomeClient(), HomeClientProps, CATEGORY_MAP, ICON_MAP, BannerPlacement(), BannerPlacementProps, Hero(), StatCounter() (+8 more) Nodes (17): HomeClient(), HomeClientProps, getHomeData(), Home(), BannerPlacement(), BannerPlacementProps, Hero(), StatCounter() (+9 more)
### Community 91 - "Reconciled Audit Roles & Assignments" ### Community 91 - "Reconciled Audit Roles & Assignments"
Cohesion: 0.12 Cohesion: 0.12
Nodes (15): 10. Documentation Engineer, 1. Lead Architect / Orchestrator, 2. React / Vite Storefront Auditor, 3. NestJS Backend Auditor, 4. Admin Features Auditor, 5. Database & Data Integrity Auditor, 6. Security Auditor, 7. TypeScript & Code Quality Auditor (+7 more) Nodes (15): 10. Documentation Engineer, 1. Lead Architect / Orchestrator, 2. React / Vite Storefront Auditor, 3. NestJS Backend Auditor, 4. Admin Features Auditor, 5. Database & Data Integrity Auditor, 6. Security Auditor, 7. TypeScript & Code Quality Auditor (+7 more)
### Community 92 - "OrdersService" ### Community 92 - "OrdersService"
Cohesion: 0.07 Cohesion: 0.06
Nodes (29): CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional (+21 more) Nodes (35): CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional (+27 more)
### Community 93 - "ProductPage.tsx" ### Community 93 - "ProductPage.tsx"
Cohesion: 0.12 Cohesion: 0.13
Nodes (16): PLAYBACK_RATES, PodcastInlinePlayer(), PodcastInlinePlayerProps, CalculatorState, ICON_MAP, ProductPage(), ProductReviews, useCalculatorStore (+8 more) Nodes (15): PLAYBACK_RATES, PodcastInlinePlayer(), PodcastInlinePlayerProps, CalculatorState, ICON_MAP, ProductPage(), ProductReviews, useCalculatorStore (+7 more)
### Community 94 - "Phase 3.1 — Human Review Preparation and Master Backlog Critique" ### Community 94 - "Phase 3.1 — Human Review Preparation and Master Backlog Critique"
Cohesion: 0.13 Cohesion: 0.13
Nodes (14): 10. Dependency & Wave Adjustments, 11. Acceptance Criteria Refinements, 12. Business and Product Decision Classification, 13. Final Recommended Backlog Summary, 1. Executive Assessment, 2. Findings That Require No Change, 3. Findings Requiring Task Refinements, 4. Tasks Requiring Splitting (+6 more) Nodes (14): 10. Dependency & Wave Adjustments, 11. Acceptance Criteria Refinements, 12. Business and Product Decision Classification, 13. Final Recommended Backlog Summary, 1. Executive Assessment, 2. Findings That Require No Change, 3. Findings Requiring Task Refinements, 4. Tasks Requiring Splitting (+6 more)
### Community 95 - "getSeoConfig" ### Community 95 - "blog/[slug]/page.tsx"
Cohesion: 0.26 Cohesion: 0.24
Nodes (11): BlogPostPage(), generateMetadata(), getBlog(), revalidate, generateMetadata(), revalidate, generateMetadata(), getWikiTerm() (+3 more) Nodes (13): BlogPostPage(), generateMetadata(), getBlog(), revalidate, safeIso(), safeLocalDate(), generateMetadata(), revalidate (+5 more)
### Community 96 - "compilerOptions" ### Community 96 - "compilerOptions"
Cohesion: 0.06 Cohesion: 0.06
@ -723,9 +724,9 @@ Nodes (32): compilerOptions, allowJs, esModuleInterop, incremental, isolatedModu
Cohesion: 0.14 Cohesion: 0.14
Nodes (14): scripts, build, build:nest, docs:generate, lint, start, start:debug, start:dev (+6 more) Nodes (14): scripts, build, build:nest, docs:generate, lint, start, start:debug, start:dev (+6 more)
### Community 99 - "HomeController" ### Community 99 - "BlogsController"
Cohesion: 0.16 Cohesion: 0.08
Nodes (10): HomeController, ApiOkResponse, ApiOperation, ApiTags, Controller, Get, HomeModule, Module (+2 more) Nodes (25): BlogsController, ApiBearerAuth, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+17 more)
### Community 100 - "Deep Audit Summary Report" ### Community 100 - "Deep Audit Summary Report"
Cohesion: 0.14 Cohesion: 0.14
@ -757,7 +758,7 @@ Nodes (11): AdminLoginDto, ApiProperty, IsEmail, IsNotEmpty, IsString, MinLength
### Community 108 - "PrismaService" ### Community 108 - "PrismaService"
Cohesion: 0.06 Cohesion: 0.06
Nodes (21): CategoryQuery, WikiQuery, MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions, SmsConfig, SmsLogQuery, CreateContactSubmissionDto (+13 more) Nodes (25): B2BModule, Module, B2BWholesaleOrderItem, BannersModule, Module, RevalidationService, Injectable, MeliPayamakPattern (+17 more)
### Community 109 - "1. Summary of Integrity Repairs Performed" ### Community 109 - "1. Summary of Integrity Repairs Performed"
Cohesion: 0.17 Cohesion: 0.17
@ -776,16 +777,16 @@ Cohesion: 0.18
Nodes (10): 1. Pre-Deployment Checklist, 2. Build Verification, 3. Deployment Strategy (Based on Target), 4. Post-Deployment Health Check, 5. Forbidden Actions, Expected JSON Output Schema, Operational Rules & Boundaries, Required Output Artifacts (What files to write/update) (+2 more) Nodes (10): 1. Pre-Deployment Checklist, 2. Build Verification, 3. Deployment Strategy (Based on Target), 4. Post-Deployment Health Check, 5. Forbidden Actions, Expected JSON Output Schema, Operational Rules & Boundaries, Required Output Artifacts (What files to write/update) (+2 more)
### Community 113 - "reviews.controller.ts" ### Community 113 - "reviews.controller.ts"
Cohesion: 0.13 Cohesion: 0.24
Nodes (17): CreateReviewDto, ApiProperty, IsInt, IsNotEmpty, IsOptional, IsString, Min, ApiProperty (+9 more) Nodes (7): ApiProperty, IsIn, IsOptional, IsString, UpdateReviewDto, ReviewsModule, Module
### Community 114 - "AppService" ### Community 114 - "AppService"
Cohesion: 0.29 Cohesion: 0.29
Nodes (5): AppController, Controller, Get, AppService, Injectable Nodes (5): AppController, Controller, Get, AppService, Injectable
### Community 115 - "seo.ts" ### Community 115 - "seo.ts"
Cohesion: 0.17 Cohesion: 0.18
Nodes (7): CatalogClient(), generateMetadata(), generateMetadata(), VideosPage(), DEFAULT_SEO_CONFIG, PageMetadataOptions, SeoConfig Nodes (6): generateMetadata(), generateMetadata(), VideosPage(), DEFAULT_SEO_CONFIG, PageMetadataOptions, SeoConfig
### Community 116 - "Vazirmatn Changelog" ### Community 116 - "Vazirmatn Changelog"
Cohesion: 0.18 Cohesion: 0.18
@ -811,6 +812,10 @@ Nodes (9): compilerOptions, esModuleInterop, module, moduleResolution, skipLibCh
Cohesion: 0.20 Cohesion: 0.20
Nodes (9): Compile and run the project, Deployment, Description, License, Project setup, Resources, Run tests, Stay in touch (+1 more) Nodes (9): Compile and run the project, Deployment, Description, License, Project setup, Resources, Run tests, Stay in touch (+1 more)
### Community 122 - "auth.module.ts"
Cohesion: 0.22
Nodes (8): DEFAULT_JWT_REFRESH_SECRET, DEFAULT_JWT_SECRET, getJwtSecret(), AuthModule, Module, JwtPayload, JwtStrategy, Injectable
### Community 124 - "Repository Map" ### Community 124 - "Repository Map"
Cohesion: 0.20 Cohesion: 0.20
Nodes (9): 1. Active Customer Storefront: React 19 + Vite Application, 2. Active Backend Service: NestJS Application, 3. Excluded Placeholder / Non-Auditable Directories, Active Applications & Non-Auditable Scopes, Documentation Governance, Important Configuration & Infrastructure Files, Mandatory Global Audit Exclusions, Repository Map (+1 more) Nodes (9): 1. Active Customer Storefront: React 19 + Vite Application, 2. Active Backend Service: NestJS Application, 3. Excluded Placeholder / Non-Auditable Directories, Active Applications & Non-Auditable Scopes, Documentation Governance, Important Configuration & Infrastructure Files, Mandatory Global Audit Exclusions, Repository Map (+1 more)
@ -827,13 +832,13 @@ Nodes (9): name, private, scripts, build, dev, lint, preview, type (+1 more)
Cohesion: 0.20 Cohesion: 0.20
Nodes (9): Arch Linux, Contributors, Install, Known problems for variable version, License, Sahel-Font, To Do (variable), طریقه استفاده از نسخه متغیر variable (+1 more) Nodes (9): Arch Linux, Contributors, Install, Known problems for variable version, License, Sahel-Font, To Do (variable), طریقه استفاده از نسخه متغیر variable (+1 more)
### Community 128 - "AdminService" ### Community 128 - "AdminController"
Cohesion: 0.16 Cohesion: 0.15
Nodes (4): Delete, Param, AdminService, Injectable Nodes (7): AdminController, ApiBearerAuth, ApiTags, Controller, Delete, Param, UseGuards
### Community 129 - "videos.controller.ts" ### Community 129 - "videos.controller.ts"
Cohesion: 0.22 Cohesion: 0.20
Nodes (7): GetVideosQueryDto, ApiPropertyOptional, IsBoolean, IsOptional, Transform, Module, VideosModule Nodes (8): GetVideosQueryDto, ApiPropertyOptional, IsBoolean, IsOptional, Transform, Module, VideosModule, VideoQuery
### Community 130 - "Sahel-Font" ### Community 130 - "Sahel-Font"
Cohesion: 0.20 Cohesion: 0.20
@ -851,6 +856,10 @@ 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 134 - "CreateReviewDto"
Cohesion: 0.17
Nodes (11): CreateReviewDto, ApiProperty, IsInt, IsNotEmpty, IsOptional, IsString, Min, Body (+3 more)
### Community 135 - "graphify reference: extra exports and benchmark" ### Community 135 - "graphify reference: extra exports and benchmark"
Cohesion: 0.22 Cohesion: 0.22
Nodes (8): graphify reference: extra exports and benchmark, Step 6b - Wiki (only if --wiki flag), Step 7 - Neo4j export (only if --neo4j or --neo4j-push flag), Step 7a - FalkorDB export (only if --falkordb or --falkordb-push flag), Step 7b - SVG export (only if --svg flag), Step 7c - GraphML export (only if --graphml flag), Step 7d - MCP server (only if --mcp flag), Step 8 - Token reduction benchmark (only if total_words > 5000) Nodes (8): graphify reference: extra exports and benchmark, Step 6b - Wiki (only if --wiki flag), Step 7 - Neo4j export (only if --neo4j or --neo4j-push flag), Step 7a - FalkorDB export (only if --falkordb or --falkordb-push flag), Step 7b - SVG export (only if --svg flag), Step 7c - GraphML export (only if --graphml flag), Step 7d - MCP server (only if --mcp flag), Step 8 - Token reduction benchmark (only if total_words > 5000)
@ -887,21 +896,17 @@ Nodes (7): backend, distMainPath, fs, http, path, { spawn, execSync }, waitForBa
Cohesion: 0.25 Cohesion: 0.25
Nodes (6): app_module_1, core_1, fs, path, swagger_1, yaml Nodes (6): app_module_1, core_1, fs, path, swagger_1, yaml
### Community 145 - "app/page.tsx" ### Community 145 - "ProductDto"
Cohesion: 0.67 Cohesion: 0.20
Nodes (3): generateMetadata(), getHomeData(), Home() Nodes (7): ProductDto, ApiPropertyOptional, IsArray, IsBoolean, IsNumber, IsOptional, IsString
### Community 146 - "System Discovery" ### Community 146 - "System Discovery"
Cohesion: 0.25 Cohesion: 0.25
Nodes (7): Active Core Applications, Current Architecture, Evidence-Based Status Matrix, Excluded / Non-Auditable Artifacts, Major Business Domains Discovered, System Discovery, Technical Architecture Summary Nodes (7): Active Core Applications, Current Architecture, Evidence-Based Status Matrix, Excluded / Non-Auditable Artifacts, Major Business Domains Discovered, System Discovery, Technical Architecture Summary
### Community 147 - "RevalidationService" ### Community 148 - "Body"
Cohesion: 0.14 Cohesion: 0.21
Nodes (5): RevalidationModule, Global, Module, RevalidationService, Injectable Nodes (3): Body, Post, CouponInput
### Community 148 - "AdminController"
Cohesion: 0.16
Nodes (6): AdminController, ApiBearerAuth, ApiTags, Controller, Post, UseGuards
### Community 149 - "SmsSettingsPage.tsx" ### Community 149 - "SmsSettingsPage.tsx"
Cohesion: 0.29 Cohesion: 0.29
@ -912,7 +917,7 @@ Cohesion: 0.29
Nodes (6): 1. Executive Vision, 2. Target Audience, 3. Functional Requirements, 4. Non-Functional Requirements (Performance, Security), 5. Epic / Feature Breakdown, Product Requirement Document (PRD) Nodes (6): 1. Executive Vision, 2. Target Audience, 3. Functional Requirements, 4. Non-Functional Requirements (Performance, Security), 5. Epic / Feature Breakdown, Product Requirement Document (PRD)
### Community 151 - "AuthService" ### Community 151 - "AuthService"
Cohesion: 0.19 Cohesion: 0.21
Nodes (3): AuthService, Injectable, normalizeMobile() Nodes (3): AuthService, Injectable, normalizeMobile()
### Community 153 - "exclude" ### Community 153 - "exclude"
@ -1001,7 +1006,7 @@ Nodes (6): Blog(), generateMetadata(), getBlogs(), getCategories(), revalidate,
### Community 179 - "BlogsService" ### Community 179 - "BlogsService"
Cohesion: 0.15 Cohesion: 0.15
Nodes (4): BlogsModule, Module, BlogsService, Injectable Nodes (5): BlogsModule, Module, BlogFilterDto, BlogsService, Injectable
### Community 180 - "API Contract Specification" ### Community 180 - "API Contract Specification"
Cohesion: 0.50 Cohesion: 0.50
@ -1019,9 +1024,13 @@ Nodes (3): Architectural Overview, Critical Review Findings & Required Enhanceme
Cohesion: 0.50 Cohesion: 0.50
Nodes (3): Overview & Content Foundation, SEO & Content Requirements, 🚀 SEO & Content Strategy Review (12_seo_content) Nodes (3): Overview & Content Foundation, SEO & Content Requirements, 🚀 SEO & Content Strategy Review (12_seo_content)
### Community 185 - "ApiResponse" ### Community 184 - "MetricsController"
Cohesion: 0.19 Cohesion: 0.18
Nodes (10): ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags, Controller, Get, Param, Query (+2 more) Nodes (5): ApiExcludeController, MetricsController, Controller, Get, Res
### Community 185 - "WikiController"
Cohesion: 0.13
Nodes (13): ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags, Controller, Get, Param, Query (+5 more)
### Community 191 - "graphify reference: add a URL and watch a folder" ### Community 191 - "graphify reference: add a URL and watch a folder"
Cohesion: 0.50 Cohesion: 0.50
@ -1047,9 +1056,13 @@ Nodes (3): Expanding the ESLint configuration, React Compiler, React + TypeScrip
Cohesion: 0.50 Cohesion: 0.50
Nodes (3): Select, SelectOption, SelectProps Nodes (3): Select, SelectOption, SelectProps
### Community 198 - "users.service.ts"
Cohesion: 0.31
Nodes (3): Module, UsersModule, UserAddressInput
### Community 199 - "auth.service.ts" ### Community 199 - "auth.service.ts"
Cohesion: 0.20 Cohesion: 0.13
Nodes (9): AdminLoginInput, LoginInput, RegisterInput, ApiProperty, IsNotEmpty, IsString, Matches, VerifyOtpDto (+1 more) Nodes (14): AdminLoginInput, LoginInput, RegisterInput, SendOtpDto, ApiProperty, IsNotEmpty, IsString, Matches (+6 more)
### Community 200 - "application/README.md" ### Community 200 - "application/README.md"
Cohesion: 0.50 Cohesion: 0.50
@ -1075,25 +1088,9 @@ Nodes (8): RegisterDto, ApiProperty, ApiPropertyOptional, IsEmail, IsNotEmpty, I
Cohesion: 0.43 Cohesion: 0.43
Nodes (7): InitiatePaymentDto, InitiateWalletTopupDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString Nodes (7): InitiatePaymentDto, InitiateWalletTopupDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString
### Community 298 - ".initiateOrderPayment" ### Community 298 - "ZibalCallbackQueryDto"
Cohesion: 0.20 Cohesion: 0.40
Nodes (10): ApiPropertyOptional, IsOptional, IsString, ZibalCallbackQueryDto, ApiBadRequestResponse, ApiOkResponse, Req, Res (+2 more) Nodes (4): ApiPropertyOptional, IsOptional, IsString, ZibalCallbackQueryDto
### Community 301 - "app.e2e-spec.js"
Cohesion: 0.50
Nodes (3): app_module_1, supertest_1, testing_1
### Community 304 - "SmsLogQueryDto"
Cohesion: 0.17
Nodes (8): SmsLogQueryDto, ApiPropertyOptional, IsIn, IsNumber, IsOptional, IsString, Type, Query
### Community 307 - "SendOtpDto"
Cohesion: 0.33
Nodes (5): SendOtpDto, ApiProperty, IsNotEmpty, IsString, Matches
### Community 312 - ".addComment"
Cohesion: 0.33
Nodes (5): ApiBearerAuth, Body, Post, Request, UseGuards
### Community 313 - "MenuManager.tsx" ### Community 313 - "MenuManager.tsx"
Cohesion: 0.33 Cohesion: 0.33
@ -1108,24 +1105,24 @@ Cohesion: 0.83
Nodes (3): GET(), handleRevalidate(), POST() Nodes (3): GET(), handleRevalidate(), POST()
## Knowledge Gaps ## Knowledge Gaps
- **1297 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1292 more) - **1299 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1294 more)
These have ≤1 connection - possible missing edges or undocumented components. These have ≤1 connection - possible missing edges or undocumented components.
- **105 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. - **107 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 `ApiResponse` to `HomeController`, `AuthController`, `BlogsController`, `PetsController`, `src/services/api.ts`, `ProductsService`, `UsersService`, `OrdersService`?** - **Why does `ApiResponse` connect `BlogsController` to `AuthController`, `PetsController`, `src/services/api.ts`, `ProductsService`, `UsersService`, `WikiController`, `OrdersService`?**
_High betweenness centrality (0.075) - this node is a cross-community bridge._ _High betweenness centrality (0.070) - this node is a cross-community bridge._
- **Why does `Roles()` connect `Roles` to `SettingsController`, `CmsController`, `tickets.controller.ts`, `ReviewsController`, `JwtAuthGuard`, `ProductsService`, `MenuService`, `WholesaleApplyDto`, `B2BService`, `FaqService`, `SslController`, `BannersService`, `TestimonialsService`, `IngredientsService`, `SmsLogQueryDto`, `PrescriptionsService`, `SmartAdvisorService`, `ContactService`, `reviews.controller.ts`?** - **Why does `Roles()` connect `Roles` to `SmsService`, `CmsController`, `tickets.controller.ts`, `ReviewsController`, `JwtAuthGuard`, `ProductsService`, `MenuService`, `WholesaleApplyDto`, `B2BService`, `FaqService`, `SslController`, `BannersService`, `TestimonialsService`, `IngredientsService`, `PrescriptionsService`, `SmartAdvisorService`, `ContactService`, `AdminTransactionFilterDto`, `reviews.controller.ts`?**
_High betweenness centrality (0.063) - this node is a cross-community bridge._ _High betweenness centrality (0.063) - this node is a cross-community bridge._
- **Why does `JwtAuthGuard` connect `JwtAuthGuard` to `videos.controller.ts`, `admin.module.ts`, `CmsController`, `tickets.controller.ts`, `PaginationDto`, `auth.controller.ts`, `PetsController`, `PrismaService`, `DoctorQueryDto`, `reviews.controller.ts`, `ProductsService`, `admin.service.ts`?** - **Why does `JwtAuthGuard` connect `JwtAuthGuard` to `videos.controller.ts`, `PaginationDto`, `CmsController`, `tickets.controller.ts`, `pets/pets.controller.ts`, `ReportsController`, `users.service.ts`, `auth.controller.ts`, `OrdersService`, `DoctorQueryDto`, `reviews.controller.ts`, `BlogsService`, `ProductsService`, `admin.controller.ts`?**
_High betweenness centrality (0.036) - this node is a cross-community bridge._ _High betweenness centrality (0.033) - 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?**
_1297 weakly-connected nodes found - possible documentation gaps or missing edges._ _1299 weakly-connected nodes found - possible documentation gaps or missing edges._
- **Should `app.module.ts` be split into smaller, more focused modules?** - **Should `app.module.ts` be split into smaller, more focused modules?**
_Cohesion score 0.07215686274509804 - nodes in this community are weakly interconnected._ _Cohesion score 0.05555555555555555 - nodes in this community are weakly interconnected._
- **Should `SmsService` be split into smaller, more focused modules?**
_Cohesion score 0.055964653902798235 - nodes in this community are weakly interconnected._
- **Should `ProductService` be split into smaller, more focused modules?** - **Should `ProductService` be split into smaller, more focused modules?**
_Cohesion score 0.06393442622950819 - nodes in this community are weakly interconnected._ _Cohesion score 0.06041986687147977 - nodes in this community are weakly interconnected._
- **Should `SafeImage.tsx` be split into smaller, more focused modules?**
_Cohesion score 0.11692307692307692 - nodes in this community are weakly interconnected._

View File

@ -0,0 +1 @@
{"nodes": [{"id": "$graphify-root$_backend_prisma_migrations_20260526160916_add_ui_texts_and_scientific_terms_migration_sql", "label": "migration.sql", "file_type": "code", "source_file": "backend/prisma/migrations/20260526160916_add_ui_texts_and_scientific_terms/migration.sql", "source_location": null}, {"id": "$graphify-root$_backend_prisma_migrations_20260526160916_add_ui_texts_and_scientific_terms_migration_ui_texts", "label": "\"ui_texts\"", "file_type": "code", "source_file": "backend/prisma/migrations/20260526160916_add_ui_texts_and_scientific_terms/migration.sql", "source_location": "L2"}, {"id": "$graphify-root$_backend_prisma_migrations_20260526160916_add_ui_texts_and_scientific_terms_migration_scientific_terms", "label": "\"scientific_terms\"", "file_type": "code", "source_file": "backend/prisma/migrations/20260526160916_add_ui_texts_and_scientific_terms/migration.sql", "source_location": "L10"}], "edges": [{"source": "$graphify-root$_backend_prisma_migrations_20260526160916_add_ui_texts_and_scientific_terms_migration_sql", "target": "$graphify-root$_backend_prisma_migrations_20260526160916_add_ui_texts_and_scientific_terms_migration_ui_texts", "relation": "contains", "confidence": "EXTRACTED", "source_file": "backend/prisma/migrations/20260526160916_add_ui_texts_and_scientific_terms/migration.sql", "source_location": "L2", "weight": 1.0}, {"source": "$graphify-root$_backend_prisma_migrations_20260526160916_add_ui_texts_and_scientific_terms_migration_sql", "target": "$graphify-root$_backend_prisma_migrations_20260526160916_add_ui_texts_and_scientific_terms_migration_scientific_terms", "relation": "contains", "confidence": "EXTRACTED", "source_file": "backend/prisma/migrations/20260526160916_add_ui_texts_and_scientific_terms/migration.sql", "source_location": "L10", "weight": 1.0}]}

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 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