feat(product-page): add high-res image zoom lightbox with pan/zoom/drag and unoptimized raw rendering
Some checks failed
Deploy Canina / deploy (push) Successful in 1m32s
E2E Playwright Tests / Run Full E2E & Security Suites (push) Failing after 7s

This commit is contained in:
parsa aghaei 2026-08-26 16:38:59 +03:30
parent 0ddc635dfd
commit a00778ffaa
13 changed files with 5169 additions and 4750 deletions

View File

@ -0,0 +1,352 @@
"use client";
import React, { useState, useRef, useEffect, useCallback } from "react";
import { motion, AnimatePresence } from "motion/react";
import {
X,
ZoomIn,
ZoomOut,
RotateCcw,
Maximize2,
Minimize2,
ChevronRight,
ChevronLeft,
Move
} from "lucide-react";
interface ProductImageZoomModalProps {
isOpen: boolean;
onClose: () => void;
images: string[];
activeImage: string;
onSelectImage: (image: string) => void;
productName: string;
}
export default function ProductImageZoomModal({
isOpen,
onClose,
images,
activeImage,
onSelectImage,
productName,
}: ProductImageZoomModalProps) {
const [scale, setScale] = useState(1);
const [position, setPosition] = useState({ x: 0, y: 0 });
const [isDragging, setIsDragging] = useState(false);
const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
const [isFullscreen, setIsFullscreen] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);
// Reset zoom & pan when image changes or modal opens
const resetZoom = useCallback(() => {
setScale(1);
setPosition({ x: 0, y: 0 });
}, []);
useEffect(() => {
if (isOpen) {
resetZoom();
document.body.style.overflow = "hidden";
} else {
document.body.style.overflow = "";
}
return () => {
document.body.style.overflow = "";
};
}, [isOpen, activeImage, resetZoom]);
// Keyboard navigation & zoom shortcuts
useEffect(() => {
if (!isOpen) return;
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === "Escape") {
onClose();
} else if (e.key === "+" || e.key === "=") {
setScale((prev) => Math.min(prev + 0.5, 4));
} else if (e.key === "-") {
setScale((prev) => {
const next = Math.max(prev - 0.5, 1);
if (next === 1) setPosition({ x: 0, y: 0 });
return next;
});
} else if (e.key === "0") {
resetZoom();
} else if (e.key === "ArrowLeft") {
navigateImage(1);
} else if (e.key === "ArrowRight") {
navigateImage(-1);
}
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, [isOpen, onClose, images, activeImage, resetZoom]);
const handleZoomIn = () => {
setScale((prev) => Math.min(prev + 0.5, 4));
};
const handleZoomOut = () => {
setScale((prev) => {
const next = Math.max(prev - 0.5, 1);
if (next === 1) setPosition({ x: 0, y: 0 });
return next;
});
};
const handleWheel = (e: React.WheelEvent) => {
e.preventDefault();
if (e.deltaY < 0) {
setScale((prev) => Math.min(prev + 0.25, 4));
} else {
setScale((prev) => {
const next = Math.max(prev - 0.25, 1);
if (next === 1) setPosition({ x: 0, y: 0 });
return next;
});
}
};
const handleMouseDown = (e: React.MouseEvent) => {
if (scale <= 1) return;
setIsDragging(true);
setDragStart({ x: e.clientX - position.x, y: e.clientY - position.y });
};
const handleMouseMove = (e: React.MouseEvent) => {
if (!isDragging || scale <= 1) return;
setPosition({
x: e.clientX - dragStart.x,
y: e.clientY - dragStart.y,
});
};
const handleMouseUp = () => {
setIsDragging(false);
};
// Touch drag for mobile
const handleTouchStart = (e: React.TouchEvent) => {
if (scale <= 1 || e.touches.length !== 1) return;
setIsDragging(true);
setDragStart({
x: e.touches[0].clientX - position.x,
y: e.touches[0].clientY - position.y,
});
};
const handleTouchMove = (e: React.TouchEvent) => {
if (!isDragging || scale <= 1 || e.touches.length !== 1) return;
setPosition({
x: e.touches[0].clientX - dragStart.x,
y: e.touches[0].clientY - dragStart.y,
});
};
const handleTouchEnd = () => {
setIsDragging(false);
};
const toggleFullscreen = () => {
if (!document.fullscreenElement) {
containerRef.current?.requestFullscreen?.().catch(() => {});
setIsFullscreen(true);
} else {
document.exitFullscreen?.().catch(() => {});
setIsFullscreen(false);
}
};
const navigateImage = (direction: number) => {
if (!images || images.length <= 1) return;
const currentIndex = images.indexOf(activeImage);
if (currentIndex === -1) return;
let nextIndex = (currentIndex + direction) % images.length;
if (nextIndex < 0) nextIndex = images.length - 1;
onSelectImage(images[nextIndex]);
resetZoom();
};
if (!isOpen) return null;
const currentImg = activeImage || images[0];
return (
<AnimatePresence>
<div
ref={containerRef}
className="fixed inset-0 z-[110] flex flex-col items-center justify-between bg-black/95 backdrop-blur-xl select-none font-vazir text-white"
dir="rtl"
onMouseMove={handleMouseMove}
onMouseUp={handleMouseUp}
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd}
>
{/* Top Control Bar */}
<div className="w-full flex items-center justify-between px-4 sm:px-6 py-3.5 bg-black/40 backdrop-blur-md border-b border-white/10 z-20 shrink-0">
<div className="flex items-center gap-3">
<button
type="button"
onClick={onClose}
className="p-2 sm:p-2.5 rounded-2xl bg-white/10 hover:bg-white/20 text-white hover:text-rose-400 transition-all cursor-pointer flex items-center gap-1.5"
title="بستن (Esc)"
>
<X className="w-5 h-5" />
<span className="text-xs font-bold hidden sm:inline">بستن</span>
</button>
<div className="flex flex-col text-right pr-2">
<span className="text-xs sm:text-sm font-black text-white/90 truncate max-w-[200px] sm:max-w-md">
{productName}
</span>
<span className="text-[10px] text-white/50 font-sans">
{images.length > 1 ? `${images.indexOf(currentImg) + 1} از ${images.length}` : 'تصویر با کیفیت اصلی'}
</span>
</div>
</div>
{/* Floating Zoom & Tool Controls */}
<div className="flex items-center gap-1.5 sm:gap-2 bg-white/10 backdrop-blur-md p-1 sm:p-1.5 rounded-2xl border border-white/15">
<button
type="button"
onClick={handleZoomIn}
disabled={scale >= 4}
className="p-2 rounded-xl bg-white/5 hover:bg-white/15 text-white disabled:opacity-30 disabled:cursor-not-allowed transition-all cursor-pointer"
title="بزرگ‌نمایی (+)"
>
<ZoomIn className="w-4 h-4" />
</button>
<span className="text-[11px] font-mono font-bold px-2 py-0.5 min-w-[48px] text-center text-cyan-300">
{Math.round(scale * 100)}%
</span>
<button
type="button"
onClick={handleZoomOut}
disabled={scale <= 1}
className="p-2 rounded-xl bg-white/5 hover:bg-white/15 text-white disabled:opacity-30 disabled:cursor-not-allowed transition-all cursor-pointer"
title="کوچک‌نمایی (-)"
>
<ZoomOut className="w-4 h-4" />
</button>
{scale > 1 && (
<button
type="button"
onClick={resetZoom}
className="p-2 rounded-xl bg-white/5 hover:bg-white/15 text-white transition-all cursor-pointer"
title="بازنشانی اندازه (0)"
>
<RotateCcw className="w-4 h-4" />
</button>
)}
<button
type="button"
onClick={toggleFullscreen}
className="p-2 rounded-xl bg-white/5 hover:bg-white/15 text-white transition-all cursor-pointer hidden sm:flex"
title="تمام‌صفحه"
>
{isFullscreen ? <Minimize2 className="w-4 h-4" /> : <Maximize2 className="w-4 h-4" />}
</button>
</div>
</div>
{/* Center Viewer Canvas with Pan and Zoom */}
<div
className="relative flex-1 w-full flex items-center justify-center overflow-hidden cursor-default"
onWheel={handleWheel}
onMouseDown={handleMouseDown}
onTouchStart={handleTouchStart}
>
{/* Navigation Next / Prev Buttons */}
{images.length > 1 && (
<>
<button
type="button"
onClick={() => navigateImage(-1)}
className="absolute right-3 sm:right-6 top-1/2 -translate-y-1/2 z-20 p-3 sm:p-3.5 rounded-full bg-black/60 hover:bg-black/90 border border-white/20 text-white backdrop-blur-md transition-all hover:scale-110 cursor-pointer shadow-2xl"
title="تصویر بعدی (فلش راست)"
>
<ChevronRight className="w-5 h-5 sm:w-6 sm:h-6" />
</button>
<button
type="button"
onClick={() => navigateImage(1)}
className="absolute left-3 sm:left-6 top-1/2 -translate-y-1/2 z-20 p-3 sm:p-3.5 rounded-full bg-black/60 hover:bg-black/90 border border-white/20 text-white backdrop-blur-md transition-all hover:scale-110 cursor-pointer shadow-2xl"
title="تصویر قبلی (فلش چپ)"
>
<ChevronLeft className="w-5 h-5 sm:w-6 sm:h-6" />
</button>
</>
)}
{/* Interactive Zoomable Image Element */}
<div
className={`relative max-w-full max-h-full flex items-center justify-center transition-transform ${
isDragging ? "cursor-grabbing duration-0" : scale > 1 ? "cursor-grab duration-150" : "cursor-zoom-in duration-200"
}`}
style={{
transform: `translate(${position.x}px, ${position.y}px) scale(${scale})`,
transformOrigin: "center center",
}}
onClick={(e) => {
if (scale === 1) {
setScale(2);
}
}}
>
{/* Raw unoptimized img element for 100% original full-resolution & clarity */}
<img
src={currentImg}
alt={productName}
draggable={false}
className="max-h-[75vh] sm:max-h-[82vh] max-w-[90vw] object-contain drop-shadow-2xl select-none pointer-events-none"
/>
</div>
{/* Drag instruction helper for zoomed view */}
{scale > 1 && (
<div className="absolute bottom-4 left-1/2 -translate-x-1/2 bg-black/70 backdrop-blur-md px-3.5 py-1.5 rounded-full border border-white/20 text-[11px] font-bold text-white/90 flex items-center gap-1.5 pointer-events-none z-10">
<Move className="w-3.5 h-3.5 text-cyan-300 animate-pulse" />
<span>برای جابجایی بکشید (Drag) برای زوم اسکرول کنید</span>
</div>
)}
</div>
{/* Bottom Thumbnail Strip */}
{images.length > 1 && (
<div className="w-full flex items-center justify-center gap-2.5 sm:gap-3 py-3 px-4 bg-black/40 backdrop-blur-md border-t border-white/10 z-20 shrink-0 overflow-x-auto">
{images.map((img, idx) => {
const isSelected = img === currentImg;
return (
<button
key={idx}
type="button"
onClick={() => {
onSelectImage(img);
resetZoom();
}}
className={`relative w-14 h-14 sm:w-16 sm:h-16 rounded-2xl overflow-hidden bg-white/10 border-2 transition-all p-1 shrink-0 cursor-pointer ${
isSelected
? "border-cyan-400 scale-105 ring-4 ring-cyan-400/30 shadow-lg"
: "border-white/15 opacity-60 hover:opacity-100 hover:border-white/40"
}`}
>
<img
src={img}
alt={`${productName} - ${idx + 1}`}
className="w-full h-full object-contain"
/>
</button>
);
})}
</div>
)}
</div>
</AnimatePresence>
);
}

