Files
trakqr/docs/spec.md
Jonathan Bourdon 6dce383e38 docs: rewrite spec.md to match current implementation
- Restructure document with clear status tables
- Mark all implemented features with 
- Mark deferred features with 
- Add complete data model with all entities
- Add system architecture diagram
- Add comprehensive API endpoints list
- Document plan limits (Free/Pro/Business)
- List all UI pages with routes
- Add security checklist (implemented vs deferred)
- Update remaining work section with priorities

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 19:11:20 -05:00

13 KiB

TrakQR - QR-First URL Shortener SaaS

Create branded short links and highly customizable QR codes, then track scans/clicks with actionable analytics.

Product Overview

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 Features (Implemented)

1.1 Authentication & Account

Feature Status Notes
Email + password signup With auto-created default workspace
Email verification Token-based, resend support
Login with JWT Rate-limited
Password reset Email-based token flow
Profile management Update email, change password
Delete account With password confirmation
SSO Deferred to post-MVP

1.2 Workspaces & Projects

Feature Status Notes
Default workspace on signup Auto-created
Multiple workspaces Based on plan limits
Workspace CRUD Create, update, delete
Projects for organization Full CRUD with descriptions
Workspace switcher UI With create/manage modals
Feature Status Notes
Create short link Custom or auto-generated slug
Destination URL validation URL format validation
UTM builder Presets for Google, Facebook, Email, Social
Enable/disable link Status field (Active/Disabled)
Expiration date Optional datetime
Password protection Optional, with POST endpoint for auth
Soft delete + restore Trash view with restore
Bulk import CSV-style paste with titles
URL allowlist/denylist Deferred - abuse prevention

1.4 QR Code Designer

Feature Status Notes
Generate from short link Required link association
Foreground/background colors Hex color pickers
Error correction levels L/M/Q/H options
Quiet zone padding Configurable
Module shapes Square, Rounded, Dots
Eye shapes Square, Rounded, Circle
Style presets 6 built-in presets
Logo upload PNG/JPG, select from assets or upload new
Logo size controls ⚠️ Fixed 20% - user controls deferred
Live preview Real-time updates
Export PNG Configurable size (256-2048px)
Export SVG Vector output
Print-ready options High contrast toggle deferred
Scan attribution Exports include ?qr={id} param

1.5 Tracking & Analytics

Feature Status Notes
Click events From redirect endpoint
Scan events When ?qr= param present
Async event logging Non-blocking, fire-and-forget
IP hashing SHA256 with daily salt
Dedupe (30-min window) Prevents duplicate counts
User agent parsing Device type detection
GeoIP lookup MaxMind GeoIP2 integration
Workspace analytics Totals, time series, breakdowns
Per-link analytics Individual link stats
Per-QR analytics Individual QR stats
Time filters 24h, 7d, 30d
Custom date range ⚠️ Backend ready, frontend UI needed
Referrer breakdown Top referrers list
Device breakdown Desktop/Mobile/Tablet
Country breakdown With flags and names
Monthly IP salt rotation Deferred - privacy enhancement
Event retention config Deferred - per-plan cleanup

1.6 Domain Management

Feature Status Notes
Add custom domain Pro/Business plans
DNS TXT verification Token-based
CNAME setup instructions UI guide
Domain status tracking Pending → Verified
Delete domain With warning

1.7 Asset Management

Feature Status Notes
Upload assets For QR logos
List workspace assets Gallery view
Delete assets With cleanup
Public asset URL For rendering

1.8 Plans & Billing

Feature Status Notes
Plan tiers (Free/Pro/Business) Configured limits
Usage tracking Links, QRs, domains, events
Plan limits enforcement In create endpoints
Stripe checkout Session-based
Stripe customer portal Manage subscription
Webhook handling Subscription events
Billing UI Plan comparison, upgrade flow

1.9 API Keys

