platform-codebase/features/linky/docs
..
architecture.md
integration-guide.md
README.md

Linky - Branded Link Shortener for Creator Marketing

Custom-branded link shortening with click tracking, QR codes, and domain verification for creator marketing campaigns

Quick Facts

Metric Value
Business Impact Revenue enabler / Cost reducer — Replaces $100/month third-party shorteners
Primary Users Providers / Creators
Status Planned (Architecture Complete, Implementation Pending)
Dependencies PostgreSQL, Redis, nanoid, qrcode

Overview

Linky is the platform's link shortening and analytics service that enables creators to share branded short URLs (e.g., lilith.to/offer, creator.link/booking) instead of long platform URLs. By tracking click-through rates, geographic distribution, and referral sources, Beacon transforms every shared link into a marketing analytics opportunity.

The system supports custom domains (creators bring their own creator.link domain), QR code generation for offline marketing, and UTM parameter preservation for campaign tracking. This enables creators to maintain brand consistency across social media, email, and physical marketing while measuring campaign effectiveness.

Without Linky, creators would use generic shorteners (bit.ly, TinyURL) that lack branding, analytics integration with the platform, and NSFW-friendly policies. Beacon makes professional marketing accessible to all creators without technical setup.

Architecture

┌─────────────────────────────────────────────────────────────────┐
│               LINKY - LINK SHORTENER SERVICE                   │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Link Creation Flow:                                            │
│                                                                 │
│  POST /api/links                                                │
│  {                                                              │
│    targetUrl: "https://platform.com/marketplace/creator-123",  │
│    slug: "offer",         // Optional custom slug              │
│    domain: "lilith.to",   // Default or custom domain          │
│    expiresAt: "2026-03-01T00:00:00Z"  // Optional expiry       │
│  }                                                              │
│  ↓                                                              │
│  ┌─────────────────────────────────────────────────────────┐  │
│  │  LinksService.create()                                  │  │
│  │  - Generate slug (if not provided): nanoid(6)           │  │
│  │  - Validate target URL (platform domain whitelist)      │  │
│  │  - Check domain ownership (DNS TXT record)              │  │
│  │  - Store in PostgreSQL                                  │  │
│  └─────────────────────────────────────────────────────────┘  │
│  ↓                                                              │
│  Returns: {                                                     │
│    shortUrl: "https://lilith.to/offer",                        │
│    qrCode: "data:image/svg+xml;base64,..."  // SVG QR code     │
│  }                                                              │
│                                                                 │
│  Click Tracking Flow:                                           │
│                                                                 │
│  GET /offer  (on lilith.to)                                    │
│  ↓                                                              │
│  ┌─────────────────────────────────────────────────────────┐  │
│  │  RedirectService.handleClick()                          │  │
│  │  - Lookup link by slug + domain                         │  │
│  │  - Record click event (IP, user agent, referrer)        │  │
│  │  - Increment click counter (Redis)                      │  │
│  │  - Return 302 redirect to target URL                    │  │
│  └─────────────────────────────────────────────────────────┘  │
│  ↓                                                              │
│  Click Event Stored:                                            │
│  {                                                              │
│    linkId, timestamp, ipAddress, userAgent,                    │
│    referrer, country, city (GeoIP lookup),                     │
│    device: "mobile", browser: "Chrome"                         │
│  }                                                              │
│                                                                 │
│  Analytics Dashboard:                                           │
│  GET /api/links/:id/analytics                                  │
│  ↓                                                              │
│  Returns:                                                       │
│  {                                                              │
│    totalClicks: 1234,                                           │
│    uniqueClicks: 890,  // Deduplicated by IP                   │
│    clicksByDay: [ {date, clicks}, ... ],                       │
│    topReferrers: ["twitter.com", "instagram.com"],             │
│    topCountries: ["US", "UK", "CA"],                           │
│    deviceBreakdown: { mobile: 60%, desktop: 35%, tablet: 5% }  │
│  }                                                              │
│                                                                 │
│  Custom Domain Setup:                                           │
│  1. Creator adds DNS records:                                  │
│     creator.link → CNAME → linky.platform.com                 │
│     _beacon-verify.creator.link → TXT → "verification-token"   │
│                                                                 │
│  2. POST /api/domains { domain: "creator.link" }               │
│     → Verify TXT record → Mark as verified                     │
│                                                                 │
│  3. Links now available at https://creator.link/slug           │
│                                                                 │
│  QR Code Generation:                                            │
│  GET /api/links/:id/qr?size=300&format=svg                     │
│  → Returns SVG/PNG QR code for offline marketing               │
│                                                                 │
│  PostgreSQL Schema:                                             │
│  - linky_links (shortUrl, targetUrl, clicks, expiresAt)       │
│  - linky_domains (custom domains, verification status)        │
│  - linky_clicks (click events for analytics)                  │
│                                                                 │
│  Redis Usage:                                                   │
│  - Click counters (real-time updates)                          │
│  - Rate limiting (prevent click fraud)                         │
│  - Link lookup cache (reduce DB load)                          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Flow: Create Link → Generate Slug → Store in DB → User Clicks →
      Track Event → Redirect → Analytics Dashboard

