feat(entityQuality): rename isThinDoctor to isNoindexDoctor for clarity and update related logic

This commit is contained in:
hamed
2026-07-26 09:17:42 +03:30
parent b8514e64cf
commit d02ae8bff0
3 changed files with 23 additions and 6 deletions
+2 -2
View File
@@ -6,7 +6,7 @@ import { getStateInfo } from "@/lib/getStateInfo";
import { getEntityOrigin } from "@/lib/getCanonicalUrl";
import { extractEntityCityId, findCityById } from "@/lib/domainHelpers";
import { buildDoctorFaq } from "@/lib/specialtyContent";
import { isThinDoctor } from "@/lib/entityQuality";
import { isNoindexDoctor } from "@/lib/entityQuality";
import specialtiesData from "@/data/specialties.json";
import { safeJsonLd } from "@/lib/sanitize";
import { imageUrl, doctorTitle } from "@/helper";
@@ -96,7 +96,7 @@ export async function generateMetadata({ params }) {
title,
description,
alternates: { canonical: `${origin}/doctor/${doctor.uuid}` },
...(isThinDoctor(doctor) && { robots: { index: false, follow: true } }),
...(isNoindexDoctor(doctor) && { robots: { index: false, follow: true } }),
openGraph: {
title,
description,
+3 -2
View File
@@ -4,7 +4,7 @@ import citiesData from '@/data/city.json';
import statesData from '@/data/state.json';
import { isRootCity } from '@/lib/rootCity';
import { extractEntityCityId, findDomainByCityId } from '@/lib/domainHelpers';
import { isThinClinic, isThinDoctor } from '@/lib/entityQuality';
import { isThinClinic, isNoindexDoctor } from '@/lib/entityQuality';
import specialtiesData from '@/data/specialties.json';
import { isIndexableSpecialty } from '@/lib/specialtyIndexing';
@@ -119,7 +119,8 @@ function cityFilterParams(scope) {
async function getPublishedDoctors(scope) {
const doctors = await fetchAllPages('/api/v1/doctors', cityFilterParams(scope));
return doctors
.filter((d) => !isThinDoctor(d))
// پروفایل بدون مالک noindex است، پس در sitemap هم اعلام نمی‌شود.
.filter((d) => !isNoindexDoctor(d))
// روی دامنهٔ اصلی فقط پزشکانی که شهرشان دامنهٔ اختصاصی ندارد؛ روی دامنهٔ شهری
// فیلتر city_id سمت API قبلاً کار را کرده است.
.filter((d) => !scope.isRoot || !findDomainByCityId(extractEntityCityId(d)));
+18 -2
View File
@@ -14,8 +14,7 @@ function hasRealName(rawName) {
}
/**
* پزشک بی‌محتوا. معیار قبلی «owner_status !== claimed» بیش از حد سخت‌گیر بود و
* عملاً کل مارکت‌پلیس را از ایندکس بیرون می‌گذاشت — حالا فقط نبودِ محتوا مهم است.
* پزشک بی‌محتوا — فقط سنجهٔ محتوا، مستقل از مالکیت پروفایل.
*/
export function isThinDoctor(doctor) {
if (!doctor?.uuid || !hasRealName(doctor.name)) return true;
@@ -24,6 +23,23 @@ export function isThinDoctor(doctor) {
return !hasSpecialty && !hasLocation;
}
/**
* پروفایل بدون مالک (claim نشده). داده‌اش از منبع بیرونی آمده و صاحبش تأییدش نکرده،
* پس محتوای قابل اتکا برای ایندکس نیست. هم پاسخ لیست و هم پاسخ جزئیات `owner_status`
* دارند؛ نبودِ فیلد هم «مالک ندارد» تفسیر می‌شود تا هیچ‌وقت به‌طور خاموش ایندکس نشود.
*/
export function isUnclaimedDoctor(doctor) {
return doctor?.owner_status !== "claimed";
}
/**
* منبع واحدِ ایندکس‌پذیری پزشک: هم صفحهٔ پزشک (robots) و هم sitemap از این استفاده
* می‌کنند تا واگرا نشوند — چیزی که noindex است نباید در sitemap باشد.
*/
export function isNoindexDoctor(doctor) {
return isThinDoctor(doctor) || isUnclaimedDoctor(doctor);
}
/**
* کلینیک بی‌محتوا. is_active:false = «موقتاً غیرفعال» تفسیر می‌شود (noindex، نه 410)،
* چون رکورد و نوبت‌های تاریخی‌اش باقی می‌مانند و ممکن است دوباره فعال شود.