Feature Status Notes
Create API key With name and expiry
List API keys Shows prefix, last used
Delete API key Revoke access
API key authentication Middleware needed

2. Plan Limits

Feature Free Pro Business
Workspaces 1 5 Unlimited
Links per workspace 50 5,000 Unlimited
QR codes per workspace 25 1,000 Unlimited
Custom domains 0 3 Unlimited
Events per month 10,000 100,000 Unlimited
Custom domains feature
Password protection
Analytics

3. Data Model

Core Entities

User
├── id, email, password_hash
├── is_email_verified, created_at
└── Relations: Workspaces, EmailVerificationTokens, PasswordResetTokens

Workspace
├── id, owner_user_id, name, plan
├── created_at
└── Relations: Projects, ShortLinks, QRCodeDesigns, Domains, Assets, Events, ApiKeys

Project
├── id, workspace_id, name, description
└── created_at

Domain
├── id, workspace_id, hostname
├── status (Pending/Verified), verification_token
└── created_at

ShortLink
├── id, workspace_id, project_id (nullable), domain_id (nullable)
├── slug, destination_url, title
├── status (Active/Disabled), expires_at, password_hash
├── click_count, is_deleted, deleted_at
└── created_at, updated_at

QRCodeDesign
├── id, workspace_id, project_id (nullable), link_id
├── name, style_json, logo_asset_id (nullable)
└── created_at, updated_at

Event
├── id, workspace_id, link_id, qr_code_id (nullable)
├── type (Click/Scan), timestamp
├── ip_hash, user_agent, referrer
├── country_code, device_type, dedupe_key
└── (partitioned by month for scale)

Asset
├── id, workspace_id, filename, storage_key
├── content_type, size_bytes
└── created_at

ApiKey
├── id, workspace_id, name, key_hash, key_prefix
├── scopes, expires_at, last_used_at, is_active
└── created_at

EmailVerificationToken
├── id, user_id, token, expires_at, used_at
└── created_at

PasswordResetToken
├── id, user_id, token, expires_at, used_at
└── created_at

4. System Architecture

Components

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   Vue 3 SPA     │────▶│  ASP.NET Core   │────▶│   PostgreSQL    │
│   + Pinia       │     │  FastEndpoints  │     │                 │
└─────────────────┘     └─────────────────┘     └─────────────────┘
                               │
                               ▼
                        ┌─────────────────┐
                        │  External APIs  │
                        │  - Stripe       │
                        │  - SMTP         │
                        │  - MaxMind      │
                        └─────────────────┘

Key Design Decisions

  1. Vertical Slice Architecture: Features organized in Features/{Feature}/ folders
  2. FastEndpoints: Lightweight alternative to MVC controllers
  3. Pinia State Management: Centralized frontend state with persistence
  4. Non-blocking Event Logging: Fire-and-forget to not slow redirects
  5. Soft Delete: Links can be restored from trash
  6. Scan Attribution: QR exports embed ?qr={id} for tracking

Public Redirect Flow

GET /{slug}?qr={id}
    │
    ▼
┌─────────────────────────────────────┐
│ 1. Resolve domain + slug → link     │
│ 2. Validate: exists, active, !expired│
│ 3. If password → return 401         │
│ 4. Log event async (scan if ?qr=)   │
│ 5. Return 302 redirect              │
└─────────────────────────────────────┘

5. API Endpoints

Authentication

  • POST /auth/register - Create account
  • POST /auth/login - Get JWT token
  • POST /auth/forgot - Request password reset
  • POST /auth/reset - Reset password with token
  • POST /auth/verify-email - Verify email
  • POST /auth/resend-verification - Resend verification email
  • GET /auth/profile - Get current user
  • PUT /auth/profile - Update profile
  • POST /auth/change-password - Change password
  • DELETE /auth/account - Delete account

