Skip to content

Latest commit

 

History

History
175 lines (128 loc) · 13.2 KB

README.md

File metadata and controls

175 lines (128 loc) · 13.2 KB

Café Roshan (Worker & Management System)

سیستم مدیریت و سفارش‌گیر یکپارچه کافه روشن بر بستر Cloudflare Workers، دیتابیس Cloudflare D1 (SQLite)، فضای ذخیره‌سازی Cloudflare KV، و ربات مدیریت تلگرام.


۱. معماری کلی سیستم (Architecture)

  • Backend / Edge Runtime: پیاده‌سازی شده با Cloudflare Workers (ماژول‌های استاندارد ES) جهت پاسخ‌دهی بلادرنگ با حداقل تاخیر در Edge.
  • Database (D1): پایگاه داده SQLite ابری برای نگهداری محصولات (products)، دسته‌بندی‌ها (categories)، تنظیمات سایت (site_settings)، سفارش‌ها (orders) و وضعیت نشست‌های ربات و تلاش‌های ناموفق ورود ادمین (bot_state).
  • Object / Blob Storage (KV): ذخیره‌سازی فایل تصاویر و کشینگ ساختار منو.
  • Static Assets: رابط کاربری عمومی مشتریان و پنل مدیریت ادمین در پوشه public/ به صورت دارایی‌های ایستا سرو می‌شوند.
  • Telegram Bot: اعلان آنی سفارش‌های ثبت‌شده به مدیران کافه و امکان تایید/رد دوطرفه، مدیریت منو و آپلود تصویر مستقیماً از تلگرام.

۲. پیش‌نیازها (Requirements)

  • Node.js: نسخه 22 یا بالاتر (node -v >= 22).
  • Wrangler: ابزار رسمی Cloudflare Workers (نسخه موجود در devDependencies).

۳. راه‌اندازی و توسعه محلی (Local Development)

نصب وابستگی‌ها

npm install
# یا در محیط‌های CI:
npm ci

اجرای تست‌های خودکار

تست‌ها با استفاده از node:test داخلی نود اجرا می‌شوند و نیازی به ابزارهای جانبی ندارند (شامل بیش از ۱۶۰ تست جامع برای اعتبارسنجی، سفارش‌ها، ادمین و ربات تلگرام):

npm test

# اجرای اختصاصی تست‌های تلگرام:
node --test test/telegram.test.js

اجرای مایگریشن‌های دیتابیس در محیط لوکال

npm run db:migrate:local

اجرای سرور توسعه محلی

npm run dev

۴. پیکربندی کلودفلر و متغیرهای محرمانه (Configuration & Secrets)

فایل wrangler.jsonc ساختار منابع ابری را مشخص می‌کند:

  • دیتابیس D1 با بایندینگ DB
  • فضای KV با بایندینگ PRODUCTS_KV
  • دارایی‌های استاتیک با بایندینگ ASSETS

متغیرهای محرمانه (Secrets)

برای محیط پروداکشن، این متغیرها را با دستور wrangler secret put <NAME> تنظیم کنید:

