Integrations
Location: dg_smart_pos_api/modules/Integrations. The stub for this page previously flagged that the module’s name suggested broader scope than the single model (PlatformProductMapping) found in an earlier scan. That model count is still accurate (Models/ really does hold only one class), but the module itself is broader than that: it owns storefront marketing/tag settings (Meta Pixel, Google Ads, GA4, GTM, Search Console verification), OAuth connect/disconnect for platform accounts, an inbound webhook receiver, and the per-variant sync-state tracking (PlatformProductMapping) between a store’s catalog and Meta Catalog / Google Merchant Center feeds. It leans on Ecommerce for the storefront/website/domain it configures and on Inventory for the stock/variant being mapped.
Data model
Section titled “Data model”PlatformProductMapping- the only model inmodules/Integrations/Models. Tracks one internal stock variant’s (internal_variant_id, belongs toModules\Inventory\Models\NewStock) sync state against one external platform (platform,external_item_id), with async_status(pending/synced/failed_rejected/failed_transient),retry_count,last_synced_at,last_error.- Everything else the module reads/writes lives on central-DB models it does not own:
App\Models\Website,App\Models\WebsiteMarketingSettings,App\Models\PlatformConnection,App\Models\PlatformConnectionEvent. This split (one tenant-scoped module model, several central models it operates on viatenancy()->central()) is why the module’s controllers explicitly wrap DB access intenancy()->central(fn () => ...)closures rather than reading them directly.
Marketing settings (self-service, no OAuth)
Section titled “Marketing settings (self-service, no OAuth)”MarketingSettingsController::show/update read and write WebsiteMarketingSettings (Pixel/GA4/GTM/verification IDs) for the current store’s website. show also returns feeds (the public google-merchant.xml/meta-catalog.csv URLs served from the shop’s own domain, not the API host) and a cached feed_readiness summary (total/ready/held_back/reasons) computed by ProductFeedQualification over StorefrontCatalogService::feedProducts(), cached 5 minutes per website since it walks the whole published catalogue. update skips readiness entirely since saving a Pixel ID can’t change it.
Platform OAuth connections
Section titled “Platform OAuth connections”PlatformConnectionController::index/connect/disconnect are the tenant-side self-service surface: connect returns an authorization URL for the frontend to redirect the browser to (via PlatformConnectorRegistry::resolve($platform)->getAuthorizationUrl()), and disconnect looks up the store’s PlatformConnection row and hands it to the connector to tear down.
OAuth callback and webhooks (central, not tenant)
Section titled “OAuth callback and webhooks (central, not tenant)”PlatformWebhookController::handle currently only logs the payload and returns 200 for any registered platform (always 200 even for an unregistered one, deliberately, so a provider doesn’t retry-storm a dead endpoint) - per its own docblock, this was built ahead of Phase 3 connector work, so no connector consumes the webhook body yet.
Route surface
Section titled “Route surface”Tenant-scoped, auth:sanctum, prefix integrations/stores/{store}, registered via modules/Integrations/Routes/integrations.php (required from routes/tenant.php):
| Method | Path | Controller method | Permission |
|---|---|---|---|
| GET | marketing-settings |
MarketingSettingsController::show |
storefront:view-settings |
| PUT | marketing-settings |
MarketingSettingsController::update |
storefront:manage-settings |
| GET | platform-connections |
PlatformConnectionController::index |
storefront:view-settings |
| POST | platform-connections/{platform}/connect |
PlatformConnectionController::connect |
storefront:manage-settings |
| POST | platform-connections/{platform}/disconnect |
PlatformConnectionController::disconnect |
storefront:manage-settings |
Central, no tenancy middleware, no X-Tenant-ID header, registered directly in routes/api.php:
| Method | Path | Controller method |
|---|---|---|
| GET | integrations/{platform}/callback |
PlatformOAuthCallbackController::handle |
| POST | integrations/{platform}/webhook |
PlatformWebhookController::handle |
A comment on the tenant-route registration in routes/tenant.php notes that MarketingSettingsController and PlatformConnectionController were pre-existing but “never wired into tenant.php until now” before this require was added, meaning they were previously unreachable from an actual tenant request despite existing in code.