Product definition
Scope: the durable product definition — what OptoLink is, who it serves, what
shipped, what is deliberately deferred. This is a digest, not a copy: the full
historical PRD (v2.0, June 2026) stays in the legacy monorepo tree
(docs/v2.1.0/OptoLink_PRD_v2.md) and is archived by B-021. Current numbers live
in Pricing & plans, not here.
What OptoLink is
A deep linking and mobile attribution platform. Short links route mobile users to in-app content (Universal Links / App Links), deferred deep linking preserves link intent across the app-store install flow (clipboard token → device fingerprint matching ladder), and click events are tracked for analytics and billing. QR codes and custom branded domains (CNAME + auto-SSL) are first-class link surfaces.
Product stages
- v1 — API platform. Deep links, deferred deep links, QR, custom domains, Base62 short codes, org provisioning via an internal Admin API, Flutter SDK. No UI, no self-service.
- v2 — Portal & self-service (shipped). Clerk identity, the self-service organisation portal, the internal ops surface, the billing framework (five plans, two currency-routed gateways), native iOS + Android + Node SDKs alongside Flutter.
The PRD's open decisions — all resolved
PRD v2 listed seven decision-required items. Where they landed:
| PRD question | Resolution |
|---|---|
| Identity provider | Clerk (the managed-provider option) — platform decision, see decisions |
| Payment provider | Both, currency-routed: USD → Stripe, EGP → Paymob — platform decision |
| Plan tiers & quotas | Shipped ladder differs from the PRD's draft — source of truth is plans.config.ts, see Pricing & plans |
| Quota enforcement behavior | Block/overage per quota key via EntitlementsService — see Entitlements enforcement |
| Ops dashboard security | Ops surface lives inside the portal app behind OpsRoleGuard (Clerk ops org), not a separate subdomain |
| Domain removal grace | 30-day grace period, then 410 — see Custom domains |
| API-key rotation overlap | CLIENT keys carry a 24-hour grace window on regenerate — see the SDK contract pages |
Audiences
- Organisations — the portal is their surface: links, domains, templates, API keys, team, billing. Roles: Owner / Admin / Developer / Analyst / Viewer (the five-role model shipped).
- SDK integrators — developers embedding OptoLink in Flutter, iOS, Android, or Node apps; they use API keys, never Clerk.
- OptoLink ops — the internal ops surface (org management, plan overrides, quota credits, audit log) reached through the ops org, not a public product.
Non-functional commitments (still policy)
- Link resolution is the revenue-critical path: p95 < 200 ms, 99.9% uptime target, and quota enforcement must never break resolution — consequences of a breach fall on the organisation (creation blocked / overage billed), never on the end user clicking a link.
- Per-org data isolation at the query level; device fingerprints TTL-purged; geo stored at country/city level, IPs not retained after resolution.
- Analytics freshness: per-link counts within 60 s; org summaries ≤ 5 min.
Locked decisions
- Free orgs are single-user by design (2026-08-09). The seat count includes
the owner (
used < limitcounts everyOrgMemberrow), so the 1-seat free tier cannot invite anyone. Intentional — do not exclude the owner or bump the limit. Source:optolink-backend/src/entitlements/plans.config.ts.
Deliberately deferred (v3 or later)
Install attribution with lookback windows, in-app event tracking, campaign management, A/B testing, fraud detection, smart banners, referral/invite links, webhooks & integrations, white-label/custom themes, aggregated/cohort reports. The full deferral table (with the PRD's reasoning) is in the legacy PRD §2.2; the shipped feature/plan mapping is Feature registry. The MAU meter from the pricing research is not shipped — it is backlog B-026.
Source-checked against optolink-backend @ 29f8589 (plans.config.ts, main.ts PORTAL_URL CORS), optolink-portal @ 7d31d45, 2026-10-07. The "resolved decisions" rows restate verified platform facts; the historical narrative is quoted from the legacy PRD without re-verification.