2nd release that day
Replaces the flat vendor dropdown on campaign deliverable assignment with a searchable, filterable, recommendation-ranked picker. Vendors are now discoverable platform-wide (cross-workspace) for assignment.
Architecture change
- Migration
b0c1d2e3f4a5addsis_platform_wide BOOLEAN NOT NULL DEFAULT TRUEtovendorstable; existing vendors backfilled totrue - Vendors can now be found and assigned across workspaces; existing tenant-scoped endpoints (
GET /vendors,/vendors/me,/vendors/{id}) preserved untouched for backward compatibility
Backend
- New
GET /vendors/service-types— public master taxonomy (21 standardized service types across 8 categories: Video, Visual, Content, Audio, Marketing, Development, Advisory) - New
GET /vendors/search— platform-wide, role-gated to advertiser/agency/SA. Supportsq,service,category,rating_min,verified_only,currency,max_budget,sort(recommended/rating/rate/name),for_deliverable_idfor context-aware recommendations - Returns per-vendor derived fields computed from single pre-query (no N+1):
active_deliverables_count,on_time_pct,distinct_clients_30d - Recommendation score blends: service match (25%) + category overlap (20%) + rating (15%) + on-time delivery (15%) + prior jobs with advertiser (10%) + verified bonus (8%) + workload inverse (5%), with explainable
match_reasonsper card - Fuzzy fallback matching for freetext
vendor.servicesvalues against standardized service types
Frontend
- New
VendorPickerModalcomponent (searchable filters + paginated card grid + match-reason chips) - New
useVendorServiceTypeshook (module-cached, static fallback) /campaigns/[id]/deliverablespage — "Browse Vendors" button replaces the flat vendor dropdown
Preserved (untouched)
GET /vendors(agency's own roster, tenant-scoped) still returns 200- Vendor self-access, deliverables, invoices, approvals — all intact
---