View File

@ -76,6 +76,7 @@ import PodcastInlinePlayer from "./PodcastInlinePlayer";
const VideoModalPlayer = dynamic(() => import("./VideoModalPlayer"), { ssr: false });
const ProductReviews = dynamic(() => import("./ProductReviews"), { ssr: false });
const ProductImageZoomModal = dynamic(() => import("./ProductImageZoomModal"), { ssr: false });
import { useRouter } from 'next/navigation';
@ -1206,70 +1207,18 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
</div>
</div>
{/* Fullscreen High-Resolution Image Zoom / Lightbox Modal */}
<AnimatePresence>
{isImageZoomOpen && (
<div
className="fixed inset-0 z-50 flex items-center justify-center p-4 sm:p-8 bg-black/85 backdrop-blur-md"
onClick={() => setIsImageZoomOpen(false)}
>
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.9 }}
className="relative max-w-4xl max-h-[90vh] w-full flex flex-col items-center justify-center"
onClick={(e) => e.stopPropagation()}
>
{/* Close Button */}
<button
onClick={() => setIsImageZoomOpen(false)}
className="absolute -top-12 left-0 sm:left-auto sm:-right-12 w-10 h-10 rounded-full bg-white/20 hover:bg-white/30 text-white flex items-center justify-center transition-colors cursor-pointer"
title="بستن"
>
<X className="w-6 h-6" />
</button>
{/* Main Zoomed Image Container */}
<div className="bg-white rounded-3xl p-6 sm:p-10 shadow-2xl border border-white/20 max-h-[75vh] flex items-center justify-center overflow-hidden w-full">
<SafeImage
src={activeImage || product.image}
alt={product.name}
className="max-h-[60vh] max-w-full w-full"
imgClassName="max-h-[60vh] max-w-full w-auto object-contain drop-shadow-2xl mx-auto"
/>
</div>
{/* Lightbox Thumbnails Navigation */}
{(() => {
const allImgs = [
product.image,
...(product.images || []).filter(img => img && img !== product.image)
].filter(Boolean);
if (allImgs.length <= 1) return null;
return (
<div className="flex items-center gap-3 mt-4 overflow-x-auto py-2 px-4 max-w-full">
{allImgs.map((img, idx) => (
<button
key={idx}
onClick={() => setActiveImage(img)}
className={`w-14 h-14 rounded-xl overflow-hidden bg-white/10 border-2 transition-all p-1 shrink-0 ${
(activeImage || product.image) === img
? 'border-white scale-110 shadow-lg'
: 'border-transparent opacity-60 hover:opacity-100'
}`}
>
<SafeImage src={img} alt="Thumbnail" className="w-full h-full" imgClassName="w-full h-full object-contain" />
</button>
))}
</div>
);
})()}
</motion.div>
</div>
)}
</AnimatePresence>
{/* Fullscreen High-Resolution Image Zoom & Inspection Lightbox Modal */}
<ProductImageZoomModal
isOpen={isImageZoomOpen}
onClose={() => setIsImageZoomOpen(false)}
images={[
product.image,
...(product.images || []).filter(img => img && img !== product.image)
].filter(Boolean) as string[]}
activeImage={activeImage || product.image || ""}
onSelectImage={(img) => setActiveImage(img)}
productName={product.nameFa || product.name}
/>
{/* Dedicated Video Modal Player */}
<VideoModalPlayer

