58 lines
2.4 KiB
TypeScript
58 lines
2.4 KiB
TypeScript
import { cache } from "react";
|
|
import { auth } from "@/auth";
|
|
import { prisma } from "@/lib/db/prisma";
|
|
import { isSuperAdmin } from "@/lib/auth/permissions";
|
|
import { getPrimaryBusiness } from "@/lib/business/get-primary-business";
|
|
|
|
/**
|
|
* Resolves "which business is the signed-in user acting on behalf of" for
|
|
* pages/actions that only need the business id/name/timezone — not full
|
|
* staff identity (see getActingStaff for that, which stays the right
|
|
* choice for anything that needs a real StaffProfile id, e.g. loyalty
|
|
* stamp authorship or appointment reassignment).
|
|
*
|
|
* A regular staff member/owner resolves via their StaffProfile, same as
|
|
* getActingStaff. A Super Administrator (see scripts/ensure-super-admin.ts)
|
|
* deliberately has no StaffProfile at all — that's what keeps them out of
|
|
* the Team list/barber picker/appointment FKs by construction rather than
|
|
* a filter — so they resolve straight to the app's one business instead
|
|
* (v1 is single-business, same assumption getPrimaryBusiness() already
|
|
* makes everywhere else). Returns null only for a signed-in user who is
|
|
* neither staff nor a super admin.
|
|
*/
|
|
export const getActingBusinessContext = cache(async () => {
|
|
const session = await auth();
|
|
if (!session?.user?.id) return null;
|
|
|
|
const staffProfile = await prisma.staffProfile.findUnique({
|
|
where: { userId: session.user.id },
|
|
select: { id: true, businessId: true, business: { select: { name: true, timezone: true } } },
|
|
});
|
|
if (staffProfile) {
|
|
return {
|
|
userId: session.user.id,
|
|
staffId: staffProfile.id,
|
|
businessId: staffProfile.businessId,
|
|
businessName: staffProfile.business.name,
|
|
businessTimezone: staffProfile.business.timezone,
|
|
};
|
|
}
|
|
|
|
if (!(await isSuperAdmin(session.user.id))) return null;
|
|
|
|
const business = await getPrimaryBusiness();
|
|
return {
|
|
userId: session.user.id,
|
|
// A Super Administrator has no StaffProfile by design (see isSuperAdmin) —
|
|
// null here is what lets callers tell "acting as real staff" apart from
|
|
// "acting as a Super Administrator with no personal staff identity",
|
|
// e.g. to withhold note authorship (see CustomerNotes' actingStaffId).
|
|
staffId: null,
|
|
businessId: business.id,
|
|
businessName: business.name,
|
|
businessTimezone: business.timezone,
|
|
};
|
|
});
|
|
|
|
export type ActingBusinessContext = NonNullable<Awaited<ReturnType<typeof getActingBusinessContext>>>;
|