Phase 2
Base app architecture:
Route groups for customer, staff and owner.
* Reusable design system with around 20 UI components.
* Complete Prisma schema.
* Authentication with email/password and Google.
* Role and permission model.
* Protected routes.
* Clean separation between features, services, components and shared utilities.
This commit is contained in:
201 files changed
+31984
No files matched your search
@@ -0,0 +1,25 @@
|
||||
import { prisma } from "@/lib/db/prisma";
|
||||
import type { Permission } from "@/generated/prisma/enums";
|
||||
|
||||
/**
|
||||
* Foundation for Phase 3+ role gating — not exercised by any UI yet.
|
||||
* Deliberately re-checks the database rather than trusting only the JWT:
|
||||
* permission changes (e.g. an owner demoting a barber) must take effect
|
||||
* without waiting for the token to expire. See
|
||||
* docs/implementation-plan.md §11 ("Permission enforcement happens AGAIN
|
||||
* at the server-action/service layer — never trust the route group alone").
|
||||
*/
|
||||
export async function getStaffPermissions(userId: string): Promise<Set<Permission>> {
|
||||
const staffProfile = await prisma.staffProfile.findUnique({
|
||||
where: { userId },
|
||||
include: { role: { include: { permissions: true } } },
|
||||
});
|
||||
|
||||
if (!staffProfile) return new Set();
|
||||
return new Set(staffProfile.role.permissions.map((rolePermission) => rolePermission.permission));
|
||||
}
|
||||
|
||||
export async function hasPermission(userId: string, permission: Permission): Promise<boolean> {
|
||||
const permissions = await getStaffPermissions(userId);
|
||||
return permissions.has(permission);
|
||||
}
|
||||
Reference in new issue
Block a user