ساختار مالکیت پلتفرم: یک مالک، مدیرانِ ساختهٔ مالک، سازمانهای مدیریتشده
- users.is_platform_owner → users.platform_role (owner|manager|user) با مهاجرت d4e5f6a7b8c9 و backfill. ایندکس یکتای جزئی uq_single_platform_owner تضمین میکند دقیقاً یک مالک وجود داشته باشد — در سطح دیتابیس، نه فقط در کد. - ثبتنام عمومی حذف شد (POST /auth/signup). حسابها فقط با POST /admin/users (فقط مالک، با رمز موقت یکبارمصرف) یا با پذیرش لینک دعوت ساخته میشوند. در مسیر دعوت، اگر حساب وجود نداشته باشد خودِ دعوتشده رمز تعیین میکند؛ اگر وجود داشته باشد لینک هرگز جای reset رمز را نمیگیرد. - ساخت سازمان فقط برای مالک و مدیران؛ کاربر عادی با دعوت عضو میشود. - تنزل یا حذف مدیر، سازمانهایش را به مالک سامانه منتقل میکند (مالکیت + عضویت، با audit). حساب مالک از API تغییرناپذیر است؛ جابهجایی صندلی فقط با POST /admin/transfer-ownership و در یک تراکنش انجام میشود. - افزودن POST /auth/change-password برای تبدیل رمز موقت به رمز خصوصی. - فرانت: صفحهٔ /admin/users، صفحهٔ /account، بازنویسی /accept-invite، حذف /signup، گارد /onboarding برای کاربر عادی، و نشان نقش پلتفرم در پوستهٔ اپ. - PRAGMA foreign_keys=ON برای SQLite تا ON DELETE CASCADE در dev و prod یکسان رفتار کند (پیشتر حذف کاربر، عضویتهایش را یتیم میگذاشت). - تست: ۳۰۰ تست بکاند (شامل tests/test_platform_hierarchy.py با ۲۲ تست) و ۶۴ تست فرانتاند؛ ruff، mypy، tsc، eslint و build تمیز.
This commit is contained in:
@@ -162,15 +162,19 @@ CORS را تنظیم میکند.
|
||||
|
||||
Next.js App Router با دو ناحیهٔ مسیر:
|
||||
|
||||
**ناحیهٔ عمومی (بدون احراز هویت):** `/login`, `/signup`, `/onboarding`
|
||||
**ناحیهٔ عمومی (بدون احراز هویت):** `/login`, `/accept-invite`, `/onboarding`
|
||||
|
||||
> `/signup` وجود ندارد: ثبتنام عمومی بسته است و حسابها فقط توسط مالک سامانه یا
|
||||
> با پذیرش لینک دعوت ساخته میشوند.
|
||||
|
||||
**ناحیهٔ اپلیکیشن (`(app)` — نیازمند نشست):**
|
||||
`/dashboard`, `/workforce`, `/workforce/[id]`, `/manager`, `/tasks`,
|
||||
`/tasks/[id]`, `/projects`, `/projects/[id]`, `/knowledge`, `/billing`,
|
||||
`/settings`, `/traces`
|
||||
|
||||
**ناحیهٔ مالک سامانه:** `/admin`, `/admin/providers`, `/admin/models`,
|
||||
`/admin/routing`, `/admin/rate-cards`, `/admin/organizations`, `/admin/errors`
|
||||
**ناحیهٔ مالک سامانه:** `/admin`, `/admin/users`, `/admin/agy-accounts`,
|
||||
`/admin/models`, `/admin/routing`, `/admin/rate-cards`, `/admin/organizations`,
|
||||
`/admin/usage`, `/admin/errors`
|
||||
|
||||
**دو نقطهٔ اتصال مرکزی:**
|
||||
|
||||
@@ -236,11 +240,13 @@ storage/artifact، tool call) یک رکورد در ledger میگذارد با
|
||||
|
||||
## ۹. تست
|
||||
|
||||
**بکاند (`apps/api/tests/`)** — ۲۱۶ تست:
|
||||
**بکاند (`apps/api/tests/`)** — ۳۰۰ تست:
|
||||
|
||||
| فایل | چه چیزی را میسنجد |
|
||||
| --- | --- |
|
||||
| `test_auth.py` | ثبتنام، ورود، نشست، نشتنداشتن hash |
|
||||
| `test_auth.py` | ورود، نشست، تغییر رمز، بستهبودن ثبتنام، نشتنداشتن hash |
|
||||
| `test_platform_hierarchy.py` | یکتایی مالک، گارد ساخت سازمان، ساخت مدیر توسط مالک، انتقال سازمان هنگام تنزل/حذف مدیر، انتقال مالکیت |
|
||||
| `test_invites.py` | دعوت، پیشنمایش ناشناس، ساخت حساب از لینک، رد reset رمز با لینک |
|
||||
| `test_tenant_isolation.py` | جداسازی مستأجر، ۴۰۴ بهجای ۴۰۳، دعوت |
|
||||
| `test_admin_control_plane.py` | دسترسی مالک سامانه، mask شدن کلید |
|
||||
| `test_platform_rules.py` | برچسب دامنه، ضدتزریق host، ضدSSRF، پورتها |
|
||||
|
||||
Reference in New Issue
Block a user