Wire production domain, CORS for tenant subdomains, celery volume mounts, and nginx reverse proxy configs for apex, API, identity, auth, and wildcard tenants. Co-authored-by: Cursor <cursoragent@cursor.com>
6.4 KiB
آخرین گام انجامشده
فاز ۴ — Tenant Onboarding و Workspace Activation
در بریف پروژه این کار «Phase 3: operationalizing tenant onboarding and workspace activation» نامیده شده؛ در شمارهگذاری داخلی مستندات، چون «فاز ۳» قبلاً به OTP Login + Tenant Management اختصاص داشت، این تحویل فاز ۴ ثبت شده است (نگاه کنید به
progress.md).
مسئله
تا پیش از این فاز، سیستم فقط «هویت + لیست ادمین» بود: کاربر با OTP/SSO وارد میشد و از پنل ادمین tenantها را میدید/میساخت، اما هیچ جریان واقعی self-service برای اینکه یک کاربر عادی workspace خودش را بسازد، مالک آن شود، پلن/دامنه/برندینگ بگیرد و وارد یک داشبورد عملیاتی شود، وجود نداشت.
راهحل
Backend (core-service):
- جدول جدید
tenant_memberships(نقشtenant_owner/tenant_admin/tenant_editor/tenant_viewer/platform_admin، وضعیتactive/invited/disabled،is_owner). - چرخهٔ عمر tenant:
draft → pending_activation → active → suspended/archived. - ستونهای برندینگ/پروفایل روی
tenants+is_primary/verification_statusرویdomains+current_tenant_idرویusers. - Seed پلنهای
FREE/STARTERو اتصال خودکار اشتراکFREEهنگام ساخت tenant. - سرویسهای جدید:
UserService(یکپارچهسازی resolve کاربر از JWT محلی یا کیکلوک)،MembershipService،OnboardingService،TenantContextService. - APIهای جدید:
GET /me,GET /me/tenants,POST /onboarding/tenant,PATCH .../branding,PATCH .../domain,POST .../complete,GET /tenant/current,POST /tenant/switch. - Migration
0005_tenant_onboarding+ تستهایtest_onboarding.py(۷ تست، جریان کامل + حالات forbidden/duplicate/owner-required).
Frontend (frontend):
lib/api.tsباapi.me/api.onboarding/api.tenantContext.hooks/useMe.tsبرای بارگذاری/api/v1/me.app/onboarding/page.tsx— ویزارد ۴ مرحلهای (کسبوکار → برندینگ → دامنه → بازبینی) با قابلیت ازسرگیری onboarding ناتمام.app/dashboard/page.tsx— داشبورد واقعی workspace + redirect خودکار به/onboardingوقتیonboarding_required=true.components/TenantSwitcher.tsx— سوییچر ساده چند-workspace.
محدودیتهای عمدی این فاز (خارج از scope)
- بدون درگاه پرداخت — فقط ساختار provisioning پلن/اشتراک.
- بدون تأیید واقعی DNS برای دامنهٔ اختصاصی (فقط رکورد
pending). - مسیر قدیمی
POST /admin/tenants(فاز ۱/۲) بازنویسی نشده و هنوز عضویت/پلن خودکار نمیسازد — عمداً دستنخورده ماند تا فازهای قبلی بازسازی نشوند. - JIT provisioning کامل کاربر Core از JWT کیکلوک پیاده نشده (کاربر SSO بدون
رکورد Core فعلاً
403 forbiddenمیگیرد؛ نگاه کنید به بخش بعد).
فاز پیشنهادی بعدی: White-label Runtime Rendering
چرا این فاز و نه یک ماژول بیزینسی؟
در همین فاز، فیلدهای برندینگ واقعی (primary_color, secondary_color,
logo_url, favicon_url) روی هر tenant ذخیره و در onboarding از کاربر
گرفته میشوند — اما frontend فعلاً رنگها را فقط از یک فایل استاتیک
(public/theme.config.json) میخواند و هیچ ارتباطی با tenant واقعی
resolveشده ندارد. یعنی خروجی onboarding (برندینگ tenant) هنوز در UI
اعمال نمیشود. تکمیل این حلقه (ذخیره برند → نمایش برند) از نظر ارزش محصول
و آمادگی فنی، اولویت بالاتری نسبت به شروع اولین ماژول بیزینسی (Accounting/
CRM/...) دارد؛ چون:
- زیرساخت لازم (فیلدهای دیتابیس، APIهای
TenantContextRead، CSS Variables موجود در frontend) از قبل آماده است — فقط باید به هم وصل شوند. - بدون این حلقه، ادعای «SaaS چندمستأجری white-label» ناقص میماند، در حالی که هر ماژول بیزینسی جدید (Accounting/CRM/...) به خودی خود به این زیرساخت وابسته نیست.
- حل تشخیص tenant از دامنه (subdomain/custom domain) که برای white-label لازم است، پیشنیاز طبیعی معماری چندمستأجری برای هر ماژول آینده نیز هست.
پیشنهاد Scope فاز بعدی
- Backend: endpoint عمومی (بدون نیاز به auth کاربر) برای resolve
theme بر اساس Host/X-Tenant-Slug، مثلاً
GET /api/v1/public/tenant-themeکهprimary_color,secondary_color,logo_url,favicon_url,business_nameرا برمیگرداند (از همان middleware تشخیص tenant موجود استفاده کند). - Frontend: بارگذاری theme از این endpoint در
ThemeProviderهنگام دسترسی از subdomain/custom domain یک tenant (بهجای/علاوهبرtheme.config.jsonاستاتیک فعلی که برای برند اصلی پلتفرم باقی میماند). - مسیر عمومی مشتری/ویزیتور tenant (بدون نیاز به لاگین) که برند tenant را میبیند — زیرساخت لازم برای هر ماژول بیزینسی آینده (مثلاً منوی دیجیتال رستوران) که باید در دامنهٔ tenant با ظاهر آن tenant نمایش داده شود.
- بعد از این فاز، اولین ماژول بیزینسی واقعی (پیشنهاد: «رستوران / منوی
دیجیتال» چون در
docs/architecture.mdبهعنوان سرویس فعلی نامبرده شده و دیتابیس مفهومی آن (restaurant_db) از قبل طراحی شده) روی همین زیرساخت white-label ساخته شود.