# راهنمای مشارکت | Contributing to IR-Toolbox

اول از همه، ممنون که وقت می‌ذارید! 🙌 هر مشارکتی — از گزارش باگ تا ابزار جدید — خوش‌آمد است.

## 🐞 گزارش باگ یا پیشنهاد ویژگی

قبل از باز کردن Issue، لطفاً یک جست‌وجو در [Issueهای موجود](https://github.com/Kourosh242/IR-Toolbox/issues) انجام دهید تا تکراری نباشد.

- 🐞 باگ: از قالب **Bug Report** استفاده کنید و اطلاعات «مرورگر، سیستم‌عامل، مراحل بازتولید» را بنویسید.
- 💡 پیشنهاد: از قالب **Feature Request** استفاده کنید و توضیح دهید مشکل چه نیازی را حل می‌کند.
- 💬 سوال یا ایده‌ی بحثی: [Discussions](https://github.com/Kourosh242/IR-Toolbox/discussions)
- 🔒 مساله امنیتی: علنی گزارش نکنید — [SECURITY.md](SECURITY.md) را ببینید.

## 🛠 راه‌اندازی محلی

سایت استاتیک است و به build نیاز ندارد:

```bash
git clone https://github.com/Kourosh242/IR-Toolbox.git
cd IR-Toolbox
python3 -m http.server 8080
```

سپس `http://localhost:8080` را باز کنید. (سرویس‌ورکر فقط روی `http://localhost` یا HTTPS کار می‌کند.)

### تست‌ها

تست‌های هسته هیچ وابستگی خارجی ندارند و با رانر داخلی Node اجرا می‌شوند:

```bash
npm test          # یا مستقیم: node --test
```

`package.json` فقط برای همین است: `"type": "module"` (چون همهٔ `.js`های پروژه ES Module هستند) و اسکریپت‌های `test` / `build:seo` / `validate:seo` / `check`. **هیچ مرحلهٔ build برای خودِ اپ و هیچ وابستگی زمانِ اجرایی وجود ندارد** — اپ با بازکردن `index.html` هم کار می‌کند.

> `happy-dom` تنها به‌عنوان `devDependency` و برای تست‌های سطح DOM اعلام شده و در حال حاضر هیچ فایلی آن را import نمی‌کند؛ نصب `node_modules` برای `npm test` لازم نیست.

یک فرمان برای همهٔ بررسی‌ها:

```bash
npm run check         # build:seo ← validate:seo ← test
``` تست‌ها در `test/core.test.mjs` منطق خالص را پوشش می‌دهند (تقویم جلالی، هش‌ها در برابر `node:crypto`، ارزیابی ریاضی، کانتینر `.ir256`، بررسی ایمنی لینک) — اگر منطق یکی از این‌ها را تغییر دادید، تست مربوطه را هم به‌روز کنید.

### صفحه‌های استاتیک SEO/GEO

پروژه علاوه بر اپ (SPA)، صفحه‌های استاتیک و قابل‌خزش هم دارد:

| مسیر | محتوا |
| --- | --- |
| `about/` | صفحهٔ هویت پروژه، حریم خصوصی، امنیت و محدودیت‌ها |
| `tools/` | هاب هر ۵۲ ابزار |
| `tools/<دسته>/` | ۹ صفحهٔ دسته |
| `tools/<اسلاگ>/` | ۵۲ صفحهٔ ابزار |
| `sitemap.xml` · `robots.txt` · `llms.txt` | تولیدشده |

این صفحه‌ها **تولیدشده** هستند؛ هرگز دستی ویرایششان نکنید. منابع محتوا:

- `seo/site.mjs` — هویت پروژه و **آدرس پایه** (تنها جایی که آدرس تولید تعریف می‌شود)
- `seo/tools-meta.mjs` — اسلاگ، توضیح، قابلیت‌ها و پرسش‌های پرتکرار هر ابزار
- `js/helps.js` — متن راهنمای واقعی هر ابزار (بخش «راهنمای استفاده»)
- `tools/*.js` — متادیتای ابزارها (ژنراتور مستقیم از `register({...})` می‌خواند)

```bash
npm run build:seo       # بازسازی صفحه‌ها + sitemap + robots + llms.txt + بلوک SEO در index.html
npm run validate:seo    # راستی‌آزمایی: عنوان/توضیح/canonical، JSON-LD، لینک شکسته، basePath…
```

**هنگام افزودن ابزار جدید** سه کار لازم است، وگرنه `build:seo` با خطا متوقف می‌شود:

1. ابزار را در `tools/<دسته>.js` با `register({...})` ثبت کنید (مثل قبل).
2. یک ورودی در `seo/tools-meta.mjs` برایش بنویسید: `id` (دقیقاً برابر `id` ابزار)،
   `slug` پایدار، `lead`، چند `features` (معمولاً ۳ تا ۷) و دقیقاً ۲ `faq`.
3. `npm run build:seo && npm run validate:seo` را اجرا کنید.

ژنراتور خودش راستی‌آزمایی می‌کند: شمار ابزارها باید با `SITE.toolCount` بخواند،
هیچ `slug` تکراری نباشد و هر ابزار در هر دو سمت وجود داشته باشد.

> 💡 پروژه روی GitHub Pages زیر مسیر `/IR-Toolbox/` منتشر می‌شود. برای رفتن روی دامنهٔ
> اختصاصی فقط `SITE.origin` (و در صورت نیاز `basePath`) را در `seo/site.mjs` عوض کنید و
> `npm run build:seo` را بزنید؛ canonical، sitemap، robots، OG و JSON-LD خودکار به‌روز می‌شوند.

> ⚠️ اسکیمای `FAQPage` عمداً استفاده نمی‌شود: گوگل از آگوست ۲۰۲۳ نمایش نتیجهٔ غنی آن را
> به سایت‌های دولتی و سلامت محدود کرده است. پرسش‌ها به‌صورت HTML خوانا نوشته می‌شوند
> (برای استخراج توسط موتورهای جستجو و دستیارهای هوش مصنوعی) اما بدون اسکیما.

## ➕ افزودن ابزار جدید

معماری اپ **رجیستری ماژولار** است؛ ابزار جدید بدون دست‌کاری هسته‌ی اپ اضافه می‌شود:

1. یک فایل در پوشه `tools/` بسازید (مثلاً `tools/my-tool.js`) و از ساختار یکی از ابزارهای موجود الگو بگیرید.
2. **در همان فایل** تابع `register({...})` را (از `js/registry.js` import) صدا بزنید — با `id` یکتا، `cat` (یکی از شناسه‌های `CATS` در `js/registry.js`)، `icon`، `fa`، `en`، `desc`، `keywords` و `mount`. خودِ `js/registry.js` فقط فهرست دسته‌ها و تابع `register` را دارد و نباید برای هر ابزار ویرایش شود؛ ثبت‌نام خودکار یعنی «import شدن = ثبت شدن».
3. فایل جدید را به `CAT_MODULES` در `js/app.js` (زیرِ کلید دسته‌ی مربوطه) اضافه کنید — ماژول‌های دسته‌ها با **import پویا** و فقط هنگام نیاز بارگذاری می‌شوند، پس فایلی که آن‌جا نیامده باشد هرگز بارگذاری (و در نتیجه ثبت) نمی‌شود.
4. اگر فایل جدیدی اضافه کرده‌اید، آن را به فهرست `CORE` در `service-worker.js` اضافه کنید و `VERSION` را یک واحد بالا ببرید (مثلاً `ir-v13` → `ir-v14`) تا کلاینت‌های قبلی کش کهنه را دور بیندازند.
5. توضیح بلند ابزار را در `js/helps.js` (کلید = `id` ابزار) بنویسید؛ در نبودِ آن، `desc` نمایش داده می‌شود.
6. تغییرات را طبق **چک‌لیست انتشار** پایین همین صفحه در همهٔ فایل‌های نسخه‌دار ثبت کنید.

## 🚀 چک‌لیست انتشار نسخهٔ جدید

بیشتر ناسازگاری‌های این مخزن از یک عادت می‌آید: **ویرایش دستیِ فایل‌های تولیدشده** به‌جای
تغییر منبع و بازتولید. برای هر انتشار، دقیقاً همین ترتیب را بروید:

**۱) منابع حقیقت را ویرایش کنید** (نه خروجی‌ها):

| فایل | چه چیزی |
| --- | --- |
| `js/changelog.js` | `VERSION` + ورودی تازهٔ `CHANGELOG` (تاریخ شمسی کامل: `۱۴۰۵-۰۶-۳۰`) |
| `seo/site.mjs` | `version` و `dateModified` (و `datePublished` فقط برای اولین انتشار) |
| `manifest.json` | `version` (و `description` اگر شمار ابزار/دسته عوض شد) |
| `package.json` | `version` |
| `CITATION.cff` | `version` و `date-released` (باید با `dateModified` یکی باشد) |
| `README.md` | نشان نسخه + خط «نسخه» + بخش تازهٔ `### vX.Y.Z` در تغییرات نسخه |
| `service-worker.js` | `VERSION` کش (مثلاً `ir-v13` ← `ir-v14`) |
| `.github/ISSUE_TEMPLATE/bug_report.yml` · `SUPPORT.md` | نمونهٔ نسخهٔ اشاره‌شده |
| `seo/tools-meta.mjs` · `scripts/build-seo.mjs` · `js/helps.js` | اگر واقعیتِ ابزار/امنیت عوض شده |

**۲) بازتولید و راستی‌آزمایی:**