View File

@ -7,9 +7,9 @@
"5": "CmsController",
"6": "tickets.controller.ts",
"7": "Button.tsx",
"8": "users.service.ts",
"8": "users.controller.ts",
"9": "devDependencies",
"10": "reviews.controller.ts",
"10": "CreateReviewDto",
"11": "MediaSelector.tsx",
"12": "index.ts",
"13": "app-audit-verification.e2e-spec.js",
@ -64,7 +64,7 @@
"62": "ProductDto",
"63": "dependencies",
"64": "compilerOptions",
"65": "app.e2e-spec.js",
"65": "BlogsService",
"66": "ApiOperation",
"67": "PetsController",
"68": "UserDashboard.tsx",
@ -75,7 +75,7 @@
"73": "Operational Rules & Boundaries",
"74": "WikiController",
"75": "PetsController",
"76": "Param",
"76": "AdminService",
"77": "seo.module.ts",
"78": "rss.xml/route.ts",
"79": "🏢 AI Software Agency — Master Orchestration Protocol v3",
@ -89,10 +89,10 @@
"87": "dependencies",
"88": "CreateEBankCheckoutDto",
"89": "seed-products.ts",
"90": "lib/services/api.ts",
"90": "api",
"91": "Reconciled Audit Roles & Assignments",
"92": "OrdersService",
"93": "BlogsService",
"93": "lib/services/api.ts",
"94": "Phase 3.1 — Human Review Preparation and Master Backlog Critique",
"95": "wiki/[slug]/page.tsx",
"96": "compilerOptions",
@ -112,7 +112,7 @@
"110": "Operational Rules & Boundaries",
"111": "Operational Rules & Boundaries",
"112": "Operational Rules & Boundaries",
"113": "AdminService",
"113": "Reports.tsx",
"114": "AppService",
"115": "VetGallery.tsx",
"116": "Vazirmatn Changelog",
@ -122,13 +122,13 @@
"120": "compilerOptions",
"121": "backend/README.md",
"122": "AdminController",
"123": "auth.service.ts",
"123": "AuthService",
"124": "Repository Map",
"125": "validate_integrity.js",
"126": "admin-panel/package.json",
"127": "Sahel-Font",
"128": ".createCoupon",
"129": "auth.controller.ts",
"128": "Body",
"129": "auth.service.ts",
"130": "Sahel-Font",
"131": "Role & Core Objective",
"132": "orchestrate.py",
@ -183,7 +183,7 @@
"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": "MetricsController",
"184": "track/page.tsx",
"185": "@eslint/eslintrc",
"186": "seed-ui-texts.ts",
"187": "seed-wiki.ts",
@ -230,7 +230,7 @@
"228": "rules/graphify.md",
"229": ".agents/workflows/graphify.md",
"230": "instructions.md",
"231": "RevalidationService",
"231": "RedisService",
"232": "helmet",
"233": "tailwindcss",
"234": "@nestjs/schematics",
@ -322,7 +322,7 @@
"320": "@testing-library/react",
"321": "orders/page.tsx",
"322": "pets/page.tsx",
"323": "eslint",
"324": "eslint-config-next",
"323": "eslint-config-prettier",
"324": "@types/react-dom",
"327": "eslint-plugin-react-refresh"
}

File diff suppressed because one or more lines are too long

View File

@ -183,7 +183,7 @@
"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": "RedisService",
"184": "MetricsController",
"185": "@eslint/eslintrc",
"186": "seed-ui-texts.ts",
"187": "seed-wiki.ts",
@ -230,7 +230,7 @@
"228": "rules/graphify.md",
"229": ".agents/workflows/graphify.md",
"230": "instructions.md",
"231": "eslint-config-prettier",
"231": "RevalidationService",
"232": "helmet",
"233": "tailwindcss",
"234": "@nestjs/schematics",
@ -322,6 +322,7 @@
"320": "@testing-library/react",
"321": "orders/page.tsx",
"322": "pets/page.tsx",
"323": "@types/react-dom",
"323": "eslint",
"324": "eslint-config-next",
"327": "eslint-plugin-react-refresh"
}

View File

