petrova.smo1.io: Custom-Domain Links for petrova.codes Artifacts
smo1 intermediate 6 min read
ELI5
petrova.codes publishes artifacts and wants short links on its own branded subdomain, petrova.smo1.io. The same edge worker serves it. The difference is that the API remembers which hostname a link belongs to, so petrova.smo1.io/report and smo1.io/report can point to different places. The configuration for the worker is in place; on 2026-10-25 the hostname itself did not yet exist in DNS.
Technical Deep Dive
Source: zoomies-edge wrangler.toml:40-48, src/handlers/redirect.ts:79-101, src/index.ts:201-256 (origin/main 5bdde59); purr-api migrations/000007_custom_domains.up.sql, internal/repository/link_repository.go:148-163, internal/service/link_service.go:26-32, 67-73, 104-111, 198-222, internal/models/link.go:112-116, 169-170, internal/service/redirect_cache.go:58-63, cmd/server/main.go:156-159 (bb6cfc2); smo1-io docs/runbooks/petrova-smo1-io-domain.md §1-5, docs/runbooks/petrova-codes-build-auth.md §1 (1f19667); DNS lookup of petrova.smo1.io, read 2026-10-25.
Prerequisites and request path
flowchart TD DNS["1. Proxied DNS record for petrova in the smo1.io zone"] --> RT["2. Worker route petrova.smo1.io/* in env.lion"] RT --> ROW["3. custom_domains row: hostname petrova.smo1.io, user_id = enterprise account"] ROW --> REQ["GET petrova.smo1.io/report"] REQ --> W["Worker: host = petrova.smo1.io"] W --> RES["purr-api /api/links/resolve?host=petrova.smo1.io and slug=report"] RES --> M{"link with domain_id = that row ?"} M -->|Yes| R302[302 to destination] M -->|No| LP[landing proxy]| Step | State on 2026-10-25 |
|---|---|
| Worker route | in wrangler.toml:40-48 on main; whether the deployed Worker carries it follows from the push-to-main deploy, not checked separately |
| DNS | petrova.smo1.io returned no address (lookup 2026-10-25): not provisioned |
custom_domains row | gated on the enterprise account from the build-auth runbook; production state UNVERIFIED |
Data model
Migration 000007 adds custom_domains(id, user_id text, hostname unique, verified_at, created_at) and links.domain_id (NULL means the apex). Custom-slug uniqueness becomes per (user_id, COALESCE(domain_id, nil-uuid), custom_slug), so an apex link and a petrova link may share a slug.
Host-aware resolution
ResolveByHostAndSlug (link_repository.go:153-163) matches custom_slug or uid, then requires COALESCE(domain_id, nil) to equal the id of the custom_domains row for the host, or nil when the host is unknown. An unknown host therefore resolves only apex links.
Creating petrova links
The petrova.codes build authenticates with a developer API key (X-API-Key) belonging to one business-tier enterprise account (build-auth runbook §1). A create request carries domain: "petrova.smo1.io" (link.go:112-116); resolveDomain refuses an unknown host (ErrDomainNotFound), a host owned by another account (ErrDomainForbidden), and a service built without the domain repository (ErrDomainsUnavailable) rather than silently creating an apex link (link_service.go:198-222). Short URLs are rendered as https://petrova.smo1.io/<slug> (link.go:169-170).
Still host-blind
- The edge’s proxy-mode probe calls
/api/links/slug/:slug, which isuid = $1 OR custom_slug = $1 LIMIT 1with no host (index.ts:243,link_repository.go:148). - Click tracking sends only the slug and resolves it the same host-blind way, so a colliding petrova custom slug can be credited to an apex link (smo1-008).
- The Redis redirect cache avoids the problem by never caching a custom-domain link under its bare slug (
redirect_cache.go:58-63).
Key Terms
- custom_domains — hostnames smo1 serves links on, each owned by one user
- domain_id — the link’s custom domain; NULL for
smo1.io - resolveDomain — create-time check that the requester owns the hostname
- ResolveByHostAndSlug — the host-aware lookup behind
/api/links/resolve
Q&A
Q: Which three things must exist before petrova.smo1.io/petrova in the smo1.io zone, the petrova.smo1.io/* route on the deployed lion Worker, and a custom_domains row for the hostname owned by the account that created the links. On 2026-10-25 the DNS record was missing.
Q: How does purr-api pick between an apex link and a petrova.smo1.io link with the same custom slug?
A: By host: /api/links/resolve joins the request’s hostname to custom_domains and only matches links whose domain_id equals that row’s id, or NULL for the apex.
Q: Which smo1 code paths are still host-blind for custom domains?
A: The Worker’s proxy-mode probe (/api/links/slug/:slug) and click-tracking attribution (/api/analytics/track by slug). Both use the uid OR custom_slug LIMIT 1 lookup.
Examples
Runbook §5’s check: create a throwaway link with domain_id set to the petrova row and custom slug rbook-test, then curl -sI https://petrova.smo1.io/rbook-test should return a 302. Run today, that curl fails at DNS resolution, which is the step to fix first.
neighbors on the map
- Deployment Topology, Proxy Conflict & CI after eu-1 finding where a smo1 component runs and how it deploys
- Click Tracking Pipeline debugging missing or duplicate click counts
- Proxy Mode implementing a white-label short link