Context
Public, read-only distribution: shareable report links and iframe embeds, driven by ReportShare tokens (#9). SSR matters here - a shared report is a marketing artifact and must render fully server-side (#11 components are SSR-safe by design).
Scope
- Share links:
/s/{token}renders the published report read-only - no auth, no project chrome, branded footer ("Made with ReportsHQ" linking home; removal is a Pro perk via #18). Tokens revocable and optionally expiring; rotating a token kills old links. - Scope control: a share exposes exactly the published snapshot with its default range; viewer-side range/filter changes are allowed but bounded to the report's own events (re-query through #10 with the share token as the authz principal - a dedicated middleware, never the bearer path).
- Embeds:
/embed/{token}variant with minimal chrome sized for iframes;X-Frame-Options/CSP set correctly for embed-only routes while the rest of the app stays deny; a copy-paste embed snippet in the share UI. - Rate limiting + caching on public routes (short-TTL cache keyed on token + range via
@stacksjs/cache; the public path must not let one viral link melt the query engine, #10). - No leakage: shares never expose project metadata, member info, ingest keys, raw event properties beyond what the published blocks aggregate; assert this in tests, not just review.
- Share management UI on the report (#13): create/copy/revoke, expiry, per-share view counter (best-effort, meterable in #18).
- OG/social meta on share pages (title, description, and an SSR-rendered preview image can be a follow-up; at minimum correct text meta).
- Feature tests: revocation immediacy, expiry, scope bounding, leakage assertions, embed headers.
Acceptance
- A share link renders the seeded report in a logged-out browser; revoking it 404s within one request; the embed snippet works from a plain HTML file.
Depends on #9, #10, #13, #18 (gating). Part of #1 (M7 Launch). Ground rules: see #1.