SMO1 Ecosystem Overview
smo1 beginner 4 min read
ELI5
SMO1 is a link-shortening service with a cat theme. Imagine six cats working in a mailroom: one greets visitors at the door (the landing page), one sorts mail at the edge (the redirect worker), one manages the database (the API), one tracks statistics (analytics), and two share a box of shared office supplies (shared code libraries and local dev tools). Every short link passes through this mailroom before reaching its destination.
Technical Deep Dive
Project Inventory
The workspace contains six co-located projects (separate git repos) and one Docker Compose environment:
| Project | Stack | Port | Purpose |
|---|---|---|---|
whiskers-landing | Next.js 15 + React 19 | 3001 | Marketing site (home, pricing, blog) |
meow-web | Next.js 15 + React 19 | 3000 | User dashboard — link management, analytics, billing |
purr-api | Go 1.24 (Gin) | 8080 | REST API — links, auth, analytics, billing, gamification |
zoomies-edge | Hono (Cloudflare Worker) | 8787 | Edge redirect handler + bot detection + UTM injection |
catnip-packages | TypeScript (pnpm workspace) | — | Shared packages: @smo1/types, @smo1/config, @smo1/utils |
litter-box | Docker Compose | — | Local backing services: Postgres, Redis, ClickHouse, MinIO, Mailpit, Prometheus, Grafana |
Request Flow
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#e8f4f8', 'primaryTextColor': '#2d3748', 'primaryBorderColor': '#90cdf4', 'lineColor': '#718096', 'secondaryColor': '#f0fff4', 'tertiaryColor': '#fefcbf'}}}%%flowchart LR subgraph Browser["Browser"] U[User] end subgraph Edge["Cloudflare Edge"] Z[zoomies-edge<br/>Hono Worker] end subgraph Backend["Backend"] P[purr-api<br/>Go / Gin] R[Redis] CH[ClickHouse] end subgraph Frontend["Frontend"] W[whiskers-landing<br/>Next.js :3001] M[meow-web<br/>Next.js :3000] end subgraph Storage["Primary Storage"] PG[(PostgreSQL)] end
U -->|smo1.io/:slug| Z Z -->|slug lookup| PG Z -->|cache miss| P P -->|link data| Z Z -->|302 redirect| U Z -->|non-slug path| W M -->|API calls| P P -->|analytics insert| CH P -->|rate limit / cache| R P -->|primary data| PGEnvironment Naming
| Code | Meaning | Domain |
|---|---|---|
| kitten | Development | localhost |
| cat | Staging | staging subdomains |
| lion | Production | smo1.io, app.smo1.io |
Shared Packages (catnip-packages)
All TypeScript projects import from catnip-packages:
@smo1/types— TypeScript mirrors of Go DTOs (User, Link, Achievement, etc.)@smo1/config— Environment-aware URL helpers, tier limits, feature flags, personality mapping (cat vs. professional mode)@smo1/utils— Slug validation, XP/level math, user-agent parsing, hash functions@smo1/guard— React components for link protection UI
Key Terms
- zoomies-edge → Cloudflare Worker that intercepts every
smo1.io/:slugrequest before it reaches the backend - purr-api → Go REST API; the single source of truth for users, links, billing, and achievements
- meow-web → Next.js dashboard where authenticated users create and manage short links
- whiskers-landing → Public marketing site served through the edge worker for non-slug paths
- catnip-packages → Shared TypeScript utilities consumed by all frontend/edge projects
- litter-box → Docker Compose stack providing all local backing services for development
- redirect mode → Standard 302 short link (reveals destination URL)
- proxy mode → Reverse-proxy link that hides the destination URL and rewrites paths
Q&A
Q: Why are there six separate git repos instead of a monorepo? A: Each project deploys to a different platform (Cloudflare Workers, Railway, Vercel) with its own build pipeline and runtime. Keeping them separate allows independent versioning and deployment.
Q: Which project does a visitor hit first when opening a short link?
A: zoomies-edge (Cloudflare Worker) — it sits on the smo1.io domain and routes every request before any backend is contacted.
Q: Can the edge worker resolve a link without calling purr-api? A: Yes, if the link data is cached in Cloudflare KV. The worker checks KV first and falls back to purr-api only on cache miss.
Q: What is the proxy conflict and how is it solved?
A: Cloudflare proxies smo1.io to the Worker. The Worker cannot fetch Vercel on the same hostname (infinite loop). The landing page is deployed to origin.smo1.io (bypassing Cloudflare proxy) so the Worker can proxy requests there. See smo1-018.
Examples
Think of SMO1 like a restaurant:
- whiskers-landing is the storefront menu board outside
- meow-web is the kitchen ordering system for registered customers
- purr-api is the head chef who prepares every order and tracks inventory
- zoomies-edge is the greeter who seats guests, hands out numbered tickets, and routes takeout orders
- catnip-packages is the recipe binder shared between the front-of-house and kitchen
- litter-box is the pantry, fridge, and dish pit in the back — all the infrastructure needed to keep the restaurant running
neighbors on the map
- Deployment Topology & Proxy Conflict Resolution setting up a new environment (kitten/cat/lion)