skills/vendix-permissions/SKILL.md
Backend RBAC permission rows, @Permissions decorators, and PermissionsGuard behavior. Trigger: When adding permissions, editing @Permissions decorators, seeding roles/permissions, or distinguishing authorization from panel_ui visibility.
npx skillsauth add rzyfront/vendix vendix-permissionsInstall 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.
Use this skill for backend authorization. Permissions protect API operations; they do not control sidebar visibility.
PermissionsGuard authorizes when either route/method permission or named permission matches.
Real behavior:
name, path, method, and status.currentPath === permission.path or currentPath.startsWith(permission.path), method matches, and status is active.@Permissions(...) name exists in active user permissions.Key files:
apps/backend/src/domains/auth/guards/permissions.guard.tsapps/backend/src/domains/auth/decorators/permissions.decorator.tsapps/backend/src/domains/auth/strategies/jwt.strategy.tsapps/backend/prisma/seeds/permissions-roles.seed.tspermissions rows have both name and route metadata:
{
name: 'store:products:create',
description: 'Create product',
path: '/api/store/products',
method: 'POST',
status: 'active'
}
Database constraints include unique name and unique [path, method].
Existing permissions use mixed historical formats:
store:products:createorganization:users:updatesuperadmin:subscriptions:plans:readsubscriptions:readauth.loginauth:sessionsPrefer domain:resource:action or domain:resource:subresource:action for new permissions unless updating an existing domain with a local convention.
Add or update @Permissions('permission:name') on the protected controller/handler.
Add or update the row in apps/backend/prisma/seeds/permissions-roles.seed.ts.
Ensure path includes the API route shape expected by PermissionsGuard.
Ensure method matches the HTTP method or uses ALL only when intentional.
Assign the permission to the correct role(s) in the seed.
Treat seed cleanup as data-impacting: removed seed permissions may be removed/deprecated from DB by seed logic.
Run the seed. Editing the seed file alone does NOT grant the permission — the row only exists in code until the seed runs against the DB. After committing the seed change you MUST re-run it:
# Standalone module run (preferred — avoids touching users/orgs/etc.)
docker exec -e NODE_OPTIONS="--max-old-space-size=4096" vendix_backend \
npx ts-node -e "import('./prisma/seeds/permissions-roles.seed').then(m => m.seedPermissionsAndRoles())"
# Full seed (idempotent but heavier)
docker exec vendix_backend npm run seed
The seed is additive: it never deletes role assignments (uses syncRolePermissions with additive-only mode), so it is safe to re-run in dev. In production, run it via the deploy pipeline alongside the migration.
No re-login required for users. JwtStrategy.validate() re-reads user.permissions from the DB on every request — once the row exists, the next API call sees it.
Symptom: 403 AUTH_PERM_001 on the new endpoint, even for owner / super_admin.
Cause: the seed defines the row in code but the DB does not have it yet. PermissionsGuard evaluates user.permissions (loaded from DB by JwtStrategy) — empty match → deny.
Fix: run the seed (step 7 above). Then retry the API call (no re-login).
| System | Purpose |
| --- | --- |
| panel_ui | Shows or hides sidebar/menu modules |
| Permissions | Allows or denies backend API operations |
| Roles | Group permissions and enable superadmin bypass |
| Subscription gates | Block store writes/features by plan/state |
Never rely on hidden frontend UI as a security boundary.
vendix-backend-auth - Global JWT auth and public routesvendix-panel-ui - Sidebar visibilityvendix-backend-api - Controller patternsvendix-prisma-seed - Seed safety patternsdevelopment
Mobile app development rules for Vendix Expo/React Native project. Trigger: When editing, creating, or modifying any file under apps/mobile, or when developing mobile-specific features.
development
Feature gating by store subscription state: global store write guard, AI feature gate, Redis feature resolution, quota consumption, frontend paywall interceptor, banner, and subscription UI states. Trigger: When adding feature gates, paywalls, subscription-based access control, protecting store write operations, AI feature gates, or rollout flags.
testing
SaaS subscription billing for Vendix stores: plan pricing, invoices, Wompi platform payments, manual payments, partner commissions, payouts, proration, and dunning. Trigger: When creating SaaS invoices, working with partner rev-share, margin/surcharge pricing, invoice sequence allocation, partner payout batches, subscription payments, manual payments, or dunning flows.
development
Periodic quota counters with Redis, UTC period keys, Lua-based idempotent AI quota consumption, request-id deduplication, and post-success consumption. Trigger: When building quota counters, enforcing monthly/daily feature caps, or reusing AI quota patterns for uploads, emails, exports, or rate-limited features.