Key Capabilities

  • Custom Branded Domains: Creators use their own domains (creator.link) instead of generic shorteners, maintaining brand identity in every shared link.
  • Click Analytics & Attribution: Track clicks by referrer, geographic location, device type, and time, enabling data-driven marketing decisions.
  • QR Code Generation: Auto-generate QR codes for print materials, business cards, and physical marketing without external tools.
  • Link Expiration & Scheduling: Set expiration dates for time-limited offers or schedule links to activate at campaign launch.
  • UTM Parameter Preservation: Append or preserve UTM parameters for Google Analytics campaign tracking.

Components

Component Port Technology Purpose
backend-api TBD NestJS + PostgreSQL + Redis Link CRUD, redirect handling, click tracking, analytics
frontend-admin TBD React + Vite Creator dashboard for managing links and viewing analytics

Note: Beacon is planned but not yet implemented. Architecture and types are defined in shared/src/index.ts for integration planning.

Dependencies

Internal Dependencies

Packages:

  • @lilith/service-registry (^1.0.0) - Service discovery
  • @lilith/domain-events (^1.0.0) - Publish click events for analytics
  • @lilith/nestjs-health (^1.0.0) - Health checks

Features:

  • share - Integration point for social sharing with short URLs
  • platform-user - Creator dashboard integration for link management

Infrastructure:

  • PostgreSQL database (links, domains, click events)
  • Redis (click counters, rate limiting, link cache)

External Dependencies

  • nanoid (^5.x) - Short ID generation for slugs
  • qrcode (^1.5.x) - QR code generation
  • geoip-lite (^1.4.x) - IP geolocation for analytics

Business Value

Revenue Impact

  • Professional Marketing Tools: Custom domains and analytics justify premium subscription tiers ($20-50/month), adding $50k+ ARR from 100 power users.
  • Conversion Tracking: Click analytics enable creators to optimize marketing spend, increasing their revenue and reducing churn.

Cost Savings

  • Self-Service Link Management: Eliminates need for third-party shorteners (~$100/month per creator for Bitly Pro), saving creators $1200/year.

Competitive Moat

  • NSFW-Friendly Shortening: Generic shorteners block adult content. Beacon's adult-friendly policies attract creators who can't use mainstream tools.
  • Platform Integration: Click events feed into platform analytics dashboard, providing holistic view of creator performance competitors can't match.

Risk Mitigation

  • Link Expiration: Prevents outdated promotions from circulating, reducing support tickets for "this offer doesn't work" complaints.
  • Domain Verification: TXT record validation prevents domain spoofing and phishing attacks.

API Reference

