import { Injectable, BadRequestException, NotFoundException, } from '@nestjs/common'; import * as QRCode from 'qrcode'; import { PrismaService } from '../prisma/prisma.service'; const ENTITY_TYPES = [ 'colonies', 'apiaries', 'queens', 'honey-batches', 'storage-containers', 'bottling-batches', ] as const; type EntityType = (typeof ENTITY_TYPES)[number]; function isEntityType(value: string): value is EntityType { return (ENTITY_TYPES as readonly string[]).includes(value); } @Injectable() export class QrService { constructor(private readonly prisma: PrismaService) {} async generateSvg(entityType: string, id: string): Promise { const url = await this.resolveUrl(entityType, id); return QRCode.toString(url, { type: 'svg', margin: 1, width: 256 }); } async resolveUrl(entityType: string, id: string): Promise { if (!isEntityType(entityType)) { throw new BadRequestException( `Unsupported QR entity type: ${entityType}`, ); } const deepLink = await this.resolveDeepLink(entityType, id); if (!deepLink) { throw new NotFoundException('Object not found'); } const frontendOrigin = process.env.FRONTEND_ORIGIN ?? 'http://localhost:3000'; return `${frontendOrigin}${deepLink}`; } private async resolveDeepLink( entityType: EntityType, id: string, ): Promise { switch (entityType) { case 'colonies': { const colony = await this.prisma.colony.findUnique({ where: { id }, }); return colony ? `/inspections/new?colonyId=${id}` : null; } case 'apiaries': { const apiary = await this.prisma.apiary.findUnique({ where: { id } }); return apiary ? `/apiaries/${id}` : null; } case 'queens': { const queen = await this.prisma.queen.findUnique({ where: { id } }); return queen ? `/queens/${id}` : null; } case 'honey-batches': { const honeyBatch = await this.prisma.honeyBatch.findUnique({ where: { id }, }); return honeyBatch ? `/honey-batches/${id}` : null; } case 'storage-containers': { const container = await this.prisma.storageContainer.findUnique({ where: { id }, }); return container ? `/storage` : null; } case 'bottling-batches': { const bottlingBatch = await this.prisma.bottlingBatch.findUnique({ where: { id }, select: { lotNumber: true }, }); return bottlingBatch ? `/herkunft/${bottlingBatch.lotNumber}` : null; } } } }