# سند سناریوی محصول (Product Scenario) ## سامانه کرال هوشمند آگهی‌های دیوار با پرچم‌گذاری AI و اطلاع‌رسانی تلگرامی این سند به عنوان مرجع توصیف محصول، فرآیندها، نیازمندی‌ها و قوانین تجاری سامانه کرال هوشمند دیوار تدوین شده است و مبنای پیاده‌سازی و راستی‌آزمایی محصول خواهد بود. --- ### ۱. خلاصهٔ محصول (Product Summary) سامانه کرال هوشمند دیوار، ابزاری است که به کاربران اجازه می‌دهد آگهی‌های ثبت شده در سایت دیوار را بر اساس دسته‌بندی‌ها یا فیلترهای جستجوی خاص به‌صورت خودکار و دوره‌ای پایش (Crawl) کنند. پس از جمع‌آوری آگهی‌ها، سیستم محتوای هر آگهی را با استفاده از مدل‌های زبانی بزرگ (LLM) تحلیل کرده و بر اساس معیارهای تعیین شده در «پرامپت تشخیصی»، آگهی‌های هدف را شناسایی و پرچم‌گذاری (Flag) می‌کند. در نهایت، آگهی‌های پرچم‌گذاری شده به کانال‌های تلگرامی متناظر با هر کرال ارسال می‌شوند تا کاربر در لحظه از فرصت‌ها مطلع گردد. --- ### ۲. هدف و ارزش اصلی (Core Goal and Value) کاهش زمان و هزینهٔ جستجوی دستی آگهی‌های دیوار و شناسایی هوشمند فرصت‌های معاملاتی/کاری خاص. ارزش کلیدی سامانه: **فیلتراسیون پیشرفته و معنایی (Semantic)** که با فیلترهای معمولی دیوار (مانند قیمت و متراژ) غیرقابل پیاده‌سازی است. به عنوان مثال: "پیدا کردن آپارتمان‌هایی در منطقه غرب تهران که مالک آن‌ها به دلیل مهاجرت مایل به معاوضه با خودرو است." --- ### ۳. کاربران و نقش‌ها (Users and Roles) در این نسخه (MVP)، سیستم تک‌کاربره یا دارای یک نقش پیش‌فرض (مدیر سیستم / کاربر نهایی) است: * **کاربر/مدیر (User/Admin):** دسترسی کامل به داشبورد وب جهت تعریف کرال‌ها، مشاهده نتایج تحلیل AI، تنظیم پرامپت‌ها، پایش وضعیت کرال‌ها و تنظیمات اتصال تلگرام. --- ### ۴. سناریوی اصلی کاربر از ابتدا تا انتها (End-to-End Main User Scenario) 1. **ورود و راه‌اندازی اولیه:** کاربر وارد داشبورد وب سامانه می‌شود. 2. **تعریف کرال جدید:** کاربر دکمه «ایجاد کرال جدید» را می‌زند و اطلاعات زیر را وارد می‌کند: * عنوان کرال: "خرید آپارتمان فوری زیر قیمت" * لینک جستجوی دیوار: `https://divar.ir/s/tehran/buy-apartment?query=...` * پرامپت تشخیصی: "بررسی کن آیا فروشنده پول لازم است یا به دلیل مهاجرت عجله دارد؟" * فاصلهٔ زمانی اجرا: "هر ۱۵ دقیقه" * پنجرهٔ زمانی مجاز: "از ساعت ۰۸:۰۰ الی ۲۳:۰۰" * کانال تلگرام: `@my_divar_alerts` * وضعیت: "فعال" 3. **زمان‌بندی و کرال:** موتور زمان‌بندی (Celery Beat) در فواصل تعیین‌شده کرال را اجرا می‌کند. آگهی‌های جدیدِ لینک دیوار جمع‌آوری شده و اطلاعات پایه (عنوان، توضیحات، قیمت، لینک، عکس‌ها) در دیتابیس ذخیره می‌شوند. 4. **ارزیابی هوشمند (AI Evaluation):** برای هر آگهی جدید که قبلاً ارزیابی نشده است، یک تسک پس‌زمینه ایجاد می‌شود. متن آگهی به همراه پرامپت تشخیصی به LLM ارسال می‌شود. 5. **دریافت نتیجه ساختاریافته:** LLM مشخص می‌کند که آیا آگهی شرایط پرچم‌گذاری را دارد یا خیر (`is_flagged: true/false`) و دلایل آن را به همراه سطح اطمینان (`confidence`) بازمی‌گرداند. 6. **اطلاع‌رسانی تلگرامی:** در صورت مثبت بودن پرچم (`is_flagged: true`)، ربات تلگرام پیامی حاوی اطلاعات کلیدی آگهی، دلایل هوش مصنوعی و لینک آگهی را به کانال تعیین‌شده ارسال می‌کند. 7. **مشاهده داشبورد:** کاربر در پنل خود لیست تمام آگهی‌های دریافت شده، وضعیت پرچم آن‌ها و نتایج تحلیل AI را مشاهده و فیلتر می‌کند. --- ### ۵. User Stories مهم (Key User Stories) * **داشبورد مدیریت کرال:** به عنوان کاربر، من می‌خواهم بتوانم کرال‌های جدید بسازم، ویرایش کنم، غیرفعال سازم یا حذف کنم تا بتوانم پایش جستجوهای مختلف را مدیریت کنم. * **پایش هوشمند:** به عنوان کاربر، من می‌خواهم سیستم به‌طور خودکار در بازه‌های زمانی معین کار کند تا نیازی به اجرای دستی و آنلاین بودن همیشگی من نباشد. * **تحلیل AI:** به عنوان کاربر، من می‌خواهم محتوای متنی آگهی‌ها با دقت تحلیل شده و تنها مواردی که با پرامپت من همخوانی دارند فیلتر شوند تا از هدررفت زمان جلوگیری شود. * **اطلاع‌رسانی سریع:** به عنوان کاربر، من می‌خواهم آگهی‌های پرچمشده بلافاصله در کانال تلگرام شخصی‌ام ارسال شوند تا بتوانم سریعاً با آگهی‌دهنده تماس بگیرم. * **مشاهده آرشیو:** به عنوان کاربر، من می‌خواهم آرشیو تمام آگهی‌های کرال‌شده (پرچمشده یا عادی) را در پنل ببینم تا مطمئن شوم هیچ داده‌ای از دست نرفته است. --- ### ۶. Acceptance Criteria برای جریان‌های اصلی (Acceptance Criteria) #### ایجاد و تنظیم کرال * کاربر نتواند کرال بدون عنوان، بدون پرامپت یا بدون لینک دیوار معتبر ذخیره کند. * فرمت بازه زمانی اجرا باید محدود به گزینه‌های استاندارد (مثلاً ۵، ۱۵، ۳۰ یا ۶۰ دقیقه) باشد. * پنجره زمانی مجاز اجرا باید با ساعت شروع و پایان مشخص شود (مثلاً ۸ تا ۲۲). #### جمع‌آوری و ذخیره‌سازی آگهی‌ها * تمام آگهی‌های استخراج شده از لینک دیوار باید با شناسه منحصربه‌فرد دیوار (Divar Token) ذخیره شوند تا از ذخیره تکراری جلوگیری شود. * حتی اگر فرآیند هوش مصنوعی یا ارسال تلگرام با خطا مواجه شود، اصل آگهی باید در دیتابیس ثبت شده باقی بماند. #### پردازش هوش مصنوعی (AI Process) * برای هر آگهی، فرآیند ارزیابی هوش مصنوعی دقیقاً **یک‌بار** انجام شود (جلوگیری از ارزیابی تکراری و اتلاف هزینه). * خروجی هوش مصنوعی باید فرمت JSON ساختاریافته داشته باشد. در صورت برگشت پاسخ نامعتبر از مدل، سیستم نباید کرش کند، بلکه باید وضعیت خطا ثبت شده و پردازش آگهی‌های بعدی ادامه یابد. #### اطلاع‌رسانی تلگرام * ارسال پیام تلگرام فقط برای آگهی‌هایی رخ دهد که خروجی AI آن‌ها `is_flagged: true` باشد. * اگر آدرس کانال تلگرام برای یک کرال خالی بود، تسک ارسال پیام بدون خطا نادیده گرفته شده و صرفاً در لاگ‌ها ثبت شود. * شکست در ارسال پیام تلگرام (مانند مسدود بودن ربات یا خطای شبکه) نباید کل روند کرال را متوقف یا تراکنش‌های دیتابیس را Rollback کند. --- ### ۷. نیازمندی‌های عملکردی با شناسه (Functional Requirements) | شناسه (ID) | عنوان نیازمندی | توصیف تفصیلی | | :--- | :--- | :--- | | **FR-01** | ایجاد و ویرایش کرال | کاربر باید بتواند نمونه‌های کرال (Crawl Task) را ایجاد، ویرایش، حذف و فعال/غیرفعال کند. | | **FR-02** | فیلدهای تنظیم کرال | فیلدهای کرال شامل: عنوان، لینک دیوار، پرامپت اختصاصی، اینتروال زمانی، پنجره زمانی، آدرس کانال تلگرام و وضعیت است. | | **FR-03** | کرال پس‌زمینه دوره‌ای | سیستم باید با Celery Beat در فواصل مشخص و در پنجره زمانی تعیین‌شده، صفحات دیوار را کرال کند. | | **FR-04** | استخراج داده‌های آگهی | برای هر آگهی باید فیلدهای: شناسه دیوار (توکن)، عنوان آگهی، متن توضیحات، قیمت، دسته‌بندی، تصاویر و لینک آگهی استخراج شوند. | | **FR-05** | یکتا‌سازی آگهی‌ها | جلوگیری از پردازش مجدد آگهی‌های تکراری با استفاده از شناسه دیوار (توکن یکتا) در سطح کل سیستم. | | **FR-06** | ذخیره همگانی آگهی‌ها | ذخیره‌سازی تمام آگهی‌های جدیدِ یافت‌شده در دیتابیس، بدون توجه به نتیجه پرچم‌گذاری هوش مصنوعی. | | **FR-07** | تحلیل معنایی با LLM | ارسال محتوای هر آگهی جدید به همراه پرامپت اختصاصی کرال به LLM API جهت دریافت پاسخ ساختاریافته JSON. | | **FR-08** | قالب‌بندی خروجی LLM | دریافت فیلدهای `is_flagged` (Boolean)، `reason` (String)، `confidence` (Float/Integer) و `extracted_fields` (JSON/Dictionary) از AI. | | **FR-09** | ارسال پیام به تلگرام | ارسال اطلاعات آگهی‌های پرچم‌گذاری شده به کانال تلگرام ثبت شده در کرال با قالب زیبا و خوانا. | | **FR-10** | داشبورد وب - نمایش کرال‌ها | پنل وب برای لیست کردن کرال‌ها به همراه آخرین زمان اجرا و وضعیت آن‌ها. | | **FR-11** | داشبورد وب - نمایش آگهی‌ها | نمایش لیست آگهی‌های کرال شده با قابلیت فیلتر بر اساس کرال، وضعیت پرچم و کلیدواژه‌ها. | | **FR-12** | اجرای دستی کرال | امکان کلیک روی دکمه «اجرای فوری» برای هر کرال جهت تست بدون انتظار برای نوبت بعدی Celery Beat. | --- ### ۸. نیازمندی‌های غیرعملکردی (Non-functional Requirements) * **قابلیت اطمینان (Reliability):** در صورت قطع ارتباط با دیوار، LLM یا تلگرام، کل سیستم نباید از کار بیفتد. سیستم باید مکانیزم Retry برای تسک‌های شکست‌خورده داشته باشد. * **مدیریت خطا (Error Handling):** خطاهای ناشی از مسدود شدن IP توسط دیوار یا تغییر ساختار HTML دیوار باید به‌صورت لاگ‌های ساختاریافته ذخیره شوند تا مدیر متوجه خرابی کرالر شود. * **لاگ‌گیری (Logging):** ثبت تمام تراکنش‌ها، دفعات اجرای کرال‌ها، نتایج پردازش هوش مصنوعی و وضعیت ارسال پیام تلگرام در دیتابیس یا فایل لاگ با فرمت استاندارد. * **مقیاس‌پذیری اولیه (Scalability):** معماری سیستم باید به‌گونه‌ای باشد که با افزایش تعداد کرال‌ها، بتوان با افزایش تعداد پروسس‌های Celery Worker ظرفیت پردازش را بالا برد. * **امنیت (Security):** * توکن‌های حساس (مانند کلید API هوش مصنوعی و توکن ربات تلگرام) باید در متغیرهای محیطی سیستم (.env) نگهداری شوند و در کدهای برنامه هاردکد نشوند. * احراز هویت داشبورد در سطح MVP ساده باشد (مثلاً یک نام کاربری و رمز عبور ادمین). * **کنترل نرخ مصرف (Rate Limiting):** پیاده‌سازی تاخیرهای رندوم (Random Delay) در زمان کرال دیوار جهت جلوگیری از بلاک شدن IP سرور. * **تکرار ناپذیری (Idempotency):** پردازش یک آگهی نباید تحت هیچ شرایطی دو بار انجام شود. دیتابیس باید تضمین کند که ثبت آگهی و تسک ارزیابی آن برای یک توکن دیوار منحصربه‌فرد، تکرار نخواهد شد. --- ### ۹. قوانین دامنه و Business Rules 1. **پرامپت اختصاصی:** هر کرال فقط و فقط دارای یک پرامپت تشخیصی است که توسط کاربر تنظیم می‌شود. 2. **ذخیره حداکثری:** سیستم حق ندارد آگهی‌های غیرمرتبط (Flagged = False) را دور بریزد. تمام آگهی‌های اسکن‌شده باید ذخیره شوند تا در آینده کاربر بتواند در صورت تغییر پرامپت، آگهی‌های قبلی را مجدداً تحلیل کند. 3. **تارگت مجزای تلگرام:** هر کرال دارای یک فیلد آدرس کانال تلگرام مجزاست. پیام‌های هر کرال فقط به کانال متناظر خودش ارسال می‌شوند. 4. **سکوت تلگرام:** اگر فیلد تلگرام یک کرال خالی باشد یا با کاراکتر خاصی غیرفعال شده باشد، هیچ پیام تلگرامی ارسال نمی‌شود و این سناریو به عنوان خطای سیستم محسوب نمی‌گردد. 5. **انحصار زمانی:** اجرای تسک‌های کرال برای هر کرال باید خارج از پنجره زمانی مجاز متوقف شود (مثلاً اگر پنجره ۸ تا ۲۲ است، در ساعت ۲۳ تسک‌ها اجرا نشوند و تا فردا صبح منتظر بمانند). --- ### ۱۰. جریان‌های فرعی و Edge Cases * **آگهی تکراری:** اگر دیوار در کرال‌های متوالی یک آگهی قدیمی را در صفحه اول جستجو نشان دهد، سیستم پس از چک کردن توکن یکتای آگهی در دیتابیس، از ذخیره مجدد و تحلیل دوباره آن خودداری می‌کند. * **خطای API هوش مصنوعی:** در صورت قطع ارتباط با LLM یا اتمام شارژ پنل، تسک پردازش آگهی وارد وضعیت `FAILED` شده و با سیاست Exponential Backoff تا حداکثر ۳ بار مجدداً تلاش می‌کند. اگر همچنان خطا باقی ماند، آگهی در دیتابیس بدون پرچم ذخیره شده و خطای مربوطه لاگ می‌شود. * **خطای تلگرام:** اگر ارسال به تلگرام به دلیل فیلترینگ یا نامعتبر بودن Channel ID شکست بخورد، این خطا در جدول لاگ اعلانات ثبت می‌شود ولی وضعیت کلی آگهی و کرال خراب نمی‌شود. * **کرال غیرفعال:** اگر یک کرال توسط کاربر غیرفعال شود (`is_active: false`)، Celery Beat باید بلافاصله از زمان‌بندی کردن آن خودداری کند و تسک‌های در صف ماندهٔ آن اجرا نشوند. * **خروجی نامعتبر هوش مصنوعی:** اگر هوش مصنوعی به جای ساختار JSON مورد نظر، یک متن عمومی یا فرمت خراب برگرداند، سیستم با یک لایه Parser خطای ساختاری را گرفته، فیلد `is_flagged` را پیش‌فرض `false` در نظر می‌گیرد و متن خام خروجی را جهت بررسی مدیر لاگ می‌کند. --- ### ۱۱. موارد خارج از Scope فعلی (Out of Scope) * **دور زدن پیشرفته Cloudflare/کپچای دیوار:** در فاز MVP، سیستم از کرال سادهٔ صفحات عمومی دیوار (بدون نیاز به لاگین) استفاده می‌کند. حل کپچاهای پیچیده تصویر یا دور زدن سپرهای امنیتی پیشرفته Cloudflare در این فاز پیاده‌سازی نمی‌شود. * **پرداخت درون‌برنامه‌ای و اشتراک:** سیستم به صورت تک‌کاربره/ادمین مدیریت می‌شود و پنل فروش اشتراک ندارد. * **اپلیکیشن موبایل:** دسترسی فقط از طریق مرورگر وب (داشبورد React) خواهد بود. * **چت تلگرام دوطرفه:** ربات تلگرام یک‌طرفه است و صرفاً پیام ارسال می‌کند و قابلیت دریافت کامند از کاربر در چت تلگرام در این فاز وجود ندارد. --- ### ۱۲. فرضیات و ابهامات * **ساختار صفحات دیوار:** فرض می‌شود لینک‌های جستجوی دیوار اطلاعات اولیه آگهی‌ها (توکن، عنوان، قیمت، توضیحات کوتاه) را در خروجی HTML یا API عمومی خود دارند. در صورت نیاز به جزئیات بیشتر (توضیحات کامل آگهی)، کرالر باید به صفحه اختصاصی هر آگهی (`/v/token`) درخواست بزند. * **محدودیت نرخ (Rate Limit) دیوار:** فرض می‌شود که تعداد کرال‌ها در حد منطقی (کمتر از ۱۰ کرال همزمان) است و با استفاده از پروکسی‌های ساده یا تاخیر تصادفی، مسدودسازی IP رخ نمی‌دهد. --- ### ۱۳. ریسک‌های محصولی/اجرایی * **ریسک تغییرات ساختاری دیوار:** سایت دیوار ممکن است در هر لحظه ساختار کلاس‌های HTML یا آدرس‌های API خود را تغییر دهد که باعث خرابی موقت کرالر می‌شود. * *کاهش ریسک:* جداسازی منطق Parser دیوار در کدهای بک‌اند به صورتی که با کمترین تغییر کد قابل اصلاح باشد. * **ریسک هزینهٔ LLM API:** ارسال همهٔ آگهی‌ها به LLM می‌تواند هزینه‌بر باشد. * *کاهش ریسک:* استفاده از مدل‌های ارزان‌تر (مانند GPT-4o-mini یا Claude 3 Haiku) و فیلتر اولیه آگهی‌ها بر اساس کلمات کلیدی ساده قبل از ارسال به LLM. --- ### ۱۴. معیارهای پذیرش MVP (MVP Acceptance Criteria) * امکان ایجاد حداقل ۵ کرال فعال همزمان با بازه‌های زمانی متفاوت. * ذخیره موفقیت‌آمیز آگهی‌های کرال شده در PostgreSQL. * تحلیل موفق آگهی‌ها توسط LLM و ذخیره نتایج به صورت کاملاً ساختاریافته. * دریافت نوتیفیکیشن تلگرام حاوی لینک آگهی و علت پرچم‌گذاری در کمتر از ۳ دقیقه پس از انتشار آگهی در دیوار (در زمان اجرای کرال). * عدم کرش یا خرابی کل سیستم در صورت مسدود شدن تلگرام یا قطع اینترنت. * اجرا شدن کل سیستم با دستور `docker compose up --build` بدون نیاز به تنظیمات دستی روی سیستم میزبان. --- ### ۱۵. Manual QA Checklist برای مسیر اصلی محصول 1. [ ] ایجاد یک کرال جدید با پرامپت مشخص (مثلاً: "فقط آگهی‌های رهن کامل بدون اجاره") و تنظیم کانال تلگرام معتبر. 2. [ ] فشردن دکمه «اجرای فوری» در داشبورد و تایید آغاز فرآیند کرال در تسک‌های Celery. 3. [ ] بررسی دیتابیس یا لیست آگهی‌ها در داشبورد و اطمینان از ثبت شدن آگهی‌های رهن کامل و آگهی‌های ترکیبی (رهن و اجاره). 4. [ ] بررسی خروجی هوش مصنوعی برای هر آگهی: آگهی‌های رهن کامل باید `is_flagged: true` و بقیه `is_flagged: false` شده باشند. 5. [ ] بررسی کانال تلگرام: پیام‌ها فقط برای آگهی‌های رهن کامل ارسال شده باشند. 6. [ ] غیرفعال کردن کرال از پنل و اطمینان از اینکه در بازه زمانی بعدی دیگر هیچ درخواستی به دیوار ارسال نمی‌شود. 7. [ ] قطع کردن موقت اتصال اینترنت (یا مسدود کردن API تلگرام) و ارسال یک آگهی پرچم‌گذاری شده جدید؛ سیستم نباید کرش کند و وضعیت خطای تلگرام باید در بخش Execution Log ثبت شود.