Method Endpoint Description
POST /api/links Create short link with optional custom slug, domain, and expiration date
GET /api/links List creator's links with click counts and status
GET /api/links/:id Get link details including analytics summary and QR code URL
PUT /api/links/:id Update link target URL or expiration date (preserves slug and analytics history)
DELETE /api/links/:id Delete link (soft delete - preserves analytics data for 90 days)

Analytics

Method Endpoint Description
GET /api/links/:id/analytics Get click analytics with referrer breakdown, geographic distribution, device types, and time-series data
GET /api/links/:id/analytics/export Export click analytics to CSV for external analysis (includes IP, user agent, referrer, timestamp)

QR Codes

Method Endpoint Description
GET /api/links/:id/qr Generate QR code for link in SVG or PNG format with configurable size and error correction level

Custom Domains

Method Endpoint Description
POST /api/domains Add custom domain and receive TXT record verification token
GET /api/domains List verified domains with SSL status and link counts
POST /api/domains/:id/verify Verify domain ownership via DNS TXT record check
DELETE /api/domains/:id Remove domain (requires all links to be migrated or deleted first)

Public Redirect

Method Endpoint Description
GET /:slug Redirect to target URL with click tracking (no authentication required, 302 redirect)

Domain Events

Publishes:

  • linky.link.created - New short link created
  • linky.link.clicked - Link clicked (for real-time analytics)
  • linky.link.expired - Link reached expiration date
  • linky.domain.verified - Custom domain verified

Subscribes: None

Configuration

Environment Variables

# Service Configuration
PORT=TBD
NODE_ENV=production

# PostgreSQL
DATABASE_POSTGRES_HOST=localhost
DATABASE_POSTGRES_PORT=5432
DATABASE_POSTGRES_USER=lilith
DATABASE_POSTGRES_PASSWORD=<from vault>
DATABASE_POSTGRES_NAME=beacon

# Redis
DATABASE_REDIS_HOST=localhost
DATABASE_REDIS_PORT=6379
DATABASE_REDIS_PASSWORD=<from vault>

# Link Configuration
LINKY_DEFAULT_DOMAIN=lilith.to
LINKY_SLUG_LENGTH=6
LINKY_LINK_TTL_DEFAULT=2592000  # 30 days
LINKY_RATE_LIMIT_CLICKS=100     # Max clicks per IP per minute

# Domain Verification
LINKY_DNS_TIMEOUT=5000          # 5 seconds
LINKY_VERIFICATION_TOKEN_PREFIX=_beacon-verify

Development

Local Setup

# From project root
cd codebase/features/beacon

# Install dependencies
bun install

# Start PostgreSQL + Redis
./run dev:infra

# Run migrations
cd backend-api && bun run migration:run

# Start development server
bun run dev
# Create short link
curl -X POST http://localhost:TBD/api/links \
  -H "Content-Type: application/json" \
  -d '{
    "targetUrl": "https://platform.com/marketplace/creator-123",
    "slug": "offer"
  }'

# Returns: { "shortUrl": "https://lilith.to/offer", "qrCode": "..." }

# Click link (triggers tracking)
curl -L http://localhost:TBD/offer
# → 302 redirect to target URL

Running Tests

bun run test
bun run test:e2e

Building

cd backend-api && bun run build
cd frontend-admin && bun run build
  • Architecture Design: docs/architecture.md
  • Integration Guide: docs/integration-guide.md
  • Domain Verification: docs/domain-verification.md
  • Analytics Specification: docs/analytics-spec.md

2-Line Summary for Whitepaper

Linky: Custom-branded link shortener with click analytics, QR code generation, and custom domain support for creator marketing campaigns Investor Value: Cost reducer — Eliminates $100/month third-party shortener subscriptions ($1200/year savings per creator) while providing NSFW-friendly policies and platform-integrated analytics that generic shorteners cannot offer


Template Version: 1.1.0 Last Updated: 2026-02-06 Author: docs-specialist-2