# 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) ```bash # 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 ```bash curl -X POST "https://api.cannaiq.co/api/discovery/platforms/dt/locations/123/verify-create" \ -H "Content-Type: application/json" \ -d '{"verifiedBy": "admin"}' ``` ### Link to Existing Dispensary ```bash 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 ```bash curl -X POST "https://api.cannaiq.co/api/orchestrator/platforms/dt/promote/123" ``` ### Get Discovery Summary ```bash 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 ```typescript // 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): ```sql -- 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