Dynamic QR management and campaign analytics platform built as a portfolio-ready full-stack MVP with Next.js, ASP.NET Core and PostgreSQL.
QRFlow turns a minimal QR generator into a coherent product: static QR generation remains instant in the browser, while authenticated users can create dynamic QR codes, edit their destination after printing and measure scans from a private dashboard.
- Separate Sign in and Create account flows
- Registration automatically creates the session and redirects to the dashboard
- Header changes when a user is authenticated and provides a real sign-out action
- Light-first visual identity with violet, mint, coral and warm-yellow accents
- Optional softer dark theme
- Spanish/English preference
- QR Builder for URL, text, Wi-Fi, email and WhatsApp
- SVG and high-resolution PNG export
- Dynamic QR persistence and HTTP 302 redirect flow
- Owner-scoped analytics and QR administration
QRFlow follows Clean Architecture boundaries and applies SOLID pragmatically:
Frontend (feature-based)
Next.js / React
|
| HTTP + JWT
v
Presentation
QRFlow.Api
|
v
Application
Use cases + ports/interfaces
|
v
Domain
Entities + business rules
^
|
Infrastructure
EF Core / PostgreSQL / ASP.NET Identity / JWT
Dependency direction:
Domain <- Application <- API
^ |
| |
Infrastructure --+
The API controllers are intentionally thin. Business behavior lives in the Domain and Application layers; Infrastructure only implements external concerns such as persistence, Identity, JWT, clock and slug generation.
See docs/ARCHITECTURE.md.
- Next.js 16
- React 19
- TypeScript
- Tailwind CSS 4
- qrcode.react
- ASP.NET Core / .NET 10 LTS
- Entity Framework Core
- ASP.NET Core Identity
- JWT bearer authentication
- PostgreSQL / Npgsql
- Rate limiting
- OpenAPI
- Health checks
- TypeScript strict mode
- ESLint
- Node built-in unit tests for frontend business logic, session rules and architecture guards
- xUnit tests for Domain/Application use cases
- PowerShell end-to-end smoke test for the local stack
- GitHub Actions quality gates
- Node.js 22+
- npm 10+
- Docker Desktop
- .NET 10 SDK only if you want to run/test the backend outside Docker
QRFlow intentionally avoids the ports already commonly used by other local projects:
Web http://localhost:3000
API http://localhost:8081
PostgreSQL localhost:5433
docker compose up -d --buildVerify:
Invoke-WebRequest http://localhost:8081/health -UseBasicParsing
Invoke-WebRequest http://localhost:8081/openapi/v1.json -UseBasicParsingCopy-Item .env.example .env.local
npm install
npm run devOpen http://localhost:3000.
Registration and login are intentionally separate experiences:
/register
-> create Identity user
-> issue JWT
-> store MVP session
-> redirect /dashboard
/login
-> validate credentials
-> issue JWT
-> redirect /dashboard
For the portfolio MVP the browser session is stored in localStorage. Before commercial production this should move to secure HttpOnly cookies or a BFF pattern.
Create dynamic QR
|
v
POST /api/qrcodes
|
v
/q/{slug} encoded in QR
|
v
scan -> resolve current destination
|
+-> record privacy-minimized ScanEvent
|
v
HTTP 302 -> destination
Changing the destination does not require regenerating or reprinting the QR.
POST /api/auth/register
POST /api/auth/login
GET /api/qrcodes JWT
POST /api/qrcodes JWT
GET /api/qrcodes/{id} JWT
PUT /api/qrcodes/{id} JWT
DELETE /api/qrcodes/{id} JWT
GET /api/analytics/overview JWT
GET /q/{slug}
GET /health
Analytics are scoped to the authenticated owner; one user cannot see another user's QR metrics.
Frontend/static quality:
npm run typecheck
npm run lint
npm test
npm run buildAll frontend checks:
npm run qualityBackend tests with .NET 10 installed:
cd backend
dotnet restore
dotnet build
dotnet testEnd-to-end local smoke test after API + web are running:
npm run test:smokeThe smoke test verifies health, frontend availability, registration/login, dynamic QR creation, same-slug destination changes, analytics, pause/reactivation and deletion.
- S — Single Responsibility: controllers, use cases, repositories, token generation, Identity and UI feature services have separate responsibilities.
- O — Open/Closed: new persistence/token implementations can be added behind Application interfaces without rewriting use cases.
- L — Liskov Substitution: Application services work against ports and are tested with in-memory fakes.
- I — Interface Segregation: QR persistence, scan persistence, analytics reads, Identity and token generation are distinct contracts.
- D — Dependency Inversion: Application depends on abstractions; PostgreSQL, Identity and JWT live behind Infrastructure adapters.
Next.js -> Vercel Hobby (personal/non-commercial portfolio MVP)
ASP.NET Core API -> Azure Container Apps Consumption (0.25 vCPU / 0.5 GiB / scale-to-zero)
PostgreSQL -> Neon Free (pooled PostgreSQL connection)
Container registry -> GitHub Container Registry (public image)
CI/CD -> GitHub Actions + Vercel Git integration
Deployment preparation includes EF Core migration tooling, production-only migration mode, GHCR publication, Azure bootstrap scripts, cost guardrails, and cloud smoke testing.
Before the first cloud deployment, generate and commit the real EF migration with:
./scripts/create-initial-migration.ps1
npm run test:backendThen follow docs/DEPLOYMENT.md. The deployment review is recorded in docs/REVIEW_2026-08-28.md.