@ -1,16 +1,16 @@
# Graph Report - canina (2026-08-26)
## Corpus Check
- 589 files · ~1,333,778 words
- 589 files · ~1,333,704 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 4114 nodes · 7414 edges · 325 communities (206 shown, 119 thin omitted)
- 4114 nodes · 7414 edges · 326 communities (207 shown, 119 thin omitted)
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 281 edges (avg confidence: 0.79)
- Token cost: 0 input · 0 output
## Graph Freshness
- Built from commit: `3109e30f`
- Built from commit: `5f58ba82`
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
- Run `graphify update .` after code changes (no API cost).
@ -198,7 +198,7 @@
- ⚙️ Backend Technical Review (05_dev_backend)
- 🎨 Frontend & Admin Panel Technical Review (06_dev_frontend)
- 🚀 SEO & Content Strategy Review (12_seo_content)
- RedisService
- MetricsController
- @eslint/eslintrc
- seed-ui-texts.ts
- seed-wiki.ts
@ -245,7 +245,7 @@
- rules/graphify.md
- .agents/workflows/graphify.md
- instructions.md
- eslint-config-prettier
- RevalidationService
- helmet
- tailwindcss
- @nestjs/schematics
@ -318,7 +318,8 @@
- MaskableField.tsx
- @eslint/js
- @testing-library/react
- @types/react-dom
- eslint
- eslint-config-next
- eslint-plugin-react-refresh
## God Nodes (most connected - your core abstractions)
@ -346,19 +347,19 @@
backend/src/orders/orders.controller.ts → frontend/admin-panel/src/types/admin.ts
## 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/store/cartStore.ts -> frontend/application/lib/services/api.ts`
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/services/authService.ts -> frontend/application/lib/services/api.ts`
- 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 (325 total, 119 thin omitted)
## Communities (326 total, 119 thin omitted)
### Community 0 - "Roles"
Cohesion: 0.24
Nodes (13): Roles(), PaymentController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get (+5 more)
### Community 1 - "app.module.ts"
Cohesion: 0.06
Nodes (41): B2BModule, Module, BannersModule, Module, CmsModule, Module, RevalidationModule, Global (+33 more)
Cohesion: 0.07
Nodes (38): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+30 more)
### Community 2 - "SmsService"
Cohesion: 0.06
@ -390,7 +391,7 @@ Nodes (14): AddressDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty,
### Community 9 - "devDependencies"
Cohesion: 0.22
Nodes (9): devDependencies, eslint, @types/bcryptjs, @types/node, typescript, eslint, @types/node, typescript (+1 more)
Nodes (9): devDependencies, eslint-config-prettier, @types/bcryptjs, @types/node, typescript, @types/node, typescript, eslint-config-prettier (+1 more)
### Community 10 - "reviews.controller.ts"
Cohesion: 0.07
@ -437,8 +438,8 @@ Cohesion: 0.07
Nodes (32): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, UpdateVideoDto (+24 more)
### Community 21 - "admin.module.ts"
Cohesion: 0.07
Nodes (20): AdminModule, Module, PetQuery, PetsService, Injectable, ReportsController, ApiBearerAuth, ApiOperation (+12 more)
Cohesion: 0.06
Nodes (23): AdminModule, Module, PetQuery, PetsService, Injectable, ReportsController, ApiBearerAuth, ApiOperation (+15 more)
### Community 22 - "FeaturedProducts.tsx"
Cohesion: 0.14
@ -554,7 +555,7 @@ Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, glo
### Community 50 - "devDependencies"
Cohesion: 0.13
Nodes (15): eslint-config-next, devDependencies, eslint, eslint-config-next, jsdom, tailwindcss, @tailwindcss/postcss, @types/node (+7 more)
Nodes (15): devDependencies, eslint, jsdom, tailwindcss, @tailwindcss/postcss, @types/node, @types/react-dom, @vitejs/plugin-react (+7 more)
### Community 51 - "BlogsController"
Cohesion: 0.07
@ -773,8 +774,8 @@ Cohesion: 0.06
Nodes (33): PaginationDto, SortOrder, ApiPropertyOptional, IsEnum, IsInt, IsOptional, IsString, Min (+25 more)
### Community 108 - "PrismaService"
Cohesion: 0.07
Nodes (19): CategoryQuery, RevalidationService, Injectable, MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions, SmsConfig, SmsLogQuery (+11 more)
Cohesion: 0.08
Nodes (17): CategoryQuery, MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions, SmsConfig, SmsLogQuery, CreateContactSubmissionDto, UpdateContactInfoItemDto (+9 more)
### Community 109 - "1. Summary of Integrity Repairs Performed"
Cohesion: 0.17
@ -1036,9 +1037,9 @@ Nodes (3): Architectural Overview, Critical Review Findings & Required Enhanceme
Cohesion: 0.50
Nodes (3): Overview & Content Foundation, SEO & Content Requirements, 🚀 SEO & Content Strategy Review (12_seo_content)
### Community 184 - "RedisService"
Cohesion: 0.10
Nodes (10): ApiExcludeController, MetricsController, Controller, Get, Res, RedisModule, Global, Module (+2 more)
### Community 184 - "MetricsController"
Cohesion: 0.20
Nodes (5): ApiExcludeController, MetricsController, Controller, Get, Res
### Community 191 - "graphify reference: add a URL and watch a folder"
Cohesion: 0.50
@ -1084,6 +1085,10 @@ Nodes (3): ADR-AUTH-001: Admin Panel Authentication Architecture & Token Managem
Cohesion: 0.67
Nodes (3): Shabnam Font README, Shabnam Font Sample, Vazir Font
### Community 231 - "RevalidationService"
Cohesion: 0.12
Nodes (7): RevalidationModule, Global, Module, RevalidationService, Injectable, RedisService, Injectable
### Community 298 - ".initiateOrderPayment"
Cohesion: 0.20
Nodes (10): ApiPropertyOptional, IsOptional, IsString, ZibalCallbackQueryDto, ApiBadRequestResponse, ApiOkResponse, Req, Res (+2 more)
@ -1113,7 +1118,7 @@ _Questions this graph is uniquely positioned to answer:_
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
_1337 weakly-connected nodes found - possible documentation gaps or missing edges._
- **Should `app.module.ts` be split into smaller, more focused modules?**
_Cohesion score 0.059562841530054644 - nodes in this community are weakly interconnected._
_Cohesion score 0.06516290726817042 - nodes in this community are weakly interconnected._
- **Should `SmsService` be split into smaller, more focused modules?**
_Cohesion score 0.055040197897340756 - nodes in this community are weakly interconnected._
- **Should `ProductService` be split into smaller, more focused modules?**

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,16 @@
# Graph Report - canina (2026-08-26)
## Corpus Check
- 589 files · ~1,333,704 words
- 590 files · ~1,334,711 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 4114 nodes · 7414 edges · 326 communities (207 shown, 119 thin omitted)
- 4118 nodes · 7419 edges · 326 communities (208 shown, 118 thin omitted)
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 281 edges (avg confidence: 0.79)
- Token cost: 0 input · 0 output
## Graph Freshness
- Built from commit: `5f58ba82`
- Built from commit: `0ddc635d`
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
- Run `graphify update .` after code changes (no API cost).
@ -23,9 +23,9 @@
- CmsController
- tickets.controller.ts
- Button.tsx
- users.service.ts
- users.controller.ts
- devDependencies
- reviews.controller.ts
- CreateReviewDto
- MediaSelector.tsx
- index.ts
- app-audit-verification.e2e-spec.js
@ -80,7 +80,7 @@
- ProductDto
- dependencies
- compilerOptions
- app.e2e-spec.js
- BlogsService
- ApiOperation
- PetsController
- UserDashboard.tsx
@ -91,7 +91,7 @@
- Operational Rules & Boundaries
- WikiController
- PetsController
- Param
- AdminService
- seo.module.ts
- rss.xml/route.ts
- 🏢 AI Software Agency — Master Orchestration Protocol v3
@ -105,10 +105,10 @@
- dependencies
- CreateEBankCheckoutDto
- seed-products.ts
- lib/services/api.ts
- api
- Reconciled Audit Roles & Assignments
- OrdersService
- BlogsService
- lib/services/api.ts
- Phase 3.1 — Human Review Preparation and Master Backlog Critique
- wiki/[slug]/page.tsx
- compilerOptions
@ -128,7 +128,7 @@
- Operational Rules & Boundaries
- Operational Rules & Boundaries
- Operational Rules & Boundaries
- AdminService
- Reports.tsx
- AppService
- VetGallery.tsx
- Vazirmatn Changelog
@ -138,13 +138,13 @@
- compilerOptions
- backend/README.md
- AdminController
- auth.service.ts
- AuthService
- Repository Map
- validate_integrity.js
- admin-panel/package.json
- Sahel-Font
- .createCoupon
- auth.controller.ts
- Body
- auth.service.ts
- Sahel-Font
- Role & Core Objective
- orchestrate.py
@ -198,7 +198,7 @@
- ⚙️ Backend Technical Review (05_dev_backend)
- 🎨 Frontend & Admin Panel Technical Review (06_dev_frontend)
- 🚀 SEO & Content Strategy Review (12_seo_content)
- MetricsController
- track/page.tsx
- @eslint/eslintrc
- seed-ui-texts.ts
- seed-wiki.ts
@ -245,7 +245,7 @@
- rules/graphify.md
- .agents/workflows/graphify.md
- instructions.md
- RevalidationService
- RedisService
- helmet
- tailwindcss
- @nestjs/schematics
@ -318,8 +318,8 @@
- MaskableField.tsx
- @eslint/js
- @testing-library/react
- eslint
- eslint-config-next
- eslint-config-prettier
- @types/react-dom
- eslint-plugin-react-refresh
## God Nodes (most connected - your core abstractions)
@ -347,19 +347,19 @@
backend/src/orders/orders.controller.ts → frontend/admin-panel/src/types/admin.ts
## Import Cycles
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/api.ts`
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/services/authService.ts -> frontend/application/lib/services/api.ts`
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/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`
## Communities (326 total, 119 thin omitted)
## Communities (326 total, 118 thin omitted)
### Community 0 - "Roles"
Cohesion: 0.24
Nodes (13): Roles(), PaymentController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get (+5 more)
### Community 1 - "app.module.ts"
Cohesion: 0.07
Nodes (38): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+30 more)
Cohesion: 0.06
Nodes (37): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+29 more)
### Community 2 - "SmsService"
Cohesion: 0.06
@ -367,11 +367,11 @@ Nodes (27): SmsService, Injectable, SmsLogQueryDto, ApiPropertyOptional, IsIn, I
### Community 3 - "ProductService"
Cohesion: 0.06
Nodes (34): dynamic, revalidate, DEFAULT_CATEGORIES, dynamic, revalidate, dynamic, revalidate, BlogCategory (+26 more)
Nodes (33): dynamic, revalidate, DEFAULT_CATEGORIES, dynamic, revalidate, dynamic, revalidate, BlogCategory (+25 more)
### Community 4 - "ProductPage.tsx"
Cohesion: 0.13
Nodes (14): revalidate, PLAYBACK_RATES, PodcastInlinePlayer(), PodcastInlinePlayerProps, CalculatorState, ICON_MAP, ProductPage(), ProductReviews (+6 more)
Nodes (13): PLAYBACK_RATES, PodcastInlinePlayer(), PodcastInlinePlayerProps, ProductImageZoomModalProps, CalculatorState, ICON_MAP, ProductImageZoomModal, ProductPage() (+5 more)
### Community 5 - "CmsController"
Cohesion: 0.09
@ -385,17 +385,17 @@ Nodes (29): AdminUpdateTicketDto, CreateTicketDto, ReplyTicketDto, ApiProperty,
Cohesion: 0.12
Nodes (14): Button(), ButtonProps, ButtonSize, ButtonVariant, Spinner(), FAQ, BlogCommentItem, ProductReview (+6 more)
### Community 8 - "users.service.ts"
### Community 8 - "users.controller.ts"
Cohesion: 0.13
Nodes (14): AddressDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, ApiPropertyOptional (+6 more)
Nodes (13): AddressDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, ApiPropertyOptional (+5 more)
### Community 9 - "devDependencies"
Cohesion: 0.22
Nodes (9): devDependencies, eslint-config-prettier, @types/bcryptjs, @types/node, typescript, @types/node, typescript, eslint-config-prettier (+1 more)
Nodes (9): devDependencies, eslint, @types/bcryptjs, @types/node, typescript, eslint, @types/node, typescript (+1 more)
### Community 10 - "reviews.controller.ts"
Cohesion: 0.07
Nodes (30): CreateReviewDto, ApiProperty, IsInt, IsNotEmpty, IsOptional, IsString, Min, ApiProperty (+22 more)
### Community 10 - "CreateReviewDto"
Cohesion: 0.08
Nodes (25): CreateReviewDto, ApiProperty, IsInt, IsNotEmpty, IsOptional, IsString, Min, ReviewsController (+17 more)
### Community 11 - "MediaSelector.tsx"
Cohesion: 0.06
@ -406,12 +406,12 @@ Cohesion: 0.06
Nodes (24): backend, frontend, playwright.config.ts, @playwright/test, tests/**/*.ts, authFile, test, compilerOptions (+16 more)
### Community 13 - "app-audit-verification.e2e-spec.js"
Cohesion: 0.06
Nodes (28): AppModule, Module, EnvironmentVariables, IsNotEmpty, IsOptional, IsString, validateEnv(), CustomHttpExceptionFilter (+20 more)
Cohesion: 0.07
Nodes (26): EnvironmentVariables, IsNotEmpty, IsOptional, IsString, validateEnv(), CustomHttpExceptionFilter, Catch, PrismaExceptionFilter (+18 more)
### Community 14 - "PetProfile.tsx"
Cohesion: 0.14
Nodes (19): metadata, Header(), MENU_ICONS, PrescriptionUploadModal(), PrescriptionUploadModalProps, CURRENT_SYMPTOMS, MEDICAL_HISTORIES, SmartAdvisor() (+11 more)
Cohesion: 0.13
Nodes (20): ClientLayout(), metadata, Header(), PetProfile(), PrescriptionUploadModal(), PrescriptionUploadModalProps, CURRENT_SYMPTOMS, MEDICAL_HISTORIES (+12 more)
### Community 15 - "src/services/api.ts"
Cohesion: 0.08
@ -426,20 +426,20 @@ Cohesion: 0.14
Nodes (18): B2BPage(), generateMetadata(), ContactPage(), generateMetadata(), generateMetadata(), getInitialVideos(), Videos(), ContactFormClient() (+10 more)
### Community 18 - "JwtAuthGuard"
Cohesion: 0.18
Cohesion: 0.19
Nodes (7): JwtAuthGuard, Injectable, ROLES_KEY, RequestWithUser, RolesGuard, Injectable, UserReqPayload
### Community 19 - "ProductsService"
Cohesion: 0.11
Nodes (14): ProductsController, ApiOperation, ApiTags, Body, Controller, Get, Param, Patch (+6 more)
Cohesion: 0.09
Nodes (19): GetProductsDto, ApiPropertyOptional, IsEnum, IsOptional, IsString, ProductsController, ApiOperation, ApiTags (+11 more)
### Community 20 - "CreateVideoDto"
Cohesion: 0.07
Nodes (32): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, UpdateVideoDto (+24 more)
Cohesion: 0.08
Nodes (29): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, UpdateVideoDto (+21 more)
### Community 21 - "admin.module.ts"
Cohesion: 0.06
Nodes (23): AdminModule, Module, PetQuery, PetsService, Injectable, ReportsController, ApiBearerAuth, ApiOperation (+15 more)
Cohesion: 0.07
Nodes (20): AdminModule, Module, PetQuery, PetsService, Injectable, ReportsController, ApiBearerAuth, ApiOperation (+12 more)
### Community 22 - "FeaturedProducts.tsx"
Cohesion: 0.14
@ -482,8 +482,8 @@ Cohesion: 0.06
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Category, Completion Statement, Confidence, Dependencies (+23 more)
### Community 32 - "adminRoutes.tsx"
Cohesion: 0.06
Nodes (24): App(), Props, RouteErrorBoundary, State, HeroBanner, VetTestimonial, BestSellerItem, CategoryDistItem (+16 more)
Cohesion: 0.08
Nodes (17): App(), Props, RouteErrorBoundary, State, HeroBanner, VetTestimonial, AdminRouteConfig, CMS (+9 more)
### Community 33 - "WholesaleService"
Cohesion: 0.14
@ -546,7 +546,7 @@ Cohesion: 0.13
Nodes (14): IngredientsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
### Community 48 - "UsersController"
Cohesion: 0.21
Cohesion: 0.20
Nodes (16): ApiBadRequestResponse, ApiBearerAuth, ApiCreatedResponse, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+8 more)
### Community 49 - "devDependencies"
@ -555,11 +555,11 @@ Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, glo
### Community 50 - "devDependencies"
Cohesion: 0.13
Nodes (15): devDependencies, eslint, jsdom, tailwindcss, @tailwindcss/postcss, @types/node, @types/react-dom, @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"
Cohesion: 0.07
Nodes (18): BlogsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+10 more)
Cohesion: 0.14
Nodes (16): BlogsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+8 more)
### Community 52 - "PrescriptionsService"
Cohesion: 0.14
@ -598,7 +598,7 @@ Cohesion: 0.22
Nodes (7): AdminTransactionFilterDto, ApiPropertyOptional, IsIn, IsNumber, IsOptional, IsString, Type
### Community 62 - "ProductDto"
Cohesion: 0.17
Cohesion: 0.22
Nodes (7): ProductDto, ApiPropertyOptional, IsArray, IsBoolean, IsNumber, IsOptional, IsString
### Community 63 - "dependencies"
@ -609,12 +609,12 @@ Nodes (23): dependencies, bcrypt, bcryptjs, class-validator, compression, ioredi
Cohesion: 0.10
Nodes (20): compilerOptions, allowImportingTsExtensions, erasableSyntaxOnly, lib, module, moduleDetection, moduleResolution, noEmit (+12 more)
### Community 65 - "app.e2e-spec.js"
Cohesion: 0.50
Nodes (3): app_module_1, supertest_1, testing_1
### Community 65 - "BlogsService"
Cohesion: 0.06
Nodes (14): BlogsService, Injectable, RevalidationModule, Global, Module, RevalidationService, Injectable, ApiProperty (+6 more)
### Community 66 - "ApiOperation"
Cohesion: 0.22
Cohesion: 0.12
Nodes (8): ApiOperation, ApiQuery, Get, Query, AdminQueryDto, ApiPropertyOptional, IsOptional, IsString
### Community 67 - "PetsController"
@ -622,8 +622,8 @@ Cohesion: 0.15
Nodes (11): PetsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Controller, Delete, Get (+3 more)
### Community 68 - "UserDashboard.tsx"
Cohesion: 0.09
Nodes (35): AuthModal, HomeClient(), VerifyContent(), AddressFormData, AddressModal(), AddressModalProps, normalizeDigits(), validateAddressForm() (+27 more)
Cohesion: 0.14
Nodes (23): AddressFormData, AddressModal(), AddressModalProps, normalizeDigits(), validateAddressForm(), BackButton(), BackButtonProps, CheckoutPage() (+15 more)
### Community 69 - "Required Review Group Closures"
Cohesion: 0.10
@ -653,6 +653,10 @@ Nodes (14): ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, De
Cohesion: 0.05
Nodes (47): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, CreatePetDto, ApiProperty (+39 more)
### Community 76 - "AdminService"
Cohesion: 0.20
Nodes (4): Delete, Param, AdminService, Injectable
### Community 77 - "seo.module.ts"
Cohesion: 0.16
Nodes (10): SeoController, ApiOperation, ApiTags, Controller, Get, Param, SeoModule, Module (+2 more)
@ -687,7 +691,7 @@ Nodes (16): 1. Active Secret Scanning (All Modified Files), 2. Docker Container
### Community 85 - "useSettingsStore"
Cohesion: 0.13
Nodes (17): ClientLayout(), B2BLandingClient(), BrandLogo(), BrandLogoProps, FAQItem, FAQSection(), Footer(), Hero() (+9 more)
Nodes (20): AuthModal, AuthModal(), AuthModalProps, extractOtpFromText(), B2BLandingClient(), BrandLogo(), BrandLogoProps, FAQItem (+12 more)
### Community 86 - "zibal.service.ts"
Cohesion: 0.16
@ -705,29 +709,29 @@ Nodes (8): CreateEBankCheckoutDto, ApiProperty, ApiPropertyOptional, IsNotEmpty,
Cohesion: 0.17
Nodes (12): prisma, main(), prisma, determineSuitableFor(), findOrCreateCategory(), getProductImageUrl(), main(), parseSize() (+4 more)
### Community 90 - "lib/services/api.ts"
Cohesion: 0.06
Nodes (20): LoginModal, ContactInfoItem, LoginModal(), LoginModalProps, api, ApiErrorPayload, baseURL, ApiErr (+12 more)
### Community 90 - "api"
Cohesion: 0.10
Nodes (13): LoginModal, ContactInfoItem, LoginModal(), LoginModalProps, api, ApiErr, AuthResponse, AuthService (+5 more)
### Community 91 - "Reconciled Audit Roles & Assignments"
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)
### Community 92 - "OrdersService"
Cohesion: 0.07
Nodes (29): CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional (+21 more)
Cohesion: 0.06
Nodes (35): CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional (+27 more)
### Community 93 - "BlogsService"
Cohesion: 0.14
Nodes (5): BlogsModule, Module, BlogFilterDto, BlogsService, Injectable
### Community 93 - "lib/services/api.ts"
Cohesion: 0.09
Nodes (21): B2BPortal, B2BPortal(), BlogPostClientProps, BlogPost, BlogPreviewSection(), OrderDetailsModal(), OrderDetailsModalProps, PLAYBACK_RATES (+13 more)
### Community 94 - "Phase 3.1 — Human Review Preparation and Master Backlog Critique"
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)
### Community 95 - "wiki/[slug]/page.tsx"
Cohesion: 0.24
Nodes (15): BlogPostPage(), generateMetadata(), getBlog(), revalidate, safeIso(), safeLocalDate(), generateMetadata(), generateMetadata() (+7 more)
Cohesion: 0.19
Nodes (16): BlogPostPage(), generateMetadata(), getBlog(), revalidate, safeIso(), safeLocalDate(), generateMetadata(), revalidate (+8 more)
### Community 96 - "compilerOptions"
Cohesion: 0.06
@ -771,11 +775,11 @@ Nodes (11): 1. Detect Test Runner from Tech Stack, 2. Execution Output Capture (
### Community 107 - "PaginationDto"
Cohesion: 0.06
Nodes (33): PaginationDto, SortOrder, ApiPropertyOptional, IsEnum, IsInt, IsOptional, IsString, Min (+25 more)
Nodes (27): BlogsModule, Module, BlogFilterDto, BlogsService, Injectable, PaginationDto, SortOrder, ApiPropertyOptional (+19 more)
### Community 108 - "PrismaService"
Cohesion: 0.08
Nodes (17): CategoryQuery, MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions, SmsConfig, SmsLogQuery, CreateContactSubmissionDto, UpdateContactInfoItemDto (+9 more)
Cohesion: 0.06
Nodes (27): ApiExcludeController, CategoryQuery, MetricsController, Controller, Get, Res, MeliPayamakPattern, MeliPayamakResponse (+19 more)
### Community 109 - "1. Summary of Integrity Repairs Performed"
Cohesion: 0.17
@ -793,13 +797,17 @@ Nodes (10): 1. Mark Active Task as Complete, 2. Documentation Updates, 3. Dynami
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)
### Community 113 - "Reports.tsx"
Cohesion: 0.20
Nodes (7): BestSellerItem, CategoryDistItem, COLORS, CustomTooltipProps, ReportData, TopCouponItem, Reports
### Community 114 - "AppService"
Cohesion: 0.29
Nodes (5): AppController, Controller, Get, AppService, Injectable
### Community 115 - "VetGallery.tsx"
Cohesion: 0.16
Nodes (12): BackButton(), BackButtonProps, VideoModalPlayer, DisplayVideoItem, FALLBACK_VIDEOS, TestimonialItem, VetGallery(), PLAYBACK_RATES (+4 more)
Cohesion: 0.20
Nodes (10): VideoModalPlayer, DisplayVideoItem, FALLBACK_VIDEOS, TestimonialItem, VetGallery(), PLAYBACK_RATES, VideoModalPlayer(), VideoModalPlayerProps (+2 more)
### Community 116 - "Vazirmatn Changelog"
Cohesion: 0.18
@ -827,11 +835,11 @@ Nodes (9): Compile and run the project, Deployment, Description, License, Projec
### Community 122 - "AdminController"
Cohesion: 0.14
Nodes (7): AdminController, ApiBearerAuth, ApiTags, Body, Controller, Put, UseGuards
Nodes (6): AdminController, ApiBearerAuth, ApiTags, Controller, Put, UseGuards
### Community 123 - "auth.service.ts"
Cohesion: 0.09
Nodes (17): AdminLoginInput, AuthService, LoginInput, RegisterInput, Injectable, SendOtpDto, ApiProperty, IsNotEmpty (+9 more)
### Community 123 - "AuthService"
Cohesion: 0.18
Nodes (4): AuthService, Injectable, normalizeMobile(), UserAddressInput
### Community 124 - "Repository Map"
Cohesion: 0.20
@ -849,9 +857,9 @@ Nodes (9): name, private, scripts, build, dev, lint, preview, type (+1 more)
Cohesion: 0.20
Nodes (9): Arch Linux, Contributors, Install, Known problems for variable version, License, Sahel-Font, To Do (variable), طریقه استفاده از نسخه متغیر variable (+1 more)
### Community 129 - "auth.controller.ts"
Cohesion: 0.10
Nodes (19): AdminLoginDto, ApiProperty, IsEmail, IsNotEmpty, IsString, MinLength, LoginDto, ApiProperty (+11 more)
### Community 129 - "auth.service.ts"
Cohesion: 0.06
Nodes (33): AdminLoginInput, LoginInput, RegisterInput, AdminLoginDto, ApiProperty, IsEmail, IsNotEmpty, IsString (+25 more)
### Community 130 - "Sahel-Font"
Cohesion: 0.20
@ -922,8 +930,8 @@ 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
### Community 147 - "HomeClient.tsx"
Cohesion: 0.09
Nodes (26): HomeClientProps, ArchivePage(), CATEGORY_MAP, ICON_MAP, BannerPlacement(), BannerPlacementProps, BlogPostClientProps, BlogPost (+18 more)
Cohesion: 0.11
Nodes (20): HomeClient(), HomeClientProps, ArchivePage(), ArchiveProductCard(), CATEGORY_MAP, ICON_MAP, BannerPlacement(), BannerPlacementProps (+12 more)
### Community 149 - "SmsSettingsPage.tsx"
Cohesion: 0.29
@ -934,8 +942,8 @@ 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)
### Community 152 - "useCartStore"
Cohesion: 0.15
Nodes (13): B2BPortal, CartDrawer, B2BPortal(), CartDrawer(), DeleteConfirmModal(), DeleteConfirmModalProps, OrderSuccess(), OrderTracking() (+5 more)
Cohesion: 0.09
Nodes (16): CartDrawer, VerifyContent(), CartDrawer(), DeleteConfirmModal(), DeleteConfirmModalProps, OrderSuccess(), mockProduct, ApiErr (+8 more)
### Community 153 - "exclude"
Cohesion: 0.22
@ -1037,10 +1045,6 @@ Nodes (3): Architectural Overview, Critical Review Findings & Required Enhanceme
Cohesion: 0.50
Nodes (3): Overview & Content Foundation, SEO & Content Requirements, 🚀 SEO & Content Strategy Review (12_seo_content)
### Community 184 - "MetricsController"
Cohesion: 0.20
Nodes (5): ApiExcludeController, MetricsController, Controller, Get, Res
### Community 191 - "graphify reference: add a URL and watch a folder"
Cohesion: 0.50
Nodes (3): For /graphify add, For --watch, graphify reference: add a URL and watch a folder
@ -1085,12 +1089,12 @@ Nodes (3): ADR-AUTH-001: Admin Panel Authentication Architecture & Token Managem
Cohesion: 0.67
Nodes (3): Shabnam Font README, Shabnam Font Sample, Vazir Font
### Community 231 - "RevalidationService"
Cohesion: 0.12
Nodes (7): RevalidationModule, Global, Module, RevalidationService, Injectable, RedisService, Injectable
### Community 231 - "RedisService"
Cohesion: 0.11
Nodes (7): AppModule, Module, RedisModule, Global, Module, RedisService, Injectable
### Community 298 - ".initiateOrderPayment"
Cohesion: 0.20
Cohesion: 0.18
Nodes (10): ApiPropertyOptional, IsOptional, IsString, ZibalCallbackQueryDto, ApiBadRequestResponse, ApiOkResponse, Req, Res (+2 more)
### Community 313 - "Modal.tsx"
@ -1102,24 +1106,24 @@ Cohesion: 0.83
Nodes (3): GET(), handleRevalidate(), POST()
## Knowledge Gaps
- **1337 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1332 more)
- **1338 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1333 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **119 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
- **118 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 `BlogsController`, `AuthController`, `PetsController`, `PaginationDto`, `HomeController`, `UsersController`, `ProductsService`, `OrdersService`?**
_High betweenness centrality (0.085) - this node is a cross-community bridge._
- **Why does `Roles()` connect `Roles` to `WholesaleService`, `B2BService`, `SmsService`, `FaqService`, `CmsController`, `tickets.controller.ts`, `SslController`, `BannersService`, `reviews.controller.ts`, `TestimonialsService`, `IngredientsService`, `JwtAuthGuard`, `ProductsService`, `PrescriptionsService`, `SmartAdvisorService`, `MenuService`, `ContactService`?**
- **Why does `Roles()` connect `Roles` to `BlogsService`, `B2BService`, `SmsService`, `FaqService`, `CmsController`, `tickets.controller.ts`, `WholesaleService`, `SslController`, `BannersService`, `CreateReviewDto`, `TestimonialsService`, `IngredientsService`, `JwtAuthGuard`, `ProductsService`, `PrescriptionsService`, `SmartAdvisorService`, `MenuService`, `ContactService`?**
_High betweenness centrality (0.066) - this node is a cross-community bridge._
- **Why does `JwtAuthGuard` connect `JwtAuthGuard` to `auth.controller.ts`, `CmsController`, `tickets.controller.ts`, `users.service.ts`, `reviews.controller.ts`, `PaginationDto`, `PetsController`, `DoctorQueryDto`, `admin.service.ts`, `CreateVideoDto`, `admin.module.ts`, `BlogsService`?**
- **Why does `JwtAuthGuard` connect `JwtAuthGuard` to `auth.service.ts`, `BlogsService`, `CmsController`, `tickets.controller.ts`, `users.controller.ts`, `PaginationDto`, `PetsController`, `DoctorQueryDto`, `admin.service.ts`, `ProductsService`, `CreateVideoDto`, `admin.module.ts`, `OrdersService`?**
_High betweenness centrality (0.033) - this node is a cross-community bridge._
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
_1337 weakly-connected nodes found - possible documentation gaps or missing edges._
_1338 weakly-connected nodes found - possible documentation gaps or missing edges._
- **Should `app.module.ts` be split into smaller, more focused modules?**
_Cohesion score 0.06516290726817042 - nodes in this community are weakly interconnected._
_Cohesion score 0.05706214689265537 - nodes in this community are weakly interconnected._
- **Should `SmsService` be split into smaller, more focused modules?**
_Cohesion score 0.055040197897340756 - nodes in this community are weakly interconnected._
- **Should `ProductService` be split into smaller, more focused modules?**
_Cohesion score 0.06093189964157706 - nodes in this community are weakly interconnected._
_Cohesion score 0.06393442622950819 - 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