chore: resolve graphify merge conflicts from develop
All checks were successful
Deploy Canina / deploy (push) Successful in 1m31s
All checks were successful
Deploy Canina / deploy (push) Successful in 1m31s
This commit is contained in:
commit
0f50d6bed1
@ -1,8 +1,7 @@
|
|||||||
/* eslint-disable @next/next/no-img-element */
|
|
||||||
"use client";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { Banner } from "../lib/types";
|
import { Banner } from "../lib/types";
|
||||||
|
import SafeImage from "./SafeImage";
|
||||||
|
|
||||||
interface BannerPlacementProps {
|
interface BannerPlacementProps {
|
||||||
banners: Banner[];
|
banners: Banner[];
|
||||||
@ -36,14 +35,14 @@ export default function BannerPlacement({
|
|||||||
const cardContent = (
|
const cardContent = (
|
||||||
<div className="group relative rounded-3xl overflow-hidden shadow-lg hover:shadow-2xl transition-all duration-300 border border-medical-gray-100 bg-white">
|
<div className="group relative rounded-3xl overflow-hidden shadow-lg hover:shadow-2xl transition-all duration-300 border border-medical-gray-100 bg-white">
|
||||||
<div className="aspect-[16/7] sm:aspect-[16/6] md:aspect-[16/7] overflow-hidden bg-medical-gray-100 relative">
|
<div className="aspect-[16/7] sm:aspect-[16/6] md:aspect-[16/7] overflow-hidden bg-medical-gray-100 relative">
|
||||||
<img
|
<SafeImage
|
||||||
src={banner.imageUrl}
|
src={banner.imageUrl}
|
||||||
alt={banner.title || "کنینا بنر"}
|
alt={banner.title || "کنینا بنر"}
|
||||||
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
className="w-full h-full"
|
||||||
loading="lazy"
|
imgClassName="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
||||||
/>
|
/>
|
||||||
{(banner.title || banner.subtitle) && (
|
{(banner.title || banner.subtitle) && (
|
||||||
<div className="absolute inset-0 bg-gradient-to-t from-black/80 via-black/30 to-transparent p-6 flex flex-col justify-end text-white text-right">
|
<div className="absolute inset-0 bg-gradient-to-t from-black/80 via-black/30 to-transparent p-6 flex flex-col justify-end text-white text-right pointer-events-none">
|
||||||
{banner.title && (
|
{banner.title && (
|
||||||
<h4 className="text-lg sm:text-xl font-black mb-1 leading-tight">
|
<h4 className="text-lg sm:text-xl font-black mb-1 leading-tight">
|
||||||
{banner.title}
|
{banner.title}
|
||||||
@ -98,14 +97,14 @@ export default function BannerPlacement({
|
|||||||
const cardContent = (
|
const cardContent = (
|
||||||
<div className="group relative rounded-3xl overflow-hidden shadow-xl hover:shadow-2xl transition-all duration-300 border border-medical-gray-200 bg-white">
|
<div className="group relative rounded-3xl overflow-hidden shadow-xl hover:shadow-2xl transition-all duration-300 border border-medical-gray-200 bg-white">
|
||||||
<div className="aspect-[21/6] sm:aspect-[21/5] min-h-[140px] sm:min-h-[180px] overflow-hidden bg-medical-gray-100 relative">
|
<div className="aspect-[21/6] sm:aspect-[21/5] min-h-[140px] sm:min-h-[180px] overflow-hidden bg-medical-gray-100 relative">
|
||||||
<img
|
<SafeImage
|
||||||
src={banner.imageUrl}
|
src={banner.imageUrl}
|
||||||
alt={banner.title || "کنینا"}
|
alt={banner.title || "کنینا"}
|
||||||
className="w-full h-full object-cover group-hover:scale-103 transition-transform duration-500"
|
className="w-full h-full"
|
||||||
loading="lazy"
|
imgClassName="w-full h-full object-cover group-hover:scale-103 transition-transform duration-500"
|
||||||
/>
|
/>
|
||||||
{(banner.title || banner.subtitle) && (
|
{(banner.title || banner.subtitle) && (
|
||||||
<div className="absolute inset-0 bg-gradient-to-l from-black/80 via-black/40 to-transparent p-6 sm:p-10 flex flex-col justify-center text-white text-right">
|
<div className="absolute inset-0 bg-gradient-to-l from-black/80 via-black/40 to-transparent p-6 sm:p-10 flex flex-col justify-center text-white text-right pointer-events-none">
|
||||||
{banner.title && (
|
{banner.title && (
|
||||||
<h4 className="text-xl sm:text-3xl font-black mb-2 leading-tight">
|
<h4 className="text-xl sm:text-3xl font-black mb-2 leading-tight">
|
||||||
{banner.title}
|
{banner.title}
|
||||||
@ -158,14 +157,14 @@ export default function BannerPlacement({
|
|||||||
const cardContent = (
|
const cardContent = (
|
||||||
<div className="group relative rounded-2xl overflow-hidden shadow-md hover:shadow-xl transition-all duration-300 border border-medical-gray-200 bg-white">
|
<div className="group relative rounded-2xl overflow-hidden shadow-md hover:shadow-xl transition-all duration-300 border border-medical-gray-200 bg-white">
|
||||||
<div className="aspect-[4/3] overflow-hidden bg-medical-gray-100 relative">
|
<div className="aspect-[4/3] overflow-hidden bg-medical-gray-100 relative">
|
||||||
<img
|
<SafeImage
|
||||||
src={banner.imageUrl}
|
src={banner.imageUrl}
|
||||||
alt={banner.title || "بنر کنینا"}
|
alt={banner.title || "بنر کنینا"}
|
||||||
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
className="w-full h-full"
|
||||||
loading="lazy"
|
imgClassName="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
||||||
/>
|
/>
|
||||||
{banner.title && (
|
{banner.title && (
|
||||||
<div className="absolute inset-0 bg-gradient-to-t from-black/80 to-transparent p-4 flex flex-col justify-end text-white text-right">
|
<div className="absolute inset-0 bg-gradient-to-t from-black/80 to-transparent p-4 flex flex-col justify-end text-white text-right pointer-events-none">
|
||||||
<span className="text-xs font-black">{banner.title}</span>
|
<span className="text-xs font-black">{banner.title}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable @next/next/no-img-element */
|
|
||||||
"use client";
|
"use client";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
import Image from "next/image";
|
||||||
import { useSettingsStore } from "../lib/store/settingsStore";
|
import { useSettingsStore } from "../lib/store/settingsStore";
|
||||||
|
|
||||||
interface BrandLogoProps {
|
interface BrandLogoProps {
|
||||||
@ -39,12 +39,18 @@ export default function BrandLogo({
|
|||||||
lg: "text-xl sm:text-3xl",
|
lg: "text-xl sm:text-3xl",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isBlobOrData = typeof logoUrl === 'string' && (logoUrl.startsWith('blob:') || logoUrl.startsWith('data:'));
|
||||||
|
|
||||||
const content = (
|
const content = (
|
||||||
<div className={`flex items-center gap-2.5 sm:gap-3 group shrink-0 ${className}`}>
|
<div className={`flex items-center gap-2.5 sm:gap-3 group shrink-0 ${className}`}>
|
||||||
{logoUrl ? (
|
{logoUrl ? (
|
||||||
<img
|
<Image
|
||||||
src={logoUrl}
|
src={logoUrl}
|
||||||
alt={`${textEn} ${textFa}`}
|
alt={`${textEn} ${textFa}`}
|
||||||
|
width={180}
|
||||||
|
height={48}
|
||||||
|
priority
|
||||||
|
unoptimized={isBlobOrData}
|
||||||
className="h-10 sm:h-12 w-auto max-w-[160px] sm:max-w-[200px] object-contain shrink-0"
|
className="h-10 sm:h-12 w-auto max-w-[160px] sm:max-w-[200px] object-contain shrink-0"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/* eslint-disable @next/next/no-img-element */
|
|
||||||
"use client";
|
"use client";
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
|
import Image from "next/image";
|
||||||
import { Phone, Mail, MapPin, Instagram, ShieldCheck, Globe, ArrowUp, Download } from "lucide-react";
|
import { Phone, Mail, MapPin, Instagram, ShieldCheck, Globe, ArrowUp, Download } from "lucide-react";
|
||||||
import { useSettingsStore } from "../lib/store/settingsStore";
|
import { useSettingsStore } from "../lib/store/settingsStore";
|
||||||
import BrandLogo from "./BrandLogo";
|
import BrandLogo from "./BrandLogo";
|
||||||
@ -190,11 +190,15 @@ export default function Footer({
|
|||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
title="درگاه پرداخت امن و معتبر زیبال"
|
title="درگاه پرداخت امن و معتبر زیبال"
|
||||||
|
className="block"
|
||||||
>
|
>
|
||||||
<img
|
<Image
|
||||||
style={{ maxWidth: '65px', height: '65px', objectFit: 'contain' }}
|
|
||||||
src="https://zibal.ir/trust/assets/2.png"
|
src="https://zibal.ir/trust/assets/2.png"
|
||||||
alt="نماد اعتماد درگاه پرداخت زیبال"
|
alt="نماد اعتماد درگاه پرداخت زیبال"
|
||||||
|
width={65}
|
||||||
|
height={65}
|
||||||
|
unoptimized
|
||||||
|
className="max-w-[65px] h-[65px] object-contain"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable @next/next/no-img-element */
|
|
||||||
"use client";
|
"use client";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
@ -26,6 +25,7 @@ import { toPersian } from "../lib/utils";
|
|||||||
import api from "../lib/services/api";
|
import api from "../lib/services/api";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { useSettingsStore } from "../lib/store/settingsStore";
|
import { useSettingsStore } from "../lib/store/settingsStore";
|
||||||
|
import SafeImage from "./SafeImage";
|
||||||
|
|
||||||
interface OrderDetailsModalProps {
|
interface OrderDetailsModalProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@ -418,14 +418,14 @@ export default function OrderDetailsModal({
|
|||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<div
|
<div
|
||||||
onClick={() => setZoomedImage(pImg)}
|
onClick={() => setZoomedImage(pImg)}
|
||||||
className="w-14 h-14 bg-medical-gray-50 rounded-xl p-1.5 flex items-center justify-center shrink-0 border border-medical-gray-200 cursor-zoom-in hover:scale-105 transition-transform"
|
className="w-14 h-14 bg-medical-gray-50 rounded-xl p-1 flex items-center justify-center shrink-0 border border-medical-gray-200 cursor-zoom-in hover:scale-105 transition-transform overflow-hidden"
|
||||||
title="مشاهده تصویر بزرگ"
|
title="مشاهده تصویر بزرگ"
|
||||||
>
|
>
|
||||||
<img
|
<SafeImage
|
||||||
src={pImg}
|
src={pImg}
|
||||||
alt={pName}
|
alt={pName}
|
||||||
className="max-w-full max-h-full object-contain"
|
className="w-full h-full"
|
||||||
onError={(e: any) => { e.currentTarget.src = '/assets/images/canina-product-placeholder.png'; }}
|
imgClassName="w-full h-full object-contain"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@ -711,10 +711,11 @@ export default function OrderDetailsModal({
|
|||||||
>
|
>
|
||||||
<X className="w-5 h-5" />
|
<X className="w-5 h-5" />
|
||||||
</button>
|
</button>
|
||||||
<img
|
<SafeImage
|
||||||
src={zoomedImage}
|
src={zoomedImage}
|
||||||
alt="نمایش کامل تصویر محصول"
|
alt="نمایش کامل تصویر محصول"
|
||||||
className="max-h-[70vh] w-auto object-contain rounded-2xl"
|
className="max-h-[70vh] w-full"
|
||||||
|
imgClassName="max-h-[70vh] w-auto object-contain rounded-2xl mx-auto"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { Product } from "../lib/data/products";
|
|||||||
import { productService } from "../lib/services/productService";
|
import { productService } from "../lib/services/productService";
|
||||||
import { motion, AnimatePresence } from "motion/react";
|
import { motion, AnimatePresence } from "motion/react";
|
||||||
import { PetProfileSkeleton } from "./Skeleton";
|
import { PetProfileSkeleton } from "./Skeleton";
|
||||||
|
import SafeImage from "./SafeImage";
|
||||||
import {
|
import {
|
||||||
Dog,
|
Dog,
|
||||||
Cat,
|
Cat,
|
||||||
@ -28,7 +29,6 @@ import {
|
|||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { usePetStore, PetProfile as GlobalPetProfile, Reminder, HealthLog } from "../lib/store/usePetStore";
|
import { usePetStore, PetProfile as GlobalPetProfile, Reminder, HealthLog } from "../lib/store/usePetStore";
|
||||||
import { useCartStore } from "../lib/store/cartStore";
|
import { useCartStore } from "../lib/store/cartStore";
|
||||||
import SafeImage from "./SafeImage";
|
|
||||||
import SmartAdvisor from "./SmartAdvisor";
|
import SmartAdvisor from "./SmartAdvisor";
|
||||||
import OrderDetailsModal from "./OrderDetailsModal";
|
import OrderDetailsModal from "./OrderDetailsModal";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
@ -554,10 +554,11 @@ export default function PetProfile({ initialView, advisorNeed, embedded = false
|
|||||||
{/* Photo preview container */}
|
{/* Photo preview container */}
|
||||||
<div className="relative w-20 h-20 rounded-2xl overflow-hidden bg-medical-gray-200 border-2 border-dashed border-medical-gray-300 flex items-center justify-center shrink-0">
|
<div className="relative w-20 h-20 rounded-2xl overflow-hidden bg-medical-gray-200 border-2 border-dashed border-medical-gray-300 flex items-center justify-center shrink-0">
|
||||||
{formData.imageUrl ? (
|
{formData.imageUrl ? (
|
||||||
<img
|
<SafeImage
|
||||||
src={formData.imageUrl.startsWith('http') ? formData.imageUrl : `${BASE_DOMAIN}${formData.imageUrl}`}
|
src={formData.imageUrl.startsWith('http') ? formData.imageUrl : `${BASE_DOMAIN}${formData.imageUrl}`}
|
||||||
alt="عکس پت"
|
alt="عکس پت"
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full"
|
||||||
|
imgClassName="w-full h-full object-cover"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Dog className="w-8 h-8 text-medical-gray-400" />
|
<Dog className="w-8 h-8 text-medical-gray-400" />
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import {
|
|||||||
Loader2,
|
Loader2,
|
||||||
Sparkles
|
Sparkles
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
|
import SafeImage from "./SafeImage";
|
||||||
|
|
||||||
interface PodcastInlinePlayerProps {
|
interface PodcastInlinePlayerProps {
|
||||||
podcast: {
|
podcast: {
|
||||||
@ -203,13 +204,11 @@ export default function PodcastInlinePlayer({ podcast }: PodcastInlinePlayerProp
|
|||||||
onClick={togglePlay}
|
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"
|
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
|
<SafeImage
|
||||||
src={displayCover}
|
src={displayCover}
|
||||||
alt={podcast.title || "کاور پادکست"}
|
alt={podcast.title || "کاور پادکست"}
|
||||||
className={`w-full h-full object-cover transition-transform duration-700 ${isPlaying ? "scale-105" : "scale-100"}`}
|
className="w-full h-full"
|
||||||
onError={(e) => {
|
imgClassName={`w-full h-full object-cover transition-transform duration-700 ${isPlaying ? "scale-105" : "scale-100"}`}
|
||||||
(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="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">
|
<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">
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import {
|
|||||||
Loader2,
|
Loader2,
|
||||||
Sparkles
|
Sparkles
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
|
import SafeImage from "./SafeImage";
|
||||||
|
|
||||||
interface PodcastPlayerModalProps {
|
interface PodcastPlayerModalProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@ -277,13 +278,11 @@ export default function PodcastPlayerModal({ isOpen, onClose, podcast }: Podcast
|
|||||||
{/* Cover Art Artwork */}
|
{/* Cover Art Artwork */}
|
||||||
<div className="relative group my-2">
|
<div className="relative group my-2">
|
||||||
<div className="w-40 h-40 sm:w-48 sm:h-48 rounded-3xl overflow-hidden shadow-2xl border-2 border-white/20 relative bg-neutral-800 flex items-center justify-center">
|
<div className="w-40 h-40 sm:w-48 sm:h-48 rounded-3xl overflow-hidden shadow-2xl border-2 border-white/20 relative bg-neutral-800 flex items-center justify-center">
|
||||||
<img
|
<SafeImage
|
||||||
src={displayCover}
|
src={displayCover}
|
||||||
alt={podcast.title || "کاور پادکست"}
|
alt={podcast.title || "کاور پادکست"}
|
||||||
className={`w-full h-full object-cover transition-transform duration-700 ${isPlaying ? "scale-105" : "scale-100"}`}
|
className="w-full h-full"
|
||||||
onError={(e) => {
|
imgClassName={`w-full h-full object-cover transition-transform duration-700 ${isPlaying ? "scale-105" : "scale-100"}`}
|
||||||
(e.target as HTMLImageElement).src = '/images/default-podcast.png';
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<div className="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent pointer-events-none" />
|
<div className="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent pointer-events-none" />
|
||||||
|
|
||||||
|
|||||||
@ -325,10 +325,11 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
|||||||
: 'border-medical-gray-200 hover:border-canina-blue/50 opacity-70 hover:opacity-100'
|
: 'border-medical-gray-200 hover:border-canina-blue/50 opacity-70 hover:opacity-100'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<img
|
<SafeImage
|
||||||
src={imgUrl}
|
src={imgUrl}
|
||||||
alt={`${product.name} - ${idx + 1}`}
|
alt={`${product.name} - ${idx + 1}`}
|
||||||
className="w-full h-full object-contain"
|
className="w-full h-full"
|
||||||
|
imgClassName="w-full h-full object-contain"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
@ -707,13 +708,11 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
|||||||
onClick={() => setIsVideoModalOpen(true)}
|
onClick={() => setIsVideoModalOpen(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-canina-blue/50 transition-all flex items-center justify-center shrink-0"
|
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-canina-blue/50 transition-all flex items-center justify-center shrink-0"
|
||||||
>
|
>
|
||||||
<img
|
<SafeImage
|
||||||
src={product.videoCover || product.image}
|
src={product.videoCover || product.image}
|
||||||
alt={product.videoTitle || product.name}
|
alt={product.videoTitle || product.name}
|
||||||
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
className="w-full h-full"
|
||||||
onError={(e) => {
|
imgClassName="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
||||||
(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="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 transition-transform">
|
<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 transition-transform">
|
||||||
@ -1137,10 +1136,11 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
|||||||
|
|
||||||
{/* Main Zoomed Image Container */}
|
{/* Main Zoomed Image Container */}
|
||||||
<div className="bg-white rounded-3xl p-6 sm:p-10 shadow-2xl border border-white/20 max-h-[75vh] flex items-center justify-center overflow-hidden w-full">
|
<div className="bg-white rounded-3xl p-6 sm:p-10 shadow-2xl border border-white/20 max-h-[75vh] flex items-center justify-center overflow-hidden w-full">
|
||||||
<img
|
<SafeImage
|
||||||
src={activeImage || product.image}
|
src={activeImage || product.image}
|
||||||
alt={product.name}
|
alt={product.name}
|
||||||
className="max-h-[60vh] max-w-full w-auto object-contain drop-shadow-2xl"
|
className="max-h-[60vh] max-w-full w-full"
|
||||||
|
imgClassName="max-h-[60vh] max-w-full w-auto object-contain drop-shadow-2xl mx-auto"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -1165,7 +1165,7 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
|||||||
: 'border-transparent opacity-60 hover:opacity-100'
|
: 'border-transparent opacity-60 hover:opacity-100'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<img src={img} alt="Thumbnail" className="w-full h-full object-contain" />
|
<SafeImage src={img} alt="Thumbnail" className="w-full h-full" imgClassName="w-full h-full object-contain" />
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -43,7 +43,23 @@ export default function SafeImage({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if external domain is in allowed remote patterns or relative path
|
||||||
const isExternal = typeof src === 'string' && (src.startsWith('http://') || src.startsWith('https://'));
|
const isExternal = typeof src === 'string' && (src.startsWith('http://') || src.startsWith('https://'));
|
||||||
|
const isBlobOrData = typeof src === 'string' && (src.startsWith('blob:') || src.startsWith('data:'));
|
||||||
|
const isAllowedHost = React.useMemo(() => {
|
||||||
|
if (!isExternal) return true;
|
||||||
|
try {
|
||||||
|
const url = new URL(src);
|
||||||
|
const allowedHosts = [
|
||||||
|
'canina.ir', 'api.canina.ir', 'stage.canina.ir', 'stageapi.canina.ir',
|
||||||
|
'apicanina.parsaaghayi.ir', 'canina.de', 'www.canina.de',
|
||||||
|
'images.unsplash.com', 'plus.unsplash.com', 'localhost', '127.0.0.1'
|
||||||
|
];
|
||||||
|
return allowedHosts.some(h => url.hostname === h || url.hostname.endsWith(`.${h}`));
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, [src, isExternal]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn("relative overflow-hidden group flex items-center justify-center", className)}>
|
<div className={cn("relative overflow-hidden group flex items-center justify-center", className)}>
|
||||||
@ -58,7 +74,7 @@ export default function SafeImage({
|
|||||||
width={500}
|
width={500}
|
||||||
height={500}
|
height={500}
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
unoptimized={isExternal}
|
unoptimized={isBlobOrData || !isAllowedHost}
|
||||||
className={cn(
|
className={cn(
|
||||||
"transition-all duration-700 w-full h-full",
|
"transition-all duration-700 w-full h-full",
|
||||||
imgClassName,
|
imgClassName,
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"0": "Roles",
|
"0": "Roles",
|
||||||
"1": "app.module.ts",
|
"1": "app.module.ts",
|
||||||
"2": "SettingsController",
|
"2": "SmsService",
|
||||||
"3": "productService.ts",
|
"3": "productService.ts",
|
||||||
"4": "VetGallery.tsx",
|
"4": "SafeImage.tsx",
|
||||||
"5": "CmsController",
|
"5": "CmsController",
|
||||||
"6": "tickets.controller.ts",
|
"6": "tickets.controller.ts",
|
||||||
"7": "PaginationDto",
|
"7": "PaginationDto",
|
||||||
@ -11,16 +11,16 @@
|
|||||||
"9": "devDependencies",
|
"9": "devDependencies",
|
||||||
"10": "CreateReviewDto",
|
"10": "CreateReviewDto",
|
||||||
"11": "Modal.tsx",
|
"11": "Modal.tsx",
|
||||||
"12": "useCartStore",
|
"12": "PetProfile.tsx",
|
||||||
"13": "app-audit-verification.e2e-spec.js",
|
"13": "main.ts",
|
||||||
"14": "userStore.ts",
|
"14": "lib/services/api.ts",
|
||||||
"15": "src/services/api.ts",
|
"15": "src/services/api.ts",
|
||||||
"16": "DoctorQueryDto",
|
"16": "DoctorQueryDto",
|
||||||
"17": "RedisService",
|
"17": "AuthService",
|
||||||
"18": "JwtAuthGuard",
|
"18": "JwtAuthGuard",
|
||||||
"19": "ProductsService",
|
"19": "ProductsService",
|
||||||
"20": "CreateVideoDto",
|
"20": "CreateVideoDto",
|
||||||
"21": "SmsService",
|
"21": "toPersian",
|
||||||
"22": "UserDashboard.tsx",
|
"22": "UserDashboard.tsx",
|
||||||
"23": "MenuService",
|
"23": "MenuService",
|
||||||
"24": "BE-001",
|
"24": "BE-001",
|
||||||
@ -34,7 +34,7 @@
|
|||||||
"32": "Button.tsx",
|
"32": "Button.tsx",
|
||||||
"33": "WholesaleApplyDto",
|
"33": "WholesaleApplyDto",
|
||||||
"34": "B2BService",
|
"34": "B2BService",
|
||||||
"35": "auth.service.ts",
|
"35": "AuthController",
|
||||||
"36": "FaqService",
|
"36": "FaqService",
|
||||||
"37": "راهنمای تست سیستم (Software Testing)",
|
"37": "راهنمای تست سیستم (Software Testing)",
|
||||||
"38": "Button",
|
"38": "Button",
|
||||||
@ -52,16 +52,16 @@
|
|||||||
"50": "devDependencies",
|
"50": "devDependencies",
|
||||||
"51": "BlogsController",
|
"51": "BlogsController",
|
||||||
"52": "PrescriptionsController",
|
"52": "PrescriptionsController",
|
||||||
"53": "SmartAdvisorController",
|
"53": "SmartAdvisorService",
|
||||||
"54": "UsersController",
|
"54": "UsersService",
|
||||||
"55": "UITexts.tsx",
|
"55": "UITexts.tsx",
|
||||||
"56": "SettingsService",
|
"56": "Orders.tsx",
|
||||||
"57": "Role & Core Objective",
|
"57": "Role & Core Objective",
|
||||||
"58": "ContactService",
|
"58": "ContactService",
|
||||||
"59": "compilerOptions",
|
"59": "compilerOptions",
|
||||||
"60": "admin.service.ts",
|
"60": "admin.service.ts",
|
||||||
"61": "CreateEBankCheckoutDto",
|
"61": "CreateEBankCheckoutDto",
|
||||||
"62": "OrdersService",
|
"62": "WikiController",
|
||||||
"63": "dependencies",
|
"63": "dependencies",
|
||||||
"64": "compilerOptions",
|
"64": "compilerOptions",
|
||||||
"65": "ProductPage.tsx",
|
"65": "ProductPage.tsx",
|
||||||
@ -75,7 +75,7 @@
|
|||||||
"73": "Operational Rules & Boundaries",
|
"73": "Operational Rules & Boundaries",
|
||||||
"74": "WikiController",
|
"74": "WikiController",
|
||||||
"75": "PetsController",
|
"75": "PetsController",
|
||||||
"76": "Orders.tsx",
|
"76": "PaymentService",
|
||||||
"77": "seo.module.ts",
|
"77": "seo.module.ts",
|
||||||
"78": "AdminService",
|
"78": "AdminService",
|
||||||
"79": "🏢 AI Software Agency — Master Orchestration Protocol v3",
|
"79": "🏢 AI Software Agency — Master Orchestration Protocol v3",
|
||||||
@ -84,29 +84,29 @@
|
|||||||
"82": "scripts",
|
"82": "scripts",
|
||||||
"83": "dependencies",
|
"83": "dependencies",
|
||||||
"84": "Role & Core Objective",
|
"84": "Role & Core Objective",
|
||||||
"85": "UsersService",
|
"85": "auth.service.ts",
|
||||||
"86": "zibal.service.ts",
|
"86": "zibal.service.ts",
|
||||||
"87": "dependencies",
|
"87": "dependencies",
|
||||||
"88": "components/Skeleton.tsx",
|
"88": "HomeClient.tsx",
|
||||||
"89": "seed-products.ts",
|
"89": "seed-products.ts",
|
||||||
"90": "SmsLogQueryDto",
|
"90": "SmsLogQueryDto",
|
||||||
"91": "Reconciled Audit Roles & Assignments",
|
"91": "Reconciled Audit Roles & Assignments",
|
||||||
"92": "OrdersController",
|
"92": "OrdersService",
|
||||||
"93": "lib/services/api.ts",
|
"93": "app-audit-verification.e2e-spec.js",
|
||||||
"94": "Phase 3.1 — Human Review Preparation and Master Backlog Critique",
|
"94": "Phase 3.1 — Human Review Preparation and Master Backlog Critique",
|
||||||
"95": "getSeoConfig",
|
"95": "getSeoConfig",
|
||||||
"96": "compilerOptions",
|
"96": "compilerOptions",
|
||||||
"97": "prisma",
|
"97": "prisma",
|
||||||
"98": "scripts",
|
"98": "scripts",
|
||||||
"99": "AuthController",
|
"99": "HomeController",
|
||||||
"100": "Deep Audit Summary Report",
|
"100": "Deep Audit Summary Report",
|
||||||
"101": "Operational Rules & Boundaries",
|
"101": "Operational Rules & Boundaries",
|
||||||
"102": "jest",
|
"102": "jest",
|
||||||
"103": "Comprehensive Change Log",
|
"103": "Comprehensive Change Log",
|
||||||
"104": "Coupons.tsx",
|
"104": "Coupons.tsx",
|
||||||
"105": "Operational Rules & Boundaries",
|
"105": "Operational Rules & Boundaries",
|
||||||
"106": "auth.module.ts",
|
"106": "auth.controller.ts",
|
||||||
"107": "HomeController",
|
"107": "payment.service.ts",
|
||||||
"108": "PrismaService",
|
"108": "PrismaService",
|
||||||
"109": "1. Summary of Integrity Repairs Performed",
|
"109": "1. Summary of Integrity Repairs Performed",
|
||||||
"110": "Operational Rules & Boundaries",
|
"110": "Operational Rules & Boundaries",
|
||||||
@ -143,7 +143,7 @@
|
|||||||
"141": "application/package.json",
|
"141": "application/package.json",
|
||||||
"142": "start-dev.js",
|
"142": "start-dev.js",
|
||||||
"143": "generate-openapi.js",
|
"143": "generate-openapi.js",
|
||||||
"144": "PaymentService",
|
"144": "RegisterDto",
|
||||||
"145": "eslint-config-prettier",
|
"145": "eslint-config-prettier",
|
||||||
"146": "System Discovery",
|
"146": "System Discovery",
|
||||||
"147": "Media.tsx",
|
"147": "Media.tsx",
|
||||||
@ -175,10 +175,10 @@
|
|||||||
"173": "Phase 3 Audit Traceability Matrix",
|
"173": "Phase 3 Audit Traceability Matrix",
|
||||||
"174": "rebuild_honest_ledger.js",
|
"174": "rebuild_honest_ledger.js",
|
||||||
"175": "validate_evidence_grade.js",
|
"175": "validate_evidence_grade.js",
|
||||||
"176": "AuthService",
|
"176": "InitiatePaymentDto",
|
||||||
"177": "blog/page.tsx",
|
"177": "blog/page.tsx",
|
||||||
"178": "prettier",
|
"178": "prettier",
|
||||||
"179": "PodcastPlayerModal.tsx",
|
"179": "VerifyOtpDto",
|
||||||
"180": "API Contract Specification",
|
"180": "API Contract Specification",
|
||||||
"181": "⚙️ Backend Technical Review (05_dev_backend)",
|
"181": "⚙️ Backend Technical Review (05_dev_backend)",
|
||||||
"182": "🎨 Frontend & Admin Panel Technical Review (06_dev_frontend)",
|
"182": "🎨 Frontend & Admin Panel Technical Review (06_dev_frontend)",
|
||||||
@ -223,7 +223,7 @@
|
|||||||
"221": "Textarea.tsx",
|
"221": "Textarea.tsx",
|
||||||
"222": "admin-panel/tsconfig.json",
|
"222": "admin-panel/tsconfig.json",
|
||||||
"223": "ts-jest",
|
"223": "ts-jest",
|
||||||
"224": "payment.service.ts",
|
"224": "SendOtpDto",
|
||||||
"225": "next.config.ts",
|
"225": "next.config.ts",
|
||||||
"226": "Shabnam Font README",
|
"226": "Shabnam Font README",
|
||||||
"227": "AGENTS.md",
|
"227": "AGENTS.md",
|
||||||
@ -306,19 +306,17 @@
|
|||||||
"304": "@testing-library/react",
|
"304": "@testing-library/react",
|
||||||
"305": "@types/react",
|
"305": "@types/react",
|
||||||
"306": "globals",
|
"306": "globals",
|
||||||
"307": "RegisterDto",
|
"307": "@types/react-dom",
|
||||||
"308": "vitest",
|
"308": "vitest",
|
||||||
"309": "axios",
|
"309": "axios",
|
||||||
"310": "tailwindcss",
|
"310": "tailwindcss",
|
||||||
"311": "InitiatePaymentDto",
|
"311": "track/page.tsx",
|
||||||
"312": "AddressDto",
|
"312": "BlogsModule",
|
||||||
"313": "track/page.tsx",
|
"313": "app/page.tsx",
|
||||||
"314": "@eslint/js",
|
"314": "@eslint/js",
|
||||||
"315": "typescript",
|
"315": "typescript",
|
||||||
"316": "app/page.tsx",
|
"316": "search/page.tsx",
|
||||||
"317": "search/page.tsx",
|
"317": "shop/page.tsx",
|
||||||
"318": "shop/page.tsx",
|
"318": "MaskableField.tsx",
|
||||||
"319": "MaskableField.tsx",
|
|
||||||
"320": "eslint-config-next",
|
|
||||||
"324": "typescript-eslint"
|
"324": "typescript-eslint"
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -1,11 +1,11 @@
|
|||||||
# Graph Report - caninairan (2026-08-24)
|
# Graph Report - caninairan (2026-08-24)
|
||||||
|
|
||||||
## Corpus Check
|
## Corpus Check
|
||||||
- 544 files · ~1,300,704 words
|
- 544 files · ~1,300,486 words
|
||||||
- Verdict: corpus is large enough that graph structure adds value.
|
- Verdict: corpus is large enough that graph structure adds value.
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
- 3905 nodes · 7020 edges · 322 communities (201 shown, 121 thin omitted)
|
- 3905 nodes · 7028 edges · 320 communities (201 shown, 119 thin omitted)
|
||||||
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 270 edges (avg confidence: 0.8)
|
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 270 edges (avg confidence: 0.8)
|
||||||
- Token cost: 0 input · 0 output
|
- Token cost: 0 input · 0 output
|
||||||
|
|
||||||
@ -17,9 +17,9 @@
|
|||||||
## Community Hubs (Navigation)
|
## Community Hubs (Navigation)
|
||||||
- Roles
|
- Roles
|
||||||
- app.module.ts
|
- app.module.ts
|
||||||
- SettingsController
|
- SmsService
|
||||||
- productService.ts
|
- productService.ts
|
||||||
- VetGallery.tsx
|
- SafeImage.tsx
|
||||||
- CmsController
|
- CmsController
|
||||||
- tickets.controller.ts
|
- tickets.controller.ts
|
||||||
- PaginationDto
|
- PaginationDto
|
||||||
@ -27,16 +27,16 @@
|
|||||||
- devDependencies
|
- devDependencies
|
||||||
- CreateReviewDto
|
- CreateReviewDto
|
||||||
- Modal.tsx
|
- Modal.tsx
|
||||||
- useCartStore
|
- PetProfile.tsx
|
||||||
- app-audit-verification.e2e-spec.js
|
- main.ts
|
||||||
- userStore.ts
|
- lib/services/api.ts
|
||||||
- src/services/api.ts
|
- src/services/api.ts
|
||||||
- DoctorQueryDto
|
- DoctorQueryDto
|
||||||
- RedisService
|
- AuthService
|
||||||
- JwtAuthGuard
|
- JwtAuthGuard
|
||||||
- ProductsService
|
- ProductsService
|
||||||
- CreateVideoDto
|
- CreateVideoDto
|
||||||
- SmsService
|
- toPersian
|
||||||
- UserDashboard.tsx
|
- UserDashboard.tsx
|
||||||
- MenuService
|
- MenuService
|
||||||
- BE-001
|
- BE-001
|
||||||
@ -50,7 +50,7 @@
|
|||||||
- Button.tsx
|
- Button.tsx
|
||||||
- WholesaleApplyDto
|
- WholesaleApplyDto
|
||||||
- B2BService
|
- B2BService
|
||||||
- auth.service.ts
|
- AuthController
|
||||||
- FaqService
|
- FaqService
|
||||||
- راهنمای تست سیستم (Software Testing)
|
- راهنمای تست سیستم (Software Testing)
|
||||||
- Button
|
- Button
|
||||||
@ -68,16 +68,16 @@
|
|||||||
- devDependencies
|
- devDependencies
|
||||||
- BlogsController
|
- BlogsController
|
||||||
- PrescriptionsController
|
- PrescriptionsController
|
||||||
- SmartAdvisorController
|
- SmartAdvisorService
|
||||||
- UsersController
|
- UsersService
|
||||||
- UITexts.tsx
|
- UITexts.tsx
|
||||||
- SettingsService
|
- Orders.tsx
|
||||||
- Role & Core Objective
|
- Role & Core Objective
|
||||||
- ContactService
|
- ContactService
|
||||||
- compilerOptions
|
- compilerOptions
|
||||||
- admin.service.ts
|
- admin.service.ts
|
||||||
- CreateEBankCheckoutDto
|
- CreateEBankCheckoutDto
|
||||||
- OrdersService
|
- WikiController
|
||||||
- dependencies
|
- dependencies
|
||||||
- compilerOptions
|
- compilerOptions
|
||||||
- ProductPage.tsx
|
- ProductPage.tsx
|
||||||
@ -91,7 +91,7 @@
|
|||||||
- Operational Rules & Boundaries
|
- Operational Rules & Boundaries
|
||||||
- WikiController
|
- WikiController
|
||||||
- PetsController
|
- PetsController
|
||||||
- Orders.tsx
|
- PaymentService
|
||||||
- seo.module.ts
|
- seo.module.ts
|
||||||
- AdminService
|
- AdminService
|
||||||
- 🏢 AI Software Agency — Master Orchestration Protocol v3
|
- 🏢 AI Software Agency — Master Orchestration Protocol v3
|
||||||
@ -100,29 +100,29 @@
|
|||||||
- scripts
|
- scripts
|
||||||
- dependencies
|
- dependencies
|
||||||
- Role & Core Objective
|
- Role & Core Objective
|
||||||
- UsersService
|
- auth.service.ts
|
||||||
- zibal.service.ts
|
- zibal.service.ts
|
||||||
- dependencies
|
- dependencies
|
||||||
- components/Skeleton.tsx
|
- HomeClient.tsx
|
||||||
- seed-products.ts
|
- seed-products.ts
|
||||||
- SmsLogQueryDto
|
- SmsLogQueryDto
|
||||||
- Reconciled Audit Roles & Assignments
|
- Reconciled Audit Roles & Assignments
|
||||||
- OrdersController
|
- OrdersService
|
||||||
- lib/services/api.ts
|
- app-audit-verification.e2e-spec.js
|
||||||
- Phase 3.1 — Human Review Preparation and Master Backlog Critique
|
- Phase 3.1 — Human Review Preparation and Master Backlog Critique
|
||||||
- getSeoConfig
|
- getSeoConfig
|
||||||
- compilerOptions
|
- compilerOptions
|
||||||
- prisma
|
- prisma
|
||||||
- scripts
|
- scripts
|
||||||
- AuthController
|
- HomeController
|
||||||
- Deep Audit Summary Report
|
- Deep Audit Summary Report
|
||||||
- Operational Rules & Boundaries
|
- Operational Rules & Boundaries
|
||||||
- jest
|
- jest
|
||||||
- Comprehensive Change Log
|
- Comprehensive Change Log
|
||||||
- Coupons.tsx
|
- Coupons.tsx
|
||||||
- Operational Rules & Boundaries
|
- Operational Rules & Boundaries
|
||||||
- auth.module.ts
|
- auth.controller.ts
|
||||||
- HomeController
|
- payment.service.ts
|
||||||
- PrismaService
|
- PrismaService
|
||||||
- 1. Summary of Integrity Repairs Performed
|
- 1. Summary of Integrity Repairs Performed
|
||||||
- Operational Rules & Boundaries
|
- Operational Rules & Boundaries
|
||||||
@ -159,7 +159,7 @@
|
|||||||
- application/package.json
|
- application/package.json
|
||||||
- start-dev.js
|
- start-dev.js
|
||||||
- generate-openapi.js
|
- generate-openapi.js
|
||||||
- PaymentService
|
- RegisterDto
|
||||||
- eslint-config-prettier
|
- eslint-config-prettier
|
||||||
- System Discovery
|
- System Discovery
|
||||||
- Media.tsx
|
- Media.tsx
|
||||||
@ -191,10 +191,10 @@
|
|||||||
- Phase 3 Audit Traceability Matrix
|
- Phase 3 Audit Traceability Matrix
|
||||||
- rebuild_honest_ledger.js
|
- rebuild_honest_ledger.js
|
||||||
- validate_evidence_grade.js
|
- validate_evidence_grade.js
|
||||||
- AuthService
|
- InitiatePaymentDto
|
||||||
- blog/page.tsx
|
- blog/page.tsx
|
||||||
- prettier
|
- prettier
|
||||||
- PodcastPlayerModal.tsx
|
- VerifyOtpDto
|
||||||
- API Contract Specification
|
- API Contract Specification
|
||||||
- ⚙️ Backend Technical Review (05_dev_backend)
|
- ⚙️ Backend Technical Review (05_dev_backend)
|
||||||
- 🎨 Frontend & Admin Panel Technical Review (06_dev_frontend)
|
- 🎨 Frontend & Admin Panel Technical Review (06_dev_frontend)
|
||||||
@ -239,7 +239,7 @@
|
|||||||
- Textarea.tsx
|
- Textarea.tsx
|
||||||
- admin-panel/tsconfig.json
|
- admin-panel/tsconfig.json
|
||||||
- ts-jest
|
- ts-jest
|
||||||
- payment.service.ts
|
- SendOtpDto
|
||||||
- next.config.ts
|
- next.config.ts
|
||||||
- Shabnam Font README
|
- Shabnam Font README
|
||||||
- AGENTS.md
|
- AGENTS.md
|
||||||
@ -307,18 +307,16 @@
|
|||||||
- @testing-library/react
|
- @testing-library/react
|
||||||
- @types/react
|
- @types/react
|
||||||
- globals
|
- globals
|
||||||
- RegisterDto
|
- @types/react-dom
|
||||||
- vitest
|
- vitest
|
||||||
- InitiatePaymentDto
|
|
||||||
- AddressDto
|
|
||||||
- track/page.tsx
|
- track/page.tsx
|
||||||
|
- BlogsModule
|
||||||
|
- app/page.tsx
|
||||||
- @eslint/js
|
- @eslint/js
|
||||||
- typescript
|
- typescript
|
||||||
- app/page.tsx
|
|
||||||
- search/page.tsx
|
- search/page.tsx
|
||||||
- shop/page.tsx
|
- shop/page.tsx
|
||||||
- MaskableField.tsx
|
- MaskableField.tsx
|
||||||
- eslint-config-next
|
|
||||||
- typescript-eslint
|
- typescript-eslint
|
||||||
|
|
||||||
## God Nodes (most connected - your core abstractions)
|
## God Nodes (most connected - your core abstractions)
|
||||||
@ -350,27 +348,27 @@
|
|||||||
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/api.ts`
|
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/api.ts`
|
||||||
- 4-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/orderService.ts -> frontend/application/lib/services/api.ts`
|
- 4-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/orderService.ts -> frontend/application/lib/services/api.ts`
|
||||||
|
|
||||||
## Communities (322 total, 121 thin omitted)
|
## Communities (320 total, 119 thin omitted)
|
||||||
|
|
||||||
### Community 0 - "Roles"
|
### Community 0 - "Roles"
|
||||||
Cohesion: 0.24
|
Cohesion: 0.24
|
||||||
Nodes (13): Roles(), PaymentController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get (+5 more)
|
Nodes (13): Roles(), PaymentController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get (+5 more)
|
||||||
|
|
||||||
### Community 1 - "app.module.ts"
|
### Community 1 - "app.module.ts"
|
||||||
Cohesion: 0.07
|
Cohesion: 0.08
|
||||||
Nodes (36): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+28 more)
|
Nodes (34): AdminModule, Module, B2BModule, Module, BannersModule, Module, CmsModule, Module (+26 more)
|
||||||
|
|
||||||
### Community 2 - "SettingsController"
|
### Community 2 - "SmsService"
|
||||||
Cohesion: 0.18
|
Cohesion: 0.06
|
||||||
Nodes (15): SettingsController, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller, Delete (+7 more)
|
Nodes (20): SmsLogQuery, SmsService, Injectable, SettingsController, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags (+12 more)
|
||||||
|
|
||||||
### Community 3 - "productService.ts"
|
### Community 3 - "productService.ts"
|
||||||
Cohesion: 0.08
|
Cohesion: 0.09
|
||||||
Nodes (29): BlogPost, CartDrawer(), CatalogPageSpread(), CatalogPageSpreadProps, CategoryMeta, getFormBadge(), getSpeciesBadge(), FlipbookCatalog() (+21 more)
|
Nodes (25): BlogPost, CatalogPageSpread(), CatalogPageSpreadProps, CategoryMeta, getFormBadge(), getSpeciesBadge(), FlipbookCatalog(), FlipbookCatalogProps (+17 more)
|
||||||
|
|
||||||
### Community 4 - "VetGallery.tsx"
|
### Community 4 - "SafeImage.tsx"
|
||||||
Cohesion: 0.22
|
Cohesion: 0.09
|
||||||
Nodes (9): DisplayVideoItem, FALLBACK_VIDEOS, TestimonialItem, VetGallery(), PLAYBACK_RATES, VideoModalPlayer(), VideoModalPlayerProps, Video (+1 more)
|
Nodes (20): BlogPost, BlogPreviewSection(), OrderDetailsModalProps, PLAYBACK_RATES, PodcastPlayerModal(), PodcastPlayerModalProps, SafeImage(), SafeImageProps (+12 more)
|
||||||
|
|
||||||
### Community 5 - "CmsController"
|
### Community 5 - "CmsController"
|
||||||
Cohesion: 0.09
|
Cohesion: 0.09
|
||||||
@ -381,12 +379,12 @@ Cohesion: 0.09
|
|||||||
Nodes (29): AdminUpdateTicketDto, CreateTicketDto, ReplyTicketDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString (+21 more)
|
Nodes (29): AdminUpdateTicketDto, CreateTicketDto, ReplyTicketDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString (+21 more)
|
||||||
|
|
||||||
### Community 7 - "PaginationDto"
|
### Community 7 - "PaginationDto"
|
||||||
Cohesion: 0.05
|
Cohesion: 0.06
|
||||||
Nodes (28): BlogsService, Injectable, BlogsModule, Module, BlogsService, Injectable, PaginationDto, SortOrder (+20 more)
|
Nodes (17): BlogsService, Injectable, BlogsService, Injectable, PaginationDto, SortOrder, ApiPropertyOptional, IsEnum (+9 more)
|
||||||
|
|
||||||
### Community 8 - "admin.module.ts"
|
### Community 8 - "admin.module.ts"
|
||||||
Cohesion: 0.09
|
Cohesion: 0.10
|
||||||
Nodes (15): AdminModule, Module, ReportsController, ApiBearerAuth, ApiOperation, ApiTags, Controller, Get (+7 more)
|
Nodes (13): ReportsController, ApiBearerAuth, ApiOperation, ApiTags, Controller, Get, UseGuards, ReportsService (+5 more)
|
||||||
|
|
||||||
### Community 9 - "devDependencies"
|
### Community 9 - "devDependencies"
|
||||||
Cohesion: 0.22
|
Cohesion: 0.22
|
||||||
@ -400,17 +398,17 @@ Nodes (29): CreateReviewDto, ApiProperty, IsInt, IsNotEmpty, IsOptional, IsStrin
|
|||||||
Cohesion: 0.07
|
Cohesion: 0.07
|
||||||
Nodes (30): ConfirmModal(), ConfirmModalProps, getFileType(), Media, MediaSelector(), MediaSelectorProps, maxWidthClasses, Modal() (+22 more)
|
Nodes (30): ConfirmModal(), ConfirmModalProps, getFileType(), Media, MediaSelector(), MediaSelectorProps, maxWidthClasses, Modal() (+22 more)
|
||||||
|
|
||||||
### Community 12 - "useCartStore"
|
### Community 12 - "PetProfile.tsx"
|
||||||
|
Cohesion: 0.13
|
||||||
|
Nodes (15): FeaturedProducts(), ProductCard(), OrderSuccess(), OrderRowSkeleton(), PetProfileSkeleton(), ProductCardSkeleton(), Skeleton(), SkeletonProps (+7 more)
|
||||||
|
|
||||||
|
### Community 13 - "main.ts"
|
||||||
Cohesion: 0.12
|
Cohesion: 0.12
|
||||||
Nodes (24): ClientLayout(), ArchiveProductCard(), CheckoutPage(), ProductCard(), Header(), MENU_ICONS, OrderSuccess(), PrescriptionUploadModal() (+16 more)
|
Nodes (8): AppModule, Module, CustomHttpExceptionFilter, Catch, PrismaExceptionFilter, Catch, DecimalInterceptor, Injectable
|
||||||
|
|
||||||
### Community 13 - "app-audit-verification.e2e-spec.js"
|
### Community 14 - "lib/services/api.ts"
|
||||||
Cohesion: 0.07
|
Cohesion: 0.06
|
||||||
Nodes (22): AppModule, Module, CustomHttpExceptionFilter, Catch, PrismaExceptionFilter, Catch, DecimalInterceptor, Injectable (+14 more)
|
Nodes (22): ContactInfoItem, PrescriptionUploadModal(), PrescriptionUploadModalProps, api, ApiErrorPayload, baseURL, ApiErr, AuthResponse (+14 more)
|
||||||
|
|
||||||
### Community 14 - "userStore.ts"
|
|
||||||
Cohesion: 0.10
|
|
||||||
Nodes (14): AuthModal(), AuthModalProps, extractOtpFromText(), LoginModal(), LoginModalProps, ApiErr, AuthResponse, AuthService (+6 more)
|
|
||||||
|
|
||||||
### Community 15 - "src/services/api.ts"
|
### Community 15 - "src/services/api.ts"
|
||||||
Cohesion: 0.07
|
Cohesion: 0.07
|
||||||
@ -420,13 +418,13 @@ Nodes (35): Layout(), ProtectedRoute(), MenuGroup, Sidebar(), SidebarProps, SubM
|
|||||||
Cohesion: 0.09
|
Cohesion: 0.09
|
||||||
Nodes (24): DoctorsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+16 more)
|
Nodes (24): DoctorsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+16 more)
|
||||||
|
|
||||||
### Community 17 - "RedisService"
|
### Community 17 - "AuthService"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.16
|
||||||
Nodes (10): ApiExcludeController, MetricsController, Controller, Get, Res, RedisModule, Global, Module (+2 more)
|
Nodes (3): AuthService, Injectable, normalizeMobile()
|
||||||
|
|
||||||
### Community 18 - "JwtAuthGuard"
|
### Community 18 - "JwtAuthGuard"
|
||||||
Cohesion: 0.20
|
Cohesion: 0.17
|
||||||
Nodes (7): JwtAuthGuard, Injectable, ROLES_KEY, RequestWithUser, RolesGuard, Injectable, UserReqPayload
|
Nodes (8): JwtAuthGuard, Injectable, B2BWholesaleOrderItem, ROLES_KEY, RequestWithUser, RolesGuard, Injectable, UserReqPayload
|
||||||
|
|
||||||
### Community 19 - "ProductsService"
|
### Community 19 - "ProductsService"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.10
|
||||||
@ -436,13 +434,17 @@ Nodes (19): GetProductsDto, ApiPropertyOptional, IsEnum, IsOptional, IsString, P
|
|||||||
Cohesion: 0.07
|
Cohesion: 0.07
|
||||||
Nodes (32): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, UpdateVideoDto (+24 more)
|
Nodes (32): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, UpdateVideoDto (+24 more)
|
||||||
|
|
||||||
|
### Community 21 - "toPersian"
|
||||||
|
Cohesion: 0.15
|
||||||
|
Nodes (23): VerifyContent(), ArchiveProductCard(), AuthModal(), AuthModalProps, extractOtpFromText(), B2BPortal(), BackButton(), BackButtonProps (+15 more)
|
||||||
|
|
||||||
### Community 22 - "UserDashboard.tsx"
|
### Community 22 - "UserDashboard.tsx"
|
||||||
Cohesion: 0.09
|
Cohesion: 0.13
|
||||||
Nodes (32): VerifyContent(), AddressModal(), AddressModalProps, BackButton(), BackButtonProps, BlogPost, BlogPreviewSection(), DeleteConfirmModal() (+24 more)
|
Nodes (17): AddressModal(), AddressModalProps, DeleteConfirmModal(), DeleteConfirmModalProps, OrderDetailsModal(), SearchableSelect(), SearchableSelectProps, PRESET_AMOUNTS (+9 more)
|
||||||
|
|
||||||
### Community 23 - "MenuService"
|
### Community 23 - "MenuService"
|
||||||
Cohesion: 0.12
|
Cohesion: 0.11
|
||||||
Nodes (16): MenuController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+8 more)
|
Nodes (18): MenuController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, Delete (+10 more)
|
||||||
|
|
||||||
### Community 24 - "BE-001"
|
### Community 24 - "BE-001"
|
||||||
Cohesion: 0.06
|
Cohesion: 0.06
|
||||||
@ -488,9 +490,9 @@ Nodes (20): ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString,
|
|||||||
Cohesion: 0.14
|
Cohesion: 0.14
|
||||||
Nodes (14): B2BController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get, Param (+6 more)
|
Nodes (14): B2BController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get, Param (+6 more)
|
||||||
|
|
||||||
### Community 35 - "auth.service.ts"
|
### Community 35 - "AuthController"
|
||||||
Cohesion: 0.08
|
Cohesion: 0.25
|
||||||
Nodes (25): AdminLoginInput, LoginInput, RegisterInput, AdminLoginDto, ApiProperty, IsEmail, IsNotEmpty, IsString (+17 more)
|
Nodes (12): AuthController, ApiBadRequestResponse, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+4 more)
|
||||||
|
|
||||||
### Community 36 - "FaqService"
|
### Community 36 - "FaqService"
|
||||||
Cohesion: 0.12
|
Cohesion: 0.12
|
||||||
@ -550,7 +552,7 @@ Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, glo
|
|||||||
|
|
||||||
### Community 50 - "devDependencies"
|
### Community 50 - "devDependencies"
|
||||||
Cohesion: 0.13
|
Cohesion: 0.13
|
||||||
Nodes (15): devDependencies, eslint, jsdom, tailwindcss, @tailwindcss/postcss, @types/node, @types/react-dom, @vitejs/plugin-react (+7 more)
|
Nodes (15): eslint-config-next, devDependencies, eslint, eslint-config-next, jsdom, tailwindcss, @tailwindcss/postcss, @types/node (+7 more)
|
||||||
|
|
||||||
### Community 51 - "BlogsController"
|
### Community 51 - "BlogsController"
|
||||||
Cohesion: 0.14
|
Cohesion: 0.14
|
||||||
@ -560,21 +562,21 @@ Nodes (16): BlogsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Bod
|
|||||||
Cohesion: 0.16
|
Cohesion: 0.16
|
||||||
Nodes (12): PrescriptionsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get, Param (+4 more)
|
Nodes (12): PrescriptionsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get, Param (+4 more)
|
||||||
|
|
||||||
### Community 53 - "SmartAdvisorController"
|
### Community 53 - "SmartAdvisorService"
|
||||||
Cohesion: 0.14
|
Cohesion: 0.11
|
||||||
Nodes (12): SmartAdvisorController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+4 more)
|
Nodes (16): SmartAdvisorController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+8 more)
|
||||||
|
|
||||||
### Community 54 - "UsersController"
|
### Community 54 - "UsersService"
|
||||||
Cohesion: 0.21
|
Cohesion: 0.05
|
||||||
Nodes (16): ApiBadRequestResponse, ApiBearerAuth, ApiCreatedResponse, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+8 more)
|
Nodes (42): DEFAULT_JWT_REFRESH_SECRET, DEFAULT_JWT_SECRET, getJwtSecret(), AuthModule, Module, JwtPayload, JwtStrategy, Injectable (+34 more)
|
||||||
|
|
||||||
### Community 55 - "UITexts.tsx"
|
### Community 55 - "UITexts.tsx"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.10
|
||||||
Nodes (18): ICON_REGISTRY, IconPickerModal(), IconPickerModalProps, COLORS, RichTextEditor(), RichTextEditorProps, ToggleSwitch(), ToggleSwitchProps (+10 more)
|
Nodes (18): ICON_REGISTRY, IconPickerModal(), IconPickerModalProps, COLORS, RichTextEditor(), RichTextEditorProps, ToggleSwitch(), ToggleSwitchProps (+10 more)
|
||||||
|
|
||||||
### Community 56 - "SettingsService"
|
### Community 56 - "Orders.tsx"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.09
|
||||||
Nodes (3): SmsLogQuery, SettingsService, Injectable
|
Nodes (20): Pagination(), PaginationProps, Skeleton(), getPaymentMethodLabel(), Order, ORDER_STATUS_MAP, OrderItem, Orders() (+12 more)
|
||||||
|
|
||||||
### Community 57 - "Role & Core Objective"
|
### Community 57 - "Role & Core Objective"
|
||||||
Cohesion: 0.09
|
Cohesion: 0.09
|
||||||
@ -596,9 +598,9 @@ Nodes (14): CouponInput, CouponTargetInput, PaginationQuery, CreateUserDto, ApiP
|
|||||||
Cohesion: 0.22
|
Cohesion: 0.22
|
||||||
Nodes (8): CreateEBankCheckoutDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsNumber, IsOptional, IsString, Min
|
Nodes (8): CreateEBankCheckoutDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsNumber, IsOptional, IsString, Min
|
||||||
|
|
||||||
### Community 62 - "OrdersService"
|
### Community 62 - "WikiController"
|
||||||
Cohesion: 0.09
|
Cohesion: 0.13
|
||||||
Nodes (19): CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional (+11 more)
|
Nodes (13): ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags, Controller, Get, Param, Query (+5 more)
|
||||||
|
|
||||||
### Community 63 - "dependencies"
|
### Community 63 - "dependencies"
|
||||||
Cohesion: 0.10
|
Cohesion: 0.10
|
||||||
@ -617,8 +619,8 @@ Cohesion: 0.12
|
|||||||
Nodes (8): ApiOperation, ApiQuery, Get, Query, AdminQueryDto, ApiPropertyOptional, IsOptional, IsString
|
Nodes (8): ApiOperation, ApiQuery, Get, Query, AdminQueryDto, ApiPropertyOptional, IsOptional, IsString
|
||||||
|
|
||||||
### Community 67 - "PetsController"
|
### Community 67 - "PetsController"
|
||||||
Cohesion: 0.11
|
Cohesion: 0.10
|
||||||
Nodes (13): PetsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Controller, Delete, Get (+5 more)
|
Nodes (14): PetsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Controller, Delete, Get (+6 more)
|
||||||
|
|
||||||
### Community 68 - "BlogsController"
|
### Community 68 - "BlogsController"
|
||||||
Cohesion: 0.17
|
Cohesion: 0.17
|
||||||
@ -652,10 +654,6 @@ Nodes (14): ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, Body, Controller, De
|
|||||||
Cohesion: 0.05
|
Cohesion: 0.05
|
||||||
Nodes (47): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, CreatePetDto, ApiProperty (+39 more)
|
Nodes (47): CreateHealthLogDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString, CreatePetDto, ApiProperty (+39 more)
|
||||||
|
|
||||||
### Community 76 - "Orders.tsx"
|
|
||||||
Cohesion: 0.09
|
|
||||||
Nodes (20): Pagination(), PaginationProps, Skeleton(), getPaymentMethodLabel(), Order, ORDER_STATUS_MAP, OrderItem, Orders() (+12 more)
|
|
||||||
|
|
||||||
### Community 77 - "seo.module.ts"
|
### Community 77 - "seo.module.ts"
|
||||||
Cohesion: 0.16
|
Cohesion: 0.16
|
||||||
Nodes (10): SeoController, ApiOperation, ApiTags, Controller, Get, Param, SeoModule, Module (+2 more)
|
Nodes (10): SeoController, ApiOperation, ApiTags, Controller, Get, Param, SeoModule, Module (+2 more)
|
||||||
@ -688,9 +686,9 @@ Nodes (21): dependencies, axios, lucide-react, react, react-dom, react-hot-toast
|
|||||||
Cohesion: 0.12
|
Cohesion: 0.12
|
||||||
Nodes (16): 1. Active Secret Scanning (All Modified Files), 2. Docker Container Verification (if Dockerfile exists), 3. CI/CD Basic Check (if `.github/workflows/` exists), 4. Failure Routing Protocol, 5. Forbidden Actions, ENFORCE MODE — Normal Operation, Expected JSON Output Schema, Operational Rules & Boundaries (+8 more)
|
Nodes (16): 1. Active Secret Scanning (All Modified Files), 2. Docker Container Verification (if Dockerfile exists), 3. CI/CD Basic Check (if `.github/workflows/` exists), 4. Failure Routing Protocol, 5. Forbidden Actions, ENFORCE MODE — Normal Operation, Expected JSON Output Schema, Operational Rules & Boundaries (+8 more)
|
||||||
|
|
||||||
### Community 85 - "UsersService"
|
### Community 85 - "auth.service.ts"
|
||||||
Cohesion: 0.12
|
Cohesion: 0.15
|
||||||
Nodes (10): normalizeMobile(), ApiPropertyOptional, IsEmail, IsOptional, IsString, MinLength, UpdateProfileDto, Injectable (+2 more)
|
Nodes (8): AdminLoginInput, LoginInput, RegisterInput, RedisModule, Global, Module, RedisService, Injectable
|
||||||
|
|
||||||
### Community 86 - "zibal.service.ts"
|
### Community 86 - "zibal.service.ts"
|
||||||
Cohesion: 0.16
|
Cohesion: 0.16
|
||||||
@ -700,9 +698,9 @@ Nodes (9): GatewayHealthResult, IPaymentGateway, PaymentInquiryResult, PaymentRe
|
|||||||
Cohesion: 0.12
|
Cohesion: 0.12
|
||||||
Nodes (17): dependencies, axios, lucide-react, motion, next, react, react-dom, sonner (+9 more)
|
Nodes (17): dependencies, axios, lucide-react, motion, next, react, react-dom, sonner (+9 more)
|
||||||
|
|
||||||
### Community 88 - "components/Skeleton.tsx"
|
### Community 88 - "HomeClient.tsx"
|
||||||
Cohesion: 0.29
|
Cohesion: 0.14
|
||||||
Nodes (5): OrderRowSkeleton(), PetProfileSkeleton(), ProductCardSkeleton(), Skeleton(), SkeletonProps
|
Nodes (17): HomeClient(), HomeClientProps, CATEGORY_MAP, ICON_MAP, BannerPlacement(), BannerPlacementProps, Hero(), StatCounter() (+9 more)
|
||||||
|
|
||||||
### Community 89 - "seed-products.ts"
|
### Community 89 - "seed-products.ts"
|
||||||
Cohesion: 0.17
|
Cohesion: 0.17
|
||||||
@ -716,13 +714,13 @@ Nodes (7): SmsLogQueryDto, ApiPropertyOptional, IsIn, IsNumber, IsOptional, IsSt
|
|||||||
Cohesion: 0.12
|
Cohesion: 0.12
|
||||||
Nodes (15): 10. Documentation Engineer, 1. Lead Architect / Orchestrator, 2. React / Vite Storefront Auditor, 3. NestJS Backend Auditor, 4. Admin Features Auditor, 5. Database & Data Integrity Auditor, 6. Security Auditor, 7. TypeScript & Code Quality Auditor (+7 more)
|
Nodes (15): 10. Documentation Engineer, 1. Lead Architect / Orchestrator, 2. React / Vite Storefront Auditor, 3. NestJS Backend Auditor, 4. Admin Features Auditor, 5. Database & Data Integrity Auditor, 6. Security Auditor, 7. TypeScript & Code Quality Auditor (+7 more)
|
||||||
|
|
||||||
### Community 92 - "OrdersController"
|
### Community 92 - "OrdersService"
|
||||||
Cohesion: 0.13
|
Cohesion: 0.08
|
||||||
Nodes (16): OrdersController, ApiBadRequestResponse, ApiBearerAuth, ApiCreatedResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags (+8 more)
|
Nodes (29): CreateOrderDto, OrderItemDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional (+21 more)
|
||||||
|
|
||||||
### Community 93 - "lib/services/api.ts"
|
### Community 93 - "app-audit-verification.e2e-spec.js"
|
||||||
Cohesion: 0.11
|
Cohesion: 0.13
|
||||||
Nodes (13): B2BPortal(), ContactInfoItem, api, ApiErrorPayload, baseURL, ApiErr, Order, OrderItem (+5 more)
|
Nodes (14): ApiErrorResponse, ErrorDetailField, ApiProperty, app_module_1, client_1, common_1, decimal_interceptor_1, fs (+6 more)
|
||||||
|
|
||||||
### Community 94 - "Phase 3.1 — Human Review Preparation and Master Backlog Critique"
|
### Community 94 - "Phase 3.1 — Human Review Preparation and Master Backlog Critique"
|
||||||
Cohesion: 0.13
|
Cohesion: 0.13
|
||||||
@ -740,9 +738,9 @@ Nodes (32): compilerOptions, allowJs, esModuleInterop, incremental, isolatedModu
|
|||||||
Cohesion: 0.14
|
Cohesion: 0.14
|
||||||
Nodes (14): scripts, build, build:nest, docs:generate, lint, start, start:debug, start:dev (+6 more)
|
Nodes (14): scripts, build, build:nest, docs:generate, lint, start, start:debug, start:dev (+6 more)
|
||||||
|
|
||||||
### Community 99 - "AuthController"
|
### Community 99 - "HomeController"
|
||||||
Cohesion: 0.27
|
Cohesion: 0.16
|
||||||
Nodes (12): AuthController, ApiBadRequestResponse, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+4 more)
|
Nodes (10): HomeController, ApiOkResponse, ApiOperation, ApiTags, Controller, Get, HomeModule, Module (+2 more)
|
||||||
|
|
||||||
### Community 100 - "Deep Audit Summary Report"
|
### Community 100 - "Deep Audit Summary Report"
|
||||||
Cohesion: 0.14
|
Cohesion: 0.14
|
||||||
@ -768,17 +766,17 @@ Nodes (13): formatPriceWithCommas(), PriceInput(), PriceInputProps, toEnglishDig
|
|||||||
Cohesion: 0.17
|
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)
|
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 106 - "auth.module.ts"
|
### Community 106 - "auth.controller.ts"
|
||||||
Cohesion: 0.15
|
|
||||||
Nodes (10): DEFAULT_JWT_REFRESH_SECRET, DEFAULT_JWT_SECRET, getJwtSecret(), AuthModule, Module, JwtPayload, JwtStrategy, Injectable (+2 more)
|
|
||||||
|
|
||||||
### Community 107 - "HomeController"
|
|
||||||
Cohesion: 0.16
|
Cohesion: 0.16
|
||||||
Nodes (10): HomeController, ApiOkResponse, ApiOperation, ApiTags, Controller, Get, HomeModule, Module (+2 more)
|
Nodes (11): AdminLoginDto, ApiProperty, IsEmail, IsNotEmpty, IsString, MinLength, LoginDto, ApiProperty (+3 more)
|
||||||
|
|
||||||
|
### Community 107 - "payment.service.ts"
|
||||||
|
Cohesion: 0.20
|
||||||
|
Nodes (8): AdminTransactionFilterDto, ApiPropertyOptional, IsIn, IsNumber, IsOptional, IsString, Type, ClientMetadata
|
||||||
|
|
||||||
### Community 108 - "PrismaService"
|
### Community 108 - "PrismaService"
|
||||||
Cohesion: 0.07
|
Cohesion: 0.07
|
||||||
Nodes (21): PetQuery, B2BWholesaleOrderItem, MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions, SmsConfig, CreateContactSubmissionDto, UpdateContactInfoItemDto (+13 more)
|
Nodes (22): ApiExcludeController, MetricsController, Controller, Get, Res, MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions (+14 more)
|
||||||
|
|
||||||
### Community 109 - "1. Summary of Integrity Repairs Performed"
|
### Community 109 - "1. Summary of Integrity Repairs Performed"
|
||||||
Cohesion: 0.17
|
Cohesion: 0.17
|
||||||
@ -900,6 +898,10 @@ Nodes (7): backend, distMainPath, fs, http, path, { spawn, execSync }, waitForBa
|
|||||||
Cohesion: 0.25
|
Cohesion: 0.25
|
||||||
Nodes (6): app_module_1, core_1, fs, path, swagger_1, yaml
|
Nodes (6): app_module_1, core_1, fs, path, swagger_1, yaml
|
||||||
|
|
||||||
|
### Community 144 - "RegisterDto"
|
||||||
|
Cohesion: 0.22
|
||||||
|
Nodes (8): RegisterDto, ApiProperty, ApiPropertyOptional, IsEmail, IsNotEmpty, IsOptional, IsString, MinLength
|
||||||
|
|
||||||
### Community 146 - "System Discovery"
|
### Community 146 - "System Discovery"
|
||||||
Cohesion: 0.25
|
Cohesion: 0.25
|
||||||
Nodes (7): Active Core Applications, Current Architecture, Evidence-Based Status Matrix, Excluded / Non-Auditable Artifacts, Major Business Domains Discovered, System Discovery, Technical Architecture Summary
|
Nodes (7): Active Core Applications, Current Architecture, Evidence-Based Status Matrix, Excluded / Non-Auditable Artifacts, Major Business Domains Discovered, System Discovery, Technical Architecture Summary
|
||||||
@ -992,13 +994,17 @@ Nodes (4): evidenceList, ledger, mandatoryMap, mandatoryScope
|
|||||||
Cohesion: 0.40
|
Cohesion: 0.40
|
||||||
Nodes (4): activeFiles, errors, validationOutput, warnings
|
Nodes (4): activeFiles, errors, validationOutput, warnings
|
||||||
|
|
||||||
|
### Community 176 - "InitiatePaymentDto"
|
||||||
|
Cohesion: 0.43
|
||||||
|
Nodes (7): InitiatePaymentDto, InitiateWalletTopupDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString
|
||||||
|
|
||||||
### Community 177 - "blog/page.tsx"
|
### Community 177 - "blog/page.tsx"
|
||||||
Cohesion: 0.50
|
Cohesion: 0.50
|
||||||
Nodes (4): Blog(), generateMetadata(), getBlogs(), BlogPage()
|
Nodes (4): Blog(), generateMetadata(), getBlogs(), BlogPage()
|
||||||
|
|
||||||
### Community 179 - "PodcastPlayerModal.tsx"
|
### Community 179 - "VerifyOtpDto"
|
||||||
Cohesion: 0.40
|
Cohesion: 0.29
|
||||||
Nodes (3): PLAYBACK_RATES, PodcastPlayerModal(), PodcastPlayerModalProps
|
Nodes (6): ApiProperty, IsNotEmpty, IsString, Matches, VerifyOtpDto, Length
|
||||||
|
|
||||||
### Community 180 - "API Contract Specification"
|
### Community 180 - "API Contract Specification"
|
||||||
Cohesion: 0.50
|
Cohesion: 0.50
|
||||||
@ -1041,8 +1047,8 @@ Cohesion: 0.50
|
|||||||
Nodes (3): Select, SelectOption, SelectProps
|
Nodes (3): Select, SelectOption, SelectProps
|
||||||
|
|
||||||
### Community 199 - "useSettingsStore"
|
### Community 199 - "useSettingsStore"
|
||||||
Cohesion: 0.08
|
Cohesion: 0.11
|
||||||
Nodes (32): HomeClient(), HomeClientProps, CATEGORY_MAP, ICON_MAP, BannerPlacement(), BannerPlacementProps, BrandLogo(), BrandLogoProps (+24 more)
|
Nodes (22): ClientLayout(), BrandLogo(), BrandLogoProps, EnamadBadge(), FAQItem, FAQSection(), Footer(), MENU_ICONS (+14 more)
|
||||||
|
|
||||||
### Community 200 - "application/README.md"
|
### Community 200 - "application/README.md"
|
||||||
Cohesion: 0.50
|
Cohesion: 0.50
|
||||||
@ -1056,57 +1062,49 @@ Nodes (3): COMPOSE_DOCKER_CLI_BUILD, DOCKER_BUILDKIT, deploy.sh script
|
|||||||
Cohesion: 0.67
|
Cohesion: 0.67
|
||||||
Nodes (3): ADR-AUTH-001: Admin Panel Authentication Architecture & Token Management, Master Task Backlog (Phase 3.3), Phase 3 Master Execution Plan
|
Nodes (3): ADR-AUTH-001: Admin Panel Authentication Architecture & Token Management, Master Task Backlog (Phase 3.3), Phase 3 Master Execution Plan
|
||||||
|
|
||||||
### Community 224 - "payment.service.ts"
|
### Community 224 - "SendOtpDto"
|
||||||
Cohesion: 0.20
|
Cohesion: 0.33
|
||||||
Nodes (8): AdminTransactionFilterDto, ApiPropertyOptional, IsIn, IsNumber, IsOptional, IsString, Type, ClientMetadata
|
Nodes (5): SendOtpDto, ApiProperty, IsNotEmpty, IsString, Matches
|
||||||
|
|
||||||
### Community 226 - "Shabnam Font README"
|
### Community 226 - "Shabnam Font README"
|
||||||
Cohesion: 0.67
|
Cohesion: 0.67
|
||||||
Nodes (3): Shabnam Font README, Shabnam Font Sample, Vazir Font
|
Nodes (3): Shabnam Font README, Shabnam Font Sample, Vazir Font
|
||||||
|
|
||||||
### Community 298 - ".initiateOrderPayment"
|
### Community 298 - ".initiateOrderPayment"
|
||||||
Cohesion: 0.15
|
Cohesion: 0.18
|
||||||
Nodes (10): ApiPropertyOptional, IsOptional, IsString, ZibalCallbackQueryDto, ApiBadRequestResponse, ApiOkResponse, Req, Res (+2 more)
|
Nodes (10): ApiPropertyOptional, IsOptional, IsString, ZibalCallbackQueryDto, ApiBadRequestResponse, ApiOkResponse, Req, Res (+2 more)
|
||||||
|
|
||||||
### Community 301 - "app.e2e-spec.js"
|
### Community 301 - "app.e2e-spec.js"
|
||||||
Cohesion: 0.50
|
Cohesion: 0.50
|
||||||
Nodes (3): app_module_1, supertest_1, testing_1
|
Nodes (3): app_module_1, supertest_1, testing_1
|
||||||
|
|
||||||
### Community 307 - "RegisterDto"
|
### Community 312 - "BlogsModule"
|
||||||
Cohesion: 0.22
|
Cohesion: 0.33
|
||||||
Nodes (8): RegisterDto, ApiProperty, ApiPropertyOptional, IsEmail, IsNotEmpty, IsOptional, IsString, MinLength
|
Nodes (4): BlogsModule, Module, OrdersModule, Module
|
||||||
|
|
||||||
### Community 311 - "InitiatePaymentDto"
|
### Community 313 - "app/page.tsx"
|
||||||
Cohesion: 0.43
|
|
||||||
Nodes (7): InitiatePaymentDto, InitiateWalletTopupDto, ApiProperty, ApiPropertyOptional, IsNotEmpty, IsOptional, IsString
|
|
||||||
|
|
||||||
### Community 312 - "AddressDto"
|
|
||||||
Cohesion: 0.29
|
|
||||||
Nodes (7): AddressDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString
|
|
||||||
|
|
||||||
### Community 316 - "app/page.tsx"
|
|
||||||
Cohesion: 0.67
|
Cohesion: 0.67
|
||||||
Nodes (3): generateMetadata(), getHomeData(), Home()
|
Nodes (3): generateMetadata(), getHomeData(), Home()
|
||||||
|
|
||||||
## Knowledge Gaps
|
## Knowledge Gaps
|
||||||
- **1278 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1273 more)
|
- **1278 isolated node(s):** `$schema`, `collection`, `sourceRoot`, `deleteOutDir`, `name` (+1273 more)
|
||||||
These have ≤1 connection - possible missing edges or undocumented components.
|
These have ≤1 connection - possible missing edges or undocumented components.
|
||||||
- **121 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
|
- **119 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
|
||||||
|
|
||||||
## Suggested Questions
|
## Suggested Questions
|
||||||
_Questions this graph is uniquely positioned to answer:_
|
_Questions this graph is uniquely positioned to answer:_
|
||||||
|
|
||||||
- **Why does `ApiResponse` connect `src/services/api.ts` to `AuthController`, `BlogsController`, `PaginationDto`, `HomeController`, `PetsController`, `ProductsService`, `UsersController`, `OrdersController`?**
|
- **Why does `ApiResponse` connect `src/services/api.ts` to `HomeController`, `AuthController`, `BlogsController`, `PetsController`, `ProductsService`, `UsersService`, `OrdersService`, `WikiController`?**
|
||||||
_High betweenness centrality (0.065) - this node is a cross-community bridge._
|
_High betweenness centrality (0.065) - this node is a cross-community bridge._
|
||||||
- **Why does `Roles()` connect `Roles` to `WholesaleApplyDto`, `B2BService`, `SettingsController`, `FaqService`, `CmsController`, `tickets.controller.ts`, `SslController`, `BannersService`, `CreateReviewDto`, `TestimonialsService`, `IngredientsService`, `JwtAuthGuard`, `ProductsService`, `PrescriptionsController`, `SmartAdvisorController`, `MenuService`, `ContactService`?**
|
- **Why does `Roles()` connect `Roles` to `WholesaleApplyDto`, `B2BService`, `SmsService`, `FaqService`, `CmsController`, `tickets.controller.ts`, `SslController`, `BannersService`, `CreateReviewDto`, `TestimonialsService`, `IngredientsService`, `JwtAuthGuard`, `ProductsService`, `PrescriptionsController`, `SmartAdvisorService`, `MenuService`, `ContactService`?**
|
||||||
_High betweenness centrality (0.064) - this node is a cross-community bridge._
|
_High betweenness centrality (0.064) - this node is a cross-community bridge._
|
||||||
- **Why does `JwtAuthGuard` connect `JwtAuthGuard` to `PetsController`, `auth.service.ts`, `CmsController`, `tickets.controller.ts`, `CategoriesController`, `MediaController`, `PaginationDto`, `admin.module.ts`, `PetsController`, `DoctorQueryDto`, `ProductsService`, `CreateVideoDto`, `UsersService`, `admin.service.ts`, `OrdersService`?**
|
- **Why does `JwtAuthGuard` connect `JwtAuthGuard` to `PetsController`, `CmsController`, `tickets.controller.ts`, `CategoriesController`, `MediaController`, `PaginationDto`, `admin.module.ts`, `auth.controller.ts`, `PetsController`, `DoctorQueryDto`, `ProductsService`, `CreateVideoDto`, `UsersService`, `admin.service.ts`?**
|
||||||
_High betweenness centrality (0.036) - this node is a cross-community bridge._
|
_High betweenness centrality (0.036) - this node is a cross-community bridge._
|
||||||
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
|
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
|
||||||
_1278 weakly-connected nodes found - possible documentation gaps or missing edges._
|
_1278 weakly-connected nodes found - possible documentation gaps or missing edges._
|
||||||
- **Should `app.module.ts` be split into smaller, more focused modules?**
|
- **Should `app.module.ts` be split into smaller, more focused modules?**
|
||||||
_Cohesion score 0.06988120195667366 - nodes in this community are weakly interconnected._
|
_Cohesion score 0.07510204081632653 - nodes in this community are weakly interconnected._
|
||||||
|
- **Should `SmsService` be split into smaller, more focused modules?**
|
||||||
|
_Cohesion score 0.060542309490416085 - nodes in this community are weakly interconnected._
|
||||||
- **Should `productService.ts` be split into smaller, more focused modules?**
|
- **Should `productService.ts` be split into smaller, more focused modules?**
|
||||||
_Cohesion score 0.07826694619147449 - nodes in this community are weakly interconnected._
|
_Cohesion score 0.08888888888888889 - 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._
|
|
||||||
2
graphify-out/cache/stat-index.json
vendored
2
graphify-out/cache/stat-index.json
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user