Two major advertiser-side UX improvements and one creator-side overhaul. Influencers are now discoverable via a scored, tabbed picker (same pattern as the vendor picker). The Media Kit page is renamed to "Public Profile" with samples, past brands, and view analytics.
Influencer Discovery (advertiser side)
- Migration
c1d2e4f5a6b7createsadvertiser_favorite_influencerstable - New endpoints on
/influencers: POST/DELETE /{ws}/favorite— idempotent star toggleGET /favorites— starred influencersGET /recent— influencers briefed in last 90 daysGET /searchextended withsort=recommended|follower_count_desc|engagement_rate_desc|rating_desc- Every row now carries
match_score,match_reasons[],has_restriction_conflict,is_favorite,rating_avg,rating_count,prior_briefs_count(4 batched queries, no N+1) - Scoring formula: 30% niche match + 10% collab types configured + 15% rating + 10% prior briefs + 8/4% verified + 5% engagement
- Recommended tab auto-excludes restriction conflicts; other tabs flag them with red "Cannot book" banner
- Frontend:
/influencerspage rewritten with 4 pill sub-tabs (Recommended / Favorites / Recent / All), URL persistence?sub=, filters always visible, star toggle on cards, match-reason chips, "Starred N days ago" / "Sent brief N days ago" badges
Public Profile (creator side)
- Migration
d1e2f3a4b5c6createsproperty_samples+media_kit_views(GDPR: SHA-256 IP hash only) - Sample Work — per-property CRUD via
POST/GET/PATCH/DELETE /workspaces/{ws}/properties/{pid}/samples. 20 active cap, URL validation, sort_order, metrics JSONB (likes/views/comments/shares/reach) - Past Brands — stored in existing
workspace.branding.past_brandsJSONB array (no schema change). Up to 20 entries with name + logo_url - View tracking (no-auth):
POST /public/media-kit/{slug-or-id}/track-view— fires on public page mount, 10-min IP-hash dedupe - Analytics (auth):
GET /media-kit/analytics— total/7d/30d views, 30-day sparkline, top 5 referrers, unique visitors - Referrer normalization : hostnames only (linkedin.com not linkedin.com/feed), internal self-referrers filtered, no-referrer visits bucketed as "Direct"
- Frontend:
- Sidebar "Media Kit" → "Public Profile"
- Properties page edit modal:
SampleWorkManagercomponent - Settings → Workspace: "Past Brands" editor with live preview strip
/profile/media-kit: analytics card at top (big 30-day count, recharts sparkline, top-3 referrers)/public/media-kit/[slug]: sample work grid per property, past-brands strip, fires view tracking on mount- PDF template extended to include samples + past brands
Files (14 new, 12 modified)
Backend: 2 migrations + 3 models + media_kit_analytics.py + extensions to briefs/marketplace/public/workspaces. Frontend: SampleWorkManager component, public.ts API client, rewrites of influencers/properties/settings/profile-media-kit pages.
---

