Skip to content

Extract /v1/attribution/* into its own api slice#115

Merged
saltyskip merged 1 commit intomainfrom
extract-attribution-slice
May 1, 2026
Merged

Extract /v1/attribution/* into its own api slice#115
saltyskip merged 1 commit intomainfrom
extract-attribution-slice

Conversation

@saltyskip
Copy link
Copy Markdown
Owner

Summary

The three SDK-authenticated attribution endpoints — click, install, identify — were living in api/links/routes.rs because they touch data on LinksRepository. But the URL surface (/v1/attribution/*) and the auth gate (pk_live_ SDK keys, not rl_live_ secret keys) make them logically distinct. Burying them under links made api/links/routes.rs less focused.

This is a transport-only split — the data domain stays unified.

What moved

Before After
api/links/routes.rs::attribution_click api/attribution/routes.rs::attribution_click
api/links/routes.rs::attribution_report api/attribution/routes.rs::attribution_report
api/links/routes.rs::link_attribution api/attribution/routes.rs::link_attribution
api/links/mod.rs::sdk route group api/attribution/mod.rs::router

What stayed

  • Data layer unchanged. Attribution document, AttributionReportRequest, ClickRequest, LinkAttributionRequest, AttributionResponse all stay in services/links/models.rs next to the Link document. The new slice imports them.
  • get_link_timeseries stays in api/links/routes.rs — it's link-scoped analytics under /v1/links/{link_id}/timeseries, not an SDK attribution path.

Helpers reused via pub(crate)

Three helpers in api/links/routes.rs are used by both link resolve flow and the new attribution slice. Made them pub(crate) rather than duplicating:

  • check_link_resolvable(link) — link-status / expiry gate
  • Platform enum
  • detect_platform(user_agent) — UA-based detection

Duplicating either would risk policy drift between the resolve path and the attribution path. pub(crate) keeps them as the single source of truth without leaking outside the crate.

OpenAPI

The three attribution paths now register under attribution::routes::* instead of links::routes::*. Schema names are unchanged, so the generated OpenAPI document is byte-identical.

Test plan

  • cargo fmt -- --check
  • cargo clippy --all-targets -- -D warnings
  • cargo test — 107 lib + 145 integration tests pass
  • No behavior change — pure code motion + transport-layer organization

🤖 Generated with Claude Code

The three SDK-authenticated attribution endpoints — click, install,
identify — were living in `api/links/routes.rs` because they touch
data on `LinksRepository`. But the URL surface (`/v1/attribution/*`)
and the auth gate (`pk_live_` SDK keys, not `rl_live_` secret keys)
make them logically distinct. Burying them under links makes
`api/links/routes.rs` less focused and less greppable.

Transport-only split: the data domain stays unified — Attribution
documents and the related DTOs live in `services/links/models.rs`
alongside the Link document. The new `api/attribution/` slice imports
those DTOs and reuses three helpers from `api/links/routes.rs` made
`pub(crate)`: `check_link_resolvable` (shared link-status gate),
`detect_platform`, and `Platform` (UA-based platform detection).
Duplicating either would risk policy drift between resolve and
attribution paths.

Removes the `sdk` route group from `api/links/mod.rs` and registers
`api/attribution::router` from `api/mod.rs`. OpenAPI registration
moves the three attribution paths under the new module path; schema
names are unchanged so the spec output is byte-identical.

`get_link_timeseries` stays in `api/links/routes.rs` — link-scoped
analytics under `/v1/links/{link_id}/timeseries`, not an SDK
attribution path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
rift Ready Ready Preview, Comment May 1, 2026 5:36pm

Request Review

@saltyskip saltyskip merged commit 7443c31 into main May 1, 2026
5 checks passed
@saltyskip saltyskip deleted the extract-attribution-slice branch May 1, 2026 17:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant