180 lines
6.5 KiB
Markdown
180 lines
6.5 KiB
Markdown
# 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` |
|