# QR-First URL Shortener SaaS (Designer + Short Links + Tracking) Note: These specs are a draft and need review. ## 0) Product Definition One-liner: Create branded short links and highly customizable QR codes, then track scans/clicks with actionable analytics. Primary users: - Solo creators / small businesses - Marketing teams in SMB/PME - Agencies managing multiple clients Core value: Beautiful QR designs + brandable short domains + trustworthy tracking in one place. ## 1) MVP Scope (what ships first) ### 1.1 User Capabilities (MVP) Auth & Account - Sign up / sign in (email + password; optional SSO later) - Email verification - Password reset - Basic account settings Projects / Workspaces - Default workspace per user - Create “Projects” to organize links/QRs (e.g., “Restaurant menus”, “Flyers Q1”) Short Link Creation - Create short link: https://d.om/abc123 or custom slug …/menu - Destination URL validation - Optional UTM builder (preset templates) - Enable/disable link - Expiration date (optional) - Password protection (optional) — may be “Pro” if you want QR Code Designer - Generate QR from a short link (default) or direct URL - Styling: - Colors (foreground/background) - Error correction level (L/M/Q/H) - Quiet zone padding - Shape presets (modules/eyes) (start with a few presets) - Center logo upload (PNG/SVG) with size + margin controls - Export: - PNG and SVG - Size presets (e.g., 256/512/1024/2048) - Print-ready options (e.g., “high contrast” toggle) Tracking & Analytics (MVP) - Track events: click (short link) and scan (QR) - Dashboard: - Total events, uniques, last 24h / 7d / 30d - Time series - Top referrers (for clicks) - Geo (country) and device (desktop/mobile) high-level - Per-link analytics and per-QR analytics Basic Admin - Subscription status - Usage quotas (links/QRs/events) ## 2) Non-Goals for MVP (explicitly out) - Team roles/permissions (RBAC) beyond “owner” - A/B routing, smart rules, rotation, geo routing - Deep campaign automation - Enterprise SSO, SCIM - Offline QR scan tracking (impossible without network in most cases) ## 3) Plans & Monetization (recommended) Free - 1 workspace - 25 short links - 25 QR designs - 10k events/month - 1 custom QR logo upload (or allow unlimited but watermark exports) Pro (individual/SMB) - Custom domains (1–3) - Higher limits - No watermark - UTM templates - Expiring links / password links (if Pro) Business - Multiple workspaces - Team seats (later) - Higher retention and export presets ## 4) Core Entities (Data Model) ### 4.1 Entities User - id, email, password_hash, verified_at, created_at Workspace - id, owner_user_id, name, plan, created_at Project - id, workspace_id, name, created_at Domain - id, workspace_id, hostname, status (pending/verified/active), verification_token, created_at ShortLink - id - workspace_id, project_id (nullable) - domain_id (nullable; else default platform domain) - slug - destination_url - title (nullable) - status (active/disabled) - expires_at (nullable) - password_hash (nullable) - created_at, updated_at QRCodeDesign - id - workspace_id, project_id (nullable) - shortlink_id (nullable; recommended default) - style_json (colors, shapes, ecc level, etc.) - logo_asset_id (nullable) - created_at, updated_at Event - id (or bigint) - workspace_id - shortlink_id - qrcode_id (nullable but strongly recommended to tag scans) - type: click | scan - ts - ip_hash (privacy-safe) - user_agent - referrer - country_code (nullable) - device_type (nullable) - dedupe_key (nullable) - raw_json (optional for debug, or drop) Asset - id, workspace_id, type (logo), storage_key, mime, size, created_at ### 4.2 Key Design Choice How do we distinguish “scan” vs “click”? When exporting a QR, embed a URL like: https://d.om/s/abc123?qr= The redirect endpoint records scan when it detects qr=, then redirects to destination, which will also produce a click unless you decide “scan implies click” and record only one. Recommendation: record one event per redirect request: - If qr present → type=scan - Else → type=click ## 5) System Behavior (Routes & Flows) ### 5.1 Public Redirect GET /{slug} Resolve domain + slug → short link Validate: - exists - active - not expired - if password-protected → show password page Log event (scan/click) Redirect 301/302 (configurable later; MVP use 302) ### 5.2 QR Export QR code is generated from: Redirect URL including qrcode id: https://{domain}/{slug}?qr={qrcode_id} ## 6) Functional Requirements (MVP checklist) Link Management - Create, edit, disable, delete (soft delete preferred) - Slug uniqueness per domain - Auto-slug generator (base62) - Destination URL allowlist/denylist (prevent abuse) QR Designer - Live preview - Save design - Export SVG/PNG - Logo upload with validation (size/mime) Analytics - Views for: - Workspace overview - Project overview - Per short link - Per QR design - Time filters: 24h / 7d / 30d / custom range - Unique definition: - Unique per day per link based on ip_hash + UA hash (privacy-safe and approximate) ## 7) Non-Functional Requirements Performance - Redirect endpoint P95 < 100ms (excluding DNS/TLS) - Event write must not block redirect (use async queue if possible) Availability - Redirect is the critical path; should stay up even if dashboard is down - Graceful degradation: if analytics store is down, still redirect Security - Rate limit public endpoints - Abuse prevention: phishing/malware reporting flow (later), basic filters now - Domain verification to prevent takeover - Strict CSP on app pages Privacy & Compliance (Canada / Quebec friendly baseline) - Avoid storing raw IP; store hashed IP with rotating salt (e.g., monthly) - Provide retention configuration per plan (e.g., 30/180/365 days) ## 8) Architecture (pragmatic MVP) Components - Web App: dashboard + designer (Vue/React) - API: CRUD for links/qr/projects/domains, analytics queries - Redirect Edge: fastest path for /{slug} (can be same API initially) Storage - PostgreSQL for core entities - Analytics: - MVP: PostgreSQL events table partitioned by month - Later: ClickHouse/BigQuery for scale Background Jobs - Domain verification checks - Event enrichment (geo/device parsing) - Cleanup & retention tasks ## 9) API Surface (minimal) - POST /auth/register|login|forgot|reset - GET/POST /workspaces - GET/POST /projects - GET/POST /links - GET/POST /qrcodes - POST /domains + verification status - GET /analytics/overview - GET /analytics/link/{id} - GET /analytics/qrcode/{id} ## 10) UI Pages (MVP) - Login / Register / Reset - Workspace switcher - Projects list - Links list + create/edit - QR designer (create/edit) with preview - Analytics dashboard (overview + per link + per QR) - Domains page (add/verify) ## 11) Pricing/Quotas Enforcement Enforce at API level: - max links, max QR codes, max events/month, max custom domains Stripe integration later; MVP can be “manual Pro” toggle or Stripe from day 1 if you want. ## 12) Implementation Notes (key decisions) - Use one redirect URL as canonical; QR adds ?qr= for attribution. - Event logging should be non-blocking: - MVP: write to DB async (background queue) or “fire-and-forget” with retry - Plan for domain verification: - Require DNS TXT record or CNAME to verify ownership - Short link collision: - Slug uniqueness per domain enforced in DB