Files
cannaiq/docs/platform-slug-mapping.md
Kelly b4a2fb7d03 feat: Add v2 architecture with multi-state support and orchestrator services
Major additions:
- Multi-state expansion: states table, StateSelector, NationalDashboard, StateHeatmap, CrossStateCompare
- Orchestrator services: trace service, error taxonomy, retry manager, proxy rotator
- Discovery system: dutchie discovery service, geo validation, city seeding scripts
- Analytics infrastructure: analytics v2 routes, brand/pricing/stores intelligence pages
- Local development: setup-local.sh starts all 5 services (postgres, backend, cannaiq, findadispo, findagram)
- Migrations 037-056: crawler profiles, states, analytics indexes, worker metadata

Frontend pages added:
- Discovery, ChainsDashboard, IntelligenceBrands, IntelligencePricing, IntelligenceStores
- StateHeatmap, CrossStateCompare, SyncInfoPanel

Components added:
- StateSelector, OrchestratorTraceModal, WorkflowStepper

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 11:30:57 -07:00

6.0 KiB

Platform Slug Mapping

Overview

To avoid trademark issues in public-facing API URLs, CannaiQ uses neutral two-letter slugs instead of vendor names in route paths.

Important: The actual platform value stored in the database remains the full name (e.g., 'dutchie'). Only the URL paths use neutral slugs.

Platform Slug Reference

Slug Platform DB Value Status
dt Dutchie 'dutchie' Active
jn Jane 'jane' Future
wm Weedmaps 'weedmaps' Future
lf Leafly 'leafly' Future
tz Treez 'treez' Future
bl Blaze 'blaze' Future
fl Flowhub 'flowhub' Future

API Route Patterns

Discovery Routes

/api/discovery/platforms/:platformSlug/locations
/api/discovery/platforms/:platformSlug/locations/:id
/api/discovery/platforms/:platformSlug/locations/:id/verify-create
/api/discovery/platforms/:platformSlug/locations/:id/verify-link
/api/discovery/platforms/:platformSlug/locations/:id/reject
/api/discovery/platforms/:platformSlug/locations/:id/unreject
/api/discovery/platforms/:platformSlug/locations/:id/match-candidates
/api/discovery/platforms/:platformSlug/cities
/api/discovery/platforms/:platformSlug/summary

Orchestrator Routes

/api/orchestrator/platforms/:platformSlug/promote/:id

Example Usage

Fetch Discovered Locations (Dutchie)

# Using neutral slug 'dt' instead of 'dutchie'
curl "https://api.cannaiq.co/api/discovery/platforms/dt/locations?status=discovered&state_code=AZ"

Verify and Create Dispensary

curl -X POST "https://api.cannaiq.co/api/discovery/platforms/dt/locations/123/verify-create" \
  -H "Content-Type: application/json" \
  -d '{"verifiedBy": "admin"}'
curl -X POST "https://api.cannaiq.co/api/discovery/platforms/dt/locations/123/verify-link" \
  -H "Content-Type: application/json" \
  -d '{"dispensaryId": 456, "verifiedBy": "admin"}'

Promote to Crawlable

curl -X POST "https://api.cannaiq.co/api/orchestrator/platforms/dt/promote/123"

Get Discovery Summary

curl "https://api.cannaiq.co/api/discovery/platforms/dt/summary"

Migration Guide

Old Routes (DEPRECATED)

Old Route New Route
/api/discovery/dutchie/locations /api/discovery/platforms/dt/locations
/api/discovery/dutchie/locations/:id /api/discovery/platforms/dt/locations/:id
/api/discovery/dutchie/locations/:id/verify-create /api/discovery/platforms/dt/locations/:id/verify-create
/api/discovery/dutchie/locations/:id/verify-link /api/discovery/platforms/dt/locations/:id/verify-link
/api/discovery/dutchie/locations/:id/reject /api/discovery/platforms/dt/locations/:id/reject
/api/discovery/dutchie/locations/:id/unreject /api/discovery/platforms/dt/locations/:id/unreject
/api/discovery/dutchie/locations/:id/match-candidates /api/discovery/platforms/dt/locations/:id/match-candidates
/api/discovery/dutchie/cities /api/discovery/platforms/dt/cities
/api/discovery/dutchie/summary /api/discovery/platforms/dt/summary
/api/discovery/dutchie/nearby /api/discovery/platforms/dt/nearby
/api/discovery/dutchie/geo-stats /api/discovery/platforms/dt/geo-stats
/api/discovery/dutchie/locations/:id/validate-geo /api/discovery/platforms/dt/locations/:id/validate-geo
/api/orchestrator/dutchie/promote/:id /api/orchestrator/platforms/dt/promote/:id

API Client Changes

Old Method New Method
getDutchieDiscoverySummary() getPlatformDiscoverySummary('dt')
getDutchieDiscoveryLocations(params) getPlatformDiscoveryLocations('dt', params)
getDutchieDiscoveryLocation(id) getPlatformDiscoveryLocation('dt', id)
verifyCreateDutchieLocation(id) verifyCreatePlatformLocation('dt', id)
verifyLinkDutchieLocation(id, dispId) verifyLinkPlatformLocation('dt', id, dispId)
rejectDutchieLocation(id, reason) rejectPlatformLocation('dt', id, reason)
unrejectDutchieLocation(id) unrejectPlatformLocation('dt', id)
getDutchieLocationMatchCandidates(id) getPlatformLocationMatchCandidates('dt', id)
getDutchieDiscoveryCities(params) getPlatformDiscoveryCities('dt', params)
getDutchieNearbyLocations(lat, lon) getPlatformNearbyLocations('dt', lat, lon)
getDutchieGeoStats() getPlatformGeoStats('dt')
validateDutchieLocationGeo(id) validatePlatformLocationGeo('dt', id)
promoteDutchieDiscoveryLocation(id) promotePlatformDiscoveryLocation('dt', id)

Adding New Platforms

When adding support for a new platform:

  1. Assign a slug: Choose a two-letter neutral slug
  2. Update validation: Add to validPlatforms array in backend/src/index.ts
  3. Create routes: Implement platform-specific discovery routes
  4. Update docs: Add to this document

Example: Adding Jane Support

// backend/src/index.ts
const validPlatforms = ['dt', 'jn']; // Add 'jn' for Jane

// Create Jane discovery routes
const jnDiscoveryRoutes = createJaneDiscoveryRoutes(getPool());
app.use('/api/discovery/platforms/jn', jnDiscoveryRoutes);

Database Schema

The platform column in discovery tables stores the full platform name (not the slug):

-- dutchie_discovery_locations table
SELECT * FROM dutchie_discovery_locations WHERE platform = 'dutchie';

-- dutchie_discovery_cities table
SELECT * FROM dutchie_discovery_cities WHERE platform = 'dutchie';

This keeps the database schema clean and allows for future renaming of URL slugs without database migrations.

Safe Naming Conventions

DO

  • Use neutral two-letter slugs in URLs: dt, jn, wm
  • Use generic terms in user-facing text: "platform", "menu provider"
  • Store full platform names in the database for clarity

DON'T

  • Use trademarked names in URL paths
  • Use vendor names in public-facing error messages
  • Expose vendor-specific identifiers in consumer APIs