# GuaranteeApp — فازبندی ساخت، تست پذیرش، سؤال‌های باز

> ساخت از صفر. فاز ۰ (آزمایش BarTender/پرینتر و هاست) موازی با فاز ۱ و ۲ انجام می‌شود و **گیت فاز ۶ به بعد** است.

---

## ۱. فازبندی

| فاز | کار | مرجع | معیار پایان |
|---|---|---|---|
| ۰ | آزمایش BarTender + BIXOLON (۱۳ مورد) و بررسی هاست (`post_max_size`, `max_allowed_packet`, خروجی HTTPS، Cron CLI) | `04 §۱۰`، `07 §۱` | همهٔ موارد پاس؛ نتیجه ثبت |
| ۱ | MySQL: `database.sql`، کلید API، هاست، HTTPS | `01`، `07` | جدول‌ها و اتصال ✅ |
| ۲ | PHP API: `lib/*`، `scan`، `warranty/activate`، `product`، `sync/*`، `restore/*`، `test.php`، Rate limit، لاگ | `02` | `test.php` تمام ✅؛ چک‌لیست `02 §۹` |
| ۳ | وب: `panel.php`، `warranty.php`، assets | `05` | اسکن واقعی روی گوشی |
| ۴ | ربات: webhook، دستورها، گزارش، کرون، اعلان‌ها، setup | `06` | جدول تست `07 §۶.۵` |
| ۵ | دسکتاپ — داده: مدل‌ها، خانواده/آپشن، Part Number، گارانتی، سریال/دسته، تاریخچه، SQLite، `CloudSyncService`، سینک خودکار | `03` | سینک موفق؛ Part Number و سریال درست؛ Unit testها |
| ۶ | دسکتاپ — چاپ: `LabelCsvWriter`، `BarTenderLauncher`، Mutex، بک‌آپ محلی، پروفایل‌ها، دیالوگ‌ها، `LabelPrintCoordinator`، چاپ مجدد زیرمجموعه | `04` | ۱۵ لیبل با ۱۵ سریال متفاوت؛ دو برند برای یک مدل |
| ۷ | پشتیبان قالب (آپلود) + `RestoreService` + `RestoreDialog` | `03 §۶`، `04 §۸` | تست بازیابی کامل |
| ۸ | دستورالعمل اپراتور (با تصویر)، بستهٔ نصب (ACL)، تست پذیرش | `04 §۱۱`، `07 §۷` | تأیید کارفرما |

وابستگی‌ها: ۲ ← ۱؛ ۳ و ۴ ← ۲؛ ۵ ← ۲ (برای سینک)؛ ۶ ← ۵ و ۰؛ ۷ ← ۶ و ۲.

---

## ۲. چک‌لیست تست پذیرش

### زنجیرهٔ سرور/وب/ربات
- [ ] سریال سینک‌نشده در پنل ← «در دیتابیس نیست» + هشدار Orphan؛ پس از سینک ← وصل می‌شود.
- [ ] بسته‌بندی تکراری ← «تکراریه»؛ `packaging` و `warehouse_exit` هر دو برای یک سریال مجازند.
- [ ] `warehouse_exit` بدون بسته‌بندی ← ثبت + هشدار زرد (مسدود نمی‌شود).
- [ ] QR لیبل ۲ ← `warranty.php` ← «فعال شد»؛ دفعهٔ دوم «قبلاً فعال شده».
- [ ] فعال‌سازی بدون سابقهٔ انبار ← هشدار ادمین؛ مشتری چیزی نمی‌بیند.
- [ ] ربات: `/inventory`، `/report`، عکس QR، متن سریال، گزارش ۲۰:۰۰، کاربر غیرمجاز، secret نامعتبر بی‌پاسخ.

### دسکتاپ — داده
- [ ] مدل بدون گارانتی ذخیره نمی‌شود؛ متن خودکار و قابل ویرایش؛ ویرایش گارانتی روی مدل قفل‌شده ممکن و `MODEL_LOCKED_CONFLICT` نمی‌دهد.
- [ ] Part Number درست (مدل با و بدون آپشن)؛ مدل قفل‌شده آپشن‌هایش غیرقابل‌تغییر.
- [ ] سریال/دسته: فرمت `PARTNCODE-YYMMDD-####` و `YYMMDD-B{n}`؛ شمارنده به‌ازای مدل و روز.
- [ ] هیچ ردی از اپراتور در UI، CSV لیبل، CSV خروجی و دیتابیس نیست.
- [ ] سینک خودکار بعد از تولید؛ `label1/2_printed_at` در MySQL ثبت؛ سینک مجدد همان دسته خطای تعارض نمی‌دهد؛ خطای ردیفی در UI دیده می‌شود.
- [ ] نشانگر «N رکورد سینک‌نشده» درست.

