Next-Generation Dynamic QR Management, Smart Context Routing & Visitor Journey Analytics Platform
π Live Demo β’ Key Features β’ Architecture β’ Quickstart β’ Tech Stack β’ Database Schema β’ Testing
π Live Application: https://scanflow-pi.vercel.app/
π Live Demo: Experience the platform in action at https://scanflow-pi.vercel.app/ (use the 1-Click Recruiter Demo Sign-In to test all features instantly).
ScanFlow transforms static QR codes into programmable, intelligent entry points.
Traditional QR codes permanently link to a static URL, making physical prints obsolete whenever campaigns, app store links, or business hours change. ScanFlow solves this by decoupling the physical QR code from its destination:
- Dynamic Routing: Route visitors conditionally based on their device (iOS/Android/Desktop), country, language, or time of day.
- Instant Sub-Millisecond Redirects: High-performance HTTP 307 redirect engine (
/r/:code) with zero noticeable latency. - Asynchronous Telemetry & Journey Tracking: Captures scan events, user agents, geo-locations, and stitches individual scans into full Visitor Journeys.
- Campaign Attribution: Group QRs under marketing campaigns to monitor aggregate conversion rates and marketing ROI.
- Enterprise Multi-Tenancy: Built with strict organization/user isolation using Better Auth and Drizzle ORM on PostgreSQL.
ScanFlow is engineered for low latency at the redirect edge while streaming granular telemetry to a PostgreSQL analytical store.
flowchart TD
subgraph Visitor Experience
A[π± Visitor Scans QR Code] -->|GET /r/:code| B[β‘ ScanFlow Redirect Engine]
end
subgraph Deterministic Routing Pipeline
B --> C[Extract Visitor Context\n- Device: Mobile/Desktop/Tablet\n- OS: iOS/Android/macOS/Windows\n- Geo: Country Code\n- Time: Current Time Window]
C --> D{Evaluate Prioritized Rules}
D -->|Rule Matched| E1[Target Variant Destination]
D -->|Fallback / No Match| E2[Default QR Destination]
end
subgraph Edge Response & Telemetry Worker
E1 --> F[HTTP 307 Instant Redirect]
E2 --> F
F --> G[π Visitor Arrives at Destination]
B -.->|Non-Blocking Async| H[Telemetry & Session Worker]
H --> I[Parse User-Agent & Headers]
H --> J[Issue/Verify 'sf_sid' Cookie]
I & J --> K[(PostgreSQL Database)]
end
subgraph Analytical Dashboard
K --> L[Real-Time Analytics Engine]
L --> M[π Overview KPI Metrics]
L --> N[πΊοΈ Chronological Scan Journey Explorer]
L --> O[π Campaign Attribution & Conversion Funnel]
end
- Instant Destination Updates: Update where a physical QR points at any moment without reprinting.
- Full Lifecycle Management: Toggle between
Active,Paused(shows customizable branded maintenance screen), andArchivedstates. - Live Customization & High-Res Export:
- Custom foreground and background color styling.
- Configurable Error Correction Levels (
L- 7%,M- 15%,Q- 25%,H- 30%). - Vector SVG and high-resolution raster PNG export (512px, 1024px, 2048px, up to crisp 4K).
- One-Click Duplication: Duplicate QR codes along with their routing configurations.
- Device Targeting: Deliver specialized experiences for Mobile, Desktop, and Tablet users.
- Mobile OS Routing: Seamlessly forward iOS users to the Apple App Store and Android users to Google Play from a single universal QR code.
- Geo-Location Rules: Route visitors to region-specific storefronts or language landing pages based on their country.
- Time-Based Windows: Route to lunch/dinner menus or daytime/nighttime landing pages based on operating hours.
- Deterministic Priority Engine: Assign numerical priority to rules with graceful fallback to the default destination.
- Session Stitching: Groups individual touchpoints into a unified visitor session using secure
sf_sidcookies. - Chronological Timeline: Step-by-step visual audit trail displaying the visitor's path from initial scan to eventual conversion.
- Dwell & Conversion Metrics: Measures time-to-convert, duration between scans, repeat visits, and bounce behaviors.
- Cross-Asset Grouping: Aggregate multiple physical flyers, billboards, packaging inserts, and table tents under unified marketing campaigns.
- Comparative ROI: Track aggregate scans, unique visitors, total sessions, and conversion rates across active campaigns.
- Direct QR Assignment: Seamlessly assign and reassign QR codes to campaigns from the builder or campaign cards.
- Better Auth Integration: Multi-tenant session authentication, password hashing, and CSRF protection.
- Tenant Boundary Isolation: Database queries strictly scoped to the authenticated tenant.
- 1-Click Demo Login: Recruiter-friendly demo sign-in on the login page for instant sandbox evaluation.
| Layer | Technologies | Purpose |
|---|---|---|
| Framework | Next.js 16 (App Router) | Server Components, Route Handlers, Proxy routing |
| UI & Styling | React 19, Tailwind CSS v4 | High-performance dynamic interfaces and design tokens |
| Primitives | shadcn/ui, Base UI, Radix | Accessible dialogs, drawers, dropdowns, and sheets |
| Visualizations | Recharts, TanStack Table v9 | Interactive area charts, telemetry trends, and data grids |
| Database | PostgreSQL | Relational store for QRs, routing logic, sessions, and events |
| ORM | Drizzle ORM & Drizzle Kit | Type-safe schema definitions, relationships, and push migrations |
| Authentication | Better Auth | Multi-tenant auth, session validation, route guards |
| QR Engine | qrcode |
High-speed server-side and client-side vector/raster generation |
| Testing | Vitest, @testing-library/react | Unit, integration, component, and coverage test runners |
- Node.js:
v20.xor higher - PostgreSQL:
v15+(local, Docker, or hosted like Neon / Supabase) - Package Manager:
npm,pnpm, orbun
git clone https://github.com/amirfaisalz/scanflow.git
cd scanflownpm installCopy .env.example to .env and configure your credentials:
cp .env.example .env# Database Connection (PostgreSQL)
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/scanflow"
# Better Auth Configuration
BETTER_AUTH_SECRET="your_32_character_random_secret_here"
BETTER_AUTH_URL="http://localhost:3323"
# Public Application URL
NEXT_PUBLIC_APP_URL="http://localhost:3323"Push the schema directly to PostgreSQL using Drizzle Kit:
npx drizzle-kit pushnpm run devOpen http://localhost:3323 in your browser.
Tip: You can use the 1-Click Recruiter Demo Sign-In button on the
/loginpage to immediately explore the full dashboard without creating a new account.
| Script | Command | Description |
|---|---|---|
npm run dev |
next dev -p 3323 |
Starts the local dev server on port 3323 |
npm run build |
next build |
Creates an optimized production build |
npm run start |
next start |
Runs the compiled production build |
npm run test |
vitest run |
Runs all unit and component tests |
npm run test:coverage |
vitest run --coverage |
Executes tests with V8 code coverage report |
npm run lint |
eslint |
Analyzes code for syntax and style issues |
ScanFlow's relational data model is managed via Drizzle ORM in lib/db/schema.ts:
ββββββββββββββββ 1:N ββββββββββββββββββ 1:N ββββββββββββββββββββ
β users β ββββββββββββββ> β qr_codes β ββββββββββββββ> β qr_rules β
ββββββββββββββββ ββββββββββββββββββ ββββββββββββββββββββ
β 1:N β 1:N
β β
βΌ 1:N βΌ 1:N
ββββββββββββββββ ββββββββββββββββββ 1:N ββββββββββββββββββββ
β campaigns β β sessions β ββββββββββββββ> β session_events β
ββββββββββββββββ ββββββββββββββββββ ββββββββββββββββββββ
users&sessions: Better Auth tables handling user identities, hashed credentials, and authentication sessions.qr_codes: Primary QR metadata, slugs, destination URLs, styling config (colors, error correction), and status.qr_rules: Condition-based routing rules (Device, OS, Country, Time) evaluated deterministically per scan.campaigns: Marketing campaign groupings with budget, start/end dates, and performance aggregations.sessions&session_events: Chronological visitor touchpoints tracking referrer, user agent, IP hash, geo-location, and conversion status.
ScanFlow maintains a comprehensive automated testing suite built with Vitest and @testing-library/react.
# Run all tests
npm run test
# Run tests with code coverage
npm run test:coverage- β QR Generation Engine: SVG/PNG rasterization, slug formatting, error correction validation.
- β Dynamic Routing Logic: Context extraction, priority evaluation, rule matching, and fallback handling.
- β API Route Handlers: Multi-tenant CRUD operations, QR duplication, and campaign assignment.
- β Interactive Components: Modal dialogs, export controllers, live preview rendering.
βββ app/
β βββ (auth)/ # Login & Register pages
β βββ api/
β β βββ auth/ # Better Auth catch-all API handler
β β βββ campaigns/ # Campaigns CRUD & QR assignment
β β βββ qr-codes/ # QR CRUD, duplicate, & routing rules API
β β βββ track/ # Telemetry & conversion tracking endpoint
β βββ dashboard/
β β βββ campaigns/ # Marketing campaigns overview & cards
β β βββ journeys/ # Visual visitor scan journey explorer
β β βββ qr-codes/ # QR management (Grid & Table views)
β β βββ page.tsx # Overview dashboard with KPI cards & charts
β βββ r/[code]/ # High-speed redirect engine handler
βββ components/
β βββ campaigns/ # Campaign cards, dialogs, and summaries
β βββ journeys/ # Step-by-step visitor journey sheet
β βββ qr/ # QR builder, live preview, export dialog, routing rules
β βββ ui/ # Accessible shadcn / Base UI primitives
βββ docs/ # Product specs, plans, and task tracking
βββ lib/
β βββ analytics/ # Session tracking & journey computation
β βββ db/ # Drizzle PostgreSQL schema & client
β βββ routing/ # Deterministic condition matching engine
β βββ auth.ts # Better Auth server configuration
β βββ qr.ts # SVG & PNG QR code generation engine
βββ tests/ # Unit and component Vitest test suite
βββ proxy.ts # Next.js 16 route protection & session guards
βββ drizzle.config.ts # Drizzle Kit configuration
Contributions, issues, and feature requests are welcome!
- Fork the repository
- Create your feature branch (
git checkout -b feat/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Run tests (
npm run test) - Push to the branch (
git push origin feat/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.