100 lines
2.8 KiB
TypeScript
100 lines
2.8 KiB
TypeScript
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
|
|
import { PrismaService } from '../prisma/prisma.service';
|
|
import { UpsertHelpTextDto } from './dto/upsert-help-text.dto';
|
|
|
|
type HelpTextScope = 'default' | 'user' | 'admin';
|
|
|
|
@Injectable()
|
|
export class HelpTextsService {
|
|
private readonly allowedScopes: HelpTextScope[] = ['default', 'user', 'admin'];
|
|
|
|
constructor(private readonly prisma: PrismaService) {}
|
|
|
|
async getResolvedByKey(keyRaw: string, roleRaw?: string) {
|
|
const key = this.normalizeKey(keyRaw);
|
|
const role = (roleRaw ?? 'user').toLowerCase();
|
|
const scopePriority: HelpTextScope[] = role === 'admin'
|
|
? ['admin', 'user', 'default']
|
|
: ['user', 'default'];
|
|
|
|
const rows = await this.prisma.helpText.findMany({
|
|
where: {
|
|
key,
|
|
isActive: true,
|
|
scope: { in: scopePriority },
|
|
},
|
|
select: {
|
|
key: true,
|
|
scope: true,
|
|
title: true,
|
|
content: true,
|
|
updatedAt: true,
|
|
},
|
|
});
|
|
|
|
for (const scope of scopePriority) {
|
|
const hit = rows.find((row) => row.scope === scope);
|
|
if (hit) {
|
|
return {
|
|
'key': hit.key,
|
|
'scope': hit.scope,
|
|
'title': hit.title,
|
|
'content': hit.content,
|
|
'updatedAt': hit.updatedAt,
|
|
};
|
|
}
|
|
}
|
|
|
|
throw new NotFoundException(`Ingen aktiv hjälptext hittades för key '${key}'.`);
|
|
}
|
|
|
|
async upsert(keyRaw: string, scopeRaw: string, dto: UpsertHelpTextDto) {
|
|
const key = this.normalizeKey(keyRaw);
|
|
const scope = this.normalizeScope(scopeRaw);
|
|
|
|
return this.prisma.helpText.upsert({
|
|
where: {
|
|
key_scope: { key, scope },
|
|
},
|
|
update: {
|
|
title: dto.title.trim(),
|
|
content: dto.content.trim(),
|
|
isActive: dto.isActive ?? true,
|
|
},
|
|
create: {
|
|
key,
|
|
scope,
|
|
title: dto.title.trim(),
|
|
content: dto.content.trim(),
|
|
isActive: dto.isActive ?? true,
|
|
},
|
|
select: {
|
|
key: true,
|
|
scope: true,
|
|
title: true,
|
|
content: true,
|
|
isActive: true,
|
|
updatedAt: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
private normalizeKey(value: string): string {
|
|
const normalized = value.trim().toLowerCase();
|
|
if (!normalized) {
|
|
throw new BadRequestException('Hjälptext-nyckel måste anges.');
|
|
}
|
|
return normalized;
|
|
}
|
|
|
|
private normalizeScope(value: string): HelpTextScope {
|
|
const normalized = value.trim().toLowerCase() as HelpTextScope;
|
|
if (!this.allowedScopes.includes(normalized)) {
|
|
throw new BadRequestException(
|
|
`Ogiltig scope '${value}'. Tillåtna scopes: ${this.allowedScopes.join(', ')}`,
|
|
);
|
|
}
|
|
return normalized;
|
|
}
|
|
}
|