feat(permissions): render both permission forms from the catalog, fix borrowed gates
The three hardcoded resource lists in the admin panel are gone. MySecretariesPage, SecretariesPage and DoctorPermissionsModal now render from GET /api/v1/permission-catalog, so a resource added to the backend registry shows up in all of them with no frontend change. Each has a test that proves exactly that by adding a resource to the mock and asserting it renders. SecretaryPermissions was an interface with a field per resource, which made "dynamic" impossible in TypeScript — every new resource would have been a compile error. It is now an open map. Only two files consumed it. The borrowed gates are corrected: - five resource pages moved off appointment_settings onto their own 'resources' - treatment-cases moved off appointments onto 'treatment' - service-categories moved onto 'services', which is what ServiceCatalogController actually manages (categories, item groups, service relations) — not resources TreatmentCaseController had no permission gate at all, only IS_AUTHENTICATED_FULLY, so any secretary could read and edit treatment cases. All seven of its actions are now gated on treatment view/update. ResourcePermissionTrait takes the resource from an overridable method instead of hardcoding appointment_settings. HolidayController overrides it back, since the holidays page really is appointment settings. The booking gate keeps its appointments.view fallback so a secretary who may book is not blocked by a resource-config permission. Defaults were picked to preserve today's effective access, so no role gains or loses a page from this move. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -297,16 +297,16 @@ export default function App() {
|
||||
<Route path="clinic-services" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['services', 'view']}><ClinicServicesPage /></RoleRoute>} />
|
||||
<Route path="clinic-services/:uuid" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['services', 'view']}><ServiceDetailPage /></RoleRoute>} />
|
||||
<Route path="inventory" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['inventory', 'view']}><InventoryPage /></RoleRoute>} />
|
||||
<Route path="treatment-cases" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} permission={['appointments', 'view']}><TreatmentCasesPage /></RoleRoute>} />
|
||||
<Route path="treatment-cases" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} permission={['treatment', 'view']}><TreatmentCasesPage /></RoleRoute>} />
|
||||
<Route path="settings/practice-domain" element={<RoleRoute roles={['clinic']} permission={['appointment_settings', 'view']}><PracticeDomainSettingsPage /></RoleRoute>} />
|
||||
<Route path="practice-domains" element={<RoleRoute roles={['admin']}><AdminPracticeDomainsPage /></RoleRoute>} />
|
||||
<Route path="service-categories" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['appointment_settings', 'view']}><CatalogCategoriesPage /></RoleRoute>} />
|
||||
<Route path="service-categories" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['services', 'view']}><CatalogCategoriesPage /></RoleRoute>} />
|
||||
<Route path="resource-booking" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['appointments', 'create']}><ResourceBookingPage /></RoleRoute>} />
|
||||
<Route path="resources" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['appointment_settings', 'view']}><ResourcesPage /></RoleRoute>} />
|
||||
<Route path="resources/types" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['appointment_settings', 'view']}><ResourceTypesPage /></RoleRoute>} />
|
||||
<Route path="resources/skills" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['appointment_settings', 'view']}><SkillsPage /></RoleRoute>} />
|
||||
<Route path="resources/pools" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['appointment_settings', 'view']}><ResourcePoolsPage /></RoleRoute>} />
|
||||
<Route path="resources/:resourceUuid" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['appointment_settings', 'view']}><ResourceDetailPage /></RoleRoute>} />
|
||||
<Route path="resources" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['resources', 'view']}><ResourcesPage /></RoleRoute>} />
|
||||
<Route path="resources/types" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['resources', 'view']}><ResourceTypesPage /></RoleRoute>} />
|
||||
<Route path="resources/skills" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['resources', 'view']}><SkillsPage /></RoleRoute>} />
|
||||
<Route path="resources/pools" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['resources', 'view']}><ResourcePoolsPage /></RoleRoute>} />
|
||||
<Route path="resources/:resourceUuid" element={<RoleRoute roles={['doctor', 'clinic', 'secretary']} blockClinicScope permission={['resources', 'view']}><ResourceDetailPage /></RoleRoute>} />
|
||||
{/* تقویم منبع در تب «ساعات کاری» همان صفحه حل شده؛ لینکهای قدیمی نباید بشکنند. */}
|
||||
<Route path="resources/:resourceUuid/calendar" element={<ResourceCalendarRedirect />} />
|
||||
{/* تقویم رسمی کشور — فقط مدیر سیستم. /holidays مالِ محیط است و فقط استثنا میزند. */}
|
||||
|
||||
Reference in New Issue
Block a user