# Feature Plan: Bulk Dynamic QR + Dynamic Barcode Generator ## Feature 1: Bulk Generator → Dynamic QR freischalten ### Ziel Nutzer können beim Bulk-Import wählen ob sie statische oder dynamische QR-Codes erstellen. Dynamisch = DB-Einträge mit Slugs + Tracking. Nur für PRO/BUSINESS. ### Aktueller Stand (Ist) - `bulk-creation/page.tsx` generiert QR-Codes rein client-seitig (kein DB-Eintrag) - `generateStaticQRCodes()` rendert SVGs lokal via `qrcode`-Library - `saveQRCodesToDatabase()` sendet an `POST /api/qrs` mit `isStatic: true` — also immer statisch - Kein Toggle Static/Dynamic vorhanden - Kein Plan-Check für Dynamic im Bulk-Flow ### Änderungen #### A) Frontend: `bulk-creation/page.tsx` 1. **Toggle "Static / Dynamic" hinzufügen** (nach Plan-Check) - Nur sichtbar/aktivierbar wenn `userPlan === 'PRO' || 'BUSINESS'` - FREE-Nutzer sehen den Toggle gesperrt mit Upgrade-Hinweis - State: `const [isDynamic, setIsDynamic] = useState(false)` 2. **Interface erweitern** ```ts interface GeneratedQR { title: string; content: string; svg: string; slug?: string; // nur bei dynamic, nach API-Antwort gesetzt redirectUrl?: string; // z.B. https://qrmaster.net/r/abc123 } ``` 3. **Generierungslogik aufteilen** - Static (wie bisher): client-seitig SVG generieren, kein DB-Eintrag nötig - Dynamic: direkt `POST /api/qrs` pro Eintrag mit `isDynamic: true` → API gibt Slug zurück → QR encodiert `/r/[slug]` statt Original-URL 4. **Preview-Spalte erweitern** - Bei dynamic: Slug-Link anzeigen + "Ziel änderbar" Badge - Download-ZIP enthält QR-SVGs die `/r/[slug]` encodieren 5. **Limit-Anzeige** - PRO: max 50 dynamic / Bulk-Run (entspricht QR-Limit) - BUSINESS: max 500 #### B) Backend: `POST /api/qrs` Keine strukturelle Änderung nötig — der bestehende Endpunkt unterstützt bereits `isDynamic: false/true` und gibt `slug` zurück. Nur sicherstellen: - Plan-Limit-Check zählt korrekt bei Bulk-Erstellung (momentan prüft `POST /api/qrs` nur ob Gesamtanzahl < Limit — das bleibt so, aber Bulk erstellt X Requests nacheinander → ggf. Rate-Limit beachten) - Evtl. neuen Endpunkt `POST /api/qrs/bulk` der ein Array entgegennimmt und in einer DB-Transaktion schreibt (besser als 500 Einzelrequests) #### C) Optionaler neuer Endpunkt: `POST /api/qrs/bulk` (empfohlen) ```ts // Body: { qrCodes: Array<{ title, content, contentType, isDynamic }>, plan } // Response: { created: Array<{ id, slug, redirectUrl }>, failed: number } // Vorteile: eine DB-Transaktion, ein CSRF-Check, schneller ``` Plan-Check: `if (isDynamic && plan === 'FREE') return 403` --- ### Reihenfolge der Umsetzung 1. Toggle + Plan-Check im Frontend 2. Dynamic-Generierungslogik (nutzt bestehenden `POST /api/qrs`) 3. (Optional) `POST /api/qrs/bulk` für Performance 4. ZIP-Download mit Redirect-URLs als Metadaten-CSV --- ## Feature 2: Dynamischer Barcode Generator ### Aufteilung: Landingpage (Marketing) + Dashboard (Funktion) **Wichtig:** "Dynamic" existiert nur im Dashboard `/create`. Die Landingpage erklärt das Konzept und treibt Nutzer zum Signup/Login — sie hat keinen eigenen Dynamic-Modus. --- ### 2a) Landingpage: `/tools/dynamic-barcode-generator` **Ziel:** SEO-Traffic auf Keyword "barcode generator" (100k–1M, 0% Competition) konvertieren zu Signups. **Was die Landingpage NICHT hat:** - Keinen Dynamic-Toggle - Keine echte Dynamic-Funktionalität **Was die Landingpage HAT:** - Bestehenden `BarcodeGeneratorClient` eingebettet (statischer Generator, unverändert) - Erklärung was ein dynamischer Barcode ist + Vorteile - Klarer CTA: "Create Dynamic Barcode → Sign up / Dashboard" **Aufbau** (`src/app/(main)/(marketing)/tools/dynamic-barcode-generator/page.tsx`): ``` Hero-Section H1: "Dynamic Barcode Generator — Update Any Barcode Without Reprinting" Subtext: Erklärt Tracking + Redirect-Konzept CTA-Button: "Create Dynamic Barcode" → /login oder /signup Tool-Section BarcodeGeneratorClient (statisch, wie bisher, keine Änderungen) Banner darunter: "Want dynamic barcodes? Sign up free →" How It Works (3 Schritte) 1. Sign up & create barcode in dashboard 2. Print it once 3. Update the destination anytime — no reprint needed Use Cases Retail-Verpackungen, Logistik-Labels, Produktkataloge, Event-Badges FAQ-Section (schema.org FAQ markup) - "Was ist ein dynamischer Barcode?" - "Wie unterscheidet sich dynamisch von statisch?" - "Welche Formate werden unterstützt?" RelatedTools-Komponente (bereits vorhanden) ``` **Metadata:** ```ts title: 'Dynamic Barcode Generator — Trackable & Editable Barcodes' description: 'Create dynamic barcodes that you can update without reprinting. Track scans, change destinations, and manage all barcodes from one dashboard.' canonical: 'https://www.qrmaster.net/tools/dynamic-barcode-generator' keywords: ['dynamic barcode generator', 'barcode generator', 'trackable barcode', 'editable barcode'] ``` **Sitemap:** `/tools/dynamic-barcode-generator` hinzufügen. --- ### 2b) Dashboard `/create` — BARCODE als ContentType **Ziel:** Eingeloggte Nutzer können Barcodes (statisch oder dynamisch) im Dashboard erstellen, speichern und tracken. **DB-Änderung (kein migrate!):** ```sql -- Direkt gegen PostgreSQL ausführen (npm run docker:db) ALTER TYPE "ContentType" ADD VALUE 'BARCODE'; ``` Danach: `npx prisma generate` **Änderungen `create/page.tsx`:** - BARCODE zu `contentTypes` Array hinzufügen - `renderContentFields()` Case: Barcode-Wert + Format-Picker (CODE128, EAN13, UPC, etc.) - Preview: `react-barcode` statt `QRCodeSVG` wenn ContentType === BARCODE - QR-spezifische Optionen ausblenden bei BARCODE (Frames, Logo, Corner Style) - Dynamic Barcode = encodiert `/r/[slug]` → nutzt bestehendes Redirect- + Tracking-System - Static Barcode = encodiert Rohwert direkt **Kein neues Backend nötig** — `POST /api/qrs` + `/r/[slug]`-Redirect funktionieren bereits. --- ### Reihenfolge der Umsetzung **Phase 1 — Landingpage (kein DB-Change):** 1. `page.tsx` unter `/tools/dynamic-barcode-generator` erstellen 2. Sitemap-Eintrag **Phase 2 — Dashboard BARCODE:** 1. SQL ausführen: `ALTER TYPE "ContentType" ADD VALUE 'BARCODE'` 2. `npx prisma generate` 3. `create/page.tsx` erweitern --- ## Abhängigkeiten zwischen den Features | Feature | Hängt ab von | |---------|-------------| | Bulk Dynamic | Bestehendem `POST /api/qrs` (bereits fertig) | | Bulk Dynamic (optional) | Neuem `POST /api/qrs/bulk` Endpunkt | | Landingpage Dynamic Barcode | Bestehendem BarcodeGeneratorClient (keine Änderungen) | | Dashboard BARCODE | SQL-Enum-Erweiterung + `prisma generate` |