# انتقال خودکار SQLite به PostgreSQL Production این فرایند تمام داده‌های پایدار فعلی را منتقل می‌کند: - کاربران، hash رمزهای قابل استفاده، superuser، گروه‌ها و permissionها - واحدهای سازمانی، عضویت‌ها، نقش‌ها و پروفایل پرسنل - مشتریان، گروه مخاطبان، دسته‌بندی‌ها و SLA - branding، عنوان صفحات، SMS templateها، NotificationPolicy و سیاست فایل‌ها - تیکت‌ها، ارسال‌های گروهی، رویدادها، پیام‌ها، رسیدهای خواندن و attachmentها - تمام فایل‌های موجود در `MEDIA_ROOT`، شامل branding، avatar و فایل تیکت داده‌های موقتی و خطرناک زیر عمداً منتقل نمی‌شوند: sessionها، OTPهای قبلی، Magic Linkهای قبلی، admin log و `NotificationJob`. انتقال outbox قبلی می‌توانست بعد از بالا آمدن worker باعث ارسال مجدد SMS یا Bale شود. ## خروجی ساخته‌شده دستور زیر از SQLite فعلی snapshot می‌گیرد: ```powershell .\.venv\Scripts\python.exe manage.py export_production_seed --output production-seed --force ``` برای وضعیت فعلی پروژه خروجی قبلاً تولید شده و شامل ۳۹۵ رکورد پایدار و ۵۷ فایل media است: ```text production-seed/ data.json.gz media.tar.gz manifest.json ``` این پوشه شامل اطلاعات شخصی و password hash است و عمداً توسط Git و Docker ignore می‌شود. آن را commit، ایمیل یا در فضای عمومی بارگذاری نکنید. ## انتقال امن به volume سرور در Coolify volume خارجی `customer_ticket_seed` را ایجاد کنید. سه فایل بالا باید مستقیماً در ریشه آن قرار بگیرند، به شکلی که container مسیر زیر را ببیند: ```text /app/production-seed/manifest.json /app/production-seed/data.json.gz /app/production-seed/media.tar.gz ``` فایل‌ها را با قابلیت Persistent Storage/File Mount خود Coolify یا یک انتقال امن مانند SCP به سرور ببرید. اگر روی سرور در `/tmp/customer-ticket-seed` قرار گرفته‌اند، مدیر سرور می‌تواند volume را این‌گونه پر کند: ```bash docker run --rm \ -v customer_ticket_seed:/target \ -v /tmp/customer-ticket-seed:/source:ro \ alpine:3.20 sh -c 'cp /source/data.json.gz /source/media.tar.gz /source/manifest.json /target/' ``` پس از کپی، نسخه موجود در `/tmp` را امن حذف کنید. volume seed در Compose فقط read-only داخل web mount می‌شود. ## اجرای خودکار در اولین startup سرویس web ترتیب زیر اجرا می‌شود: 1. انتظار برای PostgreSQL 2. اجرای migrationها 3. اعتبارسنجی SHA-256 فایل‌های seed 4. اطمینان از خالی بودن PostgreSQL و media volume 5. حذف defaultهای data migration و import کامل snapshot 6. انتقال media به volume اصلی 7. ثبت `ProductionSeedState` 8. رد کردن `bootstrap` برای حفظ دقیق snapshot به‌عنوان منبع authoritative 9. اجرای `collectstatic` و Gunicorn در deployهای بعدی ابتدا marker دیتابیسی `ProductionSeedState` بررسی می‌شود. اگر marker وجود داشته باشد، فرمان import اصلاً اجرا نمی‌شود و نبودن bundle نیز مانع startup نخواهد شد. `REQUIRE_PRODUCTION_SEED=1` فقط تا پیش از اولین import موفق الزام‌آور است. ## محدودیت‌های ایمنی - import فقط روی PostgreSQL اجرا می‌شود. - دیتابیس دارای User یا seed قبلی با checksum متفاوت پذیرفته نمی‌شود. - media volume غیرخالی overwrite نمی‌شود. - مسیرهای مشکوک، symlink و path traversal در archive رد می‌شوند. - checksum هر دو فایل پیش از هر تغییر بررسی می‌شود. - شکست import باعث rollback دیتابیس و حذف فایل‌های کپی‌شده همان اجرا می‌شود. اگر واقعاً می‌خواهید production بدون snapshot بالا بیاید، `REQUIRE_PRODUCTION_SEED=0` بگذارید؛ در این حالت فقط bootstrap استاندارد اجرا می‌شود و کاربران دارای password فعلی SQLite منتقل نخواهند شد.