نام متغیر نوع توضیحات
JWT_SECRET Secret کلید محرمانه برای امضا و اعتبارسنجی توکن‌های ادمین (HMAC-SHA256).
ADMIN_PASSWORD Secret رمز عبور ورود به پنل مدیریت وب.
TOKEN_VERSION Variable/Secret نسخه توکن‌های ادمین (پیش‌فرض "1"). در صورت نیاز به باطل‌سازی تمام نشست‌ها مقدار آن افزایش می‌یابد.
TELEGRAM_BOT_TOKEN Secret توکن ربات تلگرام کافه دریافتی از BotFather.
ADMIN_IDS Secret / Var لیست آیدی‌های عددی تلگرام مدیران (جداشده با کاما، مثلاً 1234567,8901234).
WEBHOOK_SECRET Secret رشته تصادفی و امن برای اعتبارسنجی وب‌هوک‌های دریافتی از تلگرام.
TABLE_SIGNING_SECRET Secret توصیه‌شده برای پروداکشن (اختیاری در توسعه). کلید محرمانه جهت امضای شماره میز در کدهای QR (/?t=X&sig=...) با HMAC-SHA256 برای جلوگیری از ثبت سفارش‌های جعلی خارج از کافه. سکرت فقط کلید امضاست و روشن/خاموش بودن الزام امضا از پنل وب (تب «تصاویر و تنظیمات») یا ربات (دکمه «🔐 امضای QR میزها») کنترل می‌شود (پیش‌فرض هنگام ست بودن سکرت و ثبت نشدن تنظیم: روشن).
IP_HASH_SECRET Secret توصیه‌شده. کلید محرمانه جهت هش کردن IP مشتریان با HMAC-SHA256 (جلوگیری از حملات rainbow table/brute-force روی آدرس‌های IPv4). در صورت تنظیم نشدن، از JWT_SECRET به عنوان کلید پیش‌فرض استفاده می‌شود.
ENFORCE_ORDER_HOURS Variable اختیاری. اگر "0" باشد، ساعت کاری برای ثبت سفارش چک نمی‌شود (مثلاً برای تست شبانه). پیش‌فرض: فعال.
SITE_URL Variable اختیاری. آدرس پایه سایت (مثلاً https://cafe-roshan.ir) جهت تولید لینک‌های sitemap.xml، robots.txt و تگ‌های canonical. در صورت خالی بودن از Host هدر درخواست استفاده می‌شود.

۵. مایگریشن‌های پایگاه داده (D1 Migrations)

مایگریشن‌ها در پوشه migrations/ نگهداری می‌شوند:

  • 0001_init.sql: جداول پایه دسته‌بندی‌ها و محصولات
  • 0002_add_original_price.sql: پشتیبانی از تخفیف و قیمت اولیه
  • 0003_clear_dead_image_paths.sql: پاکسازی مسیرهای منقضی تصویر
  • 0004_add_available_column.sql: فیلد موجود/ناموجود بودن محصول
  • 0005_add_orders_table.sql: جدول ثبت سفارش‌ها
  • 0006_orders_hardening.sql: فیلدهای ضدتکرار، هش آی‌پی و پیام‌های تلگرام
  • 0007_site_settings.sql: جدول تنظیمات سایت برای ذخیره لوگو، تصویر کاور و تعداد میزها (logo, cover, tableCount)
  • 0008_orders_summary_index.sql: ایندکس ترکیبی برای خلاصه‌سازی سفارش‌های در انتظار
  • 0009_orders_table_pending_index.sql: ایندکس بهینه‌سازی بررسی سقف سفارش در انتظار هر میز
  • 0010_bot_state.sql: جدول نگهداری سشن‌های چندمرحله‌ای ربات تلگرام، پیام‌های قبلی و قفل ورود ادمین با پشتیبانی از TTL/انقضا
  • 0011_normalize_image_paths.sql: یکسان‌سازی مسیر تصاویر به فرمت /images/<filename>
  • 0012_add_order_public_id.sql: افزودن شناسه عمومی تصادفی (public_id) به سفارش‌ها برای استعلام عمومی وضعیت سفارش

اعمال مایگریشن‌ها بر روی سرور Cloudflare D1:

npm run db:migrate:remote

۶. تنظیم وب‌هوک ربات تلگرام (Telegram Webhook Setup)

پس از دیپلوی ورکر، آدرس وب‌هوک تلگرام (/tg-webhook) را به همراه سکرت توکن ست کنید:

curl -F "url=https://your-domain.workers.dev/tg-webhook" \
     -F "secret_token=YOUR_WEBHOOK_SECRET" \
     https://api.telegram.org/bot<YOUR_TELEGRAM_BOT_TOKEN>/setWebhook

(مقدار secret_token باید دقیقاً با مقدار secret متغیر WEBHOOK_SECRET همخوانی داشته باشد).


۷. تدابیر امنیتی و پایداری (Security & Hardening)

  • اعتبارسنجی فایل‌های آپلودی: بررسی بایت‌های جادویی (Magic bytes) برای فرمت‌های JPEG، PNG، WebP و GIF جهت جلوگیری از آپلود بدافزار یا فایل‌های متنی با پسوند جعلی.
  • مقاومت در برابر حملات زمان‌بندی (Timing-Safe Compare): استفاده از مقایسه با زمان ثابت در بررسی رمز عبور، سکرت وب‌هوک و توکن‌ها.
  • محدودیت نرخ و قفل حساب ادمین: قفل تدریجی آی‌پی و محدودسازی پس از ۱۵ تلاش ناموفق برای ورود. (پیشنهاد می‌شود برای محافظت در لبه شبکه، یک Cloudflare Rate Limiting Rule برای مسیر /admin/api/login تنظیم گردد تا از حملات توزیع‌شده جلوگیری شود).
  • کنترل نرخ سفارشات و هانی‌پات: محدودیت ۱۰ سفارش در هر ۱۰ دقیقه برای هر آی‌پی (با ذخیره هش امن SHA-256 و بدون ذخیره آی‌پی خام)، و محدودیت ۳ سفارش در انتظار برای هر میز.
  • جلوگیری از سفارش تکراری (Idempotency): پشتیبانی از کلید یکتا برای هر سفارش جهت مقابله با ارسال مجدد در صورت قطع و وصل شبکه مشتری.
  • تایید دوطرفه سفارش (Two-Way Sync): هماهنگی کامل تغییر وضعیت سفارش‌ها بین تلگرام و پنل وب همراه با بروزرسانی پیام‌های ثبت‌شده در کانال‌های ادمین.
  • محاسبات فروش بر مبنای افق زمانی تهران: محاسبه دقیق آمار فروش امروز/هفته/ماه با در نظر گرفتن مبدا شنبه و منطقه زمانی رسمی ایران (+03:30).

وظایف زمان‌بندی‌شده (Cron Triggers)

در wrangler.jsonc برنامه زمانی * * * * * (اجرا در هر دقیقه) تنظیم شده است که عملیات زیر را به صورت خودکار انجام می‌دهد: ۱. تلاش مجدد برای اعلان سفارش‌های در انتظار: سفارش‌هایی که بین ۱ دقیقه تا ۲ ساعت گذشته ثبت شده‌اند اما اعلان تلگرامی آن‌ها ارسال نشده (tg_notified = 0) را بازیابی کرده و مجدداً برای ادمین‌ها می‌فرستد. ۲. پاکسازی وضعیت‌های منقضی: ردیف‌های منقضی‌شده از جدول bot_state (از جمله سشن‌های پیشین ربات تلگرام و شمارنده‌های موقت خطا) به صورت خودکار حذف می‌شوند.

ساعت کاری

ساعت کاری فقط در OPENING_HOURS داخل src/config.js تعریف می‌شود. نوار وضعیت سایت، لیست ساعات کاری، قفل دکمه‌ی ثبت سفارش و رد سفارش در سرور همه از همین مقدار استفاده می‌کنند. برای تغییر، همان‌جا را عوض کنید و دیپلوی کنید.


۸. دیپلوی (Deployment)

برای انتشار نسخه جدید بر روی کلودفلر:

npm run deploy

۹. محدودیت‌های شناخته‌شده (Known Limitations)

  • عدم کارکرد Cache API و ابزار تغییر اندازه تصاویر (cf.image) روی *.workers.dev: در سرویس Cloudflare Workers، قابلیت ریسایز تصویر بر بستر cf.image و رابط caches.default (کش لبه) روی دامنه‌های رایگان *.workers.dev غیرفعال است؛ در نتیجه مسیرهای بندانگشتی (/images/thumb/*) به تصویر اصلی با هدر کش fallback می‌کنند و هر بار درخواست تصویر به یک خواندن از KV (KV Read) تبدیل می‌شود که سهمیه پلن رایگان را مصرف می‌کند. برای حل این موضوع و برخورداری از مزایای کش کامل و ریسایز لبه، اتصال دامنه اختصاصی (Custom Domain) یا استفاده از Cloudflare R2 توصیه می‌شود.

۱۰. چک‌لیست بعد از دیپلوی (Post-Deployment Checklist)

پس از هر دیپلوی، دسترسی مسیرهای کلیدی را با دستورات curl زیر بررسی کنید تا از هدایت صحیح آن‌ها به Worker (از طریق run_worker_first) اطمینان حاصل شود:

# ۱. وب‌هوک تلگرام (باید توسط ورکر هندل شود، نه صفحه ۴۰۴ استاتیک)
curl -sI -X POST https://<domain>/tg-webhook | grep -i "HTTP/"

# ۲. اندپوینت ثبت و پیگیری سفارش‌ها
curl -sI -X POST https://<domain>/api/orders | grep -i "HTTP/"

# ۳. اندپوینت API ادمین (درخواست بدون توکن باید ۴۰۱ ورکر بدهد)
curl -sI https://<domain>/admin/api/me | grep -i "HTTP/"

# ۴. هندلر تصاویر
curl -sI https://<domain>/images/placeholder.jpg | grep -i "HTTP/"

# ۵. داده‌های پویا، robots و sitemap
curl -sI https://<domain>/data/products.json | grep -i "HTTP/"
curl -sI https://<domain>/data/site.json | grep -i "HTTP/"
curl -sI https://<domain>/robots.txt | grep -i "HTTP/"
curl -sI https://<domain>/sitemap.xml | grep -i "HTTP/"

# ۶. هدرهای امنیتی و CSP پنل ادمین (هدایت از طریق run_worker_first)
curl -sI https://<domain>/admin/ | grep -i -E "content-security|x-frame"