# راهنمای جامع راه‌اندازی وب اتومیتور

> **نسخه سند:** 1.13 · **آخرین‌به‌روزرسانی:** 2026-10-05  
> این راهنما برای مدیران فناوری اطلاعات و مسئول استقرار سازمان تهیه شده است.

---

## فهرست

1. [معرفی و لایسنس](#1-معرفی-و-لایسنس)
2. [محیط‌های پشتیبانی‌شده برای هاست وب](#2-محیطهای-پشتیبانیشده-برای-هاست-وب)
3. [پیش‌نیازها](#3-پیشنیازها)
4. [دریافت و محتوای بسته نصب](#4-دریافت-و-محتوای-بسته-نصب)
5. [پیکربندی دیتابیس](#5-پیکربندی-دیتابیس)
6. [اولین اجرا و ساخت خودکار دیتابیس](#6-اولین-اجرای-و-ساخت-خودکار-دیتابیس)
7. [استقرار روی سرور](#7-استقرار-روی-سرور)
8. [لایسنس](#8-لایسنس)
9. [دوره آزمایشی ۳ روزه](#9-دوره-آزمایشی-۳-روزه)
10. [حالت محدود پس از انقضا](#10-حالت-محدود-پس-از-انقضا)
11. [برندینگ سازمان](#11-برندینگ-سازمان)
12. [به‌روزرسانی نرم‌افزار](#12-بهروزرسانی-نرمافزار)
13. [آپدیت آفلاین (سرور بدون اینترنت)](#13-آپدیت-آفلاین-سرور-بدون-اینترنت)
14. [انتقال از دیتابیس قدیمی](#14-انتقال-از-دیتابیس-قدیمی)
15. [کار با پنل و افزونه](#15-کار-با-پنل-و-افزونه)
16. [عیب‌یابی](#16-عیبیابی)

---

## 1. معرفی و لایسنس

وب اتومیتور یک سامانه اتوماسیون فرآیندهای وب است که روی SQL Server اجرا می‌شود و با افزونه مرورگر Chrome کار می‌کند.

**لایسنس:** روی **هر** نصب (SaaS، on-prem، محیط dev) اعمال می‌شود — ابتدا **دوره آزمایشی**، سپس لایسنس امضاشده از vendor. تغییر `وب اتومیتور:DeploymentMode` در `appsettings.json` لایسنس را **خاموش نمی‌کند**.

| برچسب `DeploymentMode` | کاربرد (اختیاری) |
|------------------------|------------------|
| **Cloud** | برچسب پیش‌فرض؛ تفاوتی در الزام لایسنس ندارد |
| **Enterprise** | برچسب سازمانی؛ تفاوتی در الزام لایسنس ندارد |

برای هر استقرار جدا (چند دامنه، چند سرور، dev) **`وب اتومیتور:AppInstanceKey`** یکتا تعریف کنید.

---

## 2. محیط‌های پشتیبانی‌شده برای هاست وب

وب اتومیتور یک برنامه **ASP.NET Core 9** است و روی سیستم‌عامل‌های مختلف قابل اجراست. **دیتابیس** باید **SQL Server** باشد (روی همان سرور یا سرور جدا — Windows، Linux یا سرویس ابری).

### جدول محیط‌های هاست

| محیط | پشتیبانی | روش پیشنهادی |
|------|----------|--------------|
| **Windows Server 2019+** | ✅ | IIS + Hosting Bundle، یا اجرای مستقیم برنامه |
| **Linux** (Ubuntu 22.04+, RHEL 8+, Debian 12+, …) | ✅ | برنامه + **nginx** (reverse proxy) + **systemd** |
| **Azure App Service** (Windows / Linux) | ✅ | استقرار بسته ASP.NET Core |
| **Docker / Kubernetes** | ✅ | کانتینر ASP.NET Core 9 + اتصال به SQL Server |
| **macOS** | ⚠️ فقط آزمایش | اجرای مستقیم — برای production توصیه نمی‌شود |

### نکات مهم

- **سیستم‌عامل سرور وب** مستقل از **سیستم‌عامل SQL Server** است — مثلاً برنامه روی **Linux** و دیتابیس روی **Windows** کاملاً ممکن است.
- **افزونه Chrome** روی **رایانه کاربر** نصب می‌شود؛ کاربران Windows، macOS یا Linux می‌توانند از وب اتومیتور استفاده کنند.
- بسته نصب پیش‌فرض ممکن است برای **Windows** (`وب اتومیتور.Web.exe`) یا **Linux** (`وب اتومیتور.Web.dll`) باشد — هنگام دریافت بسته، **پلتفرم مقصد** را به پشتیبانی اعلام کنید.
- برای **HTTPS** در production از گواهی معتبر (Let's Encrypt، گواهی سازمان، Azure/AWS) استفاده کنید.

---

## 3. پیش‌نیازها

### سرور وب

**Windows:**
- Windows Server 2019 یا جدیدتر
- [.NET 9 ASP.NET Core Runtime](https://dotnet.microsoft.com/download/dotnet/9.0) — برای IIS از **Hosting Bundle** استفاده کنید

**Linux:**
- توزیع پشتیبانی‌شده (Ubuntu 22.04 LTS، RHEL 8+، Debian 12+ و مشابه)
- [.NET 9 ASP.NET Core Runtime](https://dotnet.microsoft.com/download/dotnet/9.0) برای Linux
- **nginx** (یا Apache) به‌عنوان reverse proxy — توصیه می‌شود

### دیتابیس (الزامی — SQL Server)

- SQL Server 2019+، SQL Express، **SQL Server on Linux**، یا **Azure SQL**
- حساب اتصال باید اجازه **ساخت دیتابیس** را داشته باشد (در اولین اجرا)
- سرور SQL می‌تواند روی ماشین دیگری باشد

### کلاینت کاربران

- مرورگر Chrome یا Edge (Chromium)
- افزونه **وب اتومیتور Global** (+ Smart Recorder اختیاری) — یک بار Load unpacked
- اگر گواهی سرور از **CA داخلی** صادر شده: گواهی **ریشه** در مخزن Trusted Root هر کلاینت (بخش ۷.۷).
  بدون این گام، پنل باز می‌شود ولی افزونه نمی‌تواند به سرور وصل شود و پنل می‌گوید افزونه نصب نیست.

### شبکه

- **HTTPS** با گواهی معتبر (توصیه می‌شود)
- برای بررسی به‌روزرسانی: دسترسی به اینترنت یا URL سفارشی که در لایسنس یا تنظیمات تعریف شده

---

## 4. دریافت و محتوای بسته نصب

بسته نصب Enterprise معمولاً به‌صورت فایل فشرده (`morobot-server.zip`) در اختیار سازمان قرار می‌گیرد.

پس از استخراج، ساختار کلی به این شکل است:

**Windows:**
```
morobot-server/
├── وب اتومیتور.Web.exe          ← برنامه اصلی
├── appsettings.json
├── docs/setup-guide.md
├── wwwroot/
└── ...
```

**Linux:**
```
morobot-server/
├── وب اتومیتور.Web.dll          ← برنامه اصلی
├── appsettings.json
├── docs/setup-guide.md
├── wwwroot/
└── ...
```

**مرحله بعد:** پوشه را روی سرور مقصد کپی کنید (مثلاً `C:\Apps\وب اتومیتور` در Windows یا `/opt/morobot` در Linux).

---

## 5. پیکربندی دیتابیس

وب اتومیتور از **SQL Server** به‌عنوان موتور دیتابیس استفاده می‌کند. **سرور، نام دیتابیس، کاربر و رمز** همگی در زمان نصب از طریق `appsettings.json` (یا متغیر محیطی `ConnectionStrings__Default`) مشخص می‌شوند — نیازی به تنظیم جدا در کد نیست.

> **PostgreSQL / MySQL:** در نسخه فعلی پشتیبانی نمی‌شود. فقط SQL Server (Windows، Linux یا Azure SQL).

### 5.0 چهار فایل تنظیمات و ترتیب بارگذاری

تنظیمات از چهار فایل خوانده می‌شود. هر لایه روی لایهٔ قبلی **override** می‌کند:

| # | فایل | چه وقت بارگذاری می‌شود | چه چیزی در آن می‌گذراند |
|---|------|------------------------|------------------------|
| ۱ | `appsettings.json` | همیشه، اولین | مقادیر پیش‌فرض مشترک همهٔ محیط‌ها |
| ۲ | `appsettings.Development.json` | فقط `ASPNETCORE_ENVIRONMENT=Development` | کلید dev، لاگ verbose |
| ۳ | `appsettings.Production.json` | فقط `ASPNETCORE_ENVIRONMENT=Production` (پیش‌فرض وقتی متغیر ست نشده) | **connection string واقعی، JWT key — همان‌جا که اپراتور ویرایش می‌کند** |
| ۴ | `appsettings.ServerUpdate.json` | **همیشه، آخرین لایه** | overrideهای اجباری بستهٔ به‌روزرسانی آفلاین |

متغیرهای محیطی بین لایهٔ ۲ و ۳ قرار می‌گیرند و بر هر چهار فایل مقدم‌اند، پس `ConnectionStrings__Default` همیشه برنده است.

> **لایه ۴ برای چیست؟** در سرور مشتری، connection string و رمزها در `appsettings.Production.json` می‌مانند. بستهٔ به‌روزرسانی آفلاین نیاز دارد بتواند یک مقدار را **به‌زور** اعمال کند (مثلاً آدرس جدید فید به‌روزرسانی) بدون اینکه اپراتور آن فایل را دستی عوض کند. چون این لایه آخرین است، بر همه‌چیز مقدم می‌شود.

### 5.1 تنظیم اتصال در appsettings.json

قبل از اولین اجرا، بخش `ConnectionStrings:Default` را مطابق SQL Server سازمان ویرایش کنید:

```json
"ConnectionStrings": {
  "Default": "Server=SQLHOST\\INSTANCE;Database=وب اتومیتورDb;User Id=morobot;Password=***;TrustServerCertificate=True;MultipleActiveResultSets=true"
}
```

> برای سرور واقعی، این را در `appsettings.Production.json` بگذارید تا در هر publish پاک نشود.

### 5.2 دسترسی دیتابیس — خودکار حل می‌شود

وب اتومیتور در اولین اجرا خودش دیتابیس را می‌سازد، ولی برای این کار **هویتِ پروسهٔ در حال اجرا** باید در SQL Server دسترسی داشته باشد. این نکتهٔ کلیدی است که معمولاً نادیده گرفته می‌شود:

> `Trusted_Connection=True` یعنی «با هویت ویندوزیِ **پروسه** احراز هویت کن». پشت IIS، این هویت **Application Pool Identity** است (`IIS APPPOOL\<نام pool>`)، و برای Windows Service معمولاً **machine account** (`DOMAIN\HOST$`). **هیچ‌کدام هویت کاربری که با آن وارد ویندوز شده‌اید نیست.**

**لازم نیست این را حدس بزنید یا دستی بررسی کنید.** اگر دسترسی کافی نباشد، برنامه بالا می‌آید و یک صفحهٔ راهنما نشان می‌دهد که دقیقاً می‌گوید چه چیزی کم است و کدام دستور SQL آن را حل می‌کند:

```
http://localhost:<port>/setup/database
```

این صفحه فقط از روی خود سرور (localhost) باز می‌شود: درخواستی که از بیرون از سرور برسد — یا آدرسش
`localhost` نباشد — فقط پاسخ `503` ساده می‌گیرد و هیچ جزئیاتی از دیتابیس نمی‌بیند. اگر سایت با
**هدر میزبان (host header)** bind شده باشد، از روی خود سرور یک Binding موقت `http://localhost` اضافه
کنید (یا از IIS Manager → Bindings همان کار را انجام دهید) تا این صفحه در دسترس باشد.
سه چیز را نشان می‌دهد:

| مورد | نمونه |
|------|-------|
| سرور و دیتابیس | `.` / `وب اتومیتورDb` |
| هویتی که برنامه با آن اجرا می‌شود | `IIS APPPOOL\Automator` |
| کد خطای SQL Server | `18456` |

و سپس **دستور آماده برای کپی** که با نام واقعی pool و دیتابیس شما ساخته شده. سه حالت ممکن است:

**الف) login وجود ندارد** (`18456`):
```sql
IF SUSER_ID(N'IIS APPPOOL\Automator') IS NULL
    CREATE LOGIN [IIS APPPOOL\Automator] FROM WINDOWS;
IF IS_SRVROLEMEMBER(N'dbcreator', N'IIS APPPOOL\Automator') = 0
    ALTER SERVER ROLE [dbcreator] ADD MEMBER [IIS APPPOOL\Automator];
```

**ب) دیتابیس وجود ندارد** (`4060`):
```sql
IF DB_ID(N'وب اتومیتورDb') IS NULL
    CREATE DATABASE [وب اتومیتورDb];
```

**ج) user داخل دیتابیس نیست** (`4060` با دیتابیس موجود):
```sql
USE [وب اتومیتورDb];
IF USER_ID(N'IIS APPPOOL\Automator') IS NULL
    CREATE USER [IIS APPPOOL\Automator] FOR LOGIN [IIS APPPOOL\Automator];
ALTER ROLE [db_owner] ADD MEMBER [IIS APPPOOL\Automator];
```

پس از اجرای دستور، دکمهٔ **«دوباره امتحان کن»** را بزنید. **نیازی به ری‌استارت سرویس نیست** — برنامه همان لحظه تست می‌کند و اگر موفق شد، به‌طور عادی ادامه می‌دهد.

> **چرا رمز گرفته نمی‌شود؟** چون احراز هویت ویندوزی است. رمز را خود ویندوز مدیریت می‌کند و برنامه هرگز آن را نمی‌بیند. تنها چیزی که کم است، ثبت یک login برای یک هویت موجود است — که یک اقدام مدیریتی یک‌باره روی سرور دیتابیس است، نه رمزی که برنامه بخواهد ذخیره کند.

### 5.3 اتصال دیتابیس داخل لایسنس (Enterprise)

در برخی قراردادها، اطلاعات اتصال دیتابیس داخل فایل لایسنس قرار داده می‌شود. پس از وارد کردن لایسنس:

- تنظیمات اتصال در سامانه ذخیره می‌شود
- برای اعمال تغییر، **یک بار سرویس را راه‌اندازی مجدد** کنید
- در پنل مدیریت فقط **نام سرور** نمایش داده می‌شود (رمز عبور نمایش داده نمی‌شود)



---

## 6. اولین اجرا و ساخت خودکار دیتابیس

در اولین اجرا، وب اتومیتور به‌صورت خودکار این کارها را انجام می‌دهد:

1. اگر دیتابیس روی SQL Server وجود نداشته باشد → **ایجاد دیتابیس**
2. **ساخت و به‌روزرسانی جداول** مورد نیاز
3. **تنظیمات اولیه** و حساب مدیر (در صورت تعریف در بسته نصب)

> اگر دسترسی کافی نباشد، برنامه **متوقف نمی‌شود**. بالا می‌آید و صفحهٔ `/setup/database` را نشان می‌دهد که هویت واقعی پروسه و دستور SQL لازم را می‌گوید (بخش ۵.۲). پس از اجرای دستور، دکمهٔ «دوباره امتحان کن» بدون ری‌استارت ادامه می‌دهد.


### راه‌اندازی برنامه

**Windows:**
```powershell
cd C:\Apps\وب اتومیتور
.\وب اتومیتور.Web.exe
```

**Linux:**
```bash
cd /opt/morobot
dotnet وب اتومیتور.Web.dll
```

برای تعیین آدرس و پورت:

**Windows:**
```powershell
$env:ASPNETCORE_URLS = "http://0.0.0.0:5000"
.\وب اتومیتور.Web.exe
```

**Linux:**
```bash
export ASPNETCORE_URLS="http://127.0.0.1:5000"
dotnet وب اتومیتور.Web.dll
```

> در production معمولاً برنامه پشت reverse proxy (IIS یا nginx) با HTTPS اجرا می‌شود — بخش ۷.

### آدرس‌های مهم

| مسیر | توضیح |
|------|--------|
| `/` | صفحه معرفی |
| `/Home/SetupGuide` | همین راهنما (نسخه وب) |
| `/Panel` | پنل کاربر |
| `/Admin` | پنل مدیر (نقش Admin) |

---

## 7. استقرار روی سرور

### 7.1 Windows — IIS (پیشنهادی برای سازمان‌های Windows)

1. نصب **ASP.NET Core Hosting Bundle 9**
2. ایجاد **Application Pool** با گزینه **No Managed Code**
3. ایجاد **Site** — مسیر فیزیکی = پوشه نصب وب اتومیتور
4. تنظیم **Binding** با HTTPS
5. فایل `web.config` همراه بسته نصب است

> **پیش از اولین اجرا، بخش ۵.۲ را ببینید.** تحت IIS، `Trusted_Connection=True` به هویت Application Pool معنا می‌شود (مثلاً `IIS APPPOOL\Automator`)، نه کاربری که با آن وارد ویندوز شده‌اید. اگر این login ساخته نشده باشد، برنامه با یک صفحهٔ راهنما بالا می‌آید و نام دقیق pool و دستور SQL لازم را نشان می‌دهد — کافی است یک‌بار اجرا کنید و «دوباره امتحان کن» را بزنید.

### 7.2 Windows — اجرای مستقیم

مناسب برای محیط آزمایشی یا سرورهای کوچک. برنامه را با `وب اتومیتور.Web.exe` اجرا کنید. برای اجرای دائم می‌توانید از **Windows Service** (مثلاً با NSSM) استفاده کنید.

### 7.3 Linux — nginx + systemd (پیشنهادی)

**۱. سرویس systemd** (فایل `/etc/systemd/system/morobot.service`):

```ini
[Unit]
Description=وب اتومیتور Web
After=network.target

[Service]
WorkingDirectory=/opt/morobot
ExecStart=/usr/bin/dotnet /opt/morobot/وب اتومیتور.Web.dll
Restart=always
RestartSec=10
Environment=ASPNETCORE_URLS=http://127.0.0.1:5000
User=www-data

[Install]
WantedBy=multi-user.target
```

```bash
sudo systemctl daemon-reload
sudo systemctl enable morobot
sudo systemctl start morobot
```

**۲. nginx** (نمونه `/etc/nginx/sites-available/morobot`):

```nginx
server {
    listen 443 ssl;
    server_name morobot.example.com;

    ssl_certificate     /etc/ssl/certs/morobot.crt;
    ssl_certificate_key /etc/ssl/private/morobot.key;

    location / {
        proxy_pass         http://127.0.0.1:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}
```

**۳. SignalR:** اگر از قابلیت‌های real-time استفاده می‌کنید، در nginx هدرهای `Upgrade` و `Connection` باید فعال باشند (در نمونه بالا هست).

### 7.4 Docker / Kubernetes

- تصویر پایه: `mcr.microsoft.com/dotnet/aspnet:9.0`
- متغیر `ConnectionStrings__Default` را در environment تنظیم کنید
- SQL Server باید از داخل کانتینر در دسترس باشد
- برای HTTPS از ingress یا load balancer استفاده کنید

### 7.5 Azure App Service

- Runtime stack: **.NET 9**
- Connection string را در **Configuration → Connection strings** تنظیم کنید
- برای Linux plan همان بسته `وب اتومیتور.Web.dll` را deploy کنید

### 7.6 پشت Reverse Proxy (عمومی)

برنامه پشت پروکسی روی HTTP محلی گوش می‌دهد و پایان دادن به TLS کار IIS/nginx است. برای اینکه برنامه
بداند HTTPS وجود دارد — و در نتیجه ریدایرکت به https و هدر HSTS را فعال کند — **پورت HTTPS را اعلام کنید**:

```bash
export ASPNETCORE_HTTPS_PORT=443     # یا HTTPS_PORT=443
```

یا در `appsettings.Production.json`:

```json
"HTTPS_PORT": "443"
```

بدون این تنظیم، برنامه فرض می‌کند گواهی/HTTPS در کار نیست و **نه ریدایرکت به https می‌سازد و نه هدر
`Strict-Transport-Security`**: ریدایرکت به آدرسی که TLS روی آن برقرار نیست، کاربر را از یک صفحهٔ سالم
به صفحهٔ خطای گواهی می‌برد و HSTS مرورگر را برای تمام مدت `max-age` به همان آدرس قفل می‌کند. اگر سرور
خودش مستقیماً HTTPS سرو کند (Kestrel با گواهی، یا پروفایل https در اجرای توسعه) این تشخیص خودکار است
و تنظیم جداگانه لازم نیست.

هدرهای `X-Forwarded-Proto` و `X-Forwarded-For` را در پروکسی فعال کنید؛ اما توجه کنید برنامه برای
تصمیم‌های خود به آن‌ها تکیه نمی‌کند: تشخیص HTTPS از پورت اعلام‌شده (بالا) می‌آید و آدرس کلاینت از سوکت
خوانده می‌شود، چون این هدرها را هر کلاینتی می‌تواند جعل کند.

### 7.7 گواهی داخلی و اعتماد کلاینت‌ها (الزامی برای کارکرد افزونه)

اگر گواهی سرور از یک **CA داخلی** صادر شده باشد (نه CA عمومی)، نصب گواهی روی سرور کافی نیست:
**گواهی ریشه باید در مخزن Trusted Root هر کلاینت هم نصب شود.** بدون آن، پنل در مرورگر باز می‌شود
(کاربر هشدار گواهی را رد می‌کند) ولی **افزونه نمی‌تواند به سرور وصل شود** و پنل به‌اشتباه می‌گوید
افزونه نصب نیست.

**چرا:** افزونه برای تأیید هویت سرور، `/extension/fingerprint` را با `fetch` می‌خواند. کلیک روی
**«Proceed»** در هشدار گواهی مرورگر فقط روی **بارگذاری خود صفحه** اثر دارد و درخواست افزونه را باز
نمی‌کند؛ پس آن درخواست با `ERR_CERT_AUTHORITY_INVALID` شکست می‌خورد — **بدون هیچ خطای دیدنی در
کنسول صفحه یا کنسول افزونه**. نتیجه: افزونه صفحه را علامت‌دار نمی‌کند و پنل فکر می‌کند افزونه نصب نیست.

**۱. فایل گواهی ریشه.** اسکریپت `tools/Install-HttpsCertificate.ps1` آن را کنار گواهی سرور export می‌کند
(پیش‌فرض `C:\certs\morobot`):

```
C:\certs\morobot\<host>-root.cer
```

**۲. نصب روی هر کلاینت** (با دسترسی ادمین):

```powershell
Import-Certificate -FilePath 'C:\certs\morobot\automator.krtax.ir-root.cer' -CertStoreLocation Cert:\LocalMachine\Root
# یا
certutil -addstore -f Root "C:\certs\morobot\automator.krtax.ir-root.cer"
```

سپس مرورگر را **کامل ببندید و باز کنید** (نه فقط تب) تا فرآیند شبکه گواهی تازه را ببیند.

**۲.۱ نصب یک‌کلیکی روی کلاینت‌ها (بدون نیاز به دانش فنی)**

سه فایل کنار هم کافی است: `Run-InstallRootCA.cmd` + `Install-ClientRootCA.ps1` (هر دو در `tools/`) + فایل `<host>-root.cer` (خروجی گام ۱). کاربر فقط `.cmd` را دابل‌کلیک و UAC را تأیید می‌کند.

اسکریپت قبل از هر تغییری ریشه را اعتبارسنجی می‌کند (self-signed، `CA=True`، تطابق Subject پیش‌فرض `CN=Internal Root CA`، و در صورت دادن `-Thumbprint` تطابق اثر انگشت)، بعد نصب می‌کند، و در پایان **خودش تأیید می‌کند**: یک handshake واقعی TLS + درخواست بدون دورزدن اعتبارسنجی به `/extension/fingerprint` — یعنی همان چیزی که افزونه لازم دارد.

| نیاز | دستور |
|---|---|
| نصب سراسری برای همهٔ کاربران ماشین | `Run-InstallRootCA.cmd` (ادمین) |
| کاربرِ **بدون دسترسی ادمین** | `Run-InstallRootCA.cmd -Scope User` |
| فایل روی مسیر شبکه | `Install-ClientRootCA.ps1 -CerPath \\fs01\share\automator.krtax.ir-root.cer` |
| دانلود با pin کردن اثر انگشت | `Install-ClientRootCA.ps1 -Url https://host/root.cer -Thumbprint <SHA1>` |
| حذف ریشه | `Run-InstallRootCA.cmd -Uninstall` |
| فقط بررسی، بدون هیچ تغییر | هر دستور بالا + `-DryRun` |

کدهای خروجی برای توزیع گروهی (SCCM/Intune/PDQ/RMM): `0` = نصب و تأیید شد، `2` = دسترسی ادمین لازم است، `1` = بقیهٔ خطاها.

> **دیالوگ تأیید ویندوز:** در حالت `-Scope User` ویندوز هنگام افزودن ریشه به مخزن کاربر یک پنجرهٔ **Security Warning** نشان می‌دهد که کاربر باید **Yes** بزند — پس این حالت «یک کلیک انسانی» لازم دارد. در حالت سراسری (اجرای ادمین) چنین دیالوگی نیست و برای نصب بی‌سروصدا با RMM/SCCM مناسب است.

> نکتهٔ کاربرِ بدون ادمین: `-Scope User` گواهی را در مخزن **همان پروفایل ویندوز** می‌گذارد؛ کروم و Edge آن را می‌خوانند، ولی Firefox مخزن جدا دارد و برای آن scope ماشین (و سوییچ `-SetFirefoxEnterpriseRoots`) لازم است.

**۲.۲ بستهٔ MSI (برای توزیع بی‌سروصدا با SCCM/Intune/GPO/PDQ/RMM)**

اگر سازمان ابزار توزیع نرم‌افزار دارد، به‌جای اسکریپت از بستهٔ MSI استفاده کنید. MSI همان کار اسکریپت را می‌کند
(نصب ریشه در مخزن ماشین + فعال‌کردن `ImportEnterpriseRoots` برای Firefox) و چیزهایی دارد که اسکریپت ندارد:
**حذف استاندارد**، **Rollback** در صورت خرابی نصب، و لاگ verbose استاندارد.

ساخت بسته (یک‌بار، روی ماشین خودتان — نیاز به .NET SDK؛ اسکریپت اگر WiX نباشد دستور نصبش را چاپ می‌کند):

```powershell
tools\installer\Build-RootCaMsi.ps1 -CerPath C:\certs\morobot\automator.krtax.ir-root.cer -OutDir C:\certs\morobot
# خروجی: وب اتومیتورRootCA-1.0.0.msi + وب اتومیتورRootCA-1.0.0.msi.sha256
```

اسکریپت ساخت، بسته را قبل از تحویل **خودش تأیید می‌کند**: اعتبار ریشه، وجود سه Custom Action
(نصب/rollback/حذف)، ترتیب زمان‌بندی آن‌ها، پالیسی رجیستری Firefox، و درستی payload گواهی؛ در پایان هم
با یک extraction تستی ثابت می‌کند گواهی واقعاً داخل بسته است.

| نیاز | دستور |
|---|---|
| نصب بی‌سروصدا (SYSTEM یا ادمین) | `msiexec /i وب اتومیتورRootCA-1.0.0.msi /qn /norestart` |
| نصب با لاگ برای عیب‌یابی | `msiexec /i وب اتومیتورRootCA-1.0.0.msi /l*v %TEMP%\وب اتومیتورRootCA.log` |
| از مسیر شبکه | `msiexec /i \\fs01\share\وب اتومیتورRootCA-1.0.0.msi /qn /norestart` |
| حذف بسته و برداشتن ریشه | `msiexec /x وب اتومیتورRootCA-1.0.0.msi /qn /norestart` |

نکته‌ها:

- بسته **per-machine** و **x64** است (بستهٔ 32 بیتی مقدار رجیستری Firefox را در `WOW6432Node` می‌نویسد و ۶۴ بیتی‌ها آن را نمی‌بینند) و برای اجرای بی‌سروصدا به دسترسی ادمین/SYSTEM نیاز دارد — که با SCCM/Intune/GPO/RMM فراهم است.
- گواهی زیر `%ProgramFiles%\وب اتومیتور Root CA\` کپی می‌شود و با **thumbprint** همان ریشه دوباره حذف می‌شود؛ پس اگر روزی ریشه را عوض کردید، بستهٔ جدید نسخهٔ دیگری است و باید توزیع شود.
- تست: روی **یک کلاینت** با ادمین نصب کنید و در لاگ دنبال `Return value 3` و `CustomAction AddRootCert returned actual error code` بگردید (نباید باشد)، سپس گام ۴ همین بخش را برای تأیید اجرا کنید.
- اگر بعداً ریشه را در `-CerPath` به گواهی دیگری تغییر دهید، باید `-Version` را هم بالا ببرید، وگرنه MSI آن را upgrade نمی‌شناسد.

**۳. توزیع گروهی (توصیه‌شده در دامنه):** GPO →
Computer Configuration → Policies → Windows Settings → Security Settings → Public Key Policies →
Trusted Root Certification Authorities → Import.

همین کار را می‌توان با بستهٔ MSI بخش ۲.۲ هم انجام داد و به‌جای Import دستی، **Computer Configuration → Policies → Software Settings → Software Installation** بسته را Publish/Assign کنید؛ مزیتش این است که حذف بسته هم از همان GPO مدیریت می‌شود.

**۴. تأیید:**

```powershell
# ساده‌ترین و همان درخواستی که افزونه می‌زند (بدون دورزدن اعتبارسنجی):
(Invoke-WebRequest https://<host>/extension/fingerprint -UseBasicParsing).Content

# معادل با curl — نکته: --ssl-no-revoke لازم است
curl.exe -sS --ssl-no-revoke https://<host>/extension/fingerprint
```

> **دو خطای متفاوت را با هم اشتباه نگیرید:**
> - `SEC_E_UNTRUSTED_ROOT` (curl کد ۶۰) ⇒ **ریشه روی کلاینت نیست** — همین را باید نصب کنید.
> - `CRYPT_E_NO_REVOCATION_CHECK` (curl کد ۳۵) ⇒ فقط **بررسی ابطال (CRL/OCSP) ممکن نشده**، چون ریشهٔ self-signed شما CRL ندارد. **نشانهٔ خرابی نیست**؛ کروم soft-fail می‌کند و گواهی را می‌پذیرد. به همین دلیل `curl` بدون `--ssl-no-revoke` اینجا نتیجهٔ گمراه‌کننده می‌دهد.

پس از اصلاح، در کنسول پنل مقدار `document.documentElement.dataset.daExtensionFingerprint`
باید با مقدار متای `da-server-fingerprint` صفحه یکی باشد.

> **جابجایی سرور:** اثر انگشت سرور از `MachineGuid` + نام ماشین + تعداد هسته + پلتفرم ساخته می‌شود.
> اگر برنامه را به ماشین/VM/کانتینر دیگری ببرید، اثر انگشت عوض می‌شود و افزونه‌های نصب‌شده روی
> کلاینت‌ها «بیگانه» می‌شوند؛ در آن صورت هر کلاینت باید بستهٔ سرور جدید را Load unpacked کند.

---

## 8. لایسنس

همه نصب‌ها (شامل Cloud و dev) از **Admin → License** درخواست فعال‌سازی و import لایسنس دارند.

### 8.1 مراحل فعال‌سازی

```
نصب → دوره آزمایشی (در صورت فعال بودن) → Admin/License → دریافت فایل activation-request
     → ارسال به پشتیبانی/فروشنده → دریافت license.morobot → Import در Admin/License
```

### 8.2 وارد کردن لایسنس

1. ورود به `/Admin/License`
2. بارگذاری فایل `.morobot` یا وارد کردن محتوای JSON
3. **داده‌های موجود (کاربر، فرآیند، منبع) حذف نمی‌شوند** — فقط اطلاعات لایسنس به‌روز می‌شود؛ import موفق همه ردیف‌ها را به «نمونه نصب» فعلی وصل می‌کند؛ import موفق همه ردیف‌ها را به «نمونه نصب» فعلی وصل می‌کند
4. برای ارتقا (مثلاً افزایش سقف کاربر): فایل لایسنس جدید با شماره نسخه بالاتر دریافت کنید

### 8.3 اطلاعات قابل مشاهده در پنل مدیریت

- نام سازمان، تاریخ اعتبار، سقف کاربر، شماره نسخه لایسنس
- نام سرور دیتابیس (بدون رمز)، وضعیت به‌روزرسانی
- **دامنه / IP مجاز** (در صورت تعریف در لایسنس؛ خالی = بدون قفل آدرس)
- **نمایش داده نمی‌شود:** امضای دیجیتال، رشته اتصال کامل، کلیدها

### 8.4 نشان کپی‌رایت

در حالت **آزمایشی** یا **محدود** (بدون لایسنس معتبر)، نوار کپی‌رایت در کل برنامه نمایش داده می‌شود. با لایسنس معتبر و برندینگ سفارشی، این نشان برداشته می‌شود.

---

## 9. دوره آزمایشی ۳ روزه

- از **اولین اجرا روی همان سرور** شروع می‌شود (اثر انگشت سخت‌افزار/OS سرور، نه مرورگر کاربر)
- یک ردیف ثابت در جدول `DeploymentTrialRecords` نگه می‌دارد؛ **حذف ردیف anchor در دیتابیس دوره آزمایشی را از نو نمی‌دهد**
- **۳ روز** بدون لایسنس: همه قابلیت‌ها فعال + نشان کپی‌رایت
- مدت دوره آزمایشی ممکن است در لایسنس سازمان متفاوت باشد (پیش‌فرض: ۳ روز)
- درخواست فعال‌سازی (`activation-request.json`) شامل `ServerFingerprintHash` است تا فروشنده بتواند نصب را تشخیص دهد
- اگر entitlement آزمایشی از نو ساخته شود (`DeploymentTrialRecords` جدید)، کاربران و فرآیندهای قدیمی (InstanceId متفاوت) بدون لایسنس قابل استفاده نیستند
- اگر entitlement آزمایشی از نو ساخته شود (`DeploymentTrialRecords` جدید)، کاربران و فرآیندهای قدیمی (InstanceId متفاوت) بدون لایسنس قابل استفاده نیستند

---

## 10. حالت محدود پس از انقضا

پس از پایان دوره آزمایشی یا انقضای لایسنس:

| مجاز | غیرمجاز |
|------|---------|
| ورود / خروج | ویرایشگر، اجرا، ضبط |
| مشاهده لیست فرآیندها | ایجاد فرآیند یا منبع جدید |
| مشاهده نمودار فرآیند (فقط خواندنی) | اکثر بخش‌های پنل مدیریت |

برای رفع محدودیت: لایسنس معتبر را در `/Admin/License` وارد کنید.

---

## 11. برندینگ سازمان

**فقط با لایسنس معتبر:** از مسیر `/Admin/Branding`

- نام برنامه، عنوان برند، نام سازمان
- آپلود لوگو و آیکون (favicon) — **قبل از ذخیره، پنجرهٔ برش تصویر** باز می‌شود تا اندازه و نسبت درست تنظیم شود
- پالت رنگ برند (رنگ اصلی، تیره/روشن، تأکید، پس‌زمینه‌ها، متن) با انتخابگر رنگ
- نمایش/پنهان‌کردن ویجت QR معرفی محصول

> **فرمت آیکون:** آیکون برند باید **PNG واقعی** باشد؛ فایل JPEG (یا WebP) که فقط پسوندش
> `.png` شده کافی نیست. همین آیکون روی آیکون‌های افزونهٔ Chrome هم می‌نشیند و Chrome فقط
> PNG را به‌عنوان آیکون manifest می‌پذیرد؛ اگر محتوای فایل PNG نباشد، آیکون‌های پیش‌فرض
> افزونه دست‌نخورده می‌مانند.

> **تفکیک از تنظیمات سامانه:** فیلدهای برندینگ فقط در `/Admin/Branding` قابل ویرایش‌اند و در
> `/Admin/Settings` نمایش داده نمی‌شوند — این دو صفحه دیگر روی هم اثر نمی‌گذارند.

### 11.1 تصویر پروفایل کاربر

هر کاربر از **پنل → تنظیمات** می‌تواند تصویر پروفایل خود را آپلود کند (با برش ۱:۱).
تصویر در نوار بالای پنل و در فهرست کاربران پنل مدیریت به‌صورت آواتار نمایش داده می‌شود؛
در صورت نبود تصویر، حرف اول نام با رنگی مشتق از نام کاربر نمایش داده می‌شود.

---

## 12. به‌روزرسانی نرم‌افزار

- امکان بررسی به‌روزرسانی بسته به تنظیمات لایسنس
- آدرس پیش‌فرض بررسی: `https://morobot.ir/checkupdate`
- **قرارداد API (GET):** `?current={نسخه_نصب}` → JSON:

```json
{
  "version": "3.0.0",
  "notes": "یادداشت انتشار",
  "downloadUrl": "https://morobot.ir/download",
  "updateAvailable": true,
  "current": "2.9.0",
  "publishedUtc": "2026-09-24T00:00:00Z"
}
```

فیلدهای `version`، `notes` و `downloadUrl` برای سازگاری با نصب‌های قدیمی کافی است. روی سرور محصول (`morobot.ir`) یا در dev: `GET https://localhost:7201/checkupdate?current=2.0.0`

- **API ادمین (نیاز به نقش Admin):** `GET /api/updates/status` — وضعیت کش‌شده؛ `POST /api/updates/check` — بررسی آنلاین و به‌روزرسانی کش
- مدیر می‌تواند آدرس را در **Settings → بخش «به‌روزرسانی»** تغییر دهد
- **بررسی دستی:** Admin/License → «بررسی آپدیت»
- **بررسی خودکار:** سامانه هر **۶ ساعت** یک‌بار بررسی می‌کند و در صورت وجود نسخهٔ جدید، به مدیر
  اعلان لحظه‌ای (SignalR) نشان می‌دهد — نیازی به refresh صفحه نیست
- **سرور بدون اینترنت:** آخرین نتیجه ذخیره‌شده نمایش داده می‌شود؛ بررسی خودکار بی‌اثر است و باید از
  روش **آپدیت آفلاین** (بخش ۱۳) استفاده شود

> اعمال به‌روزرسانی آنلاین (جایگزینی فایل‌های برنامه) دستی است: دریافت بسته جدید از پشتیبانی،
> پشتیبان‌گیری، استخراج، راه‌اندازی مجدد — یا از مسیر آپدیت آفلاین برای بستهٔ آماده استفاده کنید.

**دیتابیس:** در **اولین اجرا بعد از آپدیت**، وب اتومیتور خودکار migrationهای EF Core را روی SQL Server اعمال می‌کند — نیازی به دستور جدا نیست (فقط سرویس را restart کنید). تعداد migrationهای در انتظار اعمال در لاگ راه‌اندازی ثبت می‌شود و در صورت شکست، پیام خطا نام migration مشکل‌دار را نشان می‌دهد.

---

## 13. آپدیت آفلاین (سرور بدون اینترنت)

برای سازمان‌هایی که سرور به اینترنت دسترسی ندارد: از مسیر **`/Admin/OfflineUpdate`**
(لینک «آپدیت آفلاین» در منوی پنل مدیریت — فقط وقتی لایسنس امکان آپدیت داشته باشد).

### 13.1 بستهٔ آپدیت چیست

یک فایل `zip` که پشتیبانی/فروشنده برای شما می‌سازد. داخل آن:

```
morobot-update.json     ← مانیفست (نسخه، یادداشت، فهرست فایل‌ها با SHA-256)
update.ps1              ← اسکریپت اعمال آپدیت (فقط Windows)
وب اتومیتور.Web.dll|exe     ← فایل‌های برنامه
wwwroot/ …              ← سایر فایل‌ها
```

### 13.2 مراحل

1. فایل zip را از پشتیبانی دریافت کنید (نسخهٔ آن باید **جدیدتر** از نسخهٔ نصب‌شده باشد)
2. در `/Admin/OfflineUpdate` فایل را آپلود و «آپلود و بررسی» را بزنید
3. سامانه مانیفست را می‌خواند و **امضای SHA-256 هر فایل** را با مانیفست تطبیق می‌دهد؛ در صورت
   کوچک‌ترین مغایرت (فایل ناقص یا دست‌کاری‌شده) بسته رد می‌شود و چیزی روی سرور تغییر نمی‌کند
4. پس از تأیید، بسته در کارت **«بستهٔ آماده‌شده»** با نسخه و زمان نمایش داده می‌شود
5. **سرویس را متوقف کنید**، تیک تأیید را بزنید و «اعمال آپدیت و راه‌اندازی مجدد» را انتخاب کنید
6. اسکریپت `update.ps1` فایل‌ها را جانشین می‌کند و برنامه را دوباره اجرا می‌کند؛ نتیجه در فایل
   `update.log` کنار اسکریپت ثبت می‌شود

> اگر ترجیح می‌دهید دستی اعمال کنید، پوشهٔ آماده‌سازی را روی سرور باز کنید و دستور زیر را اجرا کنید
> (کارت «اعمال دستی» در همین صفحه دستور کامل را نشان می‌دهد):
>
> ```powershell
> powershell -ExecutionPolicy Bypass -File .\update.ps1 -TargetDir "C:\Apps\وب اتومیتور" -Restart
> ```

### 13.3 نکات

- اسکریپت **قبل از کپی** بررسی می‌کند که فایل‌های برنامه قفل نباشند؛ اگر سرویس هنوز در حال اجرا
  باشد با پیام روشن متوقف می‌شود (هیچ‌چیز نیمه‌اعمال نمی‌شود)
- در **Linux** فایل‌های بسته را دستی روی پوشهٔ نصب کپی کنید و سرویس را restart کنید
- پس از اعمال، migrationهای دیتابیس مثل بخش ۱۲ خودکار روی اولین اجرا اعمال می‌شوند
- «حذف بستهٔ آماده» بستهٔ آماده‌شده و فایل آرشیو آن را پاک می‌کند

### 13.4 تنظیمات (appsettings.json)

```json
"وب اتومیتور": {
  "OfflineUpdate": {
    "UploadDirectory": "updates/uploaded",
    "StagingDirectory": "updates/staged",
    "MaxUploadMegabytes": 512,
    "RestartCommand": ""
  }
}
```

`RestartCommand` دستوری است که اسکریپت پس از موفقیت برای راه‌اندازی مجدد اجرا می‌کند؛ اگر خالی
باشد اولین فایل اجرایی پوشهٔ مقصد اجرا می‌شود.

---

## 14. انتقال از دیتابیس قدیمی

اگر سازمان شما دیتابیس نسخهٔ قدیمی (Windows V2) دارد، **به‌صورت پیش‌فرض این امکان در دسترس
نیست**. انتقال از دیتابیس قدیمی یک عملیات حساس است و فقط زمانی فعال می‌شود که در **لایسنس
امضاشدهٔ شما** مجوز آن صادر شده باشد.

- **با مجوز:** لینک «انتقال از قدیمی» در منوی پنل مدیریت ظاهر می‌شود و `/Admin/Migrate` کار می‌کند
- **بدون مجوز:** آن صفحه **۴۰۴** برمی‌گرداند و لینکی در منو وجود ندارد
- برای دریافت این مجوز با پشتیبانی/فروشنده تماس بگیرید (در لایسنس، فیلد `allowLegacyMigration`)

---

## 15. کار با پنل و افزونه

### 15.1 افزونه وب اتومیتور Global (ضبط + اجرا + سلکتور)

**یک افزونه** به نام **وب اتومیتور Global** (`extension-global`) جایگزین سه افزونه جداگانه Recorder/Player/Selector شده است.

| افزونه | کاربرد |
|--------|--------|
| **وب اتومیتور Global** | ضبط، اجرا (Play) و کپی سلکتور |
| **Smart Recorder** | هوشمندسازی — **جدا** و اختیاری |

- **Cloud و Enterprise:** همان وب اتومیتور Global — آدرس سرور از پنلی که باز می‌کنید گرفته می‌شود
- **آیکون:** از برند وب اتومیتور (در Enterprise با برندینگ سفارشی، vendor می‌تواند آیکون‌ها را در بسته جایگزین کند — فایل‌های `icon16/32/48/128.png` باید PNG **واقعی** باشند، نه JPEG با پسوند png)
- افزونه‌های قدیمی Recorder/Player/Selector را **حذف** کنید و فقط Global + Smart (در صورت نیاز) نصب کنید

### 15.2 جریان کار پیشنهادی

1. وارد **پنل همان سروری** شوید که می‌خواهید با آن کار کنید (Cloud یا سازمانی)
2. از `/Panel/Extension/Install` افزونه‌ها را نصب کنید (یا از Chrome Web Store در Cloud)
3. **یک بار** وارد پنل شوید تا افزونه آدرس سرور را بگیرد
4. سپس فرآیند بسازید، Excel وصل کنید و Play/Record بزنید

> **قبل از ضبط یا اجرا** حتماً پنل سرور موردنظر را باز کنید تا افزونه به همان سرور متصل شود.

### 15.3 استفاده همزمان از Cloud و Enterprise

افزونه در هر لحظه **یک سرور فعال** دارد — معمولاً **آخرین پنلی** که باز کرده‌اید.

| سناریو | راه‌حل |
|--------|--------|
| فقط Cloud **یا** فقط Enterprise | همان یک مجموعه افزونه کافی است |
| **همزمان** چند Cloud / Enterprise روی یک مرورگر | **`AppInstanceKey` متفاوت** در هر deployment + Load unpacked از مسیر جدا (پنل Extension/Install) |
| **همزمان** با یک پروفایل و تداخل storage | **پروفایل جداگانه Chrome** (توصیه) |

اگر واقعاً به دو سرور **همزمان** در **یک پروفایل** نیاز دارید، از پشتیبانی بخواهید بسته افزونه با **شناسه جدا** (Extension ID متفاوت) تهیه شود تا هر دو کنار هم نصب شوند — این حالت استثنایی است.

### 15.4 نصب افزونه

**Cloud:** از پنل یا فروشگاه Chrome (در صورت انتشار رسمی)

**Enterprise (on-prem):**
1. ورود از `/Panel/Account/Login`
2. رفتن به `/Panel/Extension/Install`
3. Load unpacked از مسیر نمایش‌داده‌شده (یا دانلود zip هر افزونه)

### 15.5 نکات مهم

- افزونه روی **رایانه کاربر** نصب می‌شود، نه روی سرور
- سرور وب می‌تواند Windows یا Linux باشد — برای افزونه فرقی نمی‌کند
- کاربران می‌توانند Windows، macOS یا Linux داشته باشند — فقط Chrome/Edge لازم است
- اگر افزونه به سرور اشتباه وصل شد: پنل سرور درست را باز کنید، صفحه را refresh کنید، دوباره Record/Play بزنید

### 15.6 AppInstanceKey (مسیر افزونه)

در `appsettings.json`:

```json
"وب اتومیتور": {
  "AppInstanceKey": "cloud-prod-ir"
}
```

مسیر پوشه افزونه روی ماشین (همگام‌سازی dev/local):

`%LOCALAPPDATA%\webautomator\extension-global`

(اگر برای چند استقرار روی یک PC مقدار `AppInstanceKey` ست شده باشد: `%LOCALAPPDATA%\webautomator\{AppInstanceKey}\extension-global`)

هر وب اتومیتور با **دامنه + AppInstanceKey** یکتا باشد تا روی یک PC تداخل نداشته باشد.

---

## 16. عیب‌یابی

| مشکل | راه‌حل |
|------|--------|
| خطای اتصال SQL | بررسی connection string، فایروال SQL Server، گزینه TrustServerCertificate |
| خطا در ساخت دیتابیس | بررسی لاگ راه‌اندازی؛ اطمینان از دسترسی CREATE DATABASE |
| «لایسنس معتبر نیست» | درخواست activation-request جدید از Admin/License و دریافت لایسنس تازه |
| لایسنس قدیمی‌تر قبول نمی‌شود | لایسنس جدید باید شماره نسخه بالاتر داشته باشد |
| سقف کاربر | دریافت لایسنس با سقف کاربر بالاتر |
| تغییر اتصال دیتابیس بعد از لایسنس | appsettings.json را هماهنگ کنید و سرویس را restart کنید |
| برنامه روی Linux بالا نمی‌آید | نصب ASP.NET Core 9 Runtime برای Linux؛ مسیر `dotnet` در systemd |
| 502 از nginx | بررسی `systemctl status morobot`؛ پورت `ASPNETCORE_URLS` با `proxy_pass` یکی باشد |
| افزونه به سرور اشتباه وصل است | پنل سرور درست را باز کنید؛ refresh؛ دوباره Record/Play |
| افزونه روی دامنه سازمانی کار نمی‌کند | یک بار `/Panel` را روی همان دامنه باز کنید تا آدرس سرور ثبت شود |
| آپلود بستهٔ آپدیت رد می‌شود | فایل zip باید ساختهٔ پشتیبانی باشد (`morobot-update.json` دارد)؛ نسخهٔ بسته باید جدیدتر از نصب فعلی باشد؛ پیام دقیق روی همان صفحه نمایش داده می‌شود |
| اعمال آپدیت آفلاین انجام نمی‌شود | سرویس را متوقف کنید (فایل‌های برنامه قفل‌اند)؛ تیک تأیید را بزنید؛ `update.log` در پوشهٔ آماده‌سازی را ببینید |
| «انتقال از قدیمی» در منو نیست | مجوز آن در لایسنس شما صادر نشده است؛ با پشتیبانی تماس بگیرید |
| مقدار فیلدهای «سیستمی» در تنظیمات سامانه قابل ویرایش نیست | این‌ها را سامانه مدیریت می‌کند (نسخهٔ آپدیت، وضعیت و …) — فقط نمایشی‌اند |

---

## تماس با پشتیبانی

برای دریافت لایسنس، بسته به‌روزرسانی یا پشتیبانی استقرار با **پشتیبانی وب اتومیتور / فروشنده** تماس بگیرید.
