feat: Abfüllungs-Archiv und Social-Media-Links auf der Herkunftsseite

Abfüllungen hatten keine Übersichtsseite - die Navigation ging direkt
auf /bottling/new, sodass eine angelegte Abfüllung danach nirgends
mehr sichtbar war. Neue Seite /bottling listet alle Abfüllungen
(Archiv), Klick führt zur bestehenden Detail-/Bearbeiten-Seite.
Navigationslink zeigt jetzt auf die Liste statt direkt auf "Neu".

Neues Modul site-settings (Singleton-Tabelle SiteSettings) für
YouTube-/Instagram-/TikTok-Links, verwaltbar unter Verwaltung > Website
(neue Berechtigung site-settings:read/update). Die öffentliche
Herkunftsseite (/herkunft/[lot]) zeigt die konfigurierten Links jetzt
zusätzlich zur Chargen-Herkunft an - PublicService liefert sie über
das bereits oeffentliche /public/batches/:lotNumber mit aus, keine
zusaetzliche unauthentifizierte Route noetig.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Sonnet 5 committed 2026-09-02 19:57:29 +02:00
1 parent 33fa768062
commit 351f9ef34c
19 files changed
+612 -4

No files matched your search

@@ -0,0 +1,28 @@
import { ApiPropertyOptional } from '@nestjs/swagger';
import { IsOptional, IsUrl, MaxLength, ValidateIf } from 'class-validator';
// An empty string clears the link (stored as null); anything else must be a
// real URL - ValidateIf skips the @IsUrl check only for the empty-string
// "clear" case so a genuinely malformed value still fails validation.
export class UpdateSiteSettingsDto {
@ApiPropertyOptional({ description: 'Leerer String löscht den Link' })
@IsOptional()
@ValidateIf((_, value: string) => value !== '')
@IsUrl({ require_protocol: true })
@MaxLength(300)
youtubeUrl?: string;
@ApiPropertyOptional({ description: 'Leerer String löscht den Link' })
@IsOptional()
@ValidateIf((_, value: string) => value !== '')
@IsUrl({ require_protocol: true })
@MaxLength(300)
instagramUrl?: string;
@ApiPropertyOptional({ description: 'Leerer String löscht den Link' })
@IsOptional()
@ValidateIf((_, value: string) => value !== '')
@IsUrl({ require_protocol: true })
@MaxLength(300)
tiktokUrl?: string;
}