AdminUser held both panel staff and sales experts, so one mobile could not be both. Staff now live in "Admin" (panel only); sales experts stay in "AdminUser" untouched. Uniqueness is per table. - migration 20261026120000_split_admin_table: additive only. Creates "Admin", copies non-expert rows with their ids, re-points the "who did this" foreign keys (ledger, order status, sms, notification, upload, allocation, workshop, admin session) to "Admin" without moving data. Never writes to "AdminUser". - login, JWT, SSO, branch/workshop supervisors and the users grid use "Admin"; SALES_EXPERT create/edit still goes through admin/users into "AdminUser". - an admin cannot be turned into an expert or the reverse (different tables). - manual/: optional phase-2 script to drop the dormant admin copies from "AdminUser", and a read-only expert-login diagnostic. - docs/ADMIN-TABLE-SPLIT.md: what changed, deploy checklist, rollback. Tested on a copy with 12,000 experts: expert rows byte-identical (md5) before and after; full migration chain applies and matches schema.prisma. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
5.6 KiB
جدا شدن جدول ادمینها از کارشناسان فروش
چه چیزی عوض شد
| قبل | بعد | |
|---|---|---|
| پرسنل پنل (مدیر ارشد، تأییدکننده، سرپرست کارگاه، حسابدار) | جدول AdminUser |
جدول جدید Admin |
| کارشناس فروش | جدول AdminUser |
جدول AdminUser (بدون هیچ تغییری) |
| یکتایی شماره موبایل | یک شماره = فقط یک نقش | یکتا در هر جدول جدا؛ یک شماره میتواند هم ادمین باشد هم کارشناس |
ادمین فقط برای پنل است. کارشناس فقط برای اپها. توکن اپ کارشناس هیچوقت به پنل دسترسی نمیدهد
(JwtStrategy فقط در Admin میگردد).
مایگریشن — 20261026120000_split_admin_table
فقط افزودنی است. به AdminUser (کارشناسها) چیزی نمینویسد، حذف نمیکند و قفل نمیکند.
- جدول
Adminرا میسازد. - ردیفهای غیرکارشناس
AdminUserرا با همانidدرAdminکپی میکند (توکنهای صادرشده و همهٔ ستونهای «چه کسی انجام داد» معتبر میمانند). - کلید خارجیهای «ثبتکننده» را از
AdminUserبهAdminمنتقل میکند. نام ستونها و دیتا عوض نمیشود، فقط مقصد constraint:LedgerEntry.postedByAdminUserId،OrderStatusEventوPreOrderStatusEvent.actorAdminUserId،BranchAllocation.allocatorAdminUserId،SmsMessageوNotification.sentByAdminUserId،UploadedFile.uploadedByAdminUserId،Workshop.supervisorId،AdminSession.adminUserId. - بهصورت
NOT VALIDاضافه و بعد validate میشوند؛ اگر ردیف قدیمیای به id غیرادمین اشاره کند، deploy شکست نمیخورد و فقط یکNOTICEچاپ میشود.
بدون تغییر ماندند (چون دربارهٔ کارشناساند): Order.salesAgentId، Customer.referredByAgentId،
SalesExpertProfile.adminUserId.
قابل اجرای مجدد است (idempotent).
آزمایششده روی
کپی دیتابیس با ۱۲۰۰۰ کارشناس: چکسام (md5) تمام ردیفهای SALES_EXPERT قبل و بعد از مایگریشن یکسان بود.
زنجیرهٔ کامل مایگریشنها روی دیتابیس خالی اجرا شد و prisma migrate diff هیچ اختلافی بین schema.prisma
و دیتابیس نشان نداد.
قبل از دیپلوی روی سرور اصلی
- از دیتابیس بکاپ بگیرید.
- (اختیاری، فقطخواندنی) ببینید ردیفی هست که به id غیرادمین اشاره کند؛ برای هر جدول:
-- نمونه برای دفتر حساب؛ برای بقیهٔ جدولها/ستونها همین الگو
SELECT count(*) FROM "LedgerEntry" l
WHERE l."postedByAdminUserId" IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM "Admin" a WHERE a."id" = l."postedByAdminUserId");
قبل از اجرای مایگریشن Admin هنوز وجود ندارد؛ این کوئری را بعد از دیپلوی بزنید. جواب 0 یعنی همه چیز سالم است.
3. ابتدا مایگریشن (با بوت شدن API جدید خودکار اجرا میشود)، سپس همان کد.
چون additive است، کد قدیمی در فاصله هم کار میکند.
یک محدودیت تا «فاز ۲»
ردیفهای قدیمی ادمینها در AdminUser باقی میمانند (غیرفعال، بدون استفاده در کد). شمارهٔ آنها هنوز در
AdminUser قفل است، پس برای ادمینهای موجود ساختن کارشناس با همان شماره خطای «قبلاً ثبت شده» میدهد.
(ادمینهای تازهساخته و شمارههای جدید مشکلی ندارند.)
برای آزاد کردن آن شمارهها، بعد از اطمینان از درستی کار:
apps/api/prisma/manual/20261026_remove_dormant_admin_rows.sql
— دستی است، عمداً داخل migrations/ نیست، فقط ردیفهای غیرکارشناس را که در Admin کپی دارند حذف میکند،
و اگر تعداد کارشناسها یک عدد هم تغییر کند خودش rollback میکند.
برگشت (Rollback)
کد قبلی را دوباره deploy کنید. چیزی حذف نشده، پس کد قدیمی همهٔ ادمینهای پیشین را در AdminUser پیدا میکند.
ادمینهایی که بعد از جدا شدن ساخته شدهاند فقط در Admin هستند و باید دوباره ساخته شوند.
تغییر رفتار پنل
- جدول «کاربران» فقط ادمینها را نشان میدهد؛ کارشناسها از بخش کارشناسان.
- نقش «کارشناس فروش» از لیست نقشهای فرم ادمین حذف شد؛ فرم کارشناس همان
POST admin/usersرا باrole: SALES_EXPERTمیزند و درAdminUserساخته میشود. - نقش یک ادمین به کارشناس (و برعکس) قابل تغییر نیست، چون دو جدول جدا هستند.
- کارشناس دیگر نمیتواند با رمز خودش وارد پنل شود (قبلاً چون در همان جدول بود، میتوانست).