# Changelog — الفباPlay

همه‌ی تغییرهای مهم این پروژه در این فایل ثبت می‌شود.
قالب بر پایه‌ی [Keep a Changelog](https://keepachangelog.com/) · نسخه‌بندی [SemVer](https://semver.org/).

## [1.13.0] — ۲۰۲۶-۰۹-۲۶ «بستن بلاکرها — محتوا و کیفیت»

### تغییر
- **بازبینی ۴۰ واژه‌ی ⚑ (سند ۳۰ §۵) — حل شد** (به نیابت کاربر، جدول تصمیم در docs/33 §۶-۷): ۳۹ واژه تأیید · تنها جایگزینی `umut` (انتزاعی) → `uçurtma` 🪁 بادبادک (tr، d3، ۷ حرف، id `tr_ucurtma`) → tr.json اکنون ۱۴۱ واژه · جمع کل پک‌ها **۷۱۹** (fa 177 · en 136 · nl 125 · tr 141 · ar 140) · داستان‌ها از umut استفاده نمی‌کردند (جایگزینی امن). `REVIEWED_WORDS` در content-sprint پرچم‌های آینده را برای واژه‌های نادرِ جدید نگه می‌دارد. تأیید نهایی کاربر در جلسه‌ی بعد گرفته شود.
- نسخه 1.13.0 (تغییر داده‌ی پک tr → بافت کش SW لازم شد).

### تست/CI
- **تست یکپارچه‌ی «دو دستگاه هم‌زمان برای یک کودک»** (توصیه‌ی سند ۳۳ §۶-۵): والد/کودک اختصاصی → دو جلسه‌ی `cst_` جدا با همان آواتار → push متعارض (fa_te از هر دو + fa_sin فقط از B) → ادغام سرور: mastery/correct/wrong = **max** دو طرف · حرفِ فقط-یک‌دستگاه می‌ماند · هر دو جلسه بعد از ادغام دید یکسان دارند (api.test.js → ۴۳ تست).
- **a11y در CI** (توصیه‌ی §۶-۲): گام `npm run test:a11y` بعد از e2e-admin در workflows/ci.yml.

## [1.12.0] — ۲۰۲۶-۰۹-۲۶ «نصب‌پذیری — سرور و cPanel»

### افزودنی
- **نصب‌گر وب** (`/install` · `client/install.html` + `routes/install.js` · الگوی WordPress): بررسی محیط (Node≥۱۸ · SQLite · نوشتنی‌بودن) → ساخت حساب مدیر + SMTP اختیاری → **قفل دائمی 410** · ریدایرکت ریشه تا قبل از نصب · کلید نصب اختیاری `ALPHABET_INSTALL_KEY` · نرخ ۱۰/۱۵د.
- **نصب‌گر CLI** `scripts/install.mjs` (+ `--recover` برای دستِ گم‌شده‌ی ادمین) — همان `server/setup.js` مشترک با وب.
- **فایل تنظیمات** `config/settings.json` (`server/config.js`): اولویت env > فایل > پیش‌فرض — cPanel بدون env هم تنظیم می‌شود؛ example کامیت شد؛ JSON خراب = هشدار بی‌خطر.
- **بسته‌ساز** `scripts/release.mjs [--with-deps]` → zip ۱.۸MB / ۶.۷MB با وابستگی‌های تولیدی (برای cPanel بدون SSH؛ باید با همان Node اصلیِ cPanel ساخته شود) — داده/تست/راز هرگز داخل بسته نمی‌روند.
- Passenger: `main: server/index.js` · پورت از `PORT`/`PASSENGER_APP_PORT` · بوت‌استرپ ادمین فقط با env (بدون env → نصب‌گر مالک مرحله است).
- `INSTALL.md` (راهنمای داخل بسته) · `docs/34-install-cpanel.md` (cPanel/VPS/لوکال + عیب‌یابی + محدودیت‌های صادقانه‌ی هاست اشتراکی).
- `tests/install.test.js` (۸): وضعیت/ریدایرکت/نصب+ورود/قفل/کلید/اولویت config/CLI/جلوگیری از ادمین پیش‌فرض.



جهش محتوایی از ممیزی ۲۷ (docs/30) + ممیزی دسترس‌پذیری واقعی سند ۲۹ §۲.۴ (docs/31).

### افزودنی — تکمیلی §۲.۵ (سند ۳۲)
- **ایمیل والدین** (`server/mailer.js`): Resend/Mailgun/file/log بدون وابستگی جدید · خوش‌آمد · گزارش هفتگی (`ALPHABET_MAIL_WEEKLY=1`، فقط والد فعال).
- **فراموشی رمز خودخدمت**: کد ۶رقمی (فقط SHA-256 در DB · TTL ۱۵د · یک‌بارمصرف · ضد enumeration با 202) → تغییر رمز + بستن همه‌ی نشست‌ها + حسابرسی · UI دو مرحله‌ای ۵ زبان · نرخ ۵/۱۰ در ۱۵د.
- **بکاپ ریموت restic → S3/R2** (قاعده‌ی ۳-۲-۱ سند ۲۸): backup+forget/prune شبانه بعد از بکاپ محلی؛ نبود باینری = رویداد پایش نه کرش.
- **نشانگر آنلاین/آفلاین کودک**: `GET /children` → lastSeen؛ نقطه‌ی وضعیت + زمان نسبی در UI والدین (۷ کلید × ۵ زبان).
- **i18n پنل ادمین (fa/en)**: ~۹۰ کلید، دکمه‌ی تغییر زبان، en→ltr؛ کروم + جدول‌های اصلی (پوشش جزئی مستند در سند ۳۲ §۵).
- **ابزار پایلوت**: `scripts/pilot-report.mjs` + جدول `client_errors` (retention ۹۰ روز) → سنجه‌های retention هفته‌ی ۲ و crash-free از DB؛ exit ۲ زیر هدف.
- تست‌ها: mailer (۱۱: جریان کامل با transport فایل، TTL/یک‌بارمصرف/ضد brute-force) · pilot (۳) · ۱ تست api (lastSeen) · e2e فراموشی-رمز بدون SMTP.
- رفع flake و بدهی تست: e2e-admin والد+کودک اختصاصی می‌سازد (نفوذ داده‌ی اجراهای قبلی) · imports.test رشته‌ها را از اسکن استفاده حذف می‌کند.

### افزودنی — دسترس‌پذیری (سند ۳۱)
- `scripts/a11y-audit.mjs` (`npm run test:a11y`): axe-core + سنجش هدف لمسی در ۱۰ حالت تعاملی + چک کیبورد والدین — سنجش پایدار (انتظار پایان انیمیشن CSS/GSAP + opacity) · خروج nonzero برای CI.
- اصلاحات کنتراست: متن جوهری روی دکمه‌های روشن (1.9–2.6 → 5.0+) · سفید روی بنفش تیره (6.2) · `--c-primary-ink` برای هایلایت حرف (4.9).
- نام/نقش: aria-label دکمه‌های رنگ (۳۰ کلید i18n در ۵ زبان) · select زبان · input گیت · labelهای فرم والدین · aria-label مودال‌ها و progressbar · aria-disabled چیپ قفل.
- ساختار: `main#app` + h1 همه‌ی صفحه‌ها + h2 برای ترتیب سرفصل + `.sr-only`.
- هدف لمسی: `.btn-kid.small` و `.link-btn` → 44px · چک‌باکس‌ها ≥24px (WCAG 2.5.8).

### افزودنی
- **۷۱۹ واژه** (قبلاً ۳۰۹؛ +۴۱۰) و **۷۵ داستان** (قبلاً ۳۴؛ +۴۱) در ۵ زبان — پوشش داستانی **۱۰۰٪ حروف**؛ همه‌ی پک‌ها/داستان‌ها v1.2.0.
- `scripts/content-data.mjs` + `scripts/content-sprint.mjs`: مولد/اعتبارسنج ایدمپوتنت با `--dry`، خروجی گزارش `.tmp-content-report.json`؛ در خطا هیچ فایلی نوشته نمی‌شود.
- ۴ گارد رگرسیون جدید: `tests/packs.test.js` (آستانه ≥۵ با ۶ استثنای مستند: en X · nl X/Q/Y · tr Ğ) و `tests/story.test.js` (پوشش داستانی · کل ≥۷۰).
- `docs/30-content-sprint.md` — مستندسازی اسپرینت، استثناها و ۴۰ واژه‌ی ⚑ نیازمند بازبینی انسانی.

### تغییر
- تست قدیمی «تعداد دقیق ۳۴ داستان» → کف پوشش (نیت اصلی: قابل‌دستیابی بودن نشان قصه‌خوان) · شمارنده‌ی e2e اتاق جوایز → مقایسه‌ی پویا با فایل داده (aria-valuenow/max).
- bump 1.10.0 → 1.11.0 (بافت کش SW با تغییر داده‌ها الزامی شد) · `.gitignore`: مسیرهای محیط sandbox.

## [1.10.0] — ۲۰۲۶-۰۹-۲۶ «موج ۱ · پایدارسازی»

موج اول پایدارسازی از ممیزی ۲۷ — بیشترین کاهش ریسک در کمترین زمان.

### افزودنی
- **بکاپ خودکار روزانه** (`server/backup.js`): اسنپ‌شات امن DB روی WAL زنده با API `.backup()` + کپی audio/images/words + manifest.json + چرخش (پیش‌فرض ۱۴ نسخه). زمان‌بند: `ALPHABET_BACKUP=1`، ساعت `ALPHABET_BACKUP_HOUR` (پیش‌فرض ۳ بامداد). CLI: `scripts/backup.mjs` (با `--verify`) و `scripts/restore.mjs --yes` (با خروج اضطراری `.pre-restore` و ردِ نسخه‌ی خراب قبل از رونویسی).
- **هدرهای امنیتی** (`server/csp.js` + `server/app.js`): CSP با **صفر اسکریپت inline** در کل HTMLهای کلاینت (نسخه از `<meta name="app-version">`، تعویض CSS در `js/boot.js`) — بدون unsafe-inline/unsafe-eval · `Permissions-Policy` (دوربین/موقعیت/پرداخت بسته، میکروفون فقط برای خود — بازی «بلند بگو») · `Cross-Origin-Opener-Policy: same-origin` · X-Frame-Options/frame-ancestors فقط با `ALPHABET_FRAME_GUARD=deny` (حالت تولید).
- **git + LICENSE + CHANGELOG** — مخزن از صفر با تاریخچه‌ی تمیز؛ MIT برای کد، CC-BY-4.0 برای محتوای آموزشی.
- **Docker + Caddy** برای استقرار با TLS خودکار (`Dockerfile`، `docker-compose.yml`، `Caddyfile`، راهنمای `docs/28-deploy.md`).
- تست‌ها: `tests/backup.test.js` (۱۱: زمان‌بند، اسنپ‌شات WAL زنده، بازیابی عملی، رد نسخه‌ی خراب، چرخش، برخورد نام، retention) · `tests/monitoring.test.js` (۶) + ۵ تست موج ۱ در api/admin.

### تغییر
- `client/index.html` + `client/js/boot.js`: هر ۳ هندلر `onload=` و هر دو اسکریپت inline حذف شد؛ تعویض preload→stylesheet در ماژولِ بدونِ importِ `boot.js` انجام می‌شود (زودتر از گراف main.js — هم‌پوشانی دانلود/اعمال حفظ شد) + `fetchpriority="low"` برای CSSهای غیرحیاتی. نسخه‌ی اپ از `window.__APP_VERSION` به `<meta>` منتقل شد.
- **بازپایه‌ی بودجه‌ی Lighthouse کارایی: ۸۵ → ۸۳** (با A/B مستند روی همان ماشین/کروم: الگوی onload قدیمی = ۸۵ · CSP-clean = ۸۳-۸۴؛ FCP/SI بهتر، LCP ~۱۵۰ms بدتر). ریشه‌ای‌ترین راه‌حل (باندل esbuild، قلم موج ۳ ممیزی) بودجه را به ۸۵ برمی‌گرداند. CI با `LH_RUNS=5` پایدار شد.

### افزودنی (تکمیل موج ۱ — ۲۰۲۶-۰۹-۲۶)
- **پایش خطا** (`server/monitoring.js`): ارسال با پروتکل Envelope v7 به Sentry/GlitchTip (سلف‌هاست) — بدون وابستگی جدید، خاموش بدون `ALPHABET_SENTRY_DSN`. صف ۳۰تایی، sanitize (ایمیل/توکن/Bearer هرگز بیرون نمی‌روند)، از request فقط method+path. `uncaughtException`/`unhandledRejection` + خروج تمیز SIGTERM.
- **لاگ ساختاریافته** (`server/logger.js`): هر خط یک JSON (`ts/level/msg/fields`) با `LOG_LEVEL`.
- **گزارش خطای کلاینت**: `Diagnostics` هر ۸ ثانیه دسته‌ای (≤۱۰ رویداد، keepalive، بی‌صدا) → `POST /api/v1/diagnostics` (نرخ ۳۰/دقیقه، پاسخ ۲۰۴).
- **ریست رمز والد** (`server/passwordReset.js`): رمز موقت `AP-XXXXXXXX` — بدون جدول توکن (چیزی برای لو رفتن نیست)؛ همه‌ی نشست‌ها بسته می‌شوند؛ حسابرسی `parent_reset`؛ نقش پشتیبان مجاز؛ مودال رمز موقت در پنل ادمین.
- **«خروج از همه دستگاه‌ها»**: `POST /api/v1/parent/sessions/revoke` + دکمه در پنل والدین (۵ زبان) — refreshها + دستگاه‌های همه‌ی کودکان.
- **retention شبانه**: رویدادهای خام > ۱۸۰ روز (`ALPHABET_RETENTION_DAYS`) + refreshهای مرده، هر شب بعد از بکاپ.
- **پوشش c8**: خطوط ۸۷.۱۲٪ واقعی · آستانه ۷۵/۷۰/۶۰ در CI (`npm run test:coverage`) · **فیکس**: هندلر SIGTEM→exit تمیز باعث flush پوششِ سرورهای تستی شد (بدون آن c8 فقط importهای مستقیم را می‌دید).
- **dependabot**: هفتگی، گروهی (minor+patch)، npm + github-actions.

### رفع
- بکاپ: برخورد نامِ هم‌ثانیه دو اجرا → ادغام بی‌صدای نسخه‌ها؛ حالا پسوند `-2`، `-3`… می‌گیرد (کشف‌شده با تست).
- **باگ شکارشده با e2e**: بیلد کروم ۱۵۳ِ سندباکس، هش base64ِ بدون نویسه‌ی `/` را source نامعتبر می‌داند و **کل directive اسکریپت را بی‌اثر می‌کند** (حتی هش‌های معتبر بلاک می‌شدند) → راه‌حل قطعی: حذف کامل اسکریپت‌های inline بدون هیچ هشی.

## [1.10.0-rc] — ۲۰۲۶-۰۹-۲۵

- پروتکل تست UX سند ۲۳: سناریوی ۹ «بلند بگو» + آستانه‌های ⭐ + سنجه‌ی «تلاش دوباره‌ی خودانگیخته» + قاعده‌ی N/A-م + Q7 + چک‌لیست میکروفون.
- پیش‌اجرای فنی ۹/۹ (docs/26) · کیت جلسات `docs/ux-test-kit.xlsx` با سنجه‌های خودکار.
- ممیزی کامل پروژه (docs/27): MVP ~۹۵٪ · پایلوت ~۸۰٪ · عرضه‌ی عمومی ~۶۰٪ + نقشه‌ی سه موج.

## [1.9.0] — ۲۰۲۶-۰۹-۲۴ «بلند بگو»

- بازی گفتاری «بلند بگو»: تشخیص SpeechRecognition (سطح ۱-۵)، صدای سفارشی والد از راه دور، گیت دسترسی بعد از تسلط بر ۸ حرف، سطح ۵ با پخش صدای والد.
- تست‌های speech (۱۹) + e2e بلندبگو (۱۵).

## [1.8.0] — ۲۰۲۶-۰۹-۲۳

- داستان‌خوان «قصه‌های الفبا» + ادمین داستان‌ساز + گزارش هفتگی والدین.

## [1.7.0] — ۲۰۲۶-۰۹-۲۲

- گالری واژه‌ها با صدای والد، PWA به‌روزشونده، دوباره‌خوانی هوشمند کارت‌ها.

## [1.6.0] و قبل‌تر

- بازی اصلی حرف-به-حرف، واژه‌سنجی، شمارنده، sync آفلاین، auth والد + جلسه‌ی کودک،
  پنل ادمین، audit log، CI (واحد + e2e + بودجه‌ی Lighthouse)، rate limit، replay-پروف توکن.
