diff --git a/angular.json b/angular.json index 72cbb99..7e17eb3 100644 --- a/angular.json +++ b/angular.json @@ -49,6 +49,10 @@ { "replace": "src/app/interceptors/mock-data.interceptor.ts", "with": "src/app/interceptors/mock-data.interceptor.production.ts" + }, + { + "replace": "src/app/mock-gateway.providers.ts", + "with": "src/app/mock-gateway.providers.production.ts" } ], "styles": [ diff --git a/scripts/ci/scan-bundle.sh b/scripts/ci/scan-bundle.sh index 2379405..bdb7403 100644 --- a/scripts/ci/scan-bundle.sh +++ b/scripts/ci/scan-bundle.sh @@ -2,6 +2,13 @@ # Fails the build if a production bundle contains anything that should only # ever exist server-side. # +# It also fails on mock gateway code, for the same reason in a different +# register: a production build that can reach a *LocalGateway is a production +# build that can serve seeded fixtures as if they were real data. Those used to +# ship - a fixture string from partner-hierarchy-local.gateway.ts was present in +# a production bundle on 2026-08-21 - because naming both classes in a token +# factory kept both reachable no matter what the flag said. +# # Why this exists: the storefront used to send provider payment credentials # from the browser - an `authorization-key` header, a `userid-value` header, # and a hardcoded partner ID literal compiled into the bundle. That code is @@ -30,6 +37,8 @@ PATTERNS=( "private key block|BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY" "aws access key|AKIA[0-9A-Z]{16}" "telegram bot token|[0-9]{8,10}:AA[0-9A-Za-z_-]{33}" + "mock gateway class|[A-Za-z]+LocalGateway" + "mock gateway fixture|ptr_local|customer_vk_mock" ) failed=0 @@ -49,7 +58,9 @@ done if [[ $failed -ne 0 ]]; then echo >&2 - echo "A credential reached the browser bundle. Move it behind the API." >&2 + echo "Something reached the browser bundle that should not have." >&2 + echo "Credentials belong behind the API; mock gateways belong in dev-only" >&2 + echo "providers swapped out by angular.json fileReplacements." >&2 exit 1 fi diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 98534c8..5cdbe2f 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -16,6 +16,7 @@ import { MockMediaRepository } from './core/media/mock-media-repository.service' import { ApiConfigService } from './core/config/api-config.service'; import { TenantResolverService } from './core/config/tenant-resolver.service'; import { environment } from '../environments/environment'; +import { MOCK_GATEWAY_PROVIDERS } from './mock-gateway.providers'; export const appConfig: ApplicationConfig = { providers: [ @@ -72,6 +73,9 @@ export const appConfig: ApplicationConfig = { provideServiceWorker('ngsw-worker.js', { enabled: !isDevMode(), registrationStrategy: 'registerWhenStable:30000' - }) + }), + // Empty in production - the file is swapped at build time so no mock + // gateway is even importable there. See mock-gateway.providers.ts. + ...MOCK_GATEWAY_PROVIDERS ] }; diff --git a/src/app/core/analytics/services/analytics-gateway.token.ts b/src/app/core/analytics/services/analytics-gateway.token.ts index af1b2d2..8bb6e9e 100644 --- a/src/app/core/analytics/services/analytics-gateway.token.ts +++ b/src/app/core/analytics/services/analytics-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../environments/environment'; import { AnalyticsGateway } from './analytics-gateway.interface'; -import { AnalyticsLocalGateway } from './analytics-local.gateway'; import { AnalyticsApiGateway } from './analytics-api.gateway'; /** Swap point for docs/backend/TRACK-A-ANALYTICS-CONTRACT.md §1. */ export const ANALYTICS_GATEWAY = new InjectionToken('ANALYTICS_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(AnalyticsLocalGateway) : inject(AnalyticsApiGateway)), + factory: () => inject(AnalyticsApiGateway), }); diff --git a/src/app/core/cart/services/server-cart-gateway.token.ts b/src/app/core/cart/services/server-cart-gateway.token.ts index b622b45..a690884 100644 --- a/src/app/core/cart/services/server-cart-gateway.token.ts +++ b/src/app/core/cart/services/server-cart-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../environments/environment'; import { ServerCartGateway } from './server-cart-gateway.interface'; -import { ServerCartLocalGateway } from './server-cart-local.gateway'; import { ServerCartApiGateway } from './server-cart-api.gateway'; /** Swap point for docs/backend/PHASE-6-CART-CHECKOUT-CONTRACT.md §3, §5. */ export const SERVER_CART_GATEWAY = new InjectionToken('SERVER_CART_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(ServerCartLocalGateway) : inject(ServerCartApiGateway)), + factory: () => inject(ServerCartApiGateway), }); diff --git a/src/app/core/content-modules/services/mall-content-gateway.token.ts b/src/app/core/content-modules/services/mall-content-gateway.token.ts index 18ca97e..0b7b314 100644 --- a/src/app/core/content-modules/services/mall-content-gateway.token.ts +++ b/src/app/core/content-modules/services/mall-content-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../environments/environment'; import { MallContentGateway } from './mall-content-gateway.interface'; -import { MallContentLocalGateway } from './mall-content-local.gateway'; import { MallContentApiGateway } from './mall-content-api.gateway'; /** Swap point for docs/backend/PHASE-10-CONTENT-MODULES-CONTRACT.md. */ export const MALL_CONTENT_GATEWAY = new InjectionToken('MALL_CONTENT_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(MallContentLocalGateway) : inject(MallContentApiGateway)), + factory: () => inject(MallContentApiGateway), }); diff --git a/src/app/core/finance/services/finance-gateway.token.ts b/src/app/core/finance/services/finance-gateway.token.ts index a51d8ce..d7dd8c8 100644 --- a/src/app/core/finance/services/finance-gateway.token.ts +++ b/src/app/core/finance/services/finance-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../environments/environment'; import { FinanceGateway } from './finance-gateway.interface'; -import { FinanceLocalGateway } from './finance-local.gateway'; import { FinanceApiGateway } from './finance-api.gateway'; /** Swap point for docs/backend/PHASE-7-PAYMENTS-RECONCILIATION-CONTRACT.md. */ export const FINANCE_GATEWAY = new InjectionToken('FINANCE_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(FinanceLocalGateway) : inject(FinanceApiGateway)), + factory: () => inject(FinanceApiGateway), }); diff --git a/src/app/core/identity/services/social-identity-gateway.token.ts b/src/app/core/identity/services/social-identity-gateway.token.ts index ced18ec..e7fbe9d 100644 --- a/src/app/core/identity/services/social-identity-gateway.token.ts +++ b/src/app/core/identity/services/social-identity-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../environments/environment'; import { SocialIdentityGateway } from './social-identity-gateway.interface'; -import { SocialIdentityLocalGateway } from './social-identity-local.gateway'; import { SocialIdentityApiGateway } from './social-identity-api.gateway'; /** Swap point for docs/backend/PHASE-8-IDENTITY-MESSAGING-CONTRACT.md §2. */ export const SOCIAL_IDENTITY_GATEWAY = new InjectionToken('SOCIAL_IDENTITY_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(SocialIdentityLocalGateway) : inject(SocialIdentityApiGateway)), + factory: () => inject(SocialIdentityApiGateway), }); diff --git a/src/app/core/integrations/services/connector-gateway.token.ts b/src/app/core/integrations/services/connector-gateway.token.ts index f416cdf..290c518 100644 --- a/src/app/core/integrations/services/connector-gateway.token.ts +++ b/src/app/core/integrations/services/connector-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../environments/environment'; import { ConnectorGateway } from './connector-gateway.interface'; -import { ConnectorLocalGateway } from './connector-local.gateway'; import { ConnectorApiGateway } from './connector-api.gateway'; /** Swap point for docs/backend/PHASE-4-CONNECTOR-FRAMEWORK-CONTRACT.md §7. */ export const CONNECTOR_GATEWAY = new InjectionToken('CONNECTOR_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(ConnectorLocalGateway) : inject(ConnectorApiGateway)), + factory: () => inject(ConnectorApiGateway), }); diff --git a/src/app/core/marketplace-registry/services/marketplace-gateway.token.ts b/src/app/core/marketplace-registry/services/marketplace-gateway.token.ts index f1c492b..c8ea6c0 100644 --- a/src/app/core/marketplace-registry/services/marketplace-gateway.token.ts +++ b/src/app/core/marketplace-registry/services/marketplace-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../environments/environment'; import { MarketplaceGateway } from './marketplace-gateway.interface'; -import { MarketplaceLocalGateway } from './marketplace-local.gateway'; import { MarketplaceApiGateway } from './marketplace-api.gateway'; /** Swap point for docs/backend/PHASE-9-TENANT-REGISTRY-DOMAINS-CONTRACT.md. */ export const MARKETPLACE_GATEWAY = new InjectionToken('MARKETPLACE_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(MarketplaceLocalGateway) : inject(MarketplaceApiGateway)), + factory: () => inject(MarketplaceApiGateway), }); diff --git a/src/app/core/marketplace-registry/services/marketplace-revision-gateway.token.ts b/src/app/core/marketplace-registry/services/marketplace-revision-gateway.token.ts index e18cdf9..da6c99b 100644 --- a/src/app/core/marketplace-registry/services/marketplace-revision-gateway.token.ts +++ b/src/app/core/marketplace-registry/services/marketplace-revision-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../environments/environment'; import { MarketplaceRevisionGateway } from './marketplace-revision-gateway.interface'; -import { MarketplaceRevisionLocalGateway } from './marketplace-revision-local.gateway'; import { MarketplaceRevisionApiGateway } from './marketplace-revision-api.gateway'; /** Swap point for docs/backend/PHASE-9-TENANT-REGISTRY-DOMAINS-CONTRACT.md §5. */ export const MARKETPLACE_REVISION_GATEWAY = new InjectionToken('MARKETPLACE_REVISION_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(MarketplaceRevisionLocalGateway) : inject(MarketplaceRevisionApiGateway)), + factory: () => inject(MarketplaceRevisionApiGateway), }); diff --git a/src/app/core/offers/services/offer-gateway.token.ts b/src/app/core/offers/services/offer-gateway.token.ts index a237433..c5f4acb 100644 --- a/src/app/core/offers/services/offer-gateway.token.ts +++ b/src/app/core/offers/services/offer-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../environments/environment'; import { OfferGateway } from './offer-gateway.interface'; -import { OfferLocalGateway } from './offer-local.gateway'; import { OfferApiGateway } from './offer-api.gateway'; /** Swap point for docs/backend/PHASE-3-CATALOG-OFFER-FULFILLMENT-CONTRACT.md §7. */ export const OFFER_GATEWAY = new InjectionToken('OFFER_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(OfferLocalGateway) : inject(OfferApiGateway)), + factory: () => inject(OfferApiGateway), }); diff --git a/src/app/core/partner-hierarchy/services/partner-hierarchy-gateway.token.ts b/src/app/core/partner-hierarchy/services/partner-hierarchy-gateway.token.ts index e82017c..74b84c6 100644 --- a/src/app/core/partner-hierarchy/services/partner-hierarchy-gateway.token.ts +++ b/src/app/core/partner-hierarchy/services/partner-hierarchy-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../environments/environment'; import { PartnerHierarchyGateway } from './partner-hierarchy-gateway.interface'; -import { PartnerHierarchyLocalGateway } from './partner-hierarchy-local.gateway'; import { PartnerHierarchyApiGateway } from './partner-hierarchy-api.gateway'; /** Swap point for docs/backend/PARTNER-PROVISIONING-API-CONTRACT.md §4, §6. */ export const PARTNER_HIERARCHY_GATEWAY = new InjectionToken('PARTNER_HIERARCHY_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(PartnerHierarchyLocalGateway) : inject(PartnerHierarchyApiGateway)), + factory: () => inject(PartnerHierarchyApiGateway), }); diff --git a/src/app/core/permissions/services/permission-gateway.token.ts b/src/app/core/permissions/services/permission-gateway.token.ts index c11bdb8..5a074b2 100644 --- a/src/app/core/permissions/services/permission-gateway.token.ts +++ b/src/app/core/permissions/services/permission-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../environments/environment'; import { PermissionGateway } from './permission-gateway.interface'; -import { PermissionLocalGateway } from './permission-local.gateway'; import { PermissionApiGateway } from './permission-api.gateway'; /** Swap point for docs/backend/TRACK-S-SECURITY-RBAC-CONTRACT.md §2-3. */ export const PERMISSION_GATEWAY = new InjectionToken('PERMISSION_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(PermissionLocalGateway) : inject(PermissionApiGateway)), + factory: () => inject(PermissionApiGateway), }); diff --git a/src/app/core/pricing/services/fx-quote-gateway.token.ts b/src/app/core/pricing/services/fx-quote-gateway.token.ts index 6336fc9..2a54e53 100644 --- a/src/app/core/pricing/services/fx-quote-gateway.token.ts +++ b/src/app/core/pricing/services/fx-quote-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../environments/environment'; import { FxQuoteGateway } from './fx-quote-gateway.interface'; -import { FxQuoteLocalGateway } from './fx-quote-local.gateway'; import { FxQuoteApiGateway } from './fx-quote-api.gateway'; /** Swap point for docs/backend/PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md §3.1. */ export const FX_QUOTE_GATEWAY = new InjectionToken('FX_QUOTE_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(FxQuoteLocalGateway) : inject(FxQuoteApiGateway)), + factory: () => inject(FxQuoteApiGateway), }); diff --git a/src/app/core/sellers/services/seller-gateway.token.ts b/src/app/core/sellers/services/seller-gateway.token.ts index c1972e7..d4444c1 100644 --- a/src/app/core/sellers/services/seller-gateway.token.ts +++ b/src/app/core/sellers/services/seller-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../environments/environment'; import { SellerGateway } from './seller-gateway.interface'; -import { SellerLocalGateway } from './seller-local.gateway'; import { SellerApiGateway } from './seller-api.gateway'; /** Swap point for docs/backend/PHASE-5-SELLER-PORTAL-CONTRACT.md §3. */ export const SELLER_GATEWAY = new InjectionToken('SELLER_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(SellerLocalGateway) : inject(SellerApiGateway)), + factory: () => inject(SellerApiGateway), }); diff --git a/src/app/features/admin/dashboard/services/admin-dashboard-metrics-gateway.token.ts b/src/app/features/admin/dashboard/services/admin-dashboard-metrics-gateway.token.ts index 2ab37b2..7ff99e0 100644 --- a/src/app/features/admin/dashboard/services/admin-dashboard-metrics-gateway.token.ts +++ b/src/app/features/admin/dashboard/services/admin-dashboard-metrics-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../../environments/environment'; import { AdminDashboardMetricsGateway } from './admin-dashboard-metrics.gateway.interface'; -import { AdminDashboardMetricsLocalGateway } from './admin-dashboard-metrics.local.gateway'; import { AdminDashboardMetricsApiGateway } from './admin-dashboard-metrics-api.gateway'; /** Swap point. */ export const ADMIN_DASHBOARD_METRICS_GATEWAY = new InjectionToken('ADMIN_DASHBOARD_METRICS_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(AdminDashboardMetricsLocalGateway) : inject(AdminDashboardMetricsApiGateway)), + factory: () => inject(AdminDashboardMetricsApiGateway), }); diff --git a/src/app/features/admin/moderation/services/admin-moderation-gateway.token.ts b/src/app/features/admin/moderation/services/admin-moderation-gateway.token.ts index b860008..e847c65 100644 --- a/src/app/features/admin/moderation/services/admin-moderation-gateway.token.ts +++ b/src/app/features/admin/moderation/services/admin-moderation-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../../environments/environment'; import { AdminModerationGateway } from './admin-moderation-gateway.interface'; -import { AdminModerationLocalGateway } from './admin-moderation-local.gateway'; import { AdminModerationApiGateway } from './admin-moderation-api.gateway'; /** Swap point. */ export const ADMIN_MODERATION_GATEWAY = new InjectionToken('ADMIN_MODERATION_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(AdminModerationLocalGateway) : inject(AdminModerationApiGateway)), + factory: () => inject(AdminModerationApiGateway), }); diff --git a/src/app/features/admin/monitoring/services/admin-monitoring-gateway.token.ts b/src/app/features/admin/monitoring/services/admin-monitoring-gateway.token.ts index e95daf0..1858645 100644 --- a/src/app/features/admin/monitoring/services/admin-monitoring-gateway.token.ts +++ b/src/app/features/admin/monitoring/services/admin-monitoring-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../../environments/environment'; import { AdminMonitoringGateway } from './admin-monitoring-gateway.interface'; -import { AdminMonitoringLocalGateway } from './admin-monitoring-local.gateway'; import { AdminMonitoringApiGateway } from './admin-monitoring-api.gateway'; /** Swap point. */ export const ADMIN_MONITORING_GATEWAY = new InjectionToken('ADMIN_MONITORING_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(AdminMonitoringLocalGateway) : inject(AdminMonitoringApiGateway)), + factory: () => inject(AdminMonitoringApiGateway), }); diff --git a/src/app/features/admin/notifications/services/admin-notifications-gateway.token.ts b/src/app/features/admin/notifications/services/admin-notifications-gateway.token.ts index 91e313e..91b3b6e 100644 --- a/src/app/features/admin/notifications/services/admin-notifications-gateway.token.ts +++ b/src/app/features/admin/notifications/services/admin-notifications-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../../environments/environment'; import { AdminNotificationsGateway } from './admin-notifications-gateway.interface'; -import { AdminNotificationsLocalGateway } from './admin-notifications-local.gateway'; import { AdminNotificationsApiGateway } from './admin-notifications-api.gateway'; /** Swap point for docs/backend/PHASE-2-ORDERS-NOTIFICATIONS-CONTRACT.md §7. */ export const ADMIN_NOTIFICATIONS_GATEWAY = new InjectionToken('ADMIN_NOTIFICATIONS_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(AdminNotificationsLocalGateway) : inject(AdminNotificationsApiGateway)), + factory: () => inject(AdminNotificationsApiGateway), }); diff --git a/src/app/features/admin/orders/services/admin-orders-gateway.token.ts b/src/app/features/admin/orders/services/admin-orders-gateway.token.ts index 42dd680..2852195 100644 --- a/src/app/features/admin/orders/services/admin-orders-gateway.token.ts +++ b/src/app/features/admin/orders/services/admin-orders-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../../environments/environment'; import { AdminOrdersGateway } from './admin-orders-gateway.interface'; -import { AdminOrdersLocalGateway } from './admin-orders-local.gateway'; import { AdminOrdersApiGateway } from './admin-orders-api.gateway'; /** Swap point for docs/backend/PHASE-2-ORDERS-NOTIFICATIONS-CONTRACT.md. */ export const ADMIN_ORDERS_GATEWAY = new InjectionToken('ADMIN_ORDERS_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(AdminOrdersLocalGateway) : inject(AdminOrdersApiGateway)), + factory: () => inject(AdminOrdersApiGateway), }); diff --git a/src/app/features/admin/products/services/admin-products-gateway.token.ts b/src/app/features/admin/products/services/admin-products-gateway.token.ts index 5e414c2..a04b2c5 100644 --- a/src/app/features/admin/products/services/admin-products-gateway.token.ts +++ b/src/app/features/admin/products/services/admin-products-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../../environments/environment'; import { AdminProductsGateway } from './admin-products-gateway.interface'; -import { AdminProductsLocalGateway } from './admin-products-local.gateway'; import { AdminProductsApiGateway } from './admin-products-api.gateway'; /** Swap point for docs/backend/PHASE-3-CATALOG-OFFER-FULFILLMENT-CONTRACT.md §7. */ export const ADMIN_PRODUCTS_GATEWAY = new InjectionToken('ADMIN_PRODUCTS_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(AdminProductsLocalGateway) : inject(AdminProductsApiGateway)), + factory: () => inject(AdminProductsApiGateway), }); diff --git a/src/app/features/admin/transactions/services/admin-transactions-gateway.token.ts b/src/app/features/admin/transactions/services/admin-transactions-gateway.token.ts index 972a892..86c0fc4 100644 --- a/src/app/features/admin/transactions/services/admin-transactions-gateway.token.ts +++ b/src/app/features/admin/transactions/services/admin-transactions-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../../environments/environment'; import { AdminTransactionsGateway } from './admin-transactions-gateway.interface'; -import { AdminTransactionsLocalGateway } from './admin-transactions-local.gateway'; import { AdminTransactionsApiGateway } from './admin-transactions-api.gateway'; /** Swap point for docs/backend/PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md §6. */ export const ADMIN_TRANSACTIONS_GATEWAY = new InjectionToken('ADMIN_TRANSACTIONS_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(AdminTransactionsLocalGateway) : inject(AdminTransactionsApiGateway)), + factory: () => inject(AdminTransactionsApiGateway), }); diff --git a/src/app/features/admin/users/services/admin-users-gateway.token.ts b/src/app/features/admin/users/services/admin-users-gateway.token.ts index d144e46..22e9009 100644 --- a/src/app/features/admin/users/services/admin-users-gateway.token.ts +++ b/src/app/features/admin/users/services/admin-users-gateway.token.ts @@ -1,11 +1,9 @@ import { InjectionToken, inject } from '@angular/core'; -import { environment } from '../../../../../environments/environment'; import { AdminUsersGateway } from './admin-users-gateway.interface'; -import { AdminUsersLocalGateway } from './admin-users-local.gateway'; import { AdminUsersApiGateway } from './admin-users-api.gateway'; /** Swap point for docs/backend/TRACK-S-SECURITY-RBAC-CONTRACT.md §8. */ export const ADMIN_USERS_GATEWAY = new InjectionToken('ADMIN_USERS_GATEWAY', { providedIn: 'root', - factory: () => (environment.useMockData ? inject(AdminUsersLocalGateway) : inject(AdminUsersApiGateway)), + factory: () => inject(AdminUsersApiGateway), }); diff --git a/src/app/mock-gateway.providers.production.ts b/src/app/mock-gateway.providers.production.ts new file mode 100644 index 0000000..3d92efd --- /dev/null +++ b/src/app/mock-gateway.providers.production.ts @@ -0,0 +1,9 @@ +import { Provider } from '@angular/core'; + +/** + * Production replacement for mock-gateway.providers.ts (angular.json + * fileReplacements). Imports nothing on purpose: this file existing is what + * guarantees no *LocalGateway or its fixtures can be reached from a + * production build. + */ +export const MOCK_GATEWAY_PROVIDERS: Provider[] = []; diff --git a/src/app/mock-gateway.providers.ts b/src/app/mock-gateway.providers.ts new file mode 100644 index 0000000..2fe4c09 --- /dev/null +++ b/src/app/mock-gateway.providers.ts @@ -0,0 +1,91 @@ +import { Provider } from '@angular/core'; +import { environment } from '../environments/environment'; + +import { ADMIN_DASHBOARD_METRICS_GATEWAY } from './features/admin/dashboard/services/admin-dashboard-metrics-gateway.token'; +import { AdminDashboardMetricsLocalGateway } from './features/admin/dashboard/services/admin-dashboard-metrics.local.gateway'; +import { ADMIN_MODERATION_GATEWAY } from './features/admin/moderation/services/admin-moderation-gateway.token'; +import { AdminModerationLocalGateway } from './features/admin/moderation/services/admin-moderation-local.gateway'; +import { ADMIN_MONITORING_GATEWAY } from './features/admin/monitoring/services/admin-monitoring-gateway.token'; +import { AdminMonitoringLocalGateway } from './features/admin/monitoring/services/admin-monitoring-local.gateway'; +import { ADMIN_NOTIFICATIONS_GATEWAY } from './features/admin/notifications/services/admin-notifications-gateway.token'; +import { AdminNotificationsLocalGateway } from './features/admin/notifications/services/admin-notifications-local.gateway'; +import { ADMIN_ORDERS_GATEWAY } from './features/admin/orders/services/admin-orders-gateway.token'; +import { AdminOrdersLocalGateway } from './features/admin/orders/services/admin-orders-local.gateway'; +import { ADMIN_PRODUCTS_GATEWAY } from './features/admin/products/services/admin-products-gateway.token'; +import { AdminProductsLocalGateway } from './features/admin/products/services/admin-products-local.gateway'; +import { ADMIN_TRANSACTIONS_GATEWAY } from './features/admin/transactions/services/admin-transactions-gateway.token'; +import { AdminTransactionsLocalGateway } from './features/admin/transactions/services/admin-transactions-local.gateway'; +import { ADMIN_USERS_GATEWAY } from './features/admin/users/services/admin-users-gateway.token'; +import { AdminUsersLocalGateway } from './features/admin/users/services/admin-users-local.gateway'; +import { ANALYTICS_GATEWAY } from './core/analytics/services/analytics-gateway.token'; +import { AnalyticsLocalGateway } from './core/analytics/services/analytics-local.gateway'; +import { CONNECTOR_GATEWAY } from './core/integrations/services/connector-gateway.token'; +import { ConnectorLocalGateway } from './core/integrations/services/connector-local.gateway'; +import { FINANCE_GATEWAY } from './core/finance/services/finance-gateway.token'; +import { FinanceLocalGateway } from './core/finance/services/finance-local.gateway'; +import { FX_QUOTE_GATEWAY } from './core/pricing/services/fx-quote-gateway.token'; +import { FxQuoteLocalGateway } from './core/pricing/services/fx-quote-local.gateway'; +import { MALL_CONTENT_GATEWAY } from './core/content-modules/services/mall-content-gateway.token'; +import { MallContentLocalGateway } from './core/content-modules/services/mall-content-local.gateway'; +import { MARKETPLACE_GATEWAY } from './core/marketplace-registry/services/marketplace-gateway.token'; +import { MarketplaceLocalGateway } from './core/marketplace-registry/services/marketplace-local.gateway'; +import { MARKETPLACE_REVISION_GATEWAY } from './core/marketplace-registry/services/marketplace-revision-gateway.token'; +import { MarketplaceRevisionLocalGateway } from './core/marketplace-registry/services/marketplace-revision-local.gateway'; +import { OFFER_GATEWAY } from './core/offers/services/offer-gateway.token'; +import { OfferLocalGateway } from './core/offers/services/offer-local.gateway'; +import { PARTNER_HIERARCHY_GATEWAY } from './core/partner-hierarchy/services/partner-hierarchy-gateway.token'; +import { PartnerHierarchyLocalGateway } from './core/partner-hierarchy/services/partner-hierarchy-local.gateway'; +import { PERMISSION_GATEWAY } from './core/permissions/services/permission-gateway.token'; +import { PermissionLocalGateway } from './core/permissions/services/permission-local.gateway'; +import { SELLER_GATEWAY } from './core/sellers/services/seller-gateway.token'; +import { SellerLocalGateway } from './core/sellers/services/seller-local.gateway'; +import { SERVER_CART_GATEWAY } from './core/cart/services/server-cart-gateway.token'; +import { ServerCartLocalGateway } from './core/cart/services/server-cart-local.gateway'; +import { SOCIAL_IDENTITY_GATEWAY } from './core/identity/services/social-identity-gateway.token'; +import { SocialIdentityLocalGateway } from './core/identity/services/social-identity-local.gateway'; + +/** + * Development-only gateway overrides. + * + * This file is swapped for mock-gateway.providers.production.ts at build time + * (see angular.json fileReplacements), the same mechanism + * mock-data.interceptor.production.ts already uses. The production copy + * imports nothing, so no *LocalGateway class - and none of its seeded + * fixtures - can reach a production bundle. + * + * It used to live inside each token factory as + * factory: () => (environment.useMockData ? inject(XLocal) : inject(XApi)) + * which reads as a toggle but is not one: naming both classes in the factory + * keeps both reachable, so every mock shipped regardless of the flag. A + * fixture string from partner-hierarchy-local.gateway.ts was verifiably + * present in a production build on 2026-08-21. + * + * useExisting rather than useClass: the local gateways are already + * providedIn: 'root' singletons, and an app-level provider for the token + * wins over its tree-shakable default. + */ +export const MOCK_GATEWAY_PROVIDERS: Provider[] = environment.useMockData + ? [ + { provide: ADMIN_DASHBOARD_METRICS_GATEWAY, useExisting: AdminDashboardMetricsLocalGateway }, + { provide: ADMIN_MODERATION_GATEWAY, useExisting: AdminModerationLocalGateway }, + { provide: ADMIN_MONITORING_GATEWAY, useExisting: AdminMonitoringLocalGateway }, + { provide: ADMIN_NOTIFICATIONS_GATEWAY, useExisting: AdminNotificationsLocalGateway }, + { provide: ADMIN_ORDERS_GATEWAY, useExisting: AdminOrdersLocalGateway }, + { provide: ADMIN_PRODUCTS_GATEWAY, useExisting: AdminProductsLocalGateway }, + { provide: ADMIN_TRANSACTIONS_GATEWAY, useExisting: AdminTransactionsLocalGateway }, + { provide: ADMIN_USERS_GATEWAY, useExisting: AdminUsersLocalGateway }, + { provide: ANALYTICS_GATEWAY, useExisting: AnalyticsLocalGateway }, + { provide: CONNECTOR_GATEWAY, useExisting: ConnectorLocalGateway }, + { provide: FINANCE_GATEWAY, useExisting: FinanceLocalGateway }, + { provide: FX_QUOTE_GATEWAY, useExisting: FxQuoteLocalGateway }, + { provide: MALL_CONTENT_GATEWAY, useExisting: MallContentLocalGateway }, + { provide: MARKETPLACE_GATEWAY, useExisting: MarketplaceLocalGateway }, + { provide: MARKETPLACE_REVISION_GATEWAY, useExisting: MarketplaceRevisionLocalGateway }, + { provide: OFFER_GATEWAY, useExisting: OfferLocalGateway }, + { provide: PARTNER_HIERARCHY_GATEWAY, useExisting: PartnerHierarchyLocalGateway }, + { provide: PERMISSION_GATEWAY, useExisting: PermissionLocalGateway }, + { provide: SELLER_GATEWAY, useExisting: SellerLocalGateway }, + { provide: SERVER_CART_GATEWAY, useExisting: ServerCartLocalGateway }, + { provide: SOCIAL_IDENTITY_GATEWAY, useExisting: SocialIdentityLocalGateway }, + ] + : [];