61 lines
3.0 KiB
JavaScript
61 lines
3.0 KiB
JavaScript
// معیار «محتوای معنادار» برای ایندکسپذیری و ورود به sitemap.
|
|
// یک منبع مشترک برای صفحات موجودیت و app/sitemap.js تا هرگز واگرا نشوند:
|
|
// چیزی که noindex است نباید در sitemap باشد.
|
|
|
|
const PHONE_LIKE = /^0?9\d{9}$/;
|
|
const PLACEHOLDER_NAMES = new Set(["test", "تست", "-", "—"]);
|
|
|
|
// نامهای آلوده (شمارهتلفن، "test") نام واقعی نیستند و صفحه را بیارزش میکنند.
|
|
function hasRealName(rawName) {
|
|
const name = String(rawName || "").trim();
|
|
if (!name) return false;
|
|
if (PHONE_LIKE.test(name.replace(/[\s-]/g, ""))) return false;
|
|
return !PLACEHOLDER_NAMES.has(name.toLowerCase());
|
|
}
|
|
|
|
/**
|
|
* پزشک بیمحتوا — فقط سنجهٔ محتوا، مستقل از مالکیت پروفایل.
|
|
*/
|
|
export function isThinDoctor(doctor) {
|
|
if (!doctor?.uuid || !hasRealName(doctor.name)) return true;
|
|
const hasSpecialty = Boolean(doctor.specialties?.length);
|
|
const hasLocation = Boolean(doctor.address?.length || doctor.city?.length);
|
|
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)،
|
|
* چون رکورد و نوبتهای تاریخیاش باقی میمانند و ممکن است دوباره فعال شود.
|
|
*/
|
|
export function isThinClinic(clinic) {
|
|
if (!clinic?.uuid || !hasRealName(clinic.title || clinic.name)) return true;
|
|
if (clinic.is_active === false) return true;
|
|
// پاسخ لیست و پاسخ جزئیات فیلدهای متفاوتی دارند — هر سیگنالِ موجود کافی است.
|
|
const hasContent =
|
|
Boolean(clinic.caption) ||
|
|
Boolean(clinic.location) ||
|
|
Boolean(clinic.services?.length) ||
|
|
Boolean(clinic.specialties?.length) ||
|
|
Boolean(clinic.images_clinic?.length) ||
|
|
Number(clinic.doctors_count) > 0 ||
|
|
Boolean(clinic.doctor_list?.length || clinic.doctors?.length);
|
|
return !hasContent;
|
|
}
|