Files

56 lines
2.8 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;
}
/**
* منبع واحدِ ایندکس‌پذیری پزشک: هم صفحهٔ پزشک (robots) و هم sitemap از این استفاده
* می‌کنند تا واگرا نشوند — چیزی که noindex است نباید در sitemap باشد.
*
* سنجه فقط محتواست، نه مالکیت. شرط `owner_status !== "claimed"` برداشته شد چون
* ۸۰ صفحهٔ یاسوج و ۱۲ صفحهٔ بهبهان را از ایندکس بیرون نگه می‌داشت — پروفایل‌هایی که
* نام و تخصص و نشانی داشتند. claim یک وضعیت اداری است، نه سنجهٔ کیفیت محتوا.
*/
export function isNoindexDoctor(doctor) {
return isThinDoctor(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;
}