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

395 lines
13 KiB
Markdown

# 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 |
### 1.3 Short Link Management
| 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
### Links
- `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
- [x] JWT authentication with expiry
- [x] Rate limiting on auth endpoints (10 req/min)
- [x] Rate limiting on redirect endpoint (100 req/min)
- [x] Password hashing with BCrypt
- [x] IP hashing for privacy
- [x] CORS configuration
- [x] Global exception handling
- [x] Input validation with FluentValidation
- [x] 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
4. **Background Jobs** - Domain verification polling, event cleanup
5. **Logo Size Controls** - User-adjustable logo size/margin
6. **Additional Tests** - Auth, billing, API key endpoints
### Lower Priority
7. **Print-Ready QR** - High contrast mode
8. **Analytics Export** - CSV/JSON download
9. **Strict CSP** - Security headers
10. **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