ساختار مالکیت پلتفرم: یک مالک، مدیرانِ ساختهٔ مالک، سازمانهای مدیریتشده
- 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:
@@ -15,13 +15,31 @@ class AuditAction:
|
||||
LOGIN = "auth.login"
|
||||
LOGOUT = "auth.logout"
|
||||
SIGNUP = "auth.signup"
|
||||
#: A user changed their own password (or an owner-forced temp password was
|
||||
#: replaced). Auditable because it is the one action that can lock the
|
||||
#: legitimate owner out.
|
||||
PASSWORD_CHANGE = "auth.password_change"
|
||||
ORG_CREATE = "organization.create"
|
||||
ORG_DELETE = "organization.delete"
|
||||
#: An organization changed hands because its owning manager was demoted or
|
||||
#: deleted — the platform owner takes over. Never automatic for any other
|
||||
#: reason.
|
||||
ORG_OWNER_TRANSFER = "organization.owner_transfer"
|
||||
MEMBER_INVITE = "member.invite"
|
||||
#: An invited user redeemed their token and joined the organization.
|
||||
MEMBER_JOIN = "member.join"
|
||||
MEMBER_ROLE_CHANGE = "member.role_change"
|
||||
MEMBER_REMOVE = "member.remove"
|
||||
#: The platform owner created an account (manager or plain user).
|
||||
USER_CREATE = "user.create"
|
||||
#: A user's platform role changed (user <-> manager, or manager -> user).
|
||||
USER_PLATFORM_ROLE_CHANGE = "user.platform_role_change"
|
||||
#: An account was activated or deactivated.
|
||||
USER_ACTIVE_CHANGE = "user.active_change"
|
||||
#: An account was deleted by the platform owner.
|
||||
USER_DELETE = "user.delete"
|
||||
#: The single platform-owner seat moved to another account.
|
||||
OWNERSHIP_TRANSFER = "platform.ownership_transfer"
|
||||
EMPLOYEE_CREATE = "employee.create"
|
||||
EMPLOYEE_UPDATE = "employee.update"
|
||||
REPO_CREATE = "repo.create"
|
||||
|
||||
Reference in New Issue
Block a user