Workspaces & Projects

  • GET/POST /workspaces - List/Create workspaces
  • GET/PUT/DELETE /workspaces/{id} - Workspace operations
  • GET/POST /workspaces/{id}/projects - List/Create projects
  • GET/PUT/DELETE /workspaces/{id}/projects/{pid} - Project operations
  • GET/POST /workspaces/{id}/links - List/Create links
  • POST /workspaces/{id}/links/bulk - Bulk create
  • GET/PUT/DELETE /workspaces/{id}/links/{lid} - Link operations
  • POST /workspaces/{id}/links/{lid}/restore - Restore deleted
  • GET /workspaces/{id}/links/{lid}/analytics - Link analytics

QR Codes

  • GET/POST /workspaces/{id}/qrcodes - List/Create QR codes
  • GET/PUT/DELETE /workspaces/{id}/qrcodes/{qid} - QR operations
  • GET /workspaces/{id}/qrcodes/{qid}/preview - Get preview (data URL)
  • GET /workspaces/{id}/qrcodes/{qid}/export - Export PNG/SVG
  • GET /workspaces/{id}/qrcodes/{qid}/analytics - QR analytics

Domains & Assets

  • GET/POST /workspaces/{id}/domains - List/Add domains
  • DELETE /workspaces/{id}/domains/{did} - Delete domain
  • POST /workspaces/{id}/domains/{did}/verify - Verify domain
  • GET/POST /workspaces/{id}/assets - List/Upload assets
  • DELETE /workspaces/{id}/assets/{aid} - Delete asset
  • GET /assets/{storageKey} - Public asset URL

Analytics & Usage

  • GET /workspaces/{id}/analytics - Workspace analytics
  • GET /usage - Usage stats and limits

Billing

  • POST /billing/checkout - Create Stripe checkout
  • POST /billing/portal - Create Stripe portal session
  • GET /workspaces/{id}/subscription - Get subscription
  • POST /billing/webhook - Stripe webhooks

API Keys

  • GET/POST /workspaces/{id}/api-keys - List/Create keys
  • DELETE /workspaces/{id}/api-keys/{kid} - Delete key

Public

  • GET /{slug} - Redirect to destination
  • POST /{slug} - Redirect with password

6. UI Pages

Page Route Status
Landing /
Login /login
Register /register
Forgot Password /forgot-password
Reset Password /reset-password
Verify Email /verify-email
Dashboard /dashboard
Links List /links
Link Detail /links/:id
QR Codes List /qrcodes
QR Designer /qrcodes/new, /qrcodes/:id
QR Analytics /qrcodes/:id/analytics
Analytics /analytics
Projects /projects
Domains /domains
Settings /settings
Billing /billing

7. Security & Performance

Implemented

  • JWT authentication with expiry
  • Rate limiting on auth endpoints (10 req/min)
  • Rate limiting on redirect endpoint (100 req/min)
  • Password hashing with BCrypt
  • IP hashing for privacy
  • CORS configuration
  • Global exception handling
  • Input validation with FluentValidation
  • Ownership verification on all endpoints

Deferred

  • Strict CSP headers
  • Monthly rotating IP salt
  • URL allowlist/denylist
  • Abuse reporting flow

8. Remaining Work

High Priority

  1. API Key Authentication Middleware - Enable programmatic access
  2. Bulk Create Plan Limits - Check limits in bulk endpoint
  3. Custom Date Range UI - Date picker for analytics

Medium Priority

  1. Background Jobs - Domain verification polling, event cleanup
  2. Logo Size Controls - User-adjustable logo size/margin
  3. Additional Tests - Auth, billing, API key endpoints

Lower Priority

  1. Print-Ready QR - High contrast mode
  2. Analytics Export - CSV/JSON download
  3. Strict CSP - Security headers
  4. IP Salt Rotation - Monthly rotation for privacy

9. Non-Goals (Post-MVP)

  • Team roles/permissions (RBAC)
  • A/B routing, smart rules, geo routing
  • Deep campaign automation
  • Enterprise SSO, SCIM
  • Offline QR scan tracking