Add opt-in roll_call business module gate.
Keeps Roll Call off by default and blocks the API until super-admin enables it. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
a6c2d4764e
commit
3558c441b9
@@ -245,6 +245,7 @@ export const BUSINESS_DASHBOARD_MODULE_IDS = [
|
|||||||
'workshops',
|
'workshops',
|
||||||
'finance',
|
'finance',
|
||||||
'multilanguage_data',
|
'multilanguage_data',
|
||||||
|
'roll_call',
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
/** Optional customer-dashboard modules. Always-on: home, profile, addresses, orders, favorites. */
|
/** Optional customer-dashboard modules. Always-on: home, profile, addresses, orders, favorites. */
|
||||||
@@ -352,7 +353,8 @@ export const DEFAULT_ENABLED_BUSINESS_MODULES: BusinessModuleId[] =
|
|||||||
(id) =>
|
(id) =>
|
||||||
id !== 'workshops' &&
|
id !== 'workshops' &&
|
||||||
id !== 'multilanguage_data' &&
|
id !== 'multilanguage_data' &&
|
||||||
id !== 'store_installments',
|
id !== 'store_installments' &&
|
||||||
|
id !== 'roll_call',
|
||||||
);
|
);
|
||||||
|
|
||||||
export const DEFAULT_HOME_CHARTS: [HomeChartId, HomeChartId] = [
|
export const DEFAULT_HOME_CHARTS: [HomeChartId, HomeChartId] = [
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
import { Prisma, RollCall, RollCallTask } from '@prisma/client';
|
import { Prisma, RollCall, RollCallTask } from '@prisma/client';
|
||||||
import { AuthUser } from '../auth/auth.types';
|
import { AuthUser } from '../auth/auth.types';
|
||||||
import { PermissionsService } from '../auth/permissions.service';
|
import { PermissionsService } from '../auth/permissions.service';
|
||||||
|
import { normalizeBusinessSettings } from '../business-settings/business-settings.util';
|
||||||
import { PrismaService } from '../prisma/prisma.service';
|
import { PrismaService } from '../prisma/prisma.service';
|
||||||
import {
|
import {
|
||||||
CreateRollCallDto,
|
CreateRollCallDto,
|
||||||
@@ -26,6 +27,7 @@ export class RollCallsService {
|
|||||||
|
|
||||||
async list(businessIdRaw: string, query: ListRollCallsDto, actor: AuthUser) {
|
async list(businessIdRaw: string, query: ListRollCallsDto, actor: AuthUser) {
|
||||||
const businessId = BigInt(businessIdRaw);
|
const businessId = BigInt(businessIdRaw);
|
||||||
|
await this.assertModuleEnabled(businessId);
|
||||||
await this.assertPermission(businessId, actor.id, 'roll_calls.read');
|
await this.assertPermission(businessId, actor.id, 'roll_calls.read');
|
||||||
|
|
||||||
const page = query.page ?? 1;
|
const page = query.page ?? 1;
|
||||||
@@ -83,6 +85,7 @@ export class RollCallsService {
|
|||||||
actor: AuthUser,
|
actor: AuthUser,
|
||||||
) {
|
) {
|
||||||
const businessId = BigInt(businessIdRaw);
|
const businessId = BigInt(businessIdRaw);
|
||||||
|
await this.assertModuleEnabled(businessId);
|
||||||
await this.assertPermission(businessId, actor.id, 'roll_calls.read');
|
await this.assertPermission(businessId, actor.id, 'roll_calls.read');
|
||||||
const rollCall = await this.findOwnedOrThrow(
|
const rollCall = await this.findOwnedOrThrow(
|
||||||
businessId,
|
businessId,
|
||||||
@@ -98,6 +101,7 @@ export class RollCallsService {
|
|||||||
actor: AuthUser,
|
actor: AuthUser,
|
||||||
) {
|
) {
|
||||||
const businessId = BigInt(businessIdRaw);
|
const businessId = BigInt(businessIdRaw);
|
||||||
|
await this.assertModuleEnabled(businessId);
|
||||||
await this.assertPermission(businessId, actor.id, 'roll_calls.create');
|
await this.assertPermission(businessId, actor.id, 'roll_calls.create');
|
||||||
|
|
||||||
const workDate = this.parseWorkDate(dto.workDate);
|
const workDate = this.parseWorkDate(dto.workDate);
|
||||||
@@ -147,6 +151,7 @@ export class RollCallsService {
|
|||||||
actor: AuthUser,
|
actor: AuthUser,
|
||||||
) {
|
) {
|
||||||
const businessId = BigInt(businessIdRaw);
|
const businessId = BigInt(businessIdRaw);
|
||||||
|
await this.assertModuleEnabled(businessId);
|
||||||
await this.assertPermission(businessId, actor.id, 'roll_calls.update');
|
await this.assertPermission(businessId, actor.id, 'roll_calls.update');
|
||||||
const rollCallId = BigInt(rollCallIdRaw);
|
const rollCallId = BigInt(rollCallIdRaw);
|
||||||
await this.findOwnedOrThrow(businessId, actor.id, rollCallId);
|
await this.findOwnedOrThrow(businessId, actor.id, rollCallId);
|
||||||
@@ -213,6 +218,7 @@ export class RollCallsService {
|
|||||||
actor: AuthUser,
|
actor: AuthUser,
|
||||||
) {
|
) {
|
||||||
const businessId = BigInt(businessIdRaw);
|
const businessId = BigInt(businessIdRaw);
|
||||||
|
await this.assertModuleEnabled(businessId);
|
||||||
await this.assertPermission(businessId, actor.id, 'roll_calls.delete');
|
await this.assertPermission(businessId, actor.id, 'roll_calls.delete');
|
||||||
const rollCallId = BigInt(rollCallIdRaw);
|
const rollCallId = BigInt(rollCallIdRaw);
|
||||||
await this.findOwnedOrThrow(businessId, actor.id, rollCallId);
|
await this.findOwnedOrThrow(businessId, actor.id, rollCallId);
|
||||||
@@ -321,6 +327,24 @@ export class RollCallsService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async assertModuleEnabled(businessId: bigint) {
|
||||||
|
const business = await this.prisma.business.findFirst({
|
||||||
|
where: { id: businessId },
|
||||||
|
select: { settings: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!business) {
|
||||||
|
throw new NotFoundException('Business not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const settings = normalizeBusinessSettings(business.settings);
|
||||||
|
if (!settings.modules.enabled.includes('roll_call')) {
|
||||||
|
throw new ForbiddenException(
|
||||||
|
'Roll call module is not enabled for this business',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async assertPermission(
|
private async assertPermission(
|
||||||
businessId: bigint,
|
businessId: bigint,
|
||||||
userId: bigint,
|
userId: bigint,
|
||||||
|
|||||||
Reference in New Issue
Block a user