fix(media): add inline podcast player, video buffering track, click-outside speed menu and safe product edit trim
Some checks failed
Deploy Canina / deploy (push) Has been cancelled

This commit is contained in:
parsa aghaei 2026-08-18 15:43:45 +03:30
parent 95d79518e7
commit 36e382cf16
17 changed files with 12496 additions and 11618 deletions

View File

@ -249,7 +249,7 @@ export default function Products() {
const wMargin = bPrice && wPrice ? Math.round(((wPrice - Number(bPrice)) / Number(bPrice)) * 100) : '';
setFormData({
artNo: product.artNo,
artNo: product.artNo || '',
nameFa: product.nameFa || '',
nameEn: product.nameEn || '',
scientificTagline: product.scientificTagline || '',
@ -263,10 +263,11 @@ export default function Products() {
wholesaleMarginPercent: wMargin,
priceDisplay: product.priceDisplay || '',
unit: product.unit || '',
packageSize: Number(product.packageSize),
packageSize: Number(product.packageSize) || 0,
dosageLogic: product.dosageLogic || '',
suitableFor: product.suitableFor || 'سگ و گربه',
imageUrl: product.imageUrl || '',
slug: product.slug || '',
metaTitle: product.metaTitle || '',
metaDescription: product.metaDescription || '',
keywords: product.keywords || '',
@ -337,43 +338,43 @@ export default function Products() {
}
try {
const derivedSlug = formData.slug.trim() || slugify(formData.nameEn);
const derivedSlug = (formData.slug || '').trim() || slugify(formData.nameEn || '');
const finalPayload: Record<string, unknown> = {
artNo: formData.artNo.trim(),
nameFa: formData.nameFa.trim(),
nameEn: formData.nameEn.trim(),
scientificTagline: formData.scientificTagline.trim() || undefined,
description: formData.description.trim() || undefined,
shortDescription: formData.shortDescription.trim() || undefined,
categoryId: formData.categoryId.trim(),
artNo: (formData.artNo || '').trim(),
nameFa: (formData.nameFa || '').trim(),
nameEn: (formData.nameEn || '').trim(),
scientificTagline: (formData.scientificTagline || '').trim() || undefined,
description: (formData.description || '').trim() || undefined,
shortDescription: (formData.shortDescription || '').trim() || undefined,
categoryId: (formData.categoryId || '').trim(),
buyPrice: formData.buyPrice ? Number(formData.buyPrice) : 0,
priceValue: Number(formData.priceValue || 0),
wholesalePrice: formData.wholesalePrice ? Number(formData.wholesalePrice) : undefined,
priceValueMarginPercent: formData.priceValueMarginPercent !== '' ? Number(formData.priceValueMarginPercent) : undefined,
wholesaleMarginPercent: formData.wholesaleMarginPercent !== '' ? Number(formData.wholesaleMarginPercent) : undefined,
priceDisplay: formData.priceDisplay || `${Number(formData.priceValue || 0).toLocaleString('fa-IR')} تومان`,
unit: formData.unit.trim() || undefined,
unit: (formData.unit || '').trim() || undefined,
packageSize: Number(formData.packageSize) || 0,
dosageLogic: formData.dosageLogic.trim() || undefined,
dosageLogic: (formData.dosageLogic || '').trim() || undefined,
suitableFor: formData.suitableFor || 'سگ و گربه',
imageUrl: formData.imageUrl.trim() || undefined,
imageUrl: (formData.imageUrl || '').trim() || undefined,
images: formData.images || [],
podcastUrl: formData.podcastUrl.trim() || undefined,
podcastTitle: formData.podcastTitle.trim() || undefined,
podcastDescription: formData.podcastDescription.trim() || undefined,
podcastCover: formData.podcastCover.trim() || undefined,
videoUrl: formData.videoUrl.trim() || undefined,
videoTitle: formData.videoTitle.trim() || undefined,
videoDescription: formData.videoDescription.trim() || undefined,
videoCover: formData.videoCover.trim() || undefined,
pdfUrl: formData.pdfUrl.trim() || undefined,
pdfTitle: formData.pdfTitle.trim() || undefined,
pdfDescription: formData.pdfDescription.trim() || undefined,
pdfCover: formData.pdfCover.trim() || undefined,
metaTitle: formData.metaTitle.trim() || `${formData.nameFa || 'نام محصول'} | خرید و قیمت مکمل کنینا`,
metaDescription: formData.metaDescription.trim() || formData.shortDescription || 'خرید آنلاین مکمل اصل کنینا آلمان با بالاترین کیفیت بالینی...',
keywords: formData.keywords.trim() || undefined,
canonicalUrl: formData.canonicalUrl.trim() || `/shop/${derivedSlug}`,
podcastUrl: (formData.podcastUrl || '').trim() || undefined,
podcastTitle: (formData.podcastTitle || '').trim() || undefined,
podcastDescription: (formData.podcastDescription || '').trim() || undefined,
podcastCover: (formData.podcastCover || '').trim() || undefined,
videoUrl: (formData.videoUrl || '').trim() || undefined,
videoTitle: (formData.videoTitle || '').trim() || undefined,
videoDescription: (formData.videoDescription || '').trim() || undefined,
videoCover: (formData.videoCover || '').trim() || undefined,
pdfUrl: (formData.pdfUrl || '').trim() || undefined,
pdfTitle: (formData.pdfTitle || '').trim() || undefined,
pdfDescription: (formData.pdfDescription || '').trim() || undefined,
pdfCover: (formData.pdfCover || '').trim() || undefined,
metaTitle: (formData.metaTitle || '').trim() || `${formData.nameFa || 'نام محصول'} | خرید و قیمت مکمل کنینا`,
metaDescription: (formData.metaDescription || '').trim() || formData.shortDescription || 'خرید آنلاین مکمل اصل کنینا آلمان با بالاترین کیفیت بالینی...',
keywords: (formData.keywords || '').trim() || undefined,
canonicalUrl: (formData.canonicalUrl || '').trim() || `/shop/${derivedSlug}`,
slug: derivedSlug,
symptoms: formData.symptoms || [],
isPreorder: Boolean(formData.isPreorder),

View File

@ -0,0 +1,417 @@
"use client";
import React, { useState, useRef, useEffect, useCallback, useMemo } from "react";
import {
Play,
Pause,
RotateCcw,
RotateCw,
Volume2,
VolumeX,
Download,
Share2,
Check,
Headphones,
Loader2,
Sparkles
} from "lucide-react";
interface PodcastInlinePlayerProps {
podcast: {
audioUrl?: string;
title?: string;
description?: string;
cover?: string;
productName?: string;
fallbackCover?: string;
};
}
const PLAYBACK_RATES = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.5];
const WAVEFORM_BAR_COUNT = 44;
export default function PodcastInlinePlayer({ podcast }: PodcastInlinePlayerProps) {
const audioRef = useRef<HTMLAudioElement>(null);
const waveformRef = useRef<HTMLDivElement>(null);
const rateMenuRef = useRef<HTMLDivElement>(null);
const [isPlaying, setIsPlaying] = useState(false);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
const [volume, setVolume] = useState(1);
const [isMuted, setIsMuted] = useState(false);
const [playbackRate, setPlaybackRate] = useState(1);
const [showRateMenu, setShowRateMenu] = useState(false);
const [isBuffering, setIsBuffering] = useState(false);
const [isCopied, setIsCopied] = useState(false);
// Close rate menu when clicking outside
useEffect(() => {
function handleClickOutside(e: MouseEvent) {
if (rateMenuRef.current && !rateMenuRef.current.contains(e.target as Node)) {
setShowRateMenu(false);
}
}
if (showRateMenu) {
document.addEventListener("mousedown", handleClickOutside);
}
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [showRateMenu]);
// Deterministic heights for waveform visualization
const waveformHeights = useMemo(() => {
const seed = (podcast?.title || "canina").split("").reduce((acc, char) => acc + char.charCodeAt(0), 0);
return Array.from({ length: WAVEFORM_BAR_COUNT }).map((_, i) => {
const pseudo = Math.sin((i + 1) * 0.45 + seed) * 0.5 + 0.5;
return Math.max(22, Math.min(95, Math.floor(pseudo * 75 + 20)));
});
}, [podcast?.title]);
const togglePlay = useCallback(() => {
if (!audioRef.current) return;
if (audioRef.current.paused) {
audioRef.current.play().catch(console.error);
setIsPlaying(true);
} else {
audioRef.current.pause();
setIsPlaying(false);
}
}, []);
const seekToPercent = (percent: number) => {
if (audioRef.current && duration > 0) {
const newTime = (percent / 100) * duration;
audioRef.current.currentTime = Math.max(0, Math.min(duration, newTime));
setCurrentTime(newTime);
}
};
const handleWaveformClick = (e: React.MouseEvent<HTMLDivElement>) => {
if (!waveformRef.current || duration <= 0) return;
const rect = waveformRef.current.getBoundingClientRect();
const clickX = e.clientX - rect.left;
const percent = Math.max(0, Math.min(100, (clickX / rect.width) * 100));
seekToPercent(percent);
};
const skipTime = (seconds: number) => {
if (audioRef.current) {
audioRef.current.currentTime = Math.max(0, Math.min(audioRef.current.duration || 0, audioRef.current.currentTime + seconds));
}
};
const handleRateChange = (rate: number) => {
if (audioRef.current) {
audioRef.current.playbackRate = rate;
setPlaybackRate(rate);
setShowRateMenu(false);
}
};
const toggleMute = () => {
if (audioRef.current) {
audioRef.current.muted = !isMuted;
setIsMuted(!isMuted);
}
};
const handleVolumeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const val = Number(e.target.value);
setVolume(val);
if (audioRef.current) {
audioRef.current.volume = val;
if (val === 0) {
setIsMuted(true);
audioRef.current.muted = true;
} else {
setIsMuted(false);
audioRef.current.muted = false;
}
}
};
const handleShare = async () => {
const shareUrl = typeof window !== 'undefined' ? window.location.href : '';
if (navigator.share) {
try {
await navigator.share({
title: podcast?.title || 'پادکست و بررسی بالینی مکمل کنینا',
text: podcast?.description || '',
url: shareUrl
});
} catch {
// Fallback
}
} else {
try {
await navigator.clipboard.writeText(shareUrl);
setIsCopied(true);
setTimeout(() => setIsCopied(false), 2500);
} catch (err) {
console.error('Copy failed:', err);
}
}
};
const handleDownload = () => {
if (!podcast?.audioUrl) return;
const a = document.createElement('a');
a.href = podcast.audioUrl;
a.download = `${podcast.title || 'canina-podcast'}.mp3`;
a.target = '_blank';
a.rel = 'noopener noreferrer';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
const formatTime = (secs: number) => {
if (isNaN(secs) || secs < 0) return "00:00";
const mins = Math.floor(secs / 60);
const remainingSecs = Math.floor(secs % 60);
return `${mins.toString().padStart(2, "0")}:${remainingSecs.toString().padStart(2, "0")}`;
};
const displayCover = podcast.cover || podcast.fallbackCover || '/images/default-podcast.png';
const progressPercent = duration > 0 ? (currentTime / duration) * 100 : 0;
const volumePercent = isMuted ? 0 : volume * 100;
return (
<div className="bg-gradient-to-br from-neutral-900 via-neutral-900 to-black rounded-3xl overflow-hidden shadow-xl border border-white/10 p-6 text-white group" dir="rtl">
{/* Hidden Audio Tag */}
<audio
ref={audioRef}
src={podcast.audioUrl}
onPlay={() => setIsPlaying(true)}
onPause={() => setIsPlaying(false)}
onTimeUpdate={() => {
if (audioRef.current) setCurrentTime(audioRef.current.currentTime);
}}
onLoadedMetadata={() => {
if (audioRef.current) setDuration(audioRef.current.duration);
setIsBuffering(false);
}}
onWaiting={() => setIsBuffering(true)}
onPlaying={() => setIsBuffering(false)}
onEnded={() => setIsPlaying(false)}
/>
<div className="flex flex-col md:flex-row items-center gap-6">
{/* Artwork / Cover */}
<div
onClick={togglePlay}
className="relative w-full md:w-56 sm:w-64 aspect-square rounded-2xl overflow-hidden cursor-pointer bg-neutral-800 border border-white/15 group-hover:border-canina-blue/50 transition-all flex items-center justify-center shrink-0 shadow-lg"
>
<img
src={displayCover}
alt={podcast.title || "کاور پادکست"}
className={`w-full h-full object-cover transition-transform duration-700 ${isPlaying ? "scale-105" : "scale-100"}`}
onError={(e) => {
(e.target as HTMLImageElement).src = '/images/default-podcast.png';
}}
/>
<div className="absolute inset-0 bg-black/40 group-hover:bg-black/20 transition-colors flex items-center justify-center">
<div className="w-12 h-12 rounded-full bg-canina-blue text-white flex items-center justify-center shadow-xl shadow-canina-blue/50 group-hover:scale-110 active:scale-95 transition-transform">
{isPlaying ? <Pause className="w-5 h-5 fill-white" /> : <Play className="w-5 h-5 fill-white ml-0.5" />}
</div>
</div>
{isBuffering && (
<div className="absolute inset-0 bg-black/50 backdrop-blur-2xs flex items-center justify-center">
<Loader2 className="w-8 h-8 text-white animate-spin" />
</div>
)}
</div>
{/* Info & Soundcloud Waveform Seeker Controls */}
<div className="flex-1 w-full text-center md:text-right space-y-3">
{/* Header Row: Badge & Action buttons */}
<div className="flex items-center justify-between gap-2 flex-wrap">
<div className="flex items-center gap-2">
<span className="text-xs font-black text-canina-blue bg-canina-blue/15 px-3 py-1 rounded-full border border-canina-blue/30 flex items-center gap-1.5">
<Headphones className="w-3.5 h-3.5 animate-pulse text-canina-blue" />
<span>پادکست و تحلیل صوتی بالینی</span>
</span>
{podcast.productName && (
<span className="hidden sm:inline-flex text-xs font-bold text-white/70 items-center gap-1">
<Sparkles className="w-3 h-3 text-canina-gold" />
<span>{podcast.productName}</span>
</span>
)}
</div>
<div className="flex items-center gap-1.5">
<button
type="button"
onClick={handleShare}
className="p-2 rounded-xl bg-white/10 hover:bg-white/20 text-white transition-all cursor-pointer"
title="اشتراک‌گذاری"
>
{isCopied ? <Check className="w-4 h-4 text-emerald-400" /> : <Share2 className="w-4 h-4" />}
</button>
<button
type="button"
onClick={handleDownload}
className="p-2 rounded-xl bg-white/10 hover:bg-white/20 text-white transition-all cursor-pointer"
title="دانلود پادکست"
>
<Download className="w-4 h-4" />
</button>
</div>
</div>
<div>
<h4 className="text-base sm:text-lg font-black text-white line-clamp-1">
{podcast.title || "پادکست و بررسی صوتی بالینی مکمل"}
</h4>
<p className="text-xs text-white/70 font-medium leading-relaxed line-clamp-2 mt-1">
{podcast.description || "توضیحات صوتی دامپزشک و کادر علمی درباره اثربخشی، مکانیسم اثر و نحوه مصرف دقیق"}
</p>
</div>
{/* Soundcloud-Style Waveform Visualizer & Track */}
<div className="w-full space-y-1.5 pt-1">
<div
ref={waveformRef}
onClick={handleWaveformClick}
className="w-full h-11 flex items-center justify-between gap-[3px] px-2.5 py-1 bg-white/5 hover:bg-white/10 rounded-2xl cursor-pointer transition-all relative overflow-hidden group/wave border border-white/5"
title="برای رفتن به زمان مورد نظر کلیک کنید"
dir="ltr"
>
{waveformHeights.map((h, i) => {
const barPercent = (i / (WAVEFORM_BAR_COUNT - 1)) * 100;
const isPassed = barPercent <= progressPercent;
return (
<div
key={i}
className="flex-1 flex items-center justify-center h-full"
>
<div
className={`w-full rounded-full transition-all duration-150 ${
isPassed
? "bg-gradient-to-t from-canina-blue to-cyan-400 shadow-xs"
: "bg-white/20 group-hover/wave:bg-white/30"
} ${isPlaying && isPassed ? "opacity-100" : "opacity-80"}`}
style={{
height: `${h}%`,
transform: isPlaying && isPassed ? "scaleY(1.05)" : "scaleY(1)"
}}
/>
</div>
);
})}
</div>
{/* Time Stamp Row */}
<div className="flex items-center justify-between text-[11px] font-mono font-bold text-white/60 px-1 dir-ltr" dir="ltr">
<span>{formatTime(currentTime)}</span>
<span>{formatTime(duration)}</span>
</div>
</div>
{/* Controls Bottom Bar */}
<div className="flex items-center justify-between pt-1 flex-wrap gap-2">
{/* Speed Selector */}
<div className="relative" ref={rateMenuRef}>
<button
type="button"
onClick={() => setShowRateMenu(!showRateMenu)}
className="px-2.5 py-1 rounded-xl bg-white/10 hover:bg-white/20 text-white text-xs font-mono font-bold transition-all cursor-pointer flex items-center gap-1 border border-white/10"
title="سرعت پخش"
>
<span>{playbackRate}x</span>
</button>
{showRateMenu && (
<div className="absolute bottom-full right-0 mb-2 bg-neutral-900/95 backdrop-blur-md border border-white/15 rounded-2xl p-1.5 shadow-2xl z-30 flex flex-col gap-1 min-w-[75px]">
{PLAYBACK_RATES.map((rate) => (
<button
key={rate}
type="button"
onClick={() => handleRateChange(rate)}
className={`px-3 py-1 text-xs font-mono font-bold rounded-xl text-center transition-colors cursor-pointer ${
playbackRate === rate
? "bg-canina-blue text-white"
: "text-white/70 hover:bg-white/10 hover:text-white"
}`}
>
{rate}x
</button>
))}
</div>
)}
</div>
{/* Central Controls: -15s on Left, Play in Center, +15s on Right in RTL */}
<div className="flex items-center gap-2 sm:gap-3" dir="rtl">
<button
type="button"
onClick={togglePlay}
className="w-10 h-10 rounded-full bg-canina-blue hover:bg-canina-blue/90 text-white flex items-center justify-center transition-transform hover:scale-105 active:scale-95 cursor-pointer shadow-lg shadow-canina-blue/30 border border-white/10"
title={isPlaying ? "توقف" : "پخش"}
>
{isPlaying ? <Pause className="w-5 h-5 fill-white" /> : <Play className="w-5 h-5 fill-white ml-0.5" />}
</button>
{/* -15s */}
<button
type="button"
onClick={() => skipTime(-15)}
className="px-2.5 py-1.5 text-white/80 hover:text-white rounded-lg hover:bg-white/10 transition-colors cursor-pointer flex items-center gap-1 text-xs font-mono font-bold border border-white/10"
title="۱۵ ثانیه عقب"
>
<RotateCcw className="w-3.5 h-3.5" />
<span>-15s</span>
</button>
{/* +15s */}
<button
type="button"
onClick={() => skipTime(15)}
className="px-2.5 py-1.5 text-white/80 hover:text-white rounded-lg hover:bg-white/10 transition-colors cursor-pointer flex items-center gap-1 text-xs font-mono font-bold border border-white/10"
title="۱۵ ثانیه جلو"
>
<RotateCw className="w-3.5 h-3.5" />
<span>+15s</span>
</button>
</div>
{/* Volume Control: Directed towards speaker icon */}
<div className="flex items-center gap-2" dir="ltr">
<div className="relative w-16 hidden sm:flex items-center h-4">
<div className="absolute inset-x-0 h-1.5 bg-white/20 rounded-lg overflow-hidden pointer-events-none">
<div
className="h-full bg-canina-blue transition-all"
style={{ width: `${volumePercent}%` }}
/>
</div>
<input
type="range"
min={0}
max={1}
step={0.05}
value={isMuted ? 0 : volume}
onChange={handleVolumeChange}
className="w-full h-4 opacity-0 absolute inset-0 cursor-pointer z-10"
/>
<div
className="absolute w-2.5 h-2.5 bg-white rounded-full shadow pointer-events-none -translate-x-1/2"
style={{ left: `${volumePercent}%` }}
/>
</div>
<button
type="button"
onClick={toggleMute}
className="p-1.5 text-white/80 hover:text-white rounded-lg hover:bg-white/10 transition-colors cursor-pointer"
title={isMuted ? "صدا وصل" : "بی‌صدا"}
>
{isMuted || volume === 0 ? <VolumeX className="w-4 h-4" /> : <Volume2 className="w-4 h-4" />}
</button>
</div>
</div>
</div>
</div>
</div>
);
}

View File

@ -38,6 +38,7 @@ const WAVEFORM_BAR_COUNT = 48;
export default function PodcastPlayerModal({ isOpen, onClose, podcast }: PodcastPlayerModalProps) {
const audioRef = useRef<HTMLAudioElement>(null);
const waveformRef = useRef<HTMLDivElement>(null);
const rateMenuRef = useRef<HTMLDivElement>(null);
const [isPlaying, setIsPlaying] = useState(false);
const [currentTime, setCurrentTime] = useState(0);
@ -49,6 +50,21 @@ export default function PodcastPlayerModal({ isOpen, onClose, podcast }: Podcast
const [isBuffering, setIsBuffering] = useState(false);
const [isCopied, setIsCopied] = useState(false);
// Close rate menu on outside click
useEffect(() => {
function handleClickOutside(e: MouseEvent) {
if (rateMenuRef.current && !rateMenuRef.current.contains(e.target as Node)) {
setShowRateMenu(false);
}
}
if (showRateMenu) {
document.addEventListener("mousedown", handleClickOutside);
}
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [showRateMenu]);
// Deterministic heights for waveform visualization
const waveformHeights = useMemo(() => {
const seed = (podcast?.title || "canina").split("").reduce((acc, char) => acc + char.charCodeAt(0), 0);
@ -204,8 +220,8 @@ export default function PodcastPlayerModal({ isOpen, onClose, podcast }: Podcast
>
{/* Top Bar (Header + Close) */}
<div className="w-full flex items-center justify-between mb-4">
<div className="flex items-center gap-2.5 text-xs font-black text-purple-400 bg-purple-500/10 px-3.5 py-1.5 rounded-full border border-purple-500/20">
<Headphones className="w-4 h-4 animate-pulse" />
<div className="flex items-center gap-2.5 text-xs font-black text-canina-blue bg-canina-blue/10 px-3.5 py-1.5 rounded-full border border-canina-blue/20">
<Headphones className="w-4 h-4 animate-pulse text-canina-blue" />
<span>پادکست و تحلیل صوتی بالینی</span>
</div>
@ -285,8 +301,8 @@ export default function PodcastPlayerModal({ isOpen, onClose, podcast }: Podcast
{podcast.title || "بررسی بالینی و نحوه مصرف مکمل"}
</h3>
{podcast.productName && (
<p className="text-purple-400 text-xs font-bold flex items-center justify-center gap-1">
<Sparkles className="w-3.5 h-3.5" />
<p className="text-canina-blue text-xs font-bold flex items-center justify-center gap-1">
<Sparkles className="w-3.5 h-3.5 text-canina-gold" />
<span>محصول: {podcast.productName}</span>
</p>
)}
@ -317,7 +333,7 @@ export default function PodcastPlayerModal({ isOpen, onClose, podcast }: Podcast
<div
className={`w-full rounded-full transition-all duration-150 ${
isPassed
? "bg-gradient-to-t from-purple-500 to-canina-blue shadow-xs"
? "bg-gradient-to-t from-canina-blue to-cyan-400 shadow-xs"
: "bg-white/20 group-hover/wave:bg-white/30"
} ${isPlaying && isPassed ? "opacity-100" : "opacity-85"}`}
style={{
@ -340,7 +356,7 @@ export default function PodcastPlayerModal({ isOpen, onClose, podcast }: Podcast
{/* Main Controls Row */}
<div className="w-full flex items-center justify-between pt-2">
{/* Speed Selector Button */}
<div className="relative">
<div className="relative" ref={rateMenuRef}>
<button
type="button"
onClick={() => setShowRateMenu(!showRateMenu)}
@ -359,7 +375,7 @@ export default function PodcastPlayerModal({ isOpen, onClose, podcast }: Podcast
onClick={() => handleRateChange(rate)}
className={`px-3 py-1 text-xs font-mono font-bold rounded-xl text-center transition-colors cursor-pointer ${
playbackRate === rate
? "bg-purple-600 text-white"
? "bg-canina-blue text-white"
: "text-white/70 hover:bg-white/10 hover:text-white"
}`}
>
@ -376,7 +392,7 @@ export default function PodcastPlayerModal({ isOpen, onClose, podcast }: Podcast
<button
type="button"
onClick={togglePlay}
className="w-12 h-12 rounded-full bg-purple-600 hover:bg-purple-500 text-white flex items-center justify-center transition-transform hover:scale-105 active:scale-95 cursor-pointer shadow-xl shadow-purple-600/40 border border-white/20"
className="w-12 h-12 rounded-full bg-canina-blue hover:bg-canina-blue/90 text-white flex items-center justify-center transition-transform hover:scale-105 active:scale-95 cursor-pointer shadow-xl shadow-canina-blue/40 border border-white/20"
title={isPlaying ? "توقف" : "پخش"}
>
{isPlaying ? <Pause className="w-5 h-5 fill-white" /> : <Play className="w-5 h-5 fill-white ml-0.5" />}
@ -410,7 +426,7 @@ export default function PodcastPlayerModal({ isOpen, onClose, podcast }: Podcast
<div className="relative w-16 hidden sm:flex items-center h-4">
<div className="absolute inset-x-0 h-1.5 bg-white/20 rounded-lg overflow-hidden pointer-events-none">
<div
className="h-full bg-purple-500 transition-all"
className="h-full bg-canina-blue transition-all"
style={{ width: `${volumePercent}%` }}
/>
</div>

View File

@ -69,7 +69,7 @@ import Tooltip from "./Tooltip";
import SafeImage from "./SafeImage";
import ProductReviews from "./ProductReviews";
import VideoModalPlayer from "./VideoModalPlayer";
import PodcastPlayerModal from "./PodcastPlayerModal";
import PodcastInlinePlayer from "./PodcastInlinePlayer";
import { useRouter } from 'next/navigation';
@ -86,7 +86,6 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
const [activeImage, setActiveImage] = useState<string | null>(null);
const [isImageZoomOpen, setIsImageZoomOpen] = useState(false);
const [isVideoModalOpen, setIsVideoModalOpen] = useState(false);
const [isPodcastModalOpen, setIsPodcastModalOpen] = useState(false);
useEffect(() => {
Promise.resolve().then(() => setIsMounted(true));
@ -742,53 +741,18 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
</div>
)}
{/* Podcast Player Row */}
{/* Podcast Player Row (Inline Direct Player with Soundcloud Waveform) */}
{product.podcastUrl && (
<div className="bg-gradient-to-br from-purple-950/40 via-neutral-900 to-black rounded-3xl overflow-hidden shadow-xl border border-purple-500/20 p-6 flex flex-col md:flex-row items-center gap-6 text-white group">
{/* Podcast Cover / Artwork Box */}
<div
onClick={() => setIsPodcastModalOpen(true)}
className="relative w-full md:w-80 aspect-video rounded-2xl overflow-hidden cursor-pointer bg-neutral-800 border border-white/10 group-hover:border-purple-500/50 transition-all flex items-center justify-center shrink-0"
>
<img
src={product.podcastCover || product.image}
alt={product.podcastTitle || product.name}
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
onError={(e) => {
(e.target as HTMLImageElement).src = product.image;
}}
/>
<div className="absolute inset-0 bg-black/40 group-hover:bg-black/20 transition-colors flex items-center justify-center">
<div className="w-12 h-12 rounded-full bg-purple-600 text-white flex items-center justify-center shadow-xl shadow-purple-600/50 group-hover:scale-110 transition-transform">
<Play className="w-5 h-5 fill-white ml-0.5" />
</div>
</div>
</div>
<div className="flex-1 text-center md:text-right space-y-2">
<div className="flex items-center justify-center md:justify-start gap-2">
<span className="text-xs font-black text-purple-400 bg-purple-500/10 px-3 py-1 rounded-full border border-purple-500/20">
🎧 پادکست و بررسی صوتی بالینی
</span>
</div>
<h4 className="text-lg font-black text-white">
{product.podcastTitle || "پادکست و بررسی صوتی بالینی مکمل"}
</h4>
<p className="text-xs text-white/70 font-medium leading-relaxed">
{product.podcastDescription || "توضیحات صوتی دامپزشک و کادر علمی درباره اثربخشی، مکانیسم اثر و نحوه مصرف دقیق"}
</p>
<div className="pt-2 flex justify-center md:justify-start">
<button
type="button"
onClick={() => setIsPodcastModalOpen(true)}
className="py-2.5 px-6 bg-purple-600 hover:bg-purple-700 text-white rounded-xl font-bold text-xs transition-all flex items-center gap-2 cursor-pointer shadow-md shadow-purple-600/20"
>
<Play className="w-4 h-4 fill-white" />
<span>شنیدن پادکست</span>
</button>
</div>
</div>
</div>
<PodcastInlinePlayer
podcast={{
audioUrl: product.podcastUrl,
title: product.podcastTitle || "پادکست و بررسی صوتی بالینی مکمل",
description: product.podcastDescription || product.description,
cover: product.podcastCover,
productName: product.name,
fallbackCover: product.image,
}}
/>
)}
{/* PDF Catalog Download Row */}
@ -1208,20 +1172,6 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
description: product.videoDescription || product.description,
} : null}
/>
{/* Dedicated Custom Podcast Player Modal */}
<PodcastPlayerModal
isOpen={isPodcastModalOpen}
onClose={() => setIsPodcastModalOpen(false)}
podcast={product.podcastUrl ? {
audioUrl: product.podcastUrl,
title: product.podcastTitle || "پادکست و بررسی صوتی بالینی مکمل",
description: product.podcastDescription || product.description,
cover: product.podcastCover,
productName: product.name,
fallbackCover: product.image,
} : null}
/>
</div>
);
}

View File

@ -39,11 +39,13 @@ const PLAYBACK_RATES = [0.5, 1, 1.25, 1.5, 1.75, 2, 2.5];
export default function VideoModalPlayer({ isOpen, onClose, video }: VideoModalPlayerProps) {
const videoRef = useRef<HTMLVideoElement>(null);
const containerRef = useRef<HTMLDivElement>(null);
const rateMenuRef = useRef<HTMLDivElement>(null);
const controlsTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const [isPlaying, setIsPlaying] = useState(false);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
const [bufferedEnd, setBufferedEnd] = useState(0);
const [volume, setVolume] = useState(1);
const [isMuted, setIsMuted] = useState(false);
const [playbackRate, setPlaybackRate] = useState(1);
@ -54,6 +56,21 @@ export default function VideoModalPlayer({ isOpen, onClose, video }: VideoModalP
const [isExpandedDesc, setIsExpandedDesc] = useState(false);
const [isCopied, setIsCopied] = useState(false);
// Close rate menu when clicking outside
useEffect(() => {
function handleClickOutside(e: MouseEvent) {
if (rateMenuRef.current && !rateMenuRef.current.contains(e.target as Node)) {
setShowRateMenu(false);
}
}
if (showRateMenu) {
document.addEventListener("mousedown", handleClickOutside);
}
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [showRateMenu]);
// Reset states on open/close
useEffect(() => {
if (isOpen) {
@ -61,12 +78,30 @@ export default function VideoModalPlayer({ isOpen, onClose, video }: VideoModalP
setShowControls(true);
setIsExpandedDesc(false);
setShowRateMenu(false);
setBufferedEnd(0);
} else {
setIsPlaying(false);
setCurrentTime(0);
setBufferedEnd(0);
}
}, [isOpen, video]);
// Update buffered track
const updateBuffer = useCallback(() => {
if (videoRef.current && videoRef.current.buffered.length > 0) {
const current = videoRef.current.currentTime;
for (let i = 0; i < videoRef.current.buffered.length; i++) {
if (
videoRef.current.buffered.start(i) <= current &&
videoRef.current.buffered.end(i) >= current
) {
setBufferedEnd(videoRef.current.buffered.end(i));
break;
}
}
}
}, []);
// Handle auto-hide timer for controls
const resetControlsTimer = useCallback(() => {
setShowControls(true);
@ -214,6 +249,7 @@ export default function VideoModalPlayer({ isOpen, onClose, video }: VideoModalP
const isIframe = video.videoUrl?.includes("<iframe");
const progressPercent = duration > 0 ? (currentTime / duration) * 100 : 0;
const bufferedPercent = duration > 0 ? (bufferedEnd / duration) * 100 : 0;
const volumePercent = isMuted ? 0 : volume * 100;
return (
@ -270,11 +306,16 @@ export default function VideoModalPlayer({ isOpen, onClose, video }: VideoModalP
onPlay={() => setIsPlaying(true)}
onPause={() => setIsPlaying(false)}
onTimeUpdate={() => {
if (videoRef.current) setCurrentTime(videoRef.current.currentTime);
if (videoRef.current) {
setCurrentTime(videoRef.current.currentTime);
updateBuffer();
}
}}
onProgress={updateBuffer}
onLoadedMetadata={() => {
if (videoRef.current) setDuration(videoRef.current.duration);
setIsBuffering(false);
updateBuffer();
}}
onWaiting={() => setIsBuffering(true)}
onPlaying={() => setIsBuffering(false)}
@ -372,16 +413,22 @@ export default function VideoModalPlayer({ isOpen, onClose, video }: VideoModalP
</div>
)}
{/* Progress / Seek Bar with filled progress track */}
{/* Progress / Seek Bar with filled progress & buffer tracks */}
<div className="flex items-center gap-3 dir-ltr" dir="ltr">
<span className="text-[11px] font-mono font-bold text-white/70 w-10 text-right">
{formatTime(currentTime)}
</span>
<div className="relative flex-1 flex items-center h-4">
{/* Background Track */}
{/* Background & Buffer & Progress Track */}
<div className="absolute inset-x-0 h-1.5 bg-white/20 rounded-lg overflow-hidden pointer-events-none">
{/* Buffered bar */}
<div
className="h-full bg-canina-blue transition-all"
className="h-full bg-white/35 transition-all duration-300"
style={{ width: `${bufferedPercent}%` }}
/>
{/* Played progress bar */}
<div
className="h-full bg-canina-blue transition-all -mt-1.5"
style={{ width: `${progressPercent}%` }}
/>
</div>
@ -477,8 +524,8 @@ export default function VideoModalPlayer({ isOpen, onClose, video }: VideoModalP
{/* Right Controls (Speed Menu & Fullscreen) */}
<div className="flex items-center gap-2">
{/* Playback Rate Popup Menu */}
<div className="relative">
{/* Playback Rate Popup Menu with click-outside */}
<div className="relative" ref={rateMenuRef}>
<button
type="button"
onClick={() => setShowRateMenu(!showRateMenu)}

View File

@ -1,5 +1,6 @@
import api from './api';
import { PRODUCTS, Product, PetType } from "../data/products";
import { Banner } from "../types";
const CATEGORY_SLUG_TO_NAME: Record<string, string> = {
'joints': 'مفاصل و استخوان',
@ -323,7 +324,7 @@ export class ProductService {
}
}
public async getBanners(): Promise<Record<string, unknown>[]> {
public async getBanners(): Promise<Banner[]> {
try {
const response = await api.get('/banners');
return response.data || [];

View File

@ -1,9 +1,9 @@
{
"0": "AdminService",
"1": "ProductService",
"0": "AdminController",
"1": "productService.ts",
"2": "CmsController",
"3": "app.module.ts",
"4": "reviews.controller.ts",
"4": "CreateReviewDto",
"5": "tickets.controller.ts",
"6": "UserDashboard.tsx",
"7": "MediaSelector.tsx",
@ -18,7 +18,7 @@
"16": "lib/services/api.ts",
"17": "CreateVideoDto",
"18": "src/services/api.ts",
"19": "devDependencies",
"19": "eslint",
"20": "BE-001",
"21": "Roles",
"22": "FE-001",
@ -28,21 +28,21 @@
"26": "TEST-001",
"27": "DEVOPS-001",
"28": "DOC-001",
"29": "wholesale.controller.ts",
"29": "WholesaleApplyDto",
"30": "main.ts",
"31": "admin.module.ts",
"31": "JwtAuthGuard",
"32": "ZibalService",
"33": "راهنمای تست سیستم (Software Testing)",
"34": "CategoriesController",
"35": "B2BService",
"36": "What You Must Do When Invoked",
"37": "toPersian",
"37": "userStore.ts",
"38": "UsersService",
"39": "What You Must Do When Invoked",
"40": "SslController",
"41": "ProductPage.tsx",
"41": "PodcastPlayerModal.tsx",
"42": "IngredientsService",
"43": "admin.service.ts",
"43": "AuthService",
"44": "MediaController",
"45": "Pagination.tsx",
"46": "SmsService",
@ -56,23 +56,23 @@
"54": "compilerOptions",
"55": "Media.tsx",
"56": "compilerOptions",
"57": "PetsController",
"57": "admin.module.ts",
"58": "PaginationDto",
"59": "dependencies",
"60": "compilerOptions",
"61": "HomeClient.tsx",
"62": "BlogsController",
"63": "auth.controller.ts",
"64": "users.service.ts",
"63": "AuthController",
"64": "BannersService",
"65": "Required Review Group Closures",
"66": "Coupons.tsx",
"67": "Operational Rules & Boundaries",
"68": "Operational Rules & Boundaries",
"69": "WikiController",
"70": "auth.module.ts",
"71": "PetsController",
"70": "ApiOperation",
"71": "pets/pets.controller.ts",
"72": "seo.module.ts",
"73": "BlogsService",
"73": "admin.service.ts",
"74": "🏢 AI Software Agency — Master Orchestration Protocol v3",
"75": "Operational Rules & Boundaries",
"76": "Operational Rules & Boundaries",
@ -89,7 +89,7 @@
"87": "20260526145407_init/migration.sql",
"88": "Phase 3.1 — Human Review Preparation and Master Backlog Critique",
"89": "dependencies",
"90": "SafeImage.tsx",
"90": "ProductPage.tsx",
"91": "compilerOptions",
"92": "scripts",
"93": "Deep Audit Summary Report",
@ -101,16 +101,16 @@
"99": "Comprehensive Change Log",
"100": "Operational Rules & Boundaries",
"101": "CreateOrderDto",
"102": "SmsLogQueryDto",
"103": "ZibalCallbackQueryDto",
"104": "ValidateCouponDto",
"102": ".update",
"103": ".handleZibalCallback",
"104": "auth.service.ts",
"105": "1. Summary of Integrity Repairs Performed",
"106": "eslint-config-prettier",
"107": "Operational Rules & Boundaries",
"108": "Operational Rules & Boundaries",
"109": "Operational Rules & Boundaries",
"110": "AppService",
"111": "AdminModule",
"111": "auth.controller.ts",
"112": "@types/react-dom",
"113": "Vazirmatn Changelog",
"114": "Vazirmatn Font فونت وزیرمتن",
@ -118,7 +118,7 @@
"116": "compilerOptions",
"117": "compilerOptions",
"118": "backend/README.md",
"119": "eslint-plugin-prettier",
"119": "devDependencies",
"120": "Repository Map",
"121": "validate_integrity.js",
"122": "admin-panel/package.json",
@ -128,6 +128,7 @@
"126": "Role & Core Objective",
"127": "orchestrate.py",
"128": "backend/package.json",
"129": "PetsService",
"130": "graphify reference: extra exports and benchmark",
"131": "Phase 2 Final Quality Gate Summary Report",
"132": "Task Modifications Log",
@ -139,6 +140,7 @@
"138": "InitiatePaymentDto",
"139": "System Discovery",
"140": "Product Requirement Document (PRD)",
"141": "WikiController",
"142": "globals",
"143": "@nestjs/cli",
"144": "Baseline Command Plan & Reconciled Command History",
@ -171,7 +173,7 @@
"171": "🎨 Frontend & Admin Panel Technical Review (06_dev_frontend)",
"172": "🚀 SEO & Content Strategy Review (12_seo_content)",
"173": "@types/node",
"174": "typescript",
"174": "Body",
"175": "seed-ui-texts.ts",
"176": "seed-wiki.ts",
"177": "update-blog.dto.ts",
@ -209,9 +211,10 @@
"209": "sync_honest_manifest.js",
"210": "sync_manifest.js",
"211": "@types/multer",
"212": "@types/passport-jwt",
"213": "tailwindcss",
"214": "AppModule",
"212": "ProductDto",
"213": "PetsController",
"214": "RedisService",
"215": "WikiService",
"216": "FormField.tsx",
"217": "Input.tsx",
"218": "Textarea.tsx",
@ -235,9 +238,11 @@
"236": "vitest",
"237": "axios",
"238": "tailwindcss",
"239": "RegisterDto",
"240": "ts-loader",
"241": "AdminService",
"242": "@types/bcrypt",
"243": "@types/supertest",
"243": "MetricsController",
"244": "blog.entity.ts",
"245": "home.entity.ts",
"246": "wiki.entity.ts",
@ -282,5 +287,29 @@
"285": "Sahel Font Variable Sample",
"286": "Shabnam Font Sample",
"287": "Production Docker Compose",
"288": "Staging Docker Compose"
"288": "Staging Docker Compose",
"289": "CreateHealthLogDto",
"290": "CreateReminderDto",
"291": "NetworkBanner.tsx",
"292": "bcryptjs",
"293": "helmet",
"294": "js-yaml",
"295": "@nestjs/core",
"296": "@nestjs/jwt",
"297": "@nestjs/swagger",
"298": "@nestjs/throttler",
"299": "passport-jwt",
"300": "@prisma/client",
"301": "swagger-ui-express",
"302": "@eslint/eslintrc",
"303": "@eslint/js",
"304": "jest",
"305": "@nestjs/schematics",
"306": "@nestjs/testing",
"307": "source-map-support",
"308": "ts-jest",
"309": "tsconfig-paths",
"310": "@types/bcryptjs",
"311": "typescript-eslint",
"312": "globals"
}

File diff suppressed because one or more lines are too long

View File

@ -3,17 +3,17 @@
"1": "ProductService",
"2": "CmsController",
"3": "app.module.ts",
"4": "CreateReviewDto",
"4": "reviews.controller.ts",
"5": "tickets.controller.ts",
"6": "UserDashboard.tsx",
"7": "Spinner.tsx",
"8": "admin.module.ts",
"9": "useCartStore",
"7": "MediaSelector.tsx",
"8": "ReportsController",
"9": "PetProfile.tsx",
"10": "DoctorsService",
"11": "useSettingsStore",
"12": "adminRoutes.tsx",
"13": "PrismaService",
"14": "PaginationDto",
"14": "BlogsController",
"15": "ProductsService",
"16": "lib/services/api.ts",
"17": "CreateVideoDto",
@ -30,23 +30,23 @@
"28": "DOC-001",
"29": "wholesale.controller.ts",
"30": "main.ts",
"31": "JwtAuthGuard",
"31": "admin.module.ts",
"32": "ZibalService",
"33": "راهنمای تست سیستم (Software Testing)",
"34": "CategoriesController",
"35": "B2BService",
"36": "What You Must Do When Invoked",
"37": "BannersService",
"37": "toPersian",
"38": "UsersService",
"39": "What You Must Do When Invoked",
"40": "SslController",
"41": "toPersian",
"41": "ProductPage.tsx",
"42": "IngredientsService",
"43": "AuthService",
"43": "admin.service.ts",
"44": "MediaController",
"45": "ConfirmModal.tsx",
"46": "auth.controller.ts",
"47": "SmsService",
"45": "Pagination.tsx",
"46": "SmsService",
"47": "OrdersController",
"48": "PrescriptionsService",
"49": "SmartAdvisorService",
"50": "TestimonialsService",
@ -57,19 +57,19 @@
"55": "Media.tsx",
"56": "compilerOptions",
"57": "PetsController",
"58": "WikiController",
"58": "PaginationDto",
"59": "dependencies",
"60": "compilerOptions",
"61": "HomeClient.tsx",
"62": "BlogsController",
"63": "AuthController",
"64": "PetsService",
"63": "auth.controller.ts",
"64": "users.service.ts",
"65": "Required Review Group Closures",
"66": "Coupons.tsx",
"67": "Operational Rules & Boundaries",
"68": "Operational Rules & Boundaries",
"69": "WikiController",
"70": "pets/pets.controller.ts",
"70": "auth.module.ts",
"71": "PetsController",
"72": "seo.module.ts",
"73": "BlogsService",
@ -89,7 +89,7 @@
"87": "20260526145407_init/migration.sql",
"88": "Phase 3.1 — Human Review Preparation and Master Backlog Critique",
"89": "dependencies",
"90": "VetGallery.tsx",
"90": "SafeImage.tsx",
"91": "compilerOptions",
"92": "scripts",
"93": "Deep Audit Summary Report",
@ -97,21 +97,21 @@
"95": "Operational Rules & Boundaries",
"96": "exclude",
"97": "jest",
"98": "WikiService",
"98": "OrdersService",
"99": "Comprehensive Change Log",
"100": "Operational Rules & Boundaries",
"101": ".findAll",
"101": "CreateOrderDto",
"102": "SmsLogQueryDto",
"103": "ZibalCallbackQueryDto",
"104": "VerifyOtpDto",
"104": "ValidateCouponDto",
"105": "1. Summary of Integrity Repairs Performed",
"106": "CreateHealthLogDto",
"106": "eslint-config-prettier",
"107": "Operational Rules & Boundaries",
"108": "Operational Rules & Boundaries",
"109": "Operational Rules & Boundaries",
"110": "AppService",
"111": "CreateReminderDto",
"112": "@eslint/eslintrc",
"111": "AdminModule",
"112": "@types/react-dom",
"113": "Vazirmatn Changelog",
"114": "Vazirmatn Font فونت وزیرمتن",
"115": "Operational Rules & Boundaries",
@ -128,7 +128,6 @@
"126": "Role & Core Objective",
"127": "orchestrate.py",
"128": "backend/package.json",
"129": "RegisterDto",
"130": "graphify reference: extra exports and benchmark",
"131": "Phase 2 Final Quality Gate Summary Report",
"132": "Task Modifications Log",
@ -136,15 +135,14 @@
"134": "ErrorBoundary",
"135": "application/package.json",
"136": "generate-openapi.js",
"137": "payment.service.ts",
"137": "AdminTransactionFilterDto",
"138": "InitiatePaymentDto",
"139": "System Discovery",
"140": "Product Requirement Document (PRD)",
"141": "AdminLoginDto",
"142": "globals",
"143": "@nestjs/cli",
"144": "Baseline Command Plan & Reconciled Command History",
"145": "SmsSettingsPage.tsx",
"145": "Spinner.tsx",
"146": "ErrorPages.tsx",
"147": "with-vpn.sh",
"148": "Architecture Specification",
@ -213,8 +211,7 @@
"211": "@types/multer",
"212": "@types/passport-jwt",
"213": "tailwindcss",
"214": "MetricsController",
"215": "eslint-config-next",
"214": "AppModule",
"216": "FormField.tsx",
"217": "Input.tsx",
"218": "Textarea.tsx",

View File

@ -1,16 +1,16 @@
# Graph Report - canina (2026-08-18)
## Corpus Check
- 509 files · ~727,919 words
- 510 files · ~733,001 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 3621 nodes · 6148 edges · 287 communities (191 shown, 96 thin omitted)
- 3627 nodes · 6157 edges · 284 communities (186 shown, 98 thin omitted)
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 225 edges (avg confidence: 0.79)
- Token cost: 0 input · 0 output
## Graph Freshness
- Built from commit: `d5c05b75`
- Built from commit: `f0f50c75`
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
- Run `graphify update .` after code changes (no API cost).
@ -19,17 +19,17 @@
- ProductService
- CmsController
- app.module.ts
- CreateReviewDto
- reviews.controller.ts
- tickets.controller.ts
- UserDashboard.tsx
- Spinner.tsx
- admin.module.ts
- useCartStore
- MediaSelector.tsx
- ReportsController
- PetProfile.tsx
- DoctorsService
- useSettingsStore
- adminRoutes.tsx
- PrismaService
- PaginationDto
- BlogsController
- ProductsService
- lib/services/api.ts
- CreateVideoDto
@ -46,23 +46,23 @@
- DOC-001
- wholesale.controller.ts
- main.ts
- JwtAuthGuard
- admin.module.ts
- ZibalService
- راهنمای تست سیستم (Software Testing)
- CategoriesController
- B2BService
- What You Must Do When Invoked
- BannersService
- toPersian
- UsersService
- What You Must Do When Invoked
- SslController
- toPersian
- ProductPage.tsx
- IngredientsService
- AuthService
- admin.service.ts
- MediaController
- ConfirmModal.tsx
- auth.controller.ts
- Pagination.tsx
- SmsService
- OrdersController
- PrescriptionsService
- SmartAdvisorService
- TestimonialsService
@ -73,19 +73,19 @@
- Media.tsx
- compilerOptions
- PetsController
- WikiController
- PaginationDto
- dependencies
- compilerOptions
- HomeClient.tsx
- BlogsController
- AuthController
- PetsService
- auth.controller.ts
- users.service.ts
- Required Review Group Closures
- Coupons.tsx
- Operational Rules & Boundaries
- Operational Rules & Boundaries
- WikiController
- pets/pets.controller.ts
- auth.module.ts
- PetsController
- seo.module.ts
- BlogsService
@ -105,7 +105,7 @@
- 20260526145407_init/migration.sql
- Phase 3.1 — Human Review Preparation and Master Backlog Critique
- dependencies
- VetGallery.tsx
- SafeImage.tsx
- compilerOptions
- scripts
- Deep Audit Summary Report
@ -113,21 +113,21 @@
- Operational Rules & Boundaries
- exclude
- jest
- WikiService
- OrdersService
- Comprehensive Change Log
- Operational Rules & Boundaries
- .findAll
- CreateOrderDto
- SmsLogQueryDto
- ZibalCallbackQueryDto
- VerifyOtpDto
- ValidateCouponDto
- 1. Summary of Integrity Repairs Performed
- CreateHealthLogDto
- eslint-config-prettier
- Operational Rules & Boundaries
- Operational Rules & Boundaries
- Operational Rules & Boundaries
- AppService
- CreateReminderDto
- @eslint/eslintrc
- AdminModule
- @types/react-dom
- Vazirmatn Changelog
- Vazirmatn Font فونت وزیرمتن
- Operational Rules & Boundaries
@ -144,7 +144,6 @@
- Role & Core Objective
- orchestrate.py
- backend/package.json
- RegisterDto
- graphify reference: extra exports and benchmark
- Phase 2 Final Quality Gate Summary Report
- Task Modifications Log
@ -152,15 +151,14 @@
- ErrorBoundary
- application/package.json
- generate-openapi.js
- payment.service.ts
- AdminTransactionFilterDto
- InitiatePaymentDto
- System Discovery
- Product Requirement Document (PRD)
- AdminLoginDto
- globals
- @nestjs/cli
- Baseline Command Plan & Reconciled Command History
- SmsSettingsPage.tsx
- Spinner.tsx
- ErrorPages.tsx
- with-vpn.sh
- Architecture Specification
@ -229,8 +227,7 @@
- @types/multer
- @types/passport-jwt
- tailwindcss
- MetricsController
- eslint-config-next
- AppModule
- FormField.tsx
- Input.tsx
- Textarea.tsx
@ -321,95 +318,95 @@
- **Rastikerdar Font Ecosystem** — frontend_application_public_fonts_shabnam_font_v5_0_1_readme, frontend_application_public_fonts_vazirmatn_v33_003_readme, vazir_font [EXTRACTED 0.95]
- **Canina Deployment Stack** — scripts_compose_prod, scripts_compose_stage [EXTRACTED 1.00]
## Communities (287 total, 96 thin omitted)
## Communities (284 total, 98 thin omitted)
### Community 0 - "AdminService"
Cohesion: 0.05
Nodes (38): AdminController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+30 more)
### Community 1 - "ProductService"
Cohesion: 0.05
Nodes (41): Blog(), getBlogs(), metadata, CatalogClient(), metadata, metadata, metadata, BlogPage() (+33 more)
Cohesion: 0.06
Nodes (33): Blog(), getBlogs(), metadata, CatalogClient(), metadata, metadata, BlogPage(), BlogPost (+25 more)
### Community 2 - "CmsController"
Cohesion: 0.09
Nodes (24): CmsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+16 more)
### Community 3 - "app.module.ts"
Cohesion: 0.07
Nodes (33): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+25 more)
Cohesion: 0.08
Nodes (30): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+22 more)
### Community 4 - "CreateReviewDto"
### Community 4 - "reviews.controller.ts"
Cohesion: 0.07
Nodes (29): CreateReviewDto, ApiProperty, IsInt, IsNotEmpty, IsOptional, IsString, Min, ApiProperty (+21 more)
Nodes (31): CreateReviewDto, ApiProperty, IsInt, IsNotEmpty, IsOptional, IsString, Min, ApiProperty (+23 more)
### Community 5 - "tickets.controller.ts"
Cohesion: 0.09
Nodes (29): AdminUpdateTicketDto, CreateTicketDto, ReplyTicketDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString (+21 more)
### Community 6 - "UserDashboard.tsx"
Cohesion: 0.12
Nodes (18): AddressModal(), AddressModalProps, BackButton(), BackButtonProps, DeleteConfirmModal(), DeleteConfirmModalProps, OrderDetailsModal(), SearchableSelect() (+10 more)
Cohesion: 0.11
Nodes (22): AddressModal(), AddressModalProps, BackButton(), BackButtonProps, CheckoutPage(), DeleteConfirmModal(), DeleteConfirmModalProps, HeaderButton() (+14 more)
### Community 7 - "Spinner.tsx"
Cohesion: 0.09
Nodes (24): getFileType(), Media, MediaSelector(), MediaSelectorProps, Spinner(), BlogPost, Category, Doctor (+16 more)
### Community 8 - "admin.module.ts"
### Community 7 - "MediaSelector.tsx"
Cohesion: 0.08
Nodes (18): AdminModule, Module, PetQuery, PetsService, Injectable, ReportsController, ApiBearerAuth, ApiOperation (+10 more)
Nodes (25): ConfirmModal(), ConfirmModalProps, getFileType(), Media, MediaSelector(), MediaSelectorProps, BlogPost, Category (+17 more)
### Community 9 - "useCartStore"
Cohesion: 0.09
Nodes (28): VerifyContent(), ArchiveProductCard(), B2BPortal(), CheckoutPage(), FeaturedProducts(), ProductCard(), Header(), MENU_ICONS (+20 more)
### Community 8 - "ReportsController"
Cohesion: 0.17
Nodes (9): ReportsController, ApiBearerAuth, ApiOperation, ApiTags, Controller, Get, UseGuards, ReportsService (+1 more)
### Community 9 - "PetProfile.tsx"
Cohesion: 0.08
Nodes (25): metadata, FeaturedProducts(), ProductCard(), OrderSuccess(), PrescriptionUploadModal(), PrescriptionUploadModalProps, SearchResultsPage(), OrderRowSkeleton() (+17 more)
### Community 10 - "DoctorsService"
Cohesion: 0.13
Nodes (15): DoctorsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+7 more)
Cohesion: 0.12
Nodes (16): DoctorsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+8 more)
### Community 11 - "useSettingsStore"
Cohesion: 0.10
Nodes (24): ClientLayout(), metadata, AuthModal(), AuthModalProps, extractOtpFromText(), BrandLogo(), BrandLogoProps, EnamadBadge() (+16 more)
Cohesion: 0.12
Nodes (18): ClientLayout(), metadata, BrandLogo(), BrandLogoProps, EnamadBadge(), Footer(), Header(), MENU_ICONS (+10 more)
### Community 12 - "adminRoutes.tsx"
Cohesion: 0.09
Nodes (15): App(), ContactInfoItem, ContactSubmission, CategoryDist, DashboardData, SslStatus, Ticket, TicketMessage (+7 more)
Cohesion: 0.10
Nodes (14): App(), ContactInfoItem, ContactSubmission, CategoryDist, DashboardData, Ticket, TicketMessage, WholesaleRequest (+6 more)
### Community 13 - "PrismaService"
Cohesion: 0.07
Nodes (20): CouponTargetInput, PaginationQuery, AdminLoginInput, LoginInput, RegisterInput, MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions (+12 more)
Cohesion: 0.10
Nodes (13): WikiQuery, MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions, SmsConfig, SmsLogQuery, CreateContactSubmissionDto, UpdateContactInfoItemDto (+5 more)
### Community 14 - "PaginationDto"
Cohesion: 0.11
Nodes (15): BlogsController, ApiTags, Controller, BlogsModule, Module, BlogsService, Injectable, PaginationDto (+7 more)
### Community 14 - "BlogsController"
Cohesion: 0.13
Nodes (13): BlogsController, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags, Controller, Get, Param (+5 more)
### Community 15 - "ProductsService"
Cohesion: 0.09
Nodes (19): GetProductsDto, ApiPropertyOptional, IsEnum, IsOptional, IsString, ProductsController, ApiOperation, ApiTags (+11 more)
### Community 16 - "lib/services/api.ts"
Cohesion: 0.05
Nodes (25): metadata, ContactFormClient(), ContactInfoItem, LoginModalProps, OrderDetailsModalProps, Testimonial, PRESET_AMOUNTS, TopUpModalProps (+17 more)
Cohesion: 0.06
Nodes (18): metadata, ContactFormClient(), ContactInfoItem, OrderDetailsModal(), OrderDetailsModalProps, Testimonial, api, ApiErrorPayload (+10 more)
### Community 17 - "CreateVideoDto"
Cohesion: 0.07
Nodes (31): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, UpdateVideoDto (+23 more)
### Community 18 - "src/services/api.ts"
Cohesion: 0.13
Nodes (19): ProtectedRoute(), Login(), B2BManager, SmartAdvisorManager, ApiErrorPayload, failedQueue, useAdminAuthStore, AdminLoginPayload (+11 more)
Cohesion: 0.10
Nodes (23): ProtectedRoute(), SEARCHABLE_PAGES, Topbar(), TopbarProps, Login(), B2BManager, SmartAdvisorManager, SystemSettingsPage (+15 more)
### Community 19 - "devDependencies"
Cohesion: 0.09
Nodes (23): devDependencies, eslint, eslint-config-prettier, @eslint/js, jest, @nestjs/schematics, @nestjs/testing, source-map-support (+15 more)
Nodes (23): devDependencies, eslint, @eslint/eslintrc, @eslint/js, jest, @nestjs/schematics, @nestjs/testing, source-map-support (+15 more)
### Community 20 - "BE-001"
Cohesion: 0.06
Nodes (32): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, BE-001, Category, Completion Statement, Confidence (+24 more)
### Community 21 - "Roles"
Cohesion: 0.09
Nodes (18): Roles(), SettingsController, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+10 more)
Cohesion: 0.06
Nodes (33): BannersController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+25 more)
### Community 22 - "FE-001"
Cohesion: 0.06
@ -444,12 +441,12 @@ Cohesion: 0.10
Nodes (22): ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, WholesaleApplyDto, ApiBearerAuth, ApiOperation (+14 more)
### Community 30 - "main.ts"
Cohesion: 0.11
Nodes (11): AppModule, Module, CustomHttpExceptionFilter, Catch, PrismaExceptionFilter, Catch, DecimalInterceptor, Injectable (+3 more)
Cohesion: 0.14
Nodes (9): CustomHttpExceptionFilter, Catch, PrismaExceptionFilter, Catch, DecimalInterceptor, Injectable, ApiErrorResponse, ErrorDetailField (+1 more)
### Community 31 - "JwtAuthGuard"
Cohesion: 0.16
Nodes (8): JwtAuthGuard, Injectable, ROLES_KEY, SortOrder, RequestWithUser, RolesGuard, Injectable, UserReqPayload
### Community 31 - "admin.module.ts"
Cohesion: 0.12
Nodes (12): BlogQuery, CategoryQuery, PetQuery, SslCertInfo, JwtAuthGuard, Injectable, ROLES_KEY, RequestWithUser (+4 more)
### Community 32 - "ZibalService"
Cohesion: 0.14
@ -460,8 +457,8 @@ Cohesion: 0.07
Nodes (25): اجرای بک‌اند, اجرای فرانت‌اند, اجرای پروژه در سرور با PM2, برای راه‌اندازی بک‌اند:, برای راه‌اندازی فرانت‌اند Next.js:, بیلد کردن پروژه (Building), ذخیره پروسه‌ها تا پس از ری‌استارت سرور قطع نشوند:, راه‌اندازی و انتشار سیستم (Setup & Deployment) (+17 more)
### Community 34 - "CategoriesController"
Cohesion: 0.09
Nodes (17): CategoriesController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+9 more)
Cohesion: 0.10
Nodes (16): CategoriesController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+8 more)
### Community 35 - "B2BService"
Cohesion: 0.13
@ -471,13 +468,13 @@ Nodes (15): B2BController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controlle
Cohesion: 0.07
Nodes (26): For /graphify add and --watch, For /graphify query, For the commit hook and native CLAUDE.md integration, For --update and --cluster-only, /graphify, Honesty Rules, Interpreter guard for subcommands, Part A - Structural extraction for code files (+18 more)
### Community 37 - "BannersService"
### Community 37 - "toPersian"
Cohesion: 0.13
Nodes (15): BannersController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+7 more)
Nodes (23): VerifyContent(), ArchiveProductCard(), AuthModal(), AuthModalProps, extractOtpFromText(), B2BPortal(), CartDrawer(), LoginModal() (+15 more)
### Community 38 - "UsersService"
Cohesion: 0.06
Nodes (42): DEFAULT_JWT_REFRESH_SECRET, DEFAULT_JWT_SECRET, getJwtSecret(), AuthModule, Module, JwtPayload, JwtStrategy, Injectable (+34 more)
Cohesion: 0.12
Nodes (18): ApiBadRequestResponse, ApiBearerAuth, ApiCreatedResponse, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+10 more)
### Community 39 - "What You Must Do When Invoked"
Cohesion: 0.07
@ -487,33 +484,29 @@ Nodes (26): For /graphify add and --watch, For /graphify query, For the commit h
Cohesion: 0.13
Nodes (14): SslController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get, Post (+6 more)
### Community 41 - "toPersian"
Cohesion: 0.13
Nodes (15): HeaderButton(), HeaderButtonProps, LoginModal(), CalculatorState, ICON_MAP, ProductPage(), useCalculatorStore, ProductReviews() (+7 more)
### Community 41 - "ProductPage.tsx"
Cohesion: 0.12
Nodes (14): PLAYBACK_RATES, PodcastPlayerModal(), PodcastPlayerModalProps, CalculatorState, ICON_MAP, ProductPage(), useCalculatorStore, ProductReviews() (+6 more)
### Community 42 - "IngredientsService"
Cohesion: 0.13
Nodes (14): IngredientsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
### Community 43 - "AuthService"
Cohesion: 0.18
Nodes (3): AuthService, Injectable, normalizeMobile()
### Community 43 - "admin.service.ts"
Cohesion: 0.09
Nodes (14): CouponTargetInput, PaginationQuery, AdminLoginInput, AuthService, LoginInput, RegisterInput, Injectable, normalizeMobile() (+6 more)
### Community 44 - "MediaController"
Cohesion: 0.11
Nodes (16): MediaController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+8 more)
### Community 45 - "ConfirmModal.tsx"
Cohesion: 0.11
Nodes (13): ConfirmModal(), ConfirmModalProps, HeroBanner, VetTestimonial, DoctorOption, Video, WholesaleRequest, ProductItem (+5 more)
### Community 45 - "Pagination.tsx"
Cohesion: 0.13
Nodes (11): Pagination(), PaginationProps, Pet, GatewayHealth, Stats, Transaction, ProductItem, WikiTerm (+3 more)
### Community 46 - "auth.controller.ts"
Cohesion: 0.18
Nodes (10): LoginDto, ApiProperty, IsNotEmpty, IsString, MinLength, SendOtpDto, ApiProperty, IsNotEmpty (+2 more)
### Community 47 - "SmsService"
Cohesion: 0.05
Nodes (37): SmsService, Injectable, CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty (+29 more)
### Community 47 - "OrdersController"
Cohesion: 0.14
Nodes (16): OrdersController, ApiBadRequestResponse, ApiBearerAuth, ApiCreatedResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags (+8 more)
### Community 48 - "PrescriptionsService"
Cohesion: 0.14
@ -552,12 +545,12 @@ Cohesion: 0.09
Nodes (22): compilerOptions, allowImportingTsExtensions, erasableSyntaxOnly, jsx, lib, module, moduleDetection, moduleResolution (+14 more)
### Community 57 - "PetsController"
Cohesion: 0.15
Nodes (11): PetsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Controller, Delete, Get (+3 more)
Cohesion: 0.11
Nodes (13): PetsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Controller, Delete, Get (+5 more)
### Community 58 - "WikiController"
Cohesion: 0.13
Nodes (13): ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags, Controller, Get, Param, Query (+5 more)
### Community 58 - "PaginationDto"
Cohesion: 0.09
Nodes (22): PaginationDto, SortOrder, ApiPropertyOptional, IsEnum, IsInt, IsOptional, IsString, Min (+14 more)
### Community 59 - "dependencies"
Cohesion: 0.05
@ -568,24 +561,28 @@ Cohesion: 0.10
Nodes (20): compilerOptions, allowImportingTsExtensions, erasableSyntaxOnly, lib, module, moduleDetection, moduleResolution, noEmit (+12 more)
### Community 61 - "HomeClient.tsx"
Cohesion: 0.10
Nodes (23): HomeClient(), HomeClientProps, getHomeData(), Home(), metadata, metadata, ArchivePage(), CATEGORY_MAP (+15 more)
Cohesion: 0.11
Nodes (21): HomeClient(), HomeClientProps, getHomeData(), Home(), metadata, metadata, ArchivePage(), CATEGORY_MAP (+13 more)
### Community 62 - "BlogsController"
Cohesion: 0.13
Nodes (15): BlogsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+7 more)
### Community 63 - "AuthController"
Cohesion: 0.27
Nodes (12): AuthController, ApiBadRequestResponse, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+4 more)
### Community 63 - "auth.controller.ts"
Cohesion: 0.06
Nodes (42): AuthController, ApiBadRequestResponse, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+34 more)
### Community 64 - "users.service.ts"
Cohesion: 0.13
Nodes (14): AddressDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, ApiPropertyOptional (+6 more)
### Community 65 - "Required Review Group Closures"
Cohesion: 0.10
Nodes (19): 10. Orders Backend, 11. Settings & Administrative Backend, 12. Prisma Schema, Migrations & Seed, 13. Redis & Temporary Auth State, 14. Unit & E2E Tests, 15. Docker, NGINX, Prometheus & Deployment Config, 16. Documentation & OpenAPI Artifacts, 1. Storefront Shell & Routing (+11 more)
### Community 66 - "Coupons.tsx"
Cohesion: 0.10
Nodes (15): formatPriceWithCommas(), PriceInput(), PriceInputProps, toEnglishDigits(), Coupon, CouponFormData, CouponModalProps, CouponTarget (+7 more)
Cohesion: 0.12
Nodes (14): formatPriceWithCommas(), PriceInput(), PriceInputProps, toEnglishDigits(), Coupon, CouponFormData, CouponModalProps, CouponTarget (+6 more)
### Community 67 - "Operational Rules & Boundaries"
Cohesion: 0.11
@ -596,25 +593,21 @@ Cohesion: 0.11
Nodes (18): 1. Framework-Aware Analysis, 2. DOM & Semantic Structure Analysis, 3. Accessibility Compliance, 4. Responsive Layout Verification, 5. Fallback Inspection Mode, 6. Defect Routing Protocol, 7. Forbidden Actions, Expected JSON Output Schema (+10 more)
### Community 69 - "WikiController"
Cohesion: 0.13
Nodes (14): ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete, Get (+6 more)
Cohesion: 0.09
Nodes (16): ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete, Get (+8 more)
### Community 70 - "pets/pets.controller.ts"
Cohesion: 0.16
Nodes (13): CreatePetDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional, IsString (+5 more)
### Community 70 - "auth.module.ts"
Cohesion: 0.17
Nodes (10): DEFAULT_JWT_REFRESH_SECRET, DEFAULT_JWT_SECRET, getJwtSecret(), AuthModule, Module, JwtPayload, JwtStrategy, Injectable (+2 more)
### Community 71 - "PetsController"
Cohesion: 0.14
Nodes (20): PetsController, ApiBadRequestResponse, ApiBearerAuth, ApiCreatedResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags (+12 more)
Cohesion: 0.05
Nodes (47): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, CreatePetDto, ApiProperty (+39 more)
### Community 72 - "seo.module.ts"
Cohesion: 0.16
Nodes (10): SeoController, ApiOperation, ApiTags, Controller, Get, Param, SeoModule, Module (+2 more)
### Community 73 - "BlogsService"
Cohesion: 0.22
Nodes (3): BlogQuery, BlogsService, Injectable
### Community 74 - "🏢 AI Software Agency — Master Orchestration Protocol v3"
Cohesion: 0.11
Nodes (17): Activation, Agent Directory Reference, 🏢 AI Software Agency — Master Orchestration Protocol v3, Phase 1: Specialist Review (All agents read, none write code yet), Phase 2: Master Synthesis (02_product_manager in SYNTHESIS mode), Phase 3: Execution (Same as always), PIPELINE A — New Project (GREENFIELD), PIPELINE B — Review & Improve Existing Project (REVIEW_AND_PLAN) ★ (+9 more)
@ -645,15 +638,15 @@ Nodes (9): GatewayHealthResult, IPaymentGateway, PaymentInquiryResult, PaymentRe
### Community 81 - "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 82 - "api"
Cohesion: 0.21
Nodes (9): Layout(), MenuGroup, Sidebar(), SidebarProps, SubMenuItem, SEARCHABLE_PAGES, Topbar(), TopbarProps (+1 more)
Cohesion: 0.29
Nodes (6): Layout(), MenuGroup, Sidebar(), SidebarProps, SubMenuItem, api
### Community 83 - "Orders.tsx"
Cohesion: 0.09
Nodes (21): Pagination(), PaginationProps, Skeleton(), getPaymentMethodLabel(), Order, OrderItem, Orders(), PaymentTx (+13 more)
Cohesion: 0.14
Nodes (13): Skeleton(), getPaymentMethodLabel(), Order, ORDER_STATUS_MAP, OrderItem, Orders(), PaymentTx, toPersianDigits() (+5 more)
### Community 84 - "devDependencies"
Cohesion: 0.11
@ -679,9 +672,9 @@ Nodes (14): 10. Dependency & Wave Adjustments, 11. Acceptance Criteria Refinemen
Cohesion: 0.10
Nodes (21): dependencies, axios, lucide-react, react, react-dom, react-hot-toast, react-router-dom, recharts (+13 more)
### Community 90 - "VetGallery.tsx"
Cohesion: 0.19
Nodes (10): DisplayVideoItem, FALLBACK_VIDEOS, TestimonialItem, VetGallery(), PLAYBACK_RATES, VideoModalPlayer(), VideoModalPlayerProps, VideosPage() (+2 more)
### Community 90 - "SafeImage.tsx"
Cohesion: 0.14
Nodes (13): ProductDetailModalProps, SafeImage(), SafeImageProps, DisplayVideoItem, FALLBACK_VIDEOS, TestimonialItem, VetGallery(), PLAYBACK_RATES (+5 more)
### Community 91 - "compilerOptions"
Cohesion: 0.06
@ -711,9 +704,9 @@ Nodes (8): exclude, extends, dist, node_modules, prisma, **/*spec.ts, test, ./ts
Cohesion: 0.15
Nodes (13): jest, collectCoverageFrom, coverageDirectory, moduleFileExtensions, rootDir, testEnvironment, testRegex, transform (+5 more)
### Community 98 - "WikiService"
Cohesion: 0.22
Nodes (3): Injectable, WikiQuery, WikiService
### Community 98 - "OrdersService"
Cohesion: 0.20
Nodes (4): OrdersModule, Module, OrdersService, Injectable
### Community 99 - "Comprehensive Change Log"
Cohesion: 0.15
@ -723,9 +716,9 @@ Nodes (12): 10. `TASK-VERIFY-001`, 1. `TASK-SEC-001`, 2. `TASK-SEC-002`, 3. `TAS
Cohesion: 0.17
Nodes (11): 1. Detect Test Runner from Tech Stack, 2. Execution Output Capture (Mandatory), 3. Acceptance Criteria Verification, 4. Failure Routing Protocol, 5. Success Routing Protocol, 6. Forbidden Actions, Expected JSON Output Schema, Operational Rules & Boundaries (+3 more)
### Community 101 - ".findAll"
Cohesion: 0.32
Nodes (6): ApiNotFoundResponse, ApiOkResponse, ApiOperation, Get, Param, Query
### Community 101 - "CreateOrderDto"
Cohesion: 0.22
Nodes (11): CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional (+3 more)
### Community 102 - "SmsLogQueryDto"
Cohesion: 0.25
@ -735,18 +728,14 @@ Nodes (7): SmsLogQueryDto, ApiPropertyOptional, IsIn, IsNumber, IsOptional, IsSt
Cohesion: 0.40
Nodes (4): ApiPropertyOptional, IsOptional, IsString, ZibalCallbackQueryDto
### Community 104 - "VerifyOtpDto"
Cohesion: 0.29
Nodes (6): ApiProperty, IsNotEmpty, IsString, Matches, VerifyOtpDto, Length
### Community 104 - "ValidateCouponDto"
Cohesion: 0.50
Nodes (4): IsNotEmpty, IsNumber, IsString, ValidateCouponDto
### Community 105 - "1. Summary of Integrity Repairs Performed"
Cohesion: 0.17
Nodes (11): 1.1 Authoritative Source File Inventory Rebuilt, 1.2 Raw Finding Dispositions Reconciled, 1.3 Finding Identifier Normalization, 1.4 Rejected Finding Cleanup, 1. Summary of Integrity Repairs Performed, 2. Final Verified Finding Metrics, 3. Reference and Compiler Integrity Results, 4. Quality Gate Conclusion (+3 more)
### Community 106 - "CreateHealthLogDto"
Cohesion: 0.29
Nodes (6): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString
### Community 107 - "Operational Rules & Boundaries"
Cohesion: 0.18
Nodes (10): 1. Detect Tech Stack First (Universal), 2. Explicit Scoring Methodology (Universal), 3. Code Coverage Ratio Rule, 4. Deep Directory Scanning, 5. Forbidden Actions, Expected JSON Output Schema, Operational Rules & Boundaries, Required Output Artifacts (What files to write/update) (+2 more)
@ -763,10 +752,6 @@ Nodes (10): 1. Pre-Deployment Checklist, 2. Build Verification, 3. Deployment St
Cohesion: 0.29
Nodes (5): AppController, Controller, Get, AppService, Injectable
### Community 111 - "CreateReminderDto"
Cohesion: 0.29
Nodes (6): CreateReminderDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString
### Community 113 - "Vazirmatn Changelog"
Cohesion: 0.18
Nodes (10): 32.0.0, 32.1, 32.101, 32.102, 33.000, 33.001, 33.002, 33.003 (+2 more)
@ -827,10 +812,6 @@ Nodes (8): cmd_next_task(), cmd_progress(), cmd_reset(), cmd_status(), cmd_unblo
Cohesion: 0.22
Nodes (8): author, description, license, name, prisma, seed, private, version
### Community 129 - "RegisterDto"
Cohesion: 0.22
Nodes (8): RegisterDto, ApiProperty, ApiPropertyOptional, IsEmail, IsNotEmpty, IsOptional, IsString, MinLength
### Community 130 - "graphify reference: extra exports and benchmark"
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)
@ -859,9 +840,9 @@ Nodes (8): name, private, scripts, build, dev, lint, start, version
Cohesion: 0.25
Nodes (6): app_module_1, core_1, fs, path, swagger_1, yaml
### Community 137 - "payment.service.ts"
Cohesion: 0.20
Nodes (8): AdminTransactionFilterDto, ApiPropertyOptional, IsIn, IsNumber, IsOptional, IsString, Type, ClientMetadata
### Community 137 - "AdminTransactionFilterDto"
Cohesion: 0.22
Nodes (7): AdminTransactionFilterDto, ApiPropertyOptional, IsIn, IsNumber, IsOptional, IsString, Type
### Community 138 - "InitiatePaymentDto"
Cohesion: 0.43
@ -875,17 +856,13 @@ Nodes (7): Active Core Applications, Current Architecture, Evidence-Based Status
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 141 - "AdminLoginDto"
Cohesion: 0.29
Nodes (6): AdminLoginDto, ApiProperty, IsEmail, IsNotEmpty, IsString, MinLength
### Community 144 - "Baseline Command Plan & Reconciled Command History"
Cohesion: 0.29
Nodes (6): Attempted Command Execution Log, Backend `backend/package.json` Scripts, Baseline Command Plan & Reconciled Command History, Package Scripts Safety Analysis, Permitted Safe Checks for Phase 2, Root `package.json` Scripts
### Community 145 - "SmsSettingsPage.tsx"
Cohesion: 0.29
Nodes (5): PatternItem, SmsConfigState, SmsLogItem, SmsLogStats, SmsSettingsPage
### Community 145 - "Spinner.tsx"
Cohesion: 0.10
Nodes (15): Spinner(), ProductReview, Reviews(), toPersianDigits(), PatternItem, SmsConfigState, SmsLogItem, SmsLogStats (+7 more)
### Community 147 - "with-vpn.sh"
Cohesion: 0.62
@ -1019,33 +996,33 @@ Nodes (3): COMPOSE_DOCKER_CLI_BUILD, DOCKER_BUILDKIT, deploy.sh script
Cohesion: 0.67
Nodes (3): ADR-AUTH-001: Admin Panel Authentication Architecture & Token Management, Master Task Backlog (Phase 3.3), Phase 3 Master Execution Plan
### Community 214 - "MetricsController"
Cohesion: 0.18
Nodes (5): ApiExcludeController, MetricsController, Controller, Get, Res
### Community 214 - "AppModule"
Cohesion: 0.12
Nodes (7): ApiExcludeController, AppModule, Module, MetricsController, Controller, Get, Res
### Community 223 - "Shabnam Font README"
Cohesion: 0.67
Nodes (3): Shabnam Font README, Shabnam Font Sample, Vazir Font
## Knowledge Gaps
- **1235 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1230 more)
- **1237 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1232 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **96 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
- **98 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 `Roles()` connect `Roles` to `CmsController`, `B2BService`, `CreateReviewDto`, `BannersService`, `tickets.controller.ts`, `SslController`, `IngredientsService`, `ProductsService`, `PrescriptionsService`, `SmartAdvisorService`, `TestimonialsService`, `ContactService`, `PaymentController`, `wholesale.controller.ts`, `JwtAuthGuard`?**
- **Why does `Roles()` connect `Roles` to `CmsController`, `B2BService`, `reviews.controller.ts`, `tickets.controller.ts`, `SslController`, `IngredientsService`, `ProductsService`, `PrescriptionsService`, `SmartAdvisorService`, `TestimonialsService`, `ContactService`, `PaymentController`, `wholesale.controller.ts`, `admin.module.ts`?**
_High betweenness centrality (0.048) - this node is a cross-community bridge._
- **Why does `ApiResponse` connect `src/services/api.ts` to `UsersService`, `PetsController`, `PaginationDto`, `HomeController`, `SmsService`, `ProductsService`, `WikiController`, `AuthController`?**
_High betweenness centrality (0.037) - this node is a cross-community bridge._
- **Why does `PrismaService` connect `PrismaService` to `CmsController`, `app.module.ts`, `CreateReviewDto`, `tickets.controller.ts`, `admin.module.ts`, `payment.service.ts`, `DoctorsService`, `PaginationDto`, `ProductsService`, `CreateVideoDto`, `Roles`, `wholesale.controller.ts`, `JwtAuthGuard`, `ZibalService`, `CategoriesController`, `B2BService`, `BannersService`, `UsersService`, `IngredientsService`, `MediaController`, `SmsService`, `PrescriptionsService`, `SmartAdvisorService`, `TestimonialsService`, `ContactService`, `WikiController`, `PetsService`, `pets/pets.controller.ts`, `seo.module.ts`, `BlogsService`, `HomeController`, `zibal.service.ts`, `MetricsController`, `WikiService`?**
- **Why does `ApiResponse` connect `src/services/api.ts` to `UsersService`, `PetsController`, `BlogsController`, `HomeController`, `OrdersController`, `ProductsService`, `PaginationDto`, `auth.controller.ts`?**
_High betweenness centrality (0.038) - this node is a cross-community bridge._
- **Why does `PrismaService` connect `PrismaService` to `CmsController`, `app.module.ts`, `reviews.controller.ts`, `tickets.controller.ts`, `ReportsController`, `DoctorsService`, `BlogsController`, `ProductsService`, `CreateVideoDto`, `Roles`, `wholesale.controller.ts`, `admin.module.ts`, `ZibalService`, `CategoriesController`, `B2BService`, `UsersService`, `IngredientsService`, `admin.service.ts`, `MediaController`, `SmsService`, `PrescriptionsService`, `SmartAdvisorService`, `TestimonialsService`, `ContactService`, `PetsController`, `PaginationDto`, `users.service.ts`, `WikiController`, `PetsController`, `seo.module.ts`, `BlogsService`, `HomeController`, `zibal.service.ts`, `AppModule`, `OrdersService`?**
_High betweenness centrality (0.024) - this node is a cross-community bridge._
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
_1235 weakly-connected nodes found - possible documentation gaps or missing edges._
_1237 weakly-connected nodes found - possible documentation gaps or missing edges._
- **Should `AdminService` be split into smaller, more focused modules?**
_Cohesion score 0.050724637681159424 - nodes in this community are weakly interconnected._
_Cohesion score 0.050331731869137496 - nodes in this community are weakly interconnected._
- **Should `ProductService` be split into smaller, more focused modules?**
_Cohesion score 0.05333333333333334 - nodes in this community are weakly interconnected._
_Cohesion score 0.06390977443609022 - nodes in this community are weakly interconnected._
- **Should `CmsController` be split into smaller, more focused modules?**
_Cohesion score 0.0899854862119013 - nodes in this community are weakly interconnected._

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,25 @@
# Graph Report - canina (2026-08-18)
## Corpus Check
- 510 files · ~733,001 words
- 511 files · ~734,432 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 3627 nodes · 6157 edges · 284 communities (186 shown, 98 thin omitted)
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 225 edges (avg confidence: 0.79)
- 3634 nodes · 6166 edges · 313 communities (196 shown, 117 thin omitted)
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 228 edges (avg confidence: 0.79)
- Token cost: 0 input · 0 output
## Graph Freshness
- Built from commit: `f0f50c75`
- Built from commit: `95d79518`
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
- Run `graphify update .` after code changes (no API cost).
## Community Hubs (Navigation)
- AdminService
- ProductService
- AdminController
- productService.ts
- CmsController
- app.module.ts
- reviews.controller.ts
- CreateReviewDto
- tickets.controller.ts
- UserDashboard.tsx
- MediaSelector.tsx
@ -34,7 +34,7 @@
- lib/services/api.ts
- CreateVideoDto
- src/services/api.ts
- devDependencies
- eslint
- BE-001
- Roles
- FE-001
@ -44,21 +44,21 @@
- TEST-001
- DEVOPS-001
- DOC-001
- wholesale.controller.ts
- WholesaleApplyDto
- main.ts
- admin.module.ts
- JwtAuthGuard
- ZibalService
- راهنمای تست سیستم (Software Testing)
- CategoriesController
- B2BService
- What You Must Do When Invoked
- toPersian
- userStore.ts
- UsersService
- What You Must Do When Invoked
- SslController
- ProductPage.tsx
- PodcastPlayerModal.tsx
- IngredientsService
- admin.service.ts
- AuthService
- MediaController
- Pagination.tsx
- SmsService
@ -72,23 +72,23 @@
- compilerOptions
- Media.tsx
- compilerOptions
- PetsController
- admin.module.ts
- PaginationDto
- dependencies
- compilerOptions
- HomeClient.tsx
- BlogsController
- auth.controller.ts
- users.service.ts
- AuthController
- BannersService
- Required Review Group Closures
- Coupons.tsx
- Operational Rules & Boundaries
- Operational Rules & Boundaries
- WikiController
- auth.module.ts
- PetsController
- ApiOperation
- pets/pets.controller.ts
- seo.module.ts
- BlogsService
- admin.service.ts
- 🏢 AI Software Agency — Master Orchestration Protocol v3
- Operational Rules & Boundaries
- Operational Rules & Boundaries
@ -105,7 +105,7 @@
- 20260526145407_init/migration.sql
- Phase 3.1 — Human Review Preparation and Master Backlog Critique
- dependencies
- SafeImage.tsx
- ProductPage.tsx
- compilerOptions
- scripts
- Deep Audit Summary Report
@ -117,16 +117,16 @@
- Comprehensive Change Log
- Operational Rules & Boundaries
- CreateOrderDto
- SmsLogQueryDto
- ZibalCallbackQueryDto
- ValidateCouponDto
- .update
- .handleZibalCallback
- auth.service.ts
- 1. Summary of Integrity Repairs Performed
- eslint-config-prettier
- Operational Rules & Boundaries
- Operational Rules & Boundaries
- Operational Rules & Boundaries
- AppService
- AdminModule
- auth.controller.ts
- @types/react-dom
- Vazirmatn Changelog
- Vazirmatn Font فونت وزیرمتن
@ -134,7 +134,7 @@
- compilerOptions
- compilerOptions
- backend/README.md
- eslint-plugin-prettier
- devDependencies
- Repository Map
- validate_integrity.js
- admin-panel/package.json
@ -144,6 +144,7 @@
- Role & Core Objective
- orchestrate.py
- backend/package.json
- PetsService
- graphify reference: extra exports and benchmark
- Phase 2 Final Quality Gate Summary Report
- Task Modifications Log
@ -155,6 +156,7 @@
- InitiatePaymentDto
- System Discovery
- Product Requirement Document (PRD)
- WikiController
- globals
- @nestjs/cli
- Baseline Command Plan & Reconciled Command History
@ -187,7 +189,7 @@
- 🎨 Frontend & Admin Panel Technical Review (06_dev_frontend)
- 🚀 SEO & Content Strategy Review (12_seo_content)
- @types/node
- typescript
- Body
- seed-ui-texts.ts
- seed-wiki.ts
- update-blog.dto.ts
@ -225,9 +227,10 @@
- sync_honest_manifest.js
- sync_manifest.js
- @types/multer
- @types/passport-jwt
- tailwindcss
- AppModule
- ProductDto
- PetsController
- RedisService
- WikiService
- FormField.tsx
- Input.tsx
- Textarea.tsx
@ -249,9 +252,11 @@
- @types/react
- typescript
- vitest
- RegisterDto
- ts-loader
- AdminService
- @types/bcrypt
- @types/supertest
- MetricsController
- blog.entity.ts
- home.entity.ts
- wiki.entity.ts
@ -284,6 +289,30 @@
- Shabnam Font Sample
- Production Docker Compose
- Staging Docker Compose
- CreateHealthLogDto
- CreateReminderDto
- NetworkBanner.tsx
- bcryptjs
- helmet
- js-yaml
- @nestjs/core
- @nestjs/jwt
- @nestjs/swagger
- @nestjs/throttler
- passport-jwt
- @prisma/client
- swagger-ui-express
- @eslint/eslintrc
- @eslint/js
- jest
- @nestjs/schematics
- @nestjs/testing
- source-map-support
- ts-jest
- tsconfig-paths
- @types/bcryptjs
- typescript-eslint
- globals
## God Nodes (most connected - your core abstractions)
1. `PrismaService` - 81 edges
@ -310,43 +339,43 @@
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`
## Hyperedges (group relationships)
- **Rastikerdar Font Ecosystem** — frontend_application_public_fonts_shabnam_font_v5_0_1_readme, frontend_application_public_fonts_vazirmatn_v33_003_readme, vazir_font [EXTRACTED 0.95]
- **Canina Deployment Stack** — scripts_compose_prod, scripts_compose_stage [EXTRACTED 1.00]
## Communities (284 total, 98 thin omitted)
## Communities (313 total, 117 thin omitted)
### Community 0 - "AdminService"
Cohesion: 0.05
Nodes (38): AdminController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+30 more)
### Community 0 - "AdminController"
Cohesion: 0.13
Nodes (8): AdminController, ApiBearerAuth, ApiTags, Controller, Delete, Param, Put, UseGuards
### Community 1 - "ProductService"
### Community 1 - "productService.ts"
Cohesion: 0.06
Nodes (33): Blog(), getBlogs(), metadata, CatalogClient(), metadata, metadata, BlogPage(), BlogPost (+25 more)
Nodes (36): Blog(), getBlogs(), metadata, CatalogClient(), metadata, metadata, metadata, BlogPage() (+28 more)
### Community 2 - "CmsController"
Cohesion: 0.09
Nodes (24): CmsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+16 more)
### Community 3 - "app.module.ts"
Cohesion: 0.08
Nodes (30): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+22 more)
### Community 4 - "reviews.controller.ts"
Cohesion: 0.07
Nodes (31): CreateReviewDto, ApiProperty, IsInt, IsNotEmpty, IsOptional, IsString, Min, ApiProperty (+23 more)
Nodes (36): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+28 more)
### Community 4 - "CreateReviewDto"
Cohesion: 0.07
Nodes (29): CreateReviewDto, ApiProperty, IsInt, IsNotEmpty, IsOptional, IsString, Min, ApiProperty (+21 more)
### Community 5 - "tickets.controller.ts"
Cohesion: 0.09
Nodes (29): AdminUpdateTicketDto, CreateTicketDto, ReplyTicketDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString (+21 more)
### Community 6 - "UserDashboard.tsx"
Cohesion: 0.11
Nodes (22): AddressModal(), AddressModalProps, BackButton(), BackButtonProps, CheckoutPage(), DeleteConfirmModal(), DeleteConfirmModalProps, HeaderButton() (+14 more)
Cohesion: 0.09
Nodes (28): VerifyContent(), AddressModal(), AddressModalProps, BackButton(), BackButtonProps, DeleteConfirmModal(), DeleteConfirmModalProps, HeaderButton() (+20 more)
### Community 7 - "MediaSelector.tsx"
Cohesion: 0.08
@ -357,24 +386,24 @@ Cohesion: 0.17
Nodes (9): ReportsController, ApiBearerAuth, ApiOperation, ApiTags, Controller, Get, UseGuards, ReportsService (+1 more)
### Community 9 - "PetProfile.tsx"
Cohesion: 0.08
Nodes (25): metadata, FeaturedProducts(), ProductCard(), OrderSuccess(), PrescriptionUploadModal(), PrescriptionUploadModalProps, SearchResultsPage(), OrderRowSkeleton() (+17 more)
Cohesion: 0.14
Nodes (12): FeaturedProducts(), OrderRowSkeleton(), PetProfileSkeleton(), ProductCardSkeleton(), Skeleton(), SkeletonProps, mockProducts, HealthLog (+4 more)
### Community 10 - "DoctorsService"
Cohesion: 0.12
Nodes (16): DoctorsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+8 more)
Cohesion: 0.13
Nodes (15): DoctorsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+7 more)
### Community 11 - "useSettingsStore"
Cohesion: 0.12
Nodes (18): ClientLayout(), metadata, BrandLogo(), BrandLogoProps, EnamadBadge(), Footer(), Header(), MENU_ICONS (+10 more)
Cohesion: 0.14
Nodes (14): metadata, BrandLogo(), BrandLogoProps, EnamadBadge(), Footer(), Hero(), StatCounter(), MaintenancePage() (+6 more)
### Community 12 - "adminRoutes.tsx"
Cohesion: 0.10
Nodes (14): App(), ContactInfoItem, ContactSubmission, CategoryDist, DashboardData, Ticket, TicketMessage, WholesaleRequest (+6 more)
### Community 13 - "PrismaService"
Cohesion: 0.10
Nodes (13): WikiQuery, MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions, SmsConfig, SmsLogQuery, CreateContactSubmissionDto, UpdateContactInfoItemDto (+5 more)
Cohesion: 0.09
Nodes (14): MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions, SmsConfig, SmsLogQuery, CreateContactSubmissionDto, UpdateContactInfoItemDto, DoctorQuery (+6 more)
### Community 14 - "BlogsController"
Cohesion: 0.13
@ -386,27 +415,23 @@ Nodes (19): GetProductsDto, ApiPropertyOptional, IsEnum, IsOptional, IsString, P
### Community 16 - "lib/services/api.ts"
Cohesion: 0.06
Nodes (18): metadata, ContactFormClient(), ContactInfoItem, OrderDetailsModal(), OrderDetailsModalProps, Testimonial, api, ApiErrorPayload (+10 more)
Nodes (18): metadata, ContactFormClient(), ContactInfoItem, Testimonial, TestimonialsSection(), api, ApiErrorPayload, BASE_DOMAIN (+10 more)
### Community 17 - "CreateVideoDto"
Cohesion: 0.07
Nodes (31): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, UpdateVideoDto (+23 more)
Cohesion: 0.09
Nodes (24): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, UpdateVideoDto (+16 more)
### Community 18 - "src/services/api.ts"
Cohesion: 0.10
Nodes (23): ProtectedRoute(), SEARCHABLE_PAGES, Topbar(), TopbarProps, Login(), B2BManager, SmartAdvisorManager, SystemSettingsPage (+15 more)
### Community 19 - "devDependencies"
Cohesion: 0.09
Nodes (23): devDependencies, eslint, @eslint/eslintrc, @eslint/js, jest, @nestjs/schematics, @nestjs/testing, source-map-support (+15 more)
Cohesion: 0.12
Nodes (21): ProtectedRoute(), SEARCHABLE_PAGES, Topbar(), TopbarProps, Login(), B2BManager, SmartAdvisorManager, ApiErrorPayload (+13 more)
### Community 20 - "BE-001"
Cohesion: 0.06
Nodes (32): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, BE-001, Category, Completion Statement, Confidence (+24 more)
### Community 21 - "Roles"
Cohesion: 0.06
Nodes (33): BannersController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+25 more)
Cohesion: 0.08
Nodes (25): Roles(), SmsLogQueryDto, ApiPropertyOptional, IsIn, IsNumber, IsOptional, IsString, Type (+17 more)
### Community 22 - "FE-001"
Cohesion: 0.06
@ -436,17 +461,17 @@ Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternati
Cohesion: 0.06
Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternative Direction, Category, Completion Statement, Confidence, Dependencies (+23 more)
### Community 29 - "wholesale.controller.ts"
### Community 29 - "WholesaleApplyDto"
Cohesion: 0.10
Nodes (22): ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, WholesaleApplyDto, ApiBearerAuth, ApiOperation (+14 more)
Nodes (20): ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, WholesaleApplyDto, ApiBearerAuth, ApiOperation (+12 more)
### Community 30 - "main.ts"
Cohesion: 0.14
Nodes (9): CustomHttpExceptionFilter, Catch, PrismaExceptionFilter, Catch, DecimalInterceptor, Injectable, ApiErrorResponse, ErrorDetailField (+1 more)
### Community 31 - "admin.module.ts"
Cohesion: 0.12
Nodes (12): BlogQuery, CategoryQuery, PetQuery, SslCertInfo, JwtAuthGuard, Injectable, ROLES_KEY, RequestWithUser (+4 more)
### Community 31 - "JwtAuthGuard"
Cohesion: 0.14
Nodes (8): JwtAuthGuard, Injectable, B2BWholesaleOrderItem, ROLES_KEY, RequestWithUser, RolesGuard, Injectable, UserReqPayload
### Community 32 - "ZibalService"
Cohesion: 0.14
@ -457,24 +482,24 @@ Cohesion: 0.07
Nodes (25): اجرای بک‌اند, اجرای فرانت‌اند, اجرای پروژه در سرور با PM2, برای راه‌اندازی بک‌اند:, برای راه‌اندازی فرانت‌اند Next.js:, بیلد کردن پروژه (Building), ذخیره پروسه‌ها تا پس از ری‌استارت سرور قطع نشوند:, راه‌اندازی و انتشار سیستم (Setup & Deployment) (+17 more)
### Community 34 - "CategoriesController"
Cohesion: 0.10
Nodes (16): CategoriesController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+8 more)
Cohesion: 0.09
Nodes (17): CategoriesController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+9 more)
### Community 35 - "B2BService"
Cohesion: 0.13
Nodes (15): B2BController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get, Param (+7 more)
Cohesion: 0.14
Nodes (14): B2BController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get, Param (+6 more)
### Community 36 - "What You Must Do When Invoked"
Cohesion: 0.07
Nodes (26): For /graphify add and --watch, For /graphify query, For the commit hook and native CLAUDE.md integration, For --update and --cluster-only, /graphify, Honesty Rules, Interpreter guard for subcommands, Part A - Structural extraction for code files (+18 more)
### Community 37 - "toPersian"
Cohesion: 0.13
Nodes (23): VerifyContent(), ArchiveProductCard(), AuthModal(), AuthModalProps, extractOtpFromText(), B2BPortal(), CartDrawer(), LoginModal() (+15 more)
### Community 37 - "userStore.ts"
Cohesion: 0.09
Nodes (32): ClientLayout(), ArchiveProductCard(), AuthModal(), AuthModalProps, extractOtpFromText(), B2BPortal(), CartDrawer(), CheckoutPage() (+24 more)
### Community 38 - "UsersService"
Cohesion: 0.12
Nodes (18): ApiBadRequestResponse, ApiBearerAuth, ApiCreatedResponse, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+10 more)
Cohesion: 0.06
Nodes (42): DEFAULT_JWT_REFRESH_SECRET, DEFAULT_JWT_SECRET, getJwtSecret(), AuthModule, Module, JwtPayload, JwtStrategy, Injectable (+34 more)
### Community 39 - "What You Must Do When Invoked"
Cohesion: 0.07
@ -484,17 +509,17 @@ Nodes (26): For /graphify add and --watch, For /graphify query, For the commit h
Cohesion: 0.13
Nodes (14): SslController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get, Post (+6 more)
### Community 41 - "ProductPage.tsx"
Cohesion: 0.12
Nodes (14): PLAYBACK_RATES, PodcastPlayerModal(), PodcastPlayerModalProps, CalculatorState, ICON_MAP, ProductPage(), useCalculatorStore, ProductReviews() (+6 more)
### Community 41 - "PodcastPlayerModal.tsx"
Cohesion: 0.40
Nodes (3): PLAYBACK_RATES, PodcastPlayerModal(), PodcastPlayerModalProps
### Community 42 - "IngredientsService"
Cohesion: 0.13
Nodes (14): IngredientsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
### Community 43 - "admin.service.ts"
Cohesion: 0.09
Nodes (14): CouponTargetInput, PaginationQuery, AdminLoginInput, AuthService, LoginInput, RegisterInput, Injectable, normalizeMobile() (+6 more)
### Community 43 - "AuthService"
Cohesion: 0.18
Nodes (3): AuthService, Injectable, normalizeMobile()
### Community 44 - "MediaController"
Cohesion: 0.11
@ -505,7 +530,7 @@ Cohesion: 0.13
Nodes (11): Pagination(), PaginationProps, Pet, GatewayHealth, Stats, Transaction, ProductItem, WikiTerm (+3 more)
### Community 47 - "OrdersController"
Cohesion: 0.14
Cohesion: 0.13
Nodes (16): OrdersController, ApiBadRequestResponse, ApiBearerAuth, ApiCreatedResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags (+8 more)
### Community 48 - "PrescriptionsService"
@ -529,8 +554,8 @@ Cohesion: 0.13
Nodes (11): ContactController, Body, Controller, Get, Param, Post, Put, Query (+3 more)
### Community 53 - "PaymentController"
Cohesion: 0.20
Nodes (17): PaymentController, ApiBadRequestResponse, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+9 more)
Cohesion: 0.25
Nodes (13): PaymentController, ApiBadRequestResponse, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+5 more)
### Community 54 - "compilerOptions"
Cohesion: 0.06
@ -544,45 +569,45 @@ Nodes (20): Badge(), BadgeProps, BadgeVariant, variantStyles, ImagePreviewModal(
Cohesion: 0.09
Nodes (22): compilerOptions, allowImportingTsExtensions, erasableSyntaxOnly, jsx, lib, module, moduleDetection, moduleResolution (+14 more)
### Community 57 - "PetsController"
Cohesion: 0.11
Nodes (13): PetsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Controller, Delete, Get (+5 more)
### Community 57 - "admin.module.ts"
Cohesion: 0.06
Nodes (23): AdminModule, Module, BlogQuery, BlogsService, Injectable, PetsController, ApiBearerAuth, ApiOperation (+15 more)
### Community 58 - "PaginationDto"
Cohesion: 0.09
Nodes (22): PaginationDto, SortOrder, ApiPropertyOptional, IsEnum, IsInt, IsOptional, IsString, Min (+14 more)
Cohesion: 0.07
Nodes (24): PaginationDto, SortOrder, ApiPropertyOptional, IsEnum, IsInt, IsOptional, IsString, Min (+16 more)
### Community 59 - "dependencies"
Cohesion: 0.05
Nodes (41): dependencies, bcrypt, bcryptjs, class-transformer, class-validator, helmet, ioredis, js-yaml (+33 more)
Cohesion: 0.10
Nodes (21): dependencies, bcrypt, class-transformer, class-validator, ioredis, @nestjs/common, @nestjs/passport, @nestjs/platform-express (+13 more)
### Community 60 - "compilerOptions"
Cohesion: 0.10
Nodes (20): compilerOptions, allowImportingTsExtensions, erasableSyntaxOnly, lib, module, moduleDetection, moduleResolution, noEmit (+12 more)
### Community 61 - "HomeClient.tsx"
Cohesion: 0.11
Nodes (21): HomeClient(), HomeClientProps, getHomeData(), Home(), metadata, metadata, ArchivePage(), CATEGORY_MAP (+13 more)
Cohesion: 0.12
Nodes (20): HomeClient(), HomeClientProps, getHomeData(), Home(), metadata, metadata, ArchivePage(), CATEGORY_MAP (+12 more)
### Community 62 - "BlogsController"
Cohesion: 0.13
Nodes (15): BlogsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+7 more)
### Community 63 - "auth.controller.ts"
Cohesion: 0.06
Nodes (42): AuthController, ApiBadRequestResponse, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+34 more)
### Community 63 - "AuthController"
Cohesion: 0.27
Nodes (12): AuthController, ApiBadRequestResponse, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+4 more)
### Community 64 - "users.service.ts"
### Community 64 - "BannersService"
Cohesion: 0.13
Nodes (14): AddressDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, ApiPropertyOptional (+6 more)
Nodes (15): BannersController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+7 more)
### Community 65 - "Required Review Group Closures"
Cohesion: 0.10
Nodes (19): 10. Orders Backend, 11. Settings & Administrative Backend, 12. Prisma Schema, Migrations & Seed, 13. Redis & Temporary Auth State, 14. Unit & E2E Tests, 15. Docker, NGINX, Prometheus & Deployment Config, 16. Documentation & OpenAPI Artifacts, 1. Storefront Shell & Routing (+11 more)
### Community 66 - "Coupons.tsx"
Cohesion: 0.12
Nodes (14): formatPriceWithCommas(), PriceInput(), PriceInputProps, toEnglishDigits(), Coupon, CouponFormData, CouponModalProps, CouponTarget (+6 more)
Cohesion: 0.10
Nodes (15): formatPriceWithCommas(), PriceInput(), PriceInputProps, toEnglishDigits(), Coupon, CouponFormData, CouponModalProps, CouponTarget (+7 more)
### Community 67 - "Operational Rules & Boundaries"
Cohesion: 0.11
@ -593,21 +618,25 @@ Cohesion: 0.11
Nodes (18): 1. Framework-Aware Analysis, 2. DOM & Semantic Structure Analysis, 3. Accessibility Compliance, 4. Responsive Layout Verification, 5. Fallback Inspection Mode, 6. Defect Routing Protocol, 7. Forbidden Actions, Expected JSON Output Schema (+10 more)
### Community 69 - "WikiController"
Cohesion: 0.09
Nodes (16): ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete, Get (+8 more)
Cohesion: 0.13
Nodes (14): ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete, Get (+6 more)
### Community 70 - "auth.module.ts"
Cohesion: 0.17
Nodes (10): DEFAULT_JWT_REFRESH_SECRET, DEFAULT_JWT_SECRET, getJwtSecret(), AuthModule, Module, JwtPayload, JwtStrategy, Injectable (+2 more)
### Community 70 - "ApiOperation"
Cohesion: 0.15
Nodes (8): ApiOperation, ApiQuery, Get, Query, AdminQueryDto, ApiPropertyOptional, IsOptional, IsString
### Community 71 - "PetsController"
Cohesion: 0.05
Nodes (47): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, CreatePetDto, ApiProperty (+39 more)
### Community 71 - "pets/pets.controller.ts"
Cohesion: 0.16
Nodes (13): CreatePetDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional, IsString (+5 more)
### Community 72 - "seo.module.ts"
Cohesion: 0.16
Nodes (10): SeoController, ApiOperation, ApiTags, Controller, Get, Param, SeoModule, Module (+2 more)
### Community 73 - "admin.service.ts"
Cohesion: 0.16
Nodes (13): CouponTargetInput, PaginationQuery, CreateUserDto, ApiProperty, ApiPropertyOptional, IsEmail, IsNotEmpty, IsNumber (+5 more)
### Community 74 - "🏢 AI Software Agency — Master Orchestration Protocol v3"
Cohesion: 0.11
Nodes (17): Activation, Agent Directory Reference, 🏢 AI Software Agency — Master Orchestration Protocol v3, Phase 1: Specialist Review (All agents read, none write code yet), Phase 2: Master Synthesis (02_product_manager in SYNTHESIS mode), Phase 3: Execution (Same as always), PIPELINE A — New Project (GREENFIELD), PIPELINE B — Review & Improve Existing Project (REVIEW_AND_PLAN) ★ (+9 more)
@ -650,7 +679,7 @@ Nodes (13): Skeleton(), getPaymentMethodLabel(), Order, ORDER_STATUS_MAP, OrderI
### Community 84 - "devDependencies"
Cohesion: 0.11
Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, globals, postcss, @types/node (+11 more)
Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, postcss, tailwindcss, @types/node (+11 more)
### Community 85 - "seed-products.ts"
Cohesion: 0.17
@ -672,9 +701,9 @@ Nodes (14): 10. Dependency & Wave Adjustments, 11. Acceptance Criteria Refinemen
Cohesion: 0.10
Nodes (21): dependencies, axios, lucide-react, react, react-dom, react-hot-toast, react-router-dom, recharts (+13 more)
### Community 90 - "SafeImage.tsx"
Cohesion: 0.14
Nodes (13): ProductDetailModalProps, SafeImage(), SafeImageProps, DisplayVideoItem, FALLBACK_VIDEOS, TestimonialItem, VetGallery(), PLAYBACK_RATES (+5 more)
### Community 90 - "ProductPage.tsx"
Cohesion: 0.07
Nodes (25): ProductDetailModalProps, PLAYBACK_RATES, PodcastInlinePlayer(), PodcastInlinePlayerProps, CalculatorState, ICON_MAP, ProductPage(), useCalculatorStore (+17 more)
### Community 91 - "compilerOptions"
Cohesion: 0.06
@ -704,10 +733,6 @@ Nodes (8): exclude, extends, dist, node_modules, prisma, **/*spec.ts, test, ./ts
Cohesion: 0.15
Nodes (13): jest, collectCoverageFrom, coverageDirectory, moduleFileExtensions, rootDir, testEnvironment, testRegex, transform (+5 more)
### Community 98 - "OrdersService"
Cohesion: 0.20
Nodes (4): OrdersModule, Module, OrdersService, Injectable
### Community 99 - "Comprehensive Change Log"
Cohesion: 0.15
Nodes (12): 10. `TASK-VERIFY-001`, 1. `TASK-SEC-001`, 2. `TASK-SEC-002`, 3. `TASK-SEC-003`, 4. `TASK-FIN-001`, 5. `TASK-BUILD-001`, 6. `TASK-AUTH-001`, 7. `TASK-FE-001` (+4 more)
@ -720,17 +745,17 @@ Nodes (11): 1. Detect Test Runner from Tech Stack, 2. Execution Output Capture (
Cohesion: 0.22
Nodes (11): CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional (+3 more)
### Community 102 - "SmsLogQueryDto"
Cohesion: 0.25
Nodes (7): SmsLogQueryDto, ApiPropertyOptional, IsIn, IsNumber, IsOptional, IsString, Type
### Community 102 - ".update"
Cohesion: 0.24
Nodes (11): ApiNotFoundResponse, ApiOkResponse, ApiOperation, Body, Delete, Get, Param, Patch (+3 more)
### Community 103 - "ZibalCallbackQueryDto"
Cohesion: 0.40
Nodes (4): ApiPropertyOptional, IsOptional, IsString, ZibalCallbackQueryDto
### Community 103 - ".handleZibalCallback"
Cohesion: 0.24
Nodes (8): ApiPropertyOptional, IsOptional, IsString, ZibalCallbackQueryDto, Query, Res, Headers, Ip
### Community 104 - "ValidateCouponDto"
Cohesion: 0.50
Nodes (4): IsNotEmpty, IsNumber, IsString, ValidateCouponDto
### Community 104 - "auth.service.ts"
Cohesion: 0.13
Nodes (14): AdminLoginInput, LoginInput, RegisterInput, SendOtpDto, ApiProperty, IsNotEmpty, IsString, Matches (+6 more)
### Community 105 - "1. Summary of Integrity Repairs Performed"
Cohesion: 0.17
@ -752,6 +777,10 @@ Nodes (10): 1. Pre-Deployment Checklist, 2. Build Verification, 3. Deployment St
Cohesion: 0.29
Nodes (5): AppController, Controller, Get, AppService, Injectable
### Community 111 - "auth.controller.ts"
Cohesion: 0.16
Nodes (11): AdminLoginDto, ApiProperty, IsEmail, IsNotEmpty, IsString, MinLength, LoginDto, ApiProperty (+3 more)
### Community 113 - "Vazirmatn Changelog"
Cohesion: 0.18
Nodes (10): 32.0.0, 32.1, 32.101, 32.102, 33.000, 33.001, 33.002, 33.003 (+2 more)
@ -776,6 +805,10 @@ Nodes (9): compilerOptions, esModuleInterop, module, moduleResolution, skipLibCh
Cohesion: 0.20
Nodes (9): Compile and run the project, Deployment, Description, License, Project setup, Resources, Run tests, Stay in touch (+1 more)
### Community 119 - "devDependencies"
Cohesion: 0.22
Nodes (9): devDependencies, eslint-plugin-prettier, @types/passport-jwt, @types/supertest, typescript, typescript, eslint-plugin-prettier, @types/passport-jwt (+1 more)
### Community 120 - "Repository Map"
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)
@ -841,7 +874,7 @@ Cohesion: 0.25
Nodes (6): app_module_1, core_1, fs, path, swagger_1, yaml
### Community 137 - "AdminTransactionFilterDto"
Cohesion: 0.22
Cohesion: 0.25
Nodes (7): AdminTransactionFilterDto, ApiPropertyOptional, IsIn, IsNumber, IsOptional, IsString, Type
### Community 138 - "InitiatePaymentDto"
@ -856,13 +889,17 @@ Nodes (7): Active Core Applications, Current Architecture, Evidence-Based Status
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 141 - "WikiController"
Cohesion: 0.21
Nodes (9): ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags, Controller, Get, Param, Query (+1 more)
### Community 144 - "Baseline Command Plan & Reconciled Command History"
Cohesion: 0.29
Nodes (6): Attempted Command Execution Log, Backend `backend/package.json` Scripts, Baseline Command Plan & Reconciled Command History, Package Scripts Safety Analysis, Permitted Safe Checks for Phase 2, Root `package.json` Scripts
### Community 145 - "Spinner.tsx"
Cohesion: 0.10
Nodes (15): Spinner(), ProductReview, Reviews(), toPersianDigits(), PatternItem, SmsConfigState, SmsLogItem, SmsLogStats (+7 more)
Nodes (16): Spinner(), ProductReview, Reviews(), toPersianDigits(), PatternItem, SmsConfigState, SmsLogItem, SmsLogStats (+8 more)
### Community 147 - "with-vpn.sh"
Cohesion: 0.62
@ -956,6 +993,10 @@ 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 174 - "Body"
Cohesion: 0.24
Nodes (3): Body, Post, CouponInput
### Community 180 - "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
@ -996,33 +1037,61 @@ Nodes (3): COMPOSE_DOCKER_CLI_BUILD, DOCKER_BUILDKIT, deploy.sh script
Cohesion: 0.67
Nodes (3): ADR-AUTH-001: Admin Panel Authentication Architecture & Token Management, Master Task Backlog (Phase 3.3), Phase 3 Master Execution Plan
### Community 214 - "AppModule"
Cohesion: 0.12
Nodes (7): ApiExcludeController, AppModule, Module, MetricsController, Controller, Get, Res
### Community 212 - "ProductDto"
Cohesion: 0.22
Nodes (7): ProductDto, ApiPropertyOptional, IsArray, IsBoolean, IsNumber, IsOptional, IsString
### Community 213 - "PetsController"
Cohesion: 0.18
Nodes (9): PetsController, ApiBadRequestResponse, ApiBearerAuth, ApiCreatedResponse, ApiTags, Controller, UploadedFile, UseGuards (+1 more)
### Community 214 - "RedisService"
Cohesion: 0.14
Nodes (4): AppModule, Module, RedisService, Injectable
### Community 215 - "WikiService"
Cohesion: 0.22
Nodes (3): Injectable, WikiQuery, WikiService
### Community 223 - "Shabnam Font README"
Cohesion: 0.67
Nodes (3): Shabnam Font README, Shabnam Font Sample, Vazir Font
### Community 239 - "RegisterDto"
Cohesion: 0.22
Nodes (8): RegisterDto, ApiProperty, ApiPropertyOptional, IsEmail, IsNotEmpty, IsOptional, IsString, MinLength
### Community 243 - "MetricsController"
Cohesion: 0.29
Nodes (5): ApiExcludeController, MetricsController, Controller, Get, Res
### Community 289 - "CreateHealthLogDto"
Cohesion: 0.29
Nodes (6): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString
### Community 290 - "CreateReminderDto"
Cohesion: 0.29
Nodes (6): CreateReminderDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString
## Knowledge Gaps
- **1237 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1232 more)
- **1239 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1234 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **98 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
- **117 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 `Roles()` connect `Roles` to `CmsController`, `B2BService`, `reviews.controller.ts`, `tickets.controller.ts`, `SslController`, `IngredientsService`, `ProductsService`, `PrescriptionsService`, `SmartAdvisorService`, `TestimonialsService`, `ContactService`, `PaymentController`, `wholesale.controller.ts`, `admin.module.ts`?**
- **Why does `Roles()` connect `Roles` to `BannersService`, `CmsController`, `B2BService`, `CreateReviewDto`, `tickets.controller.ts`, `SslController`, `IngredientsService`, `ProductsService`, `PrescriptionsService`, `SmartAdvisorService`, `TestimonialsService`, `ContactService`, `PaymentController`, `WholesaleApplyDto`, `JwtAuthGuard`?**
_High betweenness centrality (0.048) - this node is a cross-community bridge._
- **Why does `ApiResponse` connect `src/services/api.ts` to `UsersService`, `PetsController`, `BlogsController`, `HomeController`, `OrdersController`, `ProductsService`, `PaginationDto`, `auth.controller.ts`?**
_High betweenness centrality (0.038) - this node is a cross-community bridge._
- **Why does `PrismaService` connect `PrismaService` to `CmsController`, `app.module.ts`, `reviews.controller.ts`, `tickets.controller.ts`, `ReportsController`, `DoctorsService`, `BlogsController`, `ProductsService`, `CreateVideoDto`, `Roles`, `wholesale.controller.ts`, `admin.module.ts`, `ZibalService`, `CategoriesController`, `B2BService`, `UsersService`, `IngredientsService`, `admin.service.ts`, `MediaController`, `SmsService`, `PrescriptionsService`, `SmartAdvisorService`, `TestimonialsService`, `ContactService`, `PetsController`, `PaginationDto`, `users.service.ts`, `WikiController`, `PetsController`, `seo.module.ts`, `BlogsService`, `HomeController`, `zibal.service.ts`, `AppModule`, `OrdersService`?**
- **Why does `ApiResponse` connect `src/services/api.ts` to `UsersService`, `WikiController`, `BlogsController`, `HomeController`, `OrdersController`, `ProductsService`, `PetsController`, `AuthController`?**
_High betweenness centrality (0.037) - this node is a cross-community bridge._
- **Why does `PrismaService` connect `PrismaService` to `PetsService`, `CmsController`, `app.module.ts`, `CreateReviewDto`, `tickets.controller.ts`, `ReportsController`, `DoctorsService`, `BlogsController`, `ProductsService`, `CreateVideoDto`, `Roles`, `WholesaleApplyDto`, `JwtAuthGuard`, `ZibalService`, `CategoriesController`, `B2BService`, `UsersService`, `IngredientsService`, `AuthService`, `MediaController`, `SmsService`, `PrescriptionsService`, `SmartAdvisorService`, `TestimonialsService`, `ContactService`, `admin.module.ts`, `PaginationDto`, `BannersService`, `pets/pets.controller.ts`, `seo.module.ts`, `admin.service.ts`, `HomeController`, `zibal.service.ts`, `RedisService`, `WikiService`, `OrdersService`, `auth.service.ts`, `AdminService`, `MetricsController`?**
_High betweenness centrality (0.024) - this node is a cross-community bridge._
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
_1237 weakly-connected nodes found - possible documentation gaps or missing edges._
- **Should `AdminService` be split into smaller, more focused modules?**
_Cohesion score 0.050331731869137496 - nodes in this community are weakly interconnected._
- **Should `ProductService` be split into smaller, more focused modules?**
_Cohesion score 0.06390977443609022 - nodes in this community are weakly interconnected._
_1239 weakly-connected nodes found - possible documentation gaps or missing edges._
- **Should `AdminController` be split into smaller, more focused modules?**
_Cohesion score 0.13043478260869565 - nodes in this community are weakly interconnected._
- **Should `productService.ts` be split into smaller, more focused modules?**
_Cohesion score 0.05888376856118792 - nodes in this community are weakly interconnected._
- **Should `CmsController` be split into smaller, more focused modules?**
_Cohesion score 0.0899854862119013 - 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