fix: VisibilityLevel als lokalen String-Type statt Prisma-Enum verwenden

Prisma-Enums sind zur Laufzeit nicht als Objekt verfuegbar wenn ts-node
den Import vor der Client-Generierung auflöst. Ersetzt durch eigenen
Type-Export aus build-visibility-filter.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Thomas Reitz 2026-03-14 22:24:18 +01:00
parent de4af77c5c
commit b484f4380f
7 changed files with 30 additions and 23 deletions

View file

@ -10,7 +10,8 @@ import { QueryActivitiesDto } from './dto/query-activities.dto';
import { VisibilityService } from '../visibility/visibility.service';
import { TeamResolverService } from '../visibility/team-resolver.service';
import { JwtPayload } from '../common/decorators/current-user.decorator';
import { Prisma, VisibilityLevel } from '.prisma/crm-client';
import { Prisma } from '.prisma/crm-client';
import { VisibilityLevel } from '../common/utils/build-visibility-filter';
@Injectable()
export class ActivitiesService {

View file

@ -1,6 +1,7 @@
import { VisibilityLevel } from '.prisma/crm-client';
import { JwtPayload } from '../decorators/current-user.decorator';
export type VisibilityLevel = 'OWN' | 'TEAM' | 'ALL';
/**
* Erzeugt einen Prisma WHERE-Filter basierend auf dem Sichtbarkeitslevel.
*
@ -30,16 +31,16 @@ export function buildVisibilityFilter(params: {
}
// Effektives Level bestimmen (TEAM_LEAD sieht mindestens TEAM)
let effectiveLevel = level;
if (user.tenantRole === 'TEAM_LEAD' && level === VisibilityLevel.OWN) {
effectiveLevel = VisibilityLevel.TEAM;
let effectiveLevel: VisibilityLevel = level;
if (user.tenantRole === 'TEAM_LEAD' && level === 'OWN') {
effectiveLevel = 'TEAM';
}
switch (effectiveLevel) {
case VisibilityLevel.ALL:
case 'ALL':
return { tenantId };
case VisibilityLevel.OWN:
case 'OWN':
return {
tenantId,
[ownerRelation]: {
@ -47,7 +48,7 @@ export function buildVisibilityFilter(params: {
},
};
case VisibilityLevel.TEAM: {
case 'TEAM': {
// Wenn Team-Member-IDs vorhanden: nach diesen filtern
if (teamMemberIds && teamMemberIds.length > 0) {
// Eigene ID immer einschliessen

View file

@ -10,7 +10,8 @@ import { VisibilityService } from '../visibility/visibility.service';
import { TeamResolverService } from '../visibility/team-resolver.service';
import { buildVisibilityFilter } from '../common/utils/build-visibility-filter';
import { JwtPayload } from '../common/decorators/current-user.decorator';
import { Prisma, VisibilityLevel } from '.prisma/crm-client';
import { Prisma } from '.prisma/crm-client';
import { VisibilityLevel } from '../common/utils/build-visibility-filter';
import { EntityStatus } from '../common/dto/contact-info.dto';
@Injectable()

View file

@ -11,7 +11,8 @@ import { VisibilityService } from '../visibility/visibility.service';
import { TeamResolverService } from '../visibility/team-resolver.service';
import { buildVisibilityFilter } from '../common/utils/build-visibility-filter';
import { JwtPayload } from '../common/decorators/current-user.decorator';
import { Prisma, VisibilityLevel } from '.prisma/crm-client';
import { Prisma } from '.prisma/crm-client';
import { VisibilityLevel } from '../common/utils/build-visibility-filter';
import { EntityStatus } from '../common/dto/contact-info.dto';
@Injectable()

View file

@ -15,7 +15,8 @@ import { VisibilityService } from '../visibility/visibility.service';
import { TeamResolverService } from '../visibility/team-resolver.service';
import { buildVisibilityFilter } from '../common/utils/build-visibility-filter';
import { JwtPayload } from '../common/decorators/current-user.decorator';
import { Prisma, VisibilityLevel } from '.prisma/crm-client';
import { Prisma } from '.prisma/crm-client';
import { VisibilityLevel } from '../common/utils/build-visibility-filter';
@Injectable()
export class DealsService {

View file

@ -1,13 +1,15 @@
import { IsEnum } from 'class-validator';
import { IsIn, IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { VisibilityLevel } from '.prisma/crm-client';
const VISIBILITY_LEVELS = ['OWN', 'TEAM', 'ALL'] as const;
export class SetVisibilityDto {
@ApiProperty({
enum: VisibilityLevel,
enum: VISIBILITY_LEVELS,
description: 'Sichtbarkeitslevel: OWN, TEAM oder ALL',
example: 'ALL',
})
@IsEnum(VisibilityLevel)
level!: VisibilityLevel;
@IsString()
@IsIn(VISIBILITY_LEVELS)
level!: 'OWN' | 'TEAM' | 'ALL';
}

View file

@ -1,7 +1,7 @@
import { Injectable, Logger } from '@nestjs/common';
import { CrmPrismaService } from '../prisma/crm-prisma.service';
import { RedisService } from '../redis/redis.service';
import { VisibilityLevel } from '.prisma/crm-client';
import { VisibilityLevel } from '../common/utils/build-visibility-filter';
const CACHE_PREFIX = 'crm_visibility';
const CACHE_TTL = 300; // 5 Minuten
@ -36,7 +36,7 @@ export class VisibilityService {
where: { tenantId_entity: { tenantId, entity } },
});
const level = setting?.level ?? VisibilityLevel.ALL;
const level = (setting?.level as VisibilityLevel) ?? 'ALL';
// In Cache schreiben
await this.redis.set(cacheKey, level, CACHE_TTL);
@ -78,14 +78,14 @@ export class VisibilityService {
});
const result: Record<string, VisibilityLevel> = {
COMPANY: VisibilityLevel.ALL,
CONTACT: VisibilityLevel.ALL,
DEAL: VisibilityLevel.ALL,
ACTIVITY: VisibilityLevel.ALL,
COMPANY: 'ALL',
CONTACT: 'ALL',
DEAL: 'ALL',
ACTIVITY: 'ALL',
};
for (const s of settings) {
result[s.entity] = s.level;
result[s.entity] = s.level as VisibilityLevel;
}
return result;