«فلان دکمه را نمیبینم» — بلیت پشتیبانی شمارهٔ ۲۰۰
وقتی قابلیتهای جدید بدون طراحی دسترسی اضافه میشوند، راهحل موقت همیشه یکی است: گرنت مدیر مشترک برای دور زدن مشکل. چند ماه بعد، هیچکس نمیداند چرا فلان پیمانکار به مالی کل سازمان دسترسی دارد یا چرا فلان عضو تیم دکمهٔ تأیید را نمیبیند.
طراحی مجوز دسترسی ویژگی یعنی پیش از انتشار هر قابلیت، نگاشت کلید ویژگی ↔ مسیر (route) ↔ نقش را روی کاغذ یا در ویکی بنویسید — نه پس از اولین بلیت پشتیبانی.
علائم و هزینهٔ دسترسی درهمریخته
| علامت | هزینه |
|---|---|
| بررسی نقش بهصورت hardcode در کد هندلر | ناهماهنگی بین فرانتاند و بکاند |
| کلید دسترسی بیشازحد ریز | بار مدیریتی روی ادمین |
| کلید دسترسی خیلی درشت | افشای اطلاعات به کاربر نامناسب |
| کش دسترسی ۶۰ ثانیهای کهنه | سردرگمی کوتاهمدت بعد از تغییر نقش |
چارچوب ۷ مرحلهای طراحی دسترسی
۱. فهرست پرسوناها
مدیر پروژه، توسعهدهنده، مسئول مالی، پیمانکار، مشتری — هر پرسونا نیاز دسترسی متفاوتی دارد و باید قبل از هر چیز نامگذاری شود.
۲. اقدام به ازای هر پرسونا
برای هر پرسونا مشخص کنید که مشاهده، ویرایش، تأیید یا دسترسی مالی لازم است — این تصمیم باید قبل از نوشتن کد گرفته شود، نه در حین رفع اشکال.
۳. قرارداد نامگذاری کلید ویژگی
الگوی DOMAIN_ACTION را ثابت نگه دارید — مثل TASK_VIEW، FINANCE_GLOBAL_VIEW، DOCUMENTS_VIEW. یک قاعدهٔ یکنواخت یعنی توسعهدهندهٔ بعدی برای حدس زدن نام کلید وقت تلف نمیکند.
۴. ثبت در routes.json
backend/routes.json منبع واحد حقیقت است. میانافزار FeatureAccess هر مسیر را به کلید ویژگی مربوطه نگاشت میکند — بهجای شرطهای پراکنده و ناسازگار در هندلرهای مختلف.
۵. آینهٔ FeatureGuard در رابط کاربری
اگر بکاند دسترسی را رد میکند اما دکمه هنوز در رابط کاربری دیده میشود، کاربر روی چیزی کلیک میکند که قرار است رد شود — تجربهٔ بدی میسازد. کامپوننت FeatureGuard همان کلید ویژگی را پیش از رندر بررسی میکند تا این «طعنهٔ دکمه» رخ ندهد.
۶. نقشهای پیشفرض به ازای قالب پروژه
پروژهٔ جدید باید با نقشهای پیشفرض معقول (مدیر، عضو، بیننده) بالا بیاید — نه با یک صفحهٔ خالی که هر بار باید از نو تنظیم شود.
۷. ماتریس تست
برای هر ترکیب نقش × کلید ویژگی، یک وضعیت مجاز/غیرمجاز مشخص باشد. حداقل مسیرهای حساس — مالی، تأیید تسک، سند — باید در تست خودکار پوشش داده شوند تا رگرسیون دسترسی زود دیده شود، نه بعد از شکایت مشتری.
سناریوهای رایج در طراحی دسترسی
تیم با پیمانکار موقت. پیمانکار باید فقط تسکهای همان پروژه را ببیند — نه مالی کل سازمان و نه پروژههای دیگر. نقش «پیمانکار» با کلیدهای محدود، نه یک حساب ادمین موقت.
مشتری فقطخواندنی. مشتری باید بتواند پیشرفت را ببیند اما نتواند تسک را ویرایش یا حذف کند — کلید مشاهده جدا از کلید ویرایش تعریف شود.
تیم مالی جدا از تیم فنی. FINANCE_GLOBAL_VIEW فقط برای نقش مالی و مدیر پروژه فعال باشد، نه برای همهٔ اعضای پیشفرض تیم.
الگوهای ضدِمقابل — این کارها را نکنید
- گرنت ادمین مشترک برای دور زدن یک مجوز کند
- کلید ویژگی که در کد استفاده میشود اما هرگز در
routes.jsonثبت نشده - دکمهای که در رابط کاربری نشان داده میشود ولی بکاند همیشه آن را رد میکند (نبود
FeatureGuard) - تغییر دسترسی که بدون توضیح تا ۶۰ ثانیه در کش قدیمی باقی میماند و کاربر فکر میکند سیستم خراب است
نقش WKFGo
WKFGo دسترسی را حول مدل FeatureAccess میسازد: هر رکورد یک (projectId, featureKey, entityType, entityId) است که میتواند به کاربر یا تیم اختصاص یابد. backend/routes.json نگاشت مسیر به کلید ویژگی را نگه میدارد و میانافزار آن را در هر درخواست بررسی میکند. در رابط کاربری، پنل مجوزهای صفحهٔ Users و کامپوننت FeatureGuard همان کلیدها را آینه میکنند تا فرانت و بکاند هرگز از هم جدا نیفتند.
کش دسترسی با TTL شصتثانیهای اجرا میشود؛ در استقرار چندنمونهای، سوییچ REALTIME_CROSS_INSTANCE یک باس ابطال کش روی Postgres LISTEN/NOTIFY فعال میکند تا تغییر مجوز بلافاصله در همهٔ نمونهها اثر بگذارد، نه با تأخیر تا ۶۰ ثانیه. SUPER_ADMIN از این قوانین عبور میکند، اما این عبور باید استثنا باقی بماند، نه الگوی پیشفرض رفع مشکل.
همین هفته شروع کنید
یک قابلیت واقعی را انتخاب کنید که اخیراً دچار مشکل دسترسی شده — پیمانکاری که بیش از حد دید، یا عضوی که دکمهٔ لازم را ندید. پرسوناها را فهرست کنید، کلید ویژگی مناسب را طبق قرارداد DOMAIN_ACTION نامگذاری کنید، آن را در routes.json ثبت کنید و FeatureGuard متناظر را در رابط کاربری اضافه کنید. سپس با یک حساب پیمانکاری واقعی تست کنید — نه با حساب ادمین خودتان.
نتیجه را در ویکی پروژه ثبت کنید تا توسعهدهندهٔ بعدی برای قابلیت مشابه از صفر شروع نکند.
FAQ
کلید ویژگی به ازای هر دکمه تعریف میشود؟
نه — درشتتر از آن. کلید به ازای هر ناحیهٔ قابلیت تعریف میشود، نه هر عنصر تکی رابط کاربری.
دسترسی روی تیم بهتر است یا روی کاربر؟
هر دو کار میکنند و مکمل هماند — نقش پایه روی تیم تعریف میشود و استثنای فردی روی کاربر مشخص اعمال میشود.
SUPER_ADMIN از همهٔ این قوانین عبور میکند؟
بله، اما این عبور باید قابل ممیزی باشد و بهعنوان استثنای مستند شده، نه رفتار روزمره.
در تناقض، deny برنده میشود یا allow؟
باید صریح طراحی شود؛ معمولاً فهرست مجاز (allow-list) پیشفرض امنتری است تا فراموشیِ یک قانون منجر به افشای اطلاعات نشود.