### چاپ
- [ ] اولین چاپ بدون پروفایل ← دیالوگ تنظیم قالب؛ دفعهٔ بعد نمی‌آید.
- [ ] یک مدل با **۲ برند**: هر پروفایل قالب درست را باز می‌کند؛ آخرین پروفایل پیش‌انتخاب می‌شود.
- [ ] یک لیبل نمایش، Ctrl+P ← ۱۵ لیبل با ۱۵ سریال متفاوت.
- [ ] ۳ نمونه QR/بارکد با اسکنر خوانده شود؛ QR لیبل ۲ صفحهٔ گارانتی را باز می‌کند.
- [ ] چک‌باکس گارانتی: تیک = متن؛ بدون تیک = خالی؛ مدل دست‌نخورده.
- [ ] تغییر ظاهر + Ctrl+S ← چاپ بعدی ظاهر جدید؛ بک‌آپ‌ها (≤ ۱۰، فقط در صورت تغییر) و بازگردانی.
- [ ] فایل قالب پاک شد ← دیالوگ تنظیم قالب؛ با انتخاب مجدد یا پشتیبان سرور کار می‌کند.
- [ ] BarTender قبلاً باز / CSV قفل / پوشه غیرقابل‌نوشتن / BarTender نصب نیست ← پیام فارسی، بدون کرش.
- [ ] چاپ ناقص ← چاپ مجدد زیرمجموعهٔ سریال‌ها برای هر دو لیبل بدون سریال جدید.
- [ ] دستهٔ ۵۰۰ ردیفی.

### بازیابی و پشتیبان
- [ ] **بازیابی کامل:** دیتابیس محلی پاک/سیستم تازه ← «بازیابی از سرور» ← مدل‌ها، آپشن‌ها، دسته‌ها، سریال‌ها، وضعیت ارسال لیبل و قالب‌ها برمی‌گردند؛ تاریخچه یکسان؛ سریال بعدی = آخرین سریال سرور + ۱؛ چاپ با قالب بازیابی‌شده بدون تنظیم مجدد.
- [ ] بازیابی روی دیتابیس غیرخالی رد می‌شود؛ بازیابی نیمه‌کاره با قطع اینترنت قابل ادامه است.
- [ ] تغییر قالب ← آپلود پشتیبان در شروع/قبل از Job بعدی؛ آفلاین بودن مانع کار نیست.

---

## ۳. تصمیم‌های بازِ باقی‌مانده

| سؤال | وضعیت |
|---|---|
| نتایج فاز ۰ (BarTender/پرینتر: روش باز کردن، Records = All، قفل CSV) | **باز** تا تست روی قالب و پرینتر واقعی |
| نام مدل روی لیبل فارسی است یا انگلیسی؟ | **باز** (فاز ۰ بند ۳) |
| دامنه/مسیر نهایی پنل و صفحهٔ گارانتی | **باز** (برای `ApiBaseUrl`/`WarrantyUrlTemplate`) |
| PIN مشترک برای `panel.php` | **باز**؛ پیش‌فرض: بدون PIN |
| chat_id ادمین‌ها | **باز** تا استقرار |
| مقایسهٔ گزارش روزانه با دیروز | **باز**؛ پیش‌فرض: فقط اعداد |
| پشتیبانی هاست از `php` CLI در Cron و اتصال خروجی به `api.qrserver.com` | **باز**؛ در فاز ۰ تأیید |
| سقف ۹×۹ آپشن | بسته؛ طرح دو‌رقمی |
| تعریف موجودی | بسته؛ بسته‌بندی − خروج (ثابت `GW_INVENTORY_MODE`) |
| چند سیستم/اپراتور، پایان گارانتی در وب، مدل پرینتر، روش اتصال | **بسته** (`00 §۲`) |

---

## ۴. ریسک‌ها

| ریسک | کاهش |
|---|---|
| سریال سینک‌نشده با خرابی سیستم از بین می‌رود | سینک خودکار بعد از هر تولید، نشانگر، دستورالعمل اپراتور |
| ذخیره‌نشدن Records = All در `.btw` | تأیید در فاز ۰؛ در صورت لزوم تأکید در دستورالعمل |
| کیفیت QR کوچک روی BIXOLON | تست چاپ واقعی ۳ نمونه در فاز ۰ |
| هاست اشتراکی: محدودیت اندازهٔ درخواست/خروجی/کرون | بررسی پیش از شروع (`07 §۱`) |
| قفل `current.csv` توسط BarTender باز | نوشتن اتمیک + پیام روشن + آزمون بند ۸ فاز ۰ |
| قالب Embedded تبدیل‌نشده | آماده‌سازی طبق `04 §۵` پیش از پذیرش |