```bash
npm run build:seo && npm run validate:seo && npm test
```

`validate:seo` یکی‌بودن نسخه در همهٔ منابع بالا، یکسان‌بودن CSP روی همهٔ صفحه‌ها،
درست‌بودن لینک‌ها/JSON-LD/sitemap و پوشش ۵۲ ابزار و ۹ دسته را بررسی می‌کند.

**۳) ویکی** را هم به‌روز کنید (مخزن جدا: `IR-Toolbox.wiki.git`) — دست‌کم
`Home.md`، `_Sidebar.md` (نسخهٔ فعلی)، `تغییرات-نسخه.md` (ورودی تازه) و هر صفحه‌ای
که واقعیت فنی‌اش عوض شده (کش Service Worker، شمارش تکرار KDF، شمار محتوا).

> ⚠️ **هرگز** `about/index.html`، `tools/**/index.html`، `404.html`، `sitemap.xml`،
> `robots.txt`، `llms.txt` و بلوک‌های `SEO:*` در `index.html` را دستی ویرایش نکنید —
> `npm run build:seo` همه‌شان را بازمی‌نویسد و ویرایش دستی بی‌صدا از بین می‌رود.
> CSP هم در `seo/site.mjs` (`SITE.csp`) تعریف می‌شود و ژنراتور خودش در همهٔ صفحه‌ها می‌گذارد.

## 🔀 روند ارسال Pull Request

1. ریپو را Fork کنید و از `main` شاخه جدید بسازید (مثلاً `feat/my-tool`).
2. تغییرات را با کامیت‌های شفاف اعمال کنید (ترجیحاً فارسی یا انگلیسی — هر دو پذیرفته است).
3. مطمئن شوید اپ در مرورگر بدون خطای کنسول اجرا می‌شود و ابزارهای همسایه خراب نشده‌اند.
4. Pull Request با توضیح «چه چیزی / چرا / چطور تست شد» ارسال کنید؛ از قالب PR استفاده کنید.

## ✍️ سبک کد

- جاوااسکریپت خالص (Vanilla)، بدون فریم‌ورک و بدون مرحله build.
- UI فارسی و راست‌چین؛ نام‌گذاری متغیرها انگلیسی.
- همه ابزارها باید **کاملاً آفلاین** و **بدون ارسال داده** کار کنند — هیچ `fetch` به سرویس بیرونی ممنوع.
- دسترس‌پذیری (کنتراست، aria) و پشتیبانی از هر ۴ پوسته را در نظر بگیرید.

با تشکر از همراهی‌تان! ⭐
