// معیار «محتوای معنادار» برای ایندکس‌پذیری و ورود به 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; }