.cursor/skills/nazim-multi-tenancy/SKILL.md
Enforces organization and school isolation for the Nazim multi-tenant SaaS. Use when adding tables, hooks, API calls, controllers, or storage paths. Covers organization_id, school_id, query keys, getCurrentSchoolId(), and RLS.
npx skillsauth add AHMADJAN-New/nazim-web nazim-multi-tenancyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
The Nazim app is a multi-tenant SaaS. Every tenant table, hook, API call, and controller must enforce organization and school isolation.
organization_id + school_id (for school-scoped)queryKey includes profile?.organization_id AND profile?.default_school_idorganization_id and school_idgetCurrentSchoolId($request) — never trust client school_idorganization_id (and school_id when applicable)queryKey: ['resource', profile?.organization_id, profile?.default_school_id ?? null, ...otherKeys]
await apiClient.resource.list({
organization_id: profile.organization_id,
school_id: profile.default_school_id,
});
enabled: !!user && !!profile && !!profile.organization_id && !!profile.default_school_id
profile.organization_id and profile.default_school_id (ignore client values)organization_id matches; reject organization_id changes$profile = DB::table('profiles')->where('id', $user->id)->first();
if (!$profile || !$profile->organization_id) {
return response()->json(['error' => 'User must be assigned to an organization'], 403);
}
$currentSchoolId = $this->getCurrentSchoolId($request); // From middleware, NOT client
$query = YourModel::whereNull('deleted_at')
->where('organization_id', $profile->organization_id)
->where('school_id', $currentSchoolId);
current_school_id from request (injected by school.context middleware)school_id for filteringorganization_id UUID NOT NULL, school_id UUID (school-scoped)organization_id and school_idorganization_id = (SELECT organization_id FROM profiles WHERE id = auth.uid())organization_id (and school_id if school-scoped)default_school_idschool_idgetCurrentSchoolId() not client school_idtools
Toast notifications for Nazim. Use when showing success/error/info messages. ALWAYS use showToast from @/lib/toast with translation keys; never toast from sonner directly. RTL positioning is automatic.
tools
Enforces status badge patterns for Nazim UI. Use when displaying status in tables, cards, or dialogs. Covers Badge variants, semantic colors, statusBadgeVariant, statusOptions with color.
development
Enforces mobile-first responsive patterns for Nazim UI. Use when building pages, tables, forms, charts, or buttons. Covers page container, FilterPanel, tabs, grids, tables, charts, cards, buttons.
development
PDF and Excel report generation for Nazim. Use when adding or changing reports. Backend uses ReportService and ReportConfig; frontend uses useServerReport. Covers branding, DateConversionService, RTL, acceptance criteria.