Fix community IDs and update sitemap functionality
- Updated community IDs for various components in graph.json to reflect correct associations. - Added new function `getPublishedDoctors()` in app/sitemap.js and established relationships with existing functions. - Adjusted source locations for several functions in app/sitemap.js to ensure accurate mapping. - Enhanced canonical URL handling in lib/getCanonicalUrl.js to prevent incorrect canonicalization for paginated specialty pages. - Updated manifest.json with new modification times and AST hashes for affected files.
This commit is contained in:
+50
-23
@@ -113,23 +113,28 @@ function cityFilterParams(scope) {
|
||||
// فیلتری انجام میشود که کلینیکها استفاده میکنند. پیش از این، نبودِ city مجبورمان
|
||||
// میکرد روی دامنهٔ اصلی کل لیست را ۳۵ بار (یکبار بهازای هر شهرِ دامنهدار) بگیریم و
|
||||
// تفاضل بگیریم — همان کاری که ~۱۳ ثانیه طول میکشید.
|
||||
async function getDoctorUrls(baseUrl, scope) {
|
||||
// پزشکانی که این دامنه منتشرشان میکند. هم URLهای پزشک و هم صفحات تخصص از همین
|
||||
// مجموعه ساخته میشوند تا نتوانند واگرا شوند.
|
||||
async function getPublishedDoctors(scope) {
|
||||
const doctors = await fetchAllPages('/api/v1/doctors', cityFilterParams(scope));
|
||||
return doctors
|
||||
.filter((d) => !isThinDoctor(d))
|
||||
// روی دامنهٔ اصلی فقط پزشکانی که شهرشان دامنهٔ اختصاصی ندارد؛ روی دامنهٔ شهری
|
||||
// فیلتر city_id سمت API قبلاً کار را کرده است.
|
||||
.filter((d) => !scope.isRoot || !findDomainByCityId(extractEntityCityId(d)))
|
||||
.map((d) =>
|
||||
withLastModified(
|
||||
{
|
||||
url: `${baseUrl}/doctor/${d.uuid}`,
|
||||
changeFrequency: 'weekly',
|
||||
priority: 0.8,
|
||||
},
|
||||
d.updated || d.created
|
||||
)
|
||||
);
|
||||
.filter((d) => !scope.isRoot || !findDomainByCityId(extractEntityCityId(d)));
|
||||
}
|
||||
|
||||
function getDoctorUrls(baseUrl, doctors) {
|
||||
return doctors.map((d) =>
|
||||
withLastModified(
|
||||
{
|
||||
url: `${baseUrl}/doctor/${d.uuid}`,
|
||||
changeFrequency: 'weekly',
|
||||
priority: 0.8,
|
||||
},
|
||||
d.updated || d.created
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
async function getClinicUrls(baseUrl, scope) {
|
||||
@@ -151,14 +156,34 @@ async function getClinicUrls(baseUrl, scope) {
|
||||
}
|
||||
|
||||
// صفحات فرود تخصص per-domain — روی هر دامنه «تخصص + آن شهر» است، پس همهجا self.
|
||||
function getSpecialtyUrls(baseUrl) {
|
||||
return specialtiesData
|
||||
.filter((s) => s?.slug && s.status === 1)
|
||||
.map((s) => ({
|
||||
url: `${baseUrl}/specialties/${s.slug}`,
|
||||
changeFrequency: 'weekly',
|
||||
priority: 0.8,
|
||||
}));
|
||||
//
|
||||
// فقط تخصصهایی که در همین دامنه واقعاً پزشک دارند اعلام میشوند؛ تولید بیقید هر ۹۳
|
||||
// تخصص برای هر ۳۵ دامنه هزاران صفحهٔ خالی به گوگل معرفی میکرد (thin content انبوه).
|
||||
//
|
||||
// منبع، همان پزشکانی است که این sitemap منتشرشان میکند — نه endpoint شمارش. آن
|
||||
// endpoint با فیلتر لیست پزشکان اختلاف دارد (مثلاً پزشکِ یافتشده از آدرس کلینیک را
|
||||
// نمیشمارد)، و اگر sitemap از یک منبع و خودِ صفحه از منبع دیگر تصمیم بگیرد، صفحهٔ
|
||||
// ایندکسپذیرِ اعلامنشده یا برعکس میسازیم. اینطور هیچ فراخوانی اضافهای هم ندارد.
|
||||
function getSpecialtyUrls(baseUrl, doctors) {
|
||||
const slugById = new Map(
|
||||
specialtiesData
|
||||
.filter((s) => s?.slug && s.status === 1)
|
||||
.map((s) => [String(s.id), s.slug])
|
||||
);
|
||||
|
||||
const slugs = new Set();
|
||||
for (const doctor of doctors) {
|
||||
for (const specialty of doctor?.specialties ?? []) {
|
||||
const slug = slugById.get(String(specialty?.id));
|
||||
if (slug) slugs.add(slug);
|
||||
}
|
||||
}
|
||||
|
||||
return [...slugs].map((slug) => ({
|
||||
url: `${baseUrl}/specialties/${slug}`,
|
||||
changeFrequency: 'weekly',
|
||||
priority: 0.8,
|
||||
}));
|
||||
}
|
||||
|
||||
// هر پست فقط در sitemap دامنهٔ canonical خودش: پست شهریافته → دامنهٔ آن شهر،
|
||||
@@ -193,15 +218,17 @@ export default async function sitemap() {
|
||||
const baseUrl = getBaseUrl(domain);
|
||||
const scope = getCityScope(domain);
|
||||
|
||||
const [doctorUrls, clinicUrls, blogUrls] = await Promise.all([
|
||||
getDoctorUrls(baseUrl, scope),
|
||||
const [doctors, clinicUrls, blogUrls] = await Promise.all([
|
||||
getPublishedDoctors(scope),
|
||||
getClinicUrls(baseUrl, scope),
|
||||
getBlogUrls(baseUrl, scope),
|
||||
]);
|
||||
|
||||
const doctorUrls = getDoctorUrls(baseUrl, doctors);
|
||||
|
||||
const allUrls = [
|
||||
...getStaticPages(baseUrl),
|
||||
...getSpecialtyUrls(baseUrl),
|
||||
...getSpecialtyUrls(baseUrl, doctors),
|
||||
...doctorUrls,
|
||||
...clinicUrls,
|
||||
...blogUrls,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { cache } from "react";
|
||||
import { notFound } from "next/navigation";
|
||||
import Layout from "@/components/layout/StLayout";
|
||||
import SpecialtyDetailPage from "@/components/specialties/detail";
|
||||
@@ -16,7 +17,8 @@ const findSpecialty = (slug) =>
|
||||
specialtiesData.find((item) => item.slug === slug && item.status === 1) ?? null;
|
||||
|
||||
// روی هر دامنهٔ شهری این صفحه خودکار «تخصص + همان شهر» است — شهر از host میآید.
|
||||
async function getDoctors(specialtyId, cityId) {
|
||||
// cache تا generateMetadata و بدنهٔ صفحه یک بار fetch کنند، نه دو بار.
|
||||
const getDoctors = cache(async (specialtyId, cityId) => {
|
||||
try {
|
||||
const res = await fetchReq(`${API_URL}/api/v1/doctors`, {
|
||||
params: {
|
||||
@@ -33,7 +35,7 @@ async function getDoctors(specialtyId, cityId) {
|
||||
} catch {
|
||||
return { items: [], total: 0 };
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { slug } = await params;
|
||||
@@ -48,9 +50,15 @@ export async function generateMetadata({ params }) {
|
||||
const description = `لیست بهترین پزشکان ${specialty.name} در ${cityName} همراه با نشانی مطب، ساعات کاری و امتیاز بیماران. رزرو نوبت آنلاین متخصص ${specialty.name}.`;
|
||||
const image = "/assets/images/og-image.png";
|
||||
|
||||
// تخصصی که در این شهر پزشکی ندارد فقط یک عنوان و متن قالبی است — thin content.
|
||||
// ایندکس نمیشود (و در sitemap هم نمیآید)، ولی follow میماند تا لینکهای
|
||||
// داخلیاش دنبال شوند. بهمحض افزودهشدن اولین پزشک، خودکار ایندکسپذیر میشود.
|
||||
const { total } = await getDoctors(specialty.id, isRoot ? null : matchedCity?.id);
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
...(total === 0 && { robots: { index: false, follow: true } }),
|
||||
// C1-a — صفحهٔ فرود تخصص per-domain است؛ canonical لایهٔ layout (self) درست است.
|
||||
openGraph: { title, description, images: [image] },
|
||||
twitter: { card: "summary_large_image", title, description, images: [image] },
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
"64": "Community 64",
|
||||
"65": "Community 65",
|
||||
"66": "Community 66",
|
||||
"67": "Community 67",
|
||||
"68": "Community 68",
|
||||
"69": "Community 69",
|
||||
"70": "Community 70",
|
||||
@@ -127,7 +126,6 @@
|
||||
"125": "Community 125",
|
||||
"126": "Community 126",
|
||||
"127": "Community 127",
|
||||
"128": "Community 128",
|
||||
"129": "Community 129",
|
||||
"130": "Community 130",
|
||||
"131": "Community 131",
|
||||
@@ -366,10 +364,6 @@
|
||||
"364": "Community 364",
|
||||
"365": "Community 365",
|
||||
"366": "Community 366",
|
||||
"367": "Community 367",
|
||||
"368": "Community 368",
|
||||
"369": "Community 369",
|
||||
"370": "Community 370",
|
||||
"371": "Community 371",
|
||||
"372": "Community 372",
|
||||
"373": "Community 373",
|
||||
@@ -383,16 +377,8 @@
|
||||
"381": "Community 381",
|
||||
"382": "Community 382",
|
||||
"383": "Community 383",
|
||||
"384": "Community 384",
|
||||
"385": "Community 385",
|
||||
"386": "Community 386",
|
||||
"387": "Community 387",
|
||||
"388": "Community 388",
|
||||
"389": "Community 389",
|
||||
"390": "Community 390",
|
||||
"391": "Community 391",
|
||||
"392": "Community 392",
|
||||
"393": "Community 393",
|
||||
"394": "Community 394",
|
||||
"395": "Community 395"
|
||||
"388": "Community 388"
|
||||
}
|
||||
|
||||
+47
-109
@@ -1,16 +1,16 @@
|
||||
# Graph Report - nobat724_front (2026-07-19)
|
||||
|
||||
## Corpus Check
|
||||
- 622 files · ~563,044 words
|
||||
- 622 files · ~563,349 words
|
||||
- Verdict: corpus is large enough that graph structure adds value.
|
||||
|
||||
## Summary
|
||||
- 2293 nodes · 2329 edges · 396 communities (360 shown, 36 thin omitted)
|
||||
- 2294 nodes · 2334 edges · 382 communities (348 shown, 34 thin omitted)
|
||||
- Extraction: 94% EXTRACTED · 6% INFERRED · 0% AMBIGUOUS · INFERRED: 139 edges (avg confidence: 0.8)
|
||||
- Token cost: 0 input · 0 output
|
||||
|
||||
## Graph Freshness
|
||||
- Built from commit: `488e5eb0`
|
||||
- Built from commit: `97e99098`
|
||||
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
|
||||
- Run `graphify update .` after code changes (no API cost).
|
||||
|
||||
@@ -82,7 +82,6 @@
|
||||
- [[_COMMUNITY_Community 64|Community 64]]
|
||||
- [[_COMMUNITY_Community 65|Community 65]]
|
||||
- [[_COMMUNITY_Community 66|Community 66]]
|
||||
- [[_COMMUNITY_Community 67|Community 67]]
|
||||
- [[_COMMUNITY_Community 68|Community 68]]
|
||||
- [[_COMMUNITY_Community 69|Community 69]]
|
||||
- [[_COMMUNITY_Community 70|Community 70]]
|
||||
@@ -137,7 +136,6 @@
|
||||
- [[_COMMUNITY_Community 124|Community 124]]
|
||||
- [[_COMMUNITY_Community 125|Community 125]]
|
||||
- [[_COMMUNITY_Community 126|Community 126]]
|
||||
- [[_COMMUNITY_Community 128|Community 128]]
|
||||
- [[_COMMUNITY_Community 140|Community 140]]
|
||||
- [[_COMMUNITY_Community 195|Community 195]]
|
||||
- [[_COMMUNITY_Community 339|Community 339]]
|
||||
@@ -145,10 +143,6 @@
|
||||
- [[_COMMUNITY_Community 348|Community 348]]
|
||||
- [[_COMMUNITY_Community 365|Community 365]]
|
||||
- [[_COMMUNITY_Community 366|Community 366]]
|
||||
- [[_COMMUNITY_Community 367|Community 367]]
|
||||
- [[_COMMUNITY_Community 368|Community 368]]
|
||||
- [[_COMMUNITY_Community 369|Community 369]]
|
||||
- [[_COMMUNITY_Community 370|Community 370]]
|
||||
- [[_COMMUNITY_Community 371|Community 371]]
|
||||
- [[_COMMUNITY_Community 372|Community 372]]
|
||||
- [[_COMMUNITY_Community 373|Community 373]]
|
||||
@@ -161,18 +155,10 @@
|
||||
- [[_COMMUNITY_Community 380|Community 380]]
|
||||
- [[_COMMUNITY_Community 381|Community 381]]
|
||||
- [[_COMMUNITY_Community 382|Community 382]]
|
||||
- [[_COMMUNITY_Community 384|Community 384]]
|
||||
- [[_COMMUNITY_Community 385|Community 385]]
|
||||
- [[_COMMUNITY_Community 386|Community 386]]
|
||||
- [[_COMMUNITY_Community 387|Community 387]]
|
||||
- [[_COMMUNITY_Community 388|Community 388]]
|
||||
- [[_COMMUNITY_Community 389|Community 389]]
|
||||
- [[_COMMUNITY_Community 390|Community 390]]
|
||||
- [[_COMMUNITY_Community 391|Community 391]]
|
||||
- [[_COMMUNITY_Community 392|Community 392]]
|
||||
- [[_COMMUNITY_Community 393|Community 393]]
|
||||
- [[_COMMUNITY_Community 394|Community 394]]
|
||||
- [[_COMMUNITY_Community 395|Community 395]]
|
||||
|
||||
## God Nodes (most connected - your core abstractions)
|
||||
1. `getStateInfo()` - 27 edges
|
||||
@@ -182,34 +168,34 @@
|
||||
5. `Doctor()` - 11 edges
|
||||
6. `Blog()` - 10 edges
|
||||
7. `Dashboard()` - 10 edges
|
||||
8. `بهینهسازی SEO تکتک شهرها در city.json (سطح حرفهای)` - 10 edges
|
||||
9. `بازطراحی حرفهای پوستر اشتراکگذاری پزشک (دانلود)` - 10 edges
|
||||
10. `وظایف` - 10 edges
|
||||
8. `sitemap()` - 10 edges
|
||||
9. `بهینهسازی SEO تکتک شهرها در city.json (سطح حرفهای)` - 10 edges
|
||||
10. `بازطراحی حرفهای پوستر اشتراکگذاری پزشک (دانلود)` - 10 edges
|
||||
|
||||
## Surprising Connections (you probably didn't know these)
|
||||
- `Dashboard()` --calls--> `safeJsonParse()` [INFERRED]
|
||||
app/dashboard/page.js → lib/sanitize.js
|
||||
- `Doctor()` --calls--> `buildDoctorFaq()` [INFERRED]
|
||||
app/doctor/[slug]/page.js → lib/specialtyContent.js
|
||||
- `SpecialtyDetail()` --calls--> `buildSpecialtyFaq()` [INFERRED]
|
||||
app/specialties/[slug]/page.js → lib/specialtyContent.js
|
||||
- `AboutUsPage()` --calls--> `getStateInfo()` [INFERRED]
|
||||
components/aboutUs/index.js → lib/getStateInfo.js
|
||||
- `ContactUsPage()` --calls--> `getStateInfo()` [INFERRED]
|
||||
components/contactUs/index.js → lib/getStateInfo.js
|
||||
- `SearchBar()` --calls--> `getStateInfo()` [INFERRED]
|
||||
components/home/search/index.js → lib/getStateInfo.js
|
||||
|
||||
## Import Cycles
|
||||
- None detected.
|
||||
|
||||
## Communities (396 total, 36 thin omitted)
|
||||
## Communities (382 total, 34 thin omitted)
|
||||
|
||||
### Community 0 - "Community 0"
|
||||
Cohesion: 0.05
|
||||
Nodes (27): BgGray(), ButtonMenu(), Col(), ModalLogout(), Footer(), head, LogoNamad(), Namads (+19 more)
|
||||
|
||||
### Community 1 - "Community 1"
|
||||
Cohesion: 0.24
|
||||
Nodes (8): Head(), convertTimestampToJalali(), convertTimestampToTime(), ButtonData(), DetailLg(), DetailSm(), Head(), Card()
|
||||
Cohesion: 0.26
|
||||
Nodes (7): Head(), convertTimestampToJalali(), convertTimestampToTime(), ButtonData(), DetailLg(), DetailSm(), Head()
|
||||
|
||||
### Community 2 - "Community 2"
|
||||
Cohesion: 0.04
|
||||
@@ -217,7 +203,7 @@ Nodes (48): dependencies, altcha, aos, axios, @casl/ability, @casl/react, date-f
|
||||
|
||||
### Community 3 - "Community 3"
|
||||
Cohesion: 0.23
|
||||
Nodes (15): getCurrentDomain(), robots(), cityFilterParams(), fetchAllPages(), getBlogUrls(), getCityScope(), getClinicUrls(), getCurrentDomain() (+7 more)
|
||||
Nodes (16): getCurrentDomain(), robots(), cityFilterParams(), fetchAllPages(), getBlogUrls(), getCityScope(), getClinicUrls(), getCurrentDomain() (+8 more)
|
||||
|
||||
### Community 4 - "Community 4"
|
||||
Cohesion: 0.06
|
||||
@@ -228,12 +214,12 @@ Cohesion: 0.06
|
||||
Nodes (26): bookingState(), DAY_NAMES, formatJalali(), AppointmentList(), ItemAppointment(), AboutDcotor(), ClaimProfileSection(), currentUserMobile() (+18 more)
|
||||
|
||||
### Community 6 - "Community 6"
|
||||
Cohesion: 0.15
|
||||
Nodes (8): Dashboard(), metadata, defineAbilitiesFor(), getUser(), buildPatientUser(), getServerAccessToken(), LogIn(), metadata
|
||||
Cohesion: 0.08
|
||||
Nodes (13): Dashboard(), metadata, defineAbilitiesFor(), getUser(), buildPatientUser(), getServerAccessToken(), clearAccessToken(), LogIn() (+5 more)
|
||||
|
||||
### Community 8 - "Community 8"
|
||||
Cohesion: 0.13
|
||||
Nodes (15): devDependencies, babel-plugin-react-compiler, cross-env, eslint, eslint-config-next, @eslint/eslintrc, jsdom, prettier (+7 more)
|
||||
Cohesion: 0.07
|
||||
Nodes (28): devDependencies, babel-plugin-react-compiler, cross-env, eslint, eslint-config-next, @eslint/eslintrc, jsdom, prettier (+20 more)
|
||||
|
||||
### Community 9 - "Community 9"
|
||||
Cohesion: 0.07
|
||||
@@ -264,8 +250,8 @@ Cohesion: 0.14
|
||||
Nodes (10): Chart(), ProgressAll(), fallbackLabels, ProgressDetail(), Form(), Content(), Rates(), numberToArStyle() (+2 more)
|
||||
|
||||
### Community 16 - "Community 16"
|
||||
Cohesion: 0.13
|
||||
Nodes (10): Head(), AboutUsPage(), ourServices, Services(), FrequentSearches(), TextHeader(), AText(), BText() (+2 more)
|
||||
Cohesion: 0.25
|
||||
Nodes (6): Head(), AboutUsPage(), ourServices, Services(), TickOrangeA(), UnderlineLG()
|
||||
|
||||
### Community 17 - "Community 17"
|
||||
Cohesion: 0.11
|
||||
@@ -316,8 +302,8 @@ Cohesion: 0.12
|
||||
Nodes (16): دیپلوی nobat724_front روی Liara (پلتفرم Next.js), زمینه, فایلهای مرتبط, مشکل / هدف, نکات مهم, وضعیت فعلی, وظایف, پروژه (+8 more)
|
||||
|
||||
### Community 29 - "Community 29"
|
||||
Cohesion: 0.13
|
||||
Nodes (11): generateMetadata(), Blogs(), generateMetadata(), Appointment(), metadata, fetchSiteContext(), getStateInfo(), siteContextCache (+3 more)
|
||||
Cohesion: 0.08
|
||||
Nodes (21): generateMetadata(), Blogs(), generateMetadata(), Clinics(), generateMetadata(), Appointment(), metadata, Doctors() (+13 more)
|
||||
|
||||
### Community 30 - "Community 30"
|
||||
Cohesion: 0.12
|
||||
@@ -380,12 +366,12 @@ Cohesion: 0.14
|
||||
Nodes (13): `hours/List.js`, آبجکت اسلات (از `adaptSlots` / API), تأیید و سختسازی غیرفعالبودن اسلاتهای گذشته در صفحهی نوبت, زمینه, فایلهای مرتبط, مشکل / هدف, نکات مهم, وضعیت فعلی (کد واقعی) (+5 more)
|
||||
|
||||
### Community 45 - "Community 45"
|
||||
Cohesion: 0.31
|
||||
Nodes (12): generateMetadata(), generateMetadata(), generateMetadata(), imageUrl(), normalizeBlog(), extractEntityCityId(), getEntityOrigin(), Blog() (+4 more)
|
||||
Cohesion: 0.21
|
||||
Nodes (17): generateMetadata(), generateMetadata(), generateMetadata(), imageUrl(), normalizeBlog(), extractEntityCityId(), findCityById(), getEntityOrigin() (+9 more)
|
||||
|
||||
### Community 46 - "Community 46"
|
||||
Cohesion: 0.22
|
||||
Nodes (6): Messages(), Message(), Head(), listTab, UserAccountPage(), NotfoundDashboard()
|
||||
Cohesion: 0.09
|
||||
Nodes (18): formatToman(), rialToToman(), Messages(), Message(), Paying(), Card(), PAYMENT_STATUS, TYPE_LABELS (+10 more)
|
||||
|
||||
### Community 47 - "Community 47"
|
||||
Cohesion: 0.15
|
||||
@@ -404,8 +390,8 @@ Cohesion: 0.15
|
||||
Nodes (12): زمینه, فایلهای مرتبط, مشکل / هدف, نمایش تعداد پزشکان هر تخصص در صفحه /specialties, نکات مهم, وضعیت فعلی (کد واقعی), وظایف, پروژه (+4 more)
|
||||
|
||||
### Community 51 - "Community 51"
|
||||
Cohesion: 0.19
|
||||
Nodes (9): Card(), PAYMENT_STATUS, TYPE_LABELS, Head(), listTab, Transactions(), List(), PAYMENT_STATUS (+1 more)
|
||||
Cohesion: 0.29
|
||||
Nodes (4): FrequentSearches(), TextHeader(), AText(), BText()
|
||||
|
||||
### Community 52 - "Community 52"
|
||||
Cohesion: 0.24
|
||||
@@ -467,10 +453,6 @@ Nodes (5): CustomToastify(), viewport, Providers(), ThemeRegistry(), theme
|
||||
Cohesion: 0.36
|
||||
Nodes (4): fixedIconData, nextIconData, prevIconData, LoadingDate()
|
||||
|
||||
### Community 67 - "Community 67"
|
||||
Cohesion: 0.53
|
||||
Nodes (5): buildDoctorFaq(), Doctor(), getBookingLocations, getDoctor, getDoctorAddresses
|
||||
|
||||
### Community 68 - "Community 68"
|
||||
Cohesion: 0.27
|
||||
Nodes (6): clearRefreshCookie(), cookieDomain(), setRefreshCookie(), POST(), POST(), POST()
|
||||
@@ -480,16 +462,16 @@ Cohesion: 0.20
|
||||
Nodes (9): رفع جهت تبدیل تاریخ تولد هنگام ایجاد پروفایل, زمینه, فایلهای مرتبط, مشکل / هدف, نکات مهم, وضعیت فعلی (کد واقعی), وظایف, پروژه (+1 more)
|
||||
|
||||
### Community 70 - "Community 70"
|
||||
Cohesion: 0.11
|
||||
Nodes (15): ClinicsPage(), DoctorsPage(), AutoComplete(), ButtonFilter(), Content(), ModalSearchCity(), AutoSearch(), FilterButton() (+7 more)
|
||||
Cohesion: 0.13
|
||||
Nodes (13): ClinicsPage(), AutoComplete(), ButtonFilter(), Content(), ModalSearchCity(), AutoSearch(), FilterButton(), SearchBar() (+5 more)
|
||||
|
||||
### Community 71 - "Community 71"
|
||||
Cohesion: 0.22
|
||||
Nodes (7): degree, Form(), gender, degree, Form(), gender, filterList()
|
||||
|
||||
### Community 72 - "Community 72"
|
||||
Cohesion: 0.27
|
||||
Nodes (13): generateMetadata(), buildCanonicalPath(), buildCanonicalQuery(), buildCanonicalUrl(), buildMainCanonicalUrl(), buildSpecialtyCanonicalPath(), CANONICAL_QUERY_KEYS, getCanonicalUrl() (+5 more)
|
||||
Cohesion: 0.26
|
||||
Nodes (13): generateMetadata(), findDomainByCityId(), buildCanonicalPath(), buildCanonicalQuery(), buildCanonicalUrl(), buildMainCanonicalUrl(), buildSpecialtyCanonicalPath(), CANONICAL_QUERY_KEYS (+5 more)
|
||||
|
||||
### Community 73 - "Community 73"
|
||||
Cohesion: 0.32
|
||||
@@ -504,8 +486,8 @@ Cohesion: 0.29
|
||||
Nodes (7): Authentication & Authorization, Development Tools, Frontend Framework, State Management & Data Fetching, UI/UX, 🏗️ معماری و تکنولوژی, کتابخانههای تخصصی
|
||||
|
||||
### Community 76 - "Community 76"
|
||||
Cohesion: 0.33
|
||||
Nodes (5): HeadTab(), setNewData(), DetailUser(), Disease(), IsTurnsDetails()
|
||||
Cohesion: 0.07
|
||||
Nodes (20): Allergies(), ItemAllergie(), HeadTab(), setNewData(), DetailUser(), Disease(), FamilyHistory(), ItemHistory() (+12 more)
|
||||
|
||||
### Community 79 - "Community 79"
|
||||
Cohesion: 0.17
|
||||
@@ -521,11 +503,11 @@ Nodes (11): رفع خطای `TypeError: fetch failed` در sitemap هنگام د
|
||||
|
||||
### Community 83 - "Community 83"
|
||||
Cohesion: 0.24
|
||||
Nodes (6): STATUS_LABELS, Head(), listTab, Turns(), List(), STATUS_LABELS
|
||||
Nodes (7): Card(), STATUS_LABELS, Head(), listTab, Turns(), List(), STATUS_LABELS
|
||||
|
||||
### Community 86 - "Community 86"
|
||||
Cohesion: 0.29
|
||||
Nodes (8): generateMetadata(), findCityById(), findDomainByCityId(), resolveCityDisplayName(), isRootCity(), findSpecialty(), getDoctors(), SpecialtyDetail()
|
||||
Cohesion: 0.27
|
||||
Nodes (8): generateMetadata(), DoctorsPage(), resolveCityDisplayName(), isRootCity(), ListDoctors(), findSpecialty(), getDoctors, SpecialtyDetail()
|
||||
|
||||
### Community 87 - "Community 87"
|
||||
Cohesion: 0.33
|
||||
@@ -588,16 +570,12 @@ Cohesion: 0.14
|
||||
Nodes (13): زمینه, فایلهای مرتبط, مشکل / هدف, نوار موبایل — `components/doctor/appointmentList/index.js:20-24`, نکات مهم, وضعیت فعلی, وضعیت «نوبتدهی فعال/غیرفعال» پروفایل پزشک از booking_locations, وظایف (+5 more)
|
||||
|
||||
### Community 126 - "Community 126"
|
||||
Cohesion: 0.39
|
||||
Nodes (6): bodyVariants(), buildSpecialtyFaq(), buildSpecialtyIntro(), closingVariants(), openingVariants(), pick()
|
||||
|
||||
### Community 128 - "Community 128"
|
||||
Cohesion: 0.40
|
||||
Nodes (3): Allergies(), ItemAllergie(), ModalAddAlergie()
|
||||
Cohesion: 0.33
|
||||
Nodes (7): bodyVariants(), buildDoctorFaq(), buildSpecialtyFaq(), buildSpecialtyIntro(), closingVariants(), openingVariants(), pick()
|
||||
|
||||
### Community 140 - "Community 140"
|
||||
Cohesion: 0.50
|
||||
Nodes (4): RootLayout(), normalize(), Pageguide(), safeJsonLd()
|
||||
Cohesion: 0.40
|
||||
Nodes (5): RootLayout(), normalize(), Pageguide(), getRequestOrigin(), safeJsonLd()
|
||||
|
||||
### Community 365 - "Community 365"
|
||||
Cohesion: 0.08
|
||||
@@ -607,22 +585,6 @@ Nodes (23): endpoint جدید, انتخاب محل نوبتدهی (مطب ش
|
||||
Cohesion: 0.11
|
||||
Nodes (18): P10 — بلاگ شهر-محور (C4), P11 — FAQPage schema و متن مقدمهٔ یکتا (M1 + M2), P1 — بررسی robots.txt (پیشنیاز اعتبارسنجی), P2 — هلپرهای مشترک (زیرساخت), P3 — رفع noindex سیستمیک صفحات لیست (C5 — بدترین باگ), P4 — استراتژی canonical سهدسته + تصمیم pagination (C1-a/b/c + M3-B), P5 — بازسازی sitemap (C2), P6 — صفحات موجودیت: Soft-404 و noindex کلینیک خالی (H4 + H7) (+10 more)
|
||||
|
||||
### Community 367 - "Community 367"
|
||||
Cohesion: 0.40
|
||||
Nodes (3): FamilyHistory(), ItemHistory(), ModalAddHistory()
|
||||
|
||||
### Community 368 - "Community 368"
|
||||
Cohesion: 0.40
|
||||
Nodes (3): Medications(), ItemMedication(), ModalAddMedications()
|
||||
|
||||
### Community 369 - "Community 369"
|
||||
Cohesion: 0.40
|
||||
Nodes (3): ModalAddRelatives(), Relatives(), ItemRelatives()
|
||||
|
||||
### Community 370 - "Community 370"
|
||||
Cohesion: 0.40
|
||||
Nodes (3): ModalAddSurgeries(), Surgeries(), ItemSurgeries()
|
||||
|
||||
### Community 372 - "Community 372"
|
||||
Cohesion: 0.60
|
||||
Nodes (4): hasRealName(), isThinClinic(), isThinDoctor(), PLACEHOLDER_NAMES
|
||||
@@ -651,10 +613,6 @@ Nodes (4): SearchBar(), ButtonFilter(), Fields(), RedirectLink()
|
||||
Cohesion: 0.40
|
||||
Nodes (3): KOHGILUYEH, scope, YASUJ
|
||||
|
||||
### Community 384 - "Community 384"
|
||||
Cohesion: 0.15
|
||||
Nodes (10): Clinics(), generateMetadata(), Doctors(), generateMetadata(), buildClinicParams(), buildDoctorParams(), listingRobots(), USER_FILTER_KEYS (+2 more)
|
||||
|
||||
### Community 385 - "Community 385"
|
||||
Cohesion: 0.17
|
||||
Nodes (11): تأیید زندهٔ فیکسهای SEO بعد از deploy, زمینه, نکات مهم, هدف, وظایف, پروژه, ۱. پیش از deploy, ۲. اجرای معیارهای پذیرش روی production (+3 more)
|
||||
@@ -668,42 +626,22 @@ Cohesion: 0.20
|
||||
Nodes (9): زمینه, سادهسازی sitemap با شهرِ موجود در پاسخ + آستانهٔ sitemap-index, نکات مهم, وضعیت فعلی, وظایف, پروژه, ۱. حذف ۳۵ sweep و یکسانسازی با الگوی کلینیک, ۲. آستانهٔ sitemap-index (مستقل از backend) (+1 more)
|
||||
|
||||
### Community 388 - "Community 388"
|
||||
Cohesion: 0.36
|
||||
Nodes (3): SubmitData(), ButtonFixed(), Paying()
|
||||
|
||||
### Community 389 - "Community 389"
|
||||
Cohesion: 0.25
|
||||
Nodes (8): scripts, build, dev, lint, start, test, test:cov, test:watch
|
||||
|
||||
### Community 390 - "Community 390"
|
||||
Cohesion: 0.29
|
||||
Nodes (4): ProvinceContext, ProvinceProvider(), Probe(), useProvince()
|
||||
|
||||
### Community 391 - "Community 391"
|
||||
Cohesion: 0.38
|
||||
Nodes (3): Content(), Form(), EditField()
|
||||
|
||||
### Community 392 - "Community 392"
|
||||
Cohesion: 0.29
|
||||
Nodes (3): clearAccessToken(), handleSessionExpired(), removeToken()
|
||||
|
||||
### Community 394 - "Community 394"
|
||||
Cohesion: 0.33
|
||||
Nodes (5): engines, node, name, private, version
|
||||
Cohesion: 0.12
|
||||
Nodes (9): ProvinceContext, ProvinceProvider(), Probe(), useProvince(), Content(), Form(), SubmitData(), EditField() (+1 more)
|
||||
|
||||
## Knowledge Gaps
|
||||
- **839 isolated node(s):** `metadata`, `fallbackLabels`, `MaterialUISwitch`, `fixedIconData`, `metadata` (+834 more)
|
||||
These have ≤1 connection - possible missing edges or undocumented components.
|
||||
- **36 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
|
||||
- **34 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 `imageUrl()` connect `Community 45` to `Community 0`, `Community 67`, `Community 4`, `Community 7`, `Community 81`, `Community 55`, `Community 56`, `Community 89`, `Community 380`?**
|
||||
_High betweenness centrality (0.034) - this node is a cross-community bridge._
|
||||
- **Why does `getStateInfo()` connect `Community 29` to `Community 384`, `Community 0`, `Community 6`, `Community 72`, `Community 140`, `Community 45`, `Community 14`, `Community 16`, `Community 86`, `Community 377`?**
|
||||
_High betweenness centrality (0.025) - this node is a cross-community bridge._
|
||||
- **Why does `isRootCity()` connect `Community 86` to `Community 390`, `Community 3`, `Community 29`, `Community 70`?**
|
||||
- **Why does `imageUrl()` connect `Community 45` to `Community 0`, `Community 4`, `Community 7`, `Community 81`, `Community 55`, `Community 56`, `Community 89`, `Community 380`?**
|
||||
_High betweenness centrality (0.032) - this node is a cross-community bridge._
|
||||
- **Why does `getStateInfo()` connect `Community 29` to `Community 0`, `Community 6`, `Community 72`, `Community 140`, `Community 45`, `Community 14`, `Community 16`, `Community 51`, `Community 86`, `Community 377`?**
|
||||
_High betweenness centrality (0.027) - this node is a cross-community bridge._
|
||||
- **Why does `isRootCity()` connect `Community 86` to `Community 3`, `Community 388`, `Community 70`, `Community 72`, `Community 45`, `Community 29`?**
|
||||
_High betweenness centrality (0.021) - this node is a cross-community bridge._
|
||||
- **Are the 25 inferred relationships involving `getStateInfo()` (e.g. with `generateMetadata()` and `AboutUsPage()`) actually correct?**
|
||||
_`getStateInfo()` has 25 INFERRED edges - model-reasoned connections that need verification._
|
||||
|
||||
File diff suppressed because one or more lines are too long
+209
-145
File diff suppressed because it is too large
Load Diff
@@ -470,8 +470,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"app/sitemap.js": {
|
||||
"mtime": 1784439328.547212,
|
||||
"ast_hash": "55446268ff56f6d3a6bcad0901094d96",
|
||||
"mtime": 1784440637.2554798,
|
||||
"ast_hash": "d39cc36c63881609f82a5bd1f06ef9fe",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"app/specialties/page.js": {
|
||||
@@ -2590,8 +2590,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"lib/getCanonicalUrl.js": {
|
||||
"mtime": 1784407010.2048862,
|
||||
"ast_hash": "382b422d12683c05d27032df15d46bd5",
|
||||
"mtime": 1784440389.9873533,
|
||||
"ast_hash": "609829af60b5c58314e83051eedf18b5",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"lib/getStateInfo.js": {
|
||||
@@ -3470,8 +3470,8 @@
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"app/specialties/[slug]/page.js": {
|
||||
"mtime": 1784406541.9613838,
|
||||
"ast_hash": "9bcbf931390b23e3159e7a0eac913688",
|
||||
"mtime": 1784440484.996775,
|
||||
"ast_hash": "1349171f2f2b743fe4be5994b16dec90",
|
||||
"semantic_hash": ""
|
||||
},
|
||||
"components/doctor/appointmentList/bookingState.js": {
|
||||
|
||||
@@ -73,6 +73,11 @@ export function buildSpecialtyCanonicalPath(pathname, search) {
|
||||
const specialtyName = params.get("specialty");
|
||||
if (!specialtyName) return null;
|
||||
|
||||
// صفحهٔ ۲ به بعد محتوای متفاوتی دارد و صفحهٔ فرود تخصص pagination ندارد؛
|
||||
// canonical کردن صفحهٔ N به صفحهٔ ۱ خلاف راهنمای گوگل است و یا نادیده گرفته
|
||||
// میشود یا مسیر کشف پزشکان صفحات بعدی را میبندد. آنها self-canonical میمانند.
|
||||
if (Number(params.get("page")) > 1) return null;
|
||||
|
||||
const hasOtherFilter = [...params.keys()].some((key) => !HOST_INJECTED_KEYS.has(key));
|
||||
if (hasOtherFilter) return null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user