Database schema
SQLite (libSQL) schema defined in db/schema.ts. Apply with drizzle-kit push.
users
Internal user id, unique clerk_user_id, optional email, created_at.
workspaces
name, plan (free | pro), Stripe fields (stripe_customer_id, stripe_subscription_id, subscription_status, current_period_end), created_at.
workspace_members
Composite PK (workspace_id, user_id), role (default owner), created_at. Cascade delete when workspace or user is removed.
links
id(uuid),slug(unique),destination_urlbot_title,bot_description, optionalog_image_urlcreated_at, optionalworkspace_id(null = legacy anonymous links still resolvable)- Optional:
campaign,notes,utm_source,utm_medium,utm_campaign expires_at,is_active(boolean, default true)
link_clicks
id, link_id → links, slug, created_at, optional referrer, country. Indexed on (link_id, created_at).
api_keys
id, workspace_id, key_hash (SHA-256 of raw key), optional name, created_at, last_used_at.
custom_domains
id, workspace_id, unique host, verified boolean, created_at.
stripe_events_processed
event_id (PK), created_at — idempotent webhook processing.
rate_limit_buckets
id, key (fingerprint string), window_start, count — per-minute buckets for create-link rate limiting.