Phase 2: share system + analytics feed (backend)
- share_links model/queries; opaque 12-char base62 tokens (PRD §17.1)
- POST /v1/cards/{id}/share — create share link (owner-scoped, modality-validated)
- GET /v1/s/{token} — record modality-attributed event (qr→qr_scan, nfc→nfc_tap)
and 302-redirect to the profile; unknown/expired → 404
- GET /v1/cards/{id}/share-links — list a card's links
- analytics_events now carry the share_token correlation
- GET /v1/cards/{id}/analytics/feed — chronological event feed (§6.7.2)
6 new integration tests; 73 backend tests total. fmt + clippy clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
c30d3afeec
commit
e66813ef58
@@ -4,7 +4,7 @@
|
||||
use axum::routing::{get, post};
|
||||
use axum::Router;
|
||||
|
||||
use crate::handlers::{analytics, assets, auth, cards, health, wallet};
|
||||
use crate::handlers::{analytics, assets, auth, cards, health, share, wallet};
|
||||
use crate::middleware::cors;
|
||||
use crate::state::AppState;
|
||||
|
||||
@@ -34,6 +34,10 @@ pub fn build_router(state: AppState) -> Router {
|
||||
.route("/cards/:id/wallet/apple", post(wallet::apple_pass))
|
||||
.route("/cards/handle/:handle", get(cards::get_card_by_handle))
|
||||
.route("/cards/:id/analytics", get(analytics::summary))
|
||||
.route("/cards/:id/analytics/feed", get(analytics::feed))
|
||||
.route("/cards/:id/share", post(share::create_share))
|
||||
.route("/cards/:id/share-links", get(share::list_shares))
|
||||
.route("/s/:token", get(share::resolve_share))
|
||||
.route("/analytics/event", post(analytics::ingest_event))
|
||||
.route("/assets/upload", post(assets::presign_upload))
|
||||
.route("/assets/*key", axum::routing::delete(assets::delete_asset));
|
||||
|
||||
Reference in New Issue
Block a user