@tokenoftrust/storefront-runner 1.4.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (474) hide show
  1. package/apps/storefront/astro.config.mjs +17 -1
  2. package/apps/storefront/env.d.ts +54 -5
  3. package/apps/storefront/integrations/materialize-guard.mjs +54 -0
  4. package/apps/storefront/migrations-apps/0002_good_switch.sql +26 -0
  5. package/apps/storefront/migrations-apps/0003_mute_marauders.sql +12 -0
  6. package/apps/storefront/migrations-apps/0004_deep_morph.sql +36 -0
  7. package/apps/storefront/migrations-apps/0005_common_mystique.sql +23 -0
  8. package/apps/storefront/migrations-apps/0006_broad_microchip.sql +16 -0
  9. package/apps/storefront/migrations-apps/0007_brave_outlaw_kid.sql +15 -0
  10. package/apps/storefront/migrations-apps/0008_blue_dazzler.sql +11 -0
  11. package/apps/storefront/migrations-apps/0009_bored_shinobi_shaw.sql +15 -0
  12. package/apps/storefront/migrations-apps/0010_ws4_verified_provider_measurement.sql +35 -0
  13. package/apps/storefront/migrations-apps/meta/0002_snapshot.json +1160 -0
  14. package/apps/storefront/migrations-apps/meta/0003_snapshot.json +1235 -0
  15. package/apps/storefront/migrations-apps/meta/0004_snapshot.json +1474 -0
  16. package/apps/storefront/migrations-apps/meta/0005_snapshot.json +1617 -0
  17. package/apps/storefront/migrations-apps/meta/0006_snapshot.json +1716 -0
  18. package/apps/storefront/migrations-apps/meta/0007_snapshot.json +1812 -0
  19. package/apps/storefront/migrations-apps/meta/0008_snapshot.json +1881 -0
  20. package/apps/storefront/migrations-apps/meta/0009_snapshot.json +1979 -0
  21. package/apps/storefront/migrations-apps/meta/_journal.json +56 -0
  22. package/apps/storefront/public/apps/tot.demo.analytics/0.1.0/entry.js +42 -0
  23. package/apps/storefront/public/js/dashboard-team.js +38 -2
  24. package/apps/storefront/public/platform/amplitude-http/v1/entry.mjs +19 -0
  25. package/apps/storefront/public/platform/google-measurement/v1/entry.mjs +19 -0
  26. package/apps/storefront/public/shared/commerce-chrome.css +20 -2
  27. package/apps/storefront/scripts/build-v84-clean-clone-standalone.mjs +68 -0
  28. package/apps/storefront/scripts/deny-v84-clean-clone-standalone-capabilities.mjs +111 -0
  29. package/apps/storefront/scripts/deny-v84-dogfood-capabilities.mjs +2 -0
  30. package/apps/storefront/scripts/deny-v84-lifecycle-capabilities.mjs +247 -0
  31. package/apps/storefront/scripts/dogfood-v84-nonportable-routes.ts +73 -0
  32. package/apps/storefront/scripts/fixed-v84-native-install-producer.ts +79 -0
  33. package/apps/storefront/scripts/generated/v84-clean-clone-replay.bundle.mjs +10982 -0
  34. package/apps/storefront/scripts/import-v84-through-ws2.ts +38 -0
  35. package/apps/storefront/scripts/initialize-v84-lifecycle-tooling-dependency.ts +2 -0
  36. package/apps/storefront/scripts/initialize-v84-lifecycle-tooling.ts +4 -0
  37. package/apps/storefront/scripts/install-v84-native-through-ws1.ts +185 -0
  38. package/apps/storefront/scripts/prove-clone-isolation.ts +506 -0
  39. package/apps/storefront/scripts/replay-v84-clean-clone-pass.ts +148 -0
  40. package/apps/storefront/scripts/replay-v84-clean-clone-standalone.ts +35 -0
  41. package/apps/storefront/scripts/replay-v84-clean-clone.ts +214 -0
  42. package/apps/storefront/scripts/run-fixed-v84-native-install-producer.mjs +18 -0
  43. package/apps/storefront/scripts/run-v84-clone-isolation-proof.mjs +18 -0
  44. package/apps/storefront/scripts/run-v84-clone-lifecycle-proof.mjs +18 -0
  45. package/apps/storefront/scripts/run-v84-import-through-ws2-proof.mjs +17 -0
  46. package/apps/storefront/scripts/run-v84-nonportable-route-dogfood.mjs +15 -0
  47. package/apps/storefront/scripts/sanitize-v84-proof-environment.mjs +21 -0
  48. package/apps/storefront/scripts/v84CleanCloneGraphPin.ts +42 -0
  49. package/apps/storefront/scripts/v84CleanCloneSourceGraph.ts +145 -0
  50. package/apps/storefront/scripts/validate-v84-clone-lifecycle.ts +18 -0
  51. package/apps/storefront/src/components/Img.astro +1 -1
  52. package/apps/storefront/src/components/Seo.astro +65 -1
  53. package/apps/storefront/src/components/admin/AdminBlogDetailRail.astro +878 -0
  54. package/apps/storefront/src/components/admin/AdminBlogTab.astro +1435 -0
  55. package/apps/storefront/src/components/admin/AdminCustomersTab.astro +3 -7
  56. package/apps/storefront/src/components/admin/AdminIntegrationsTab.astro +105 -0
  57. package/apps/storefront/src/components/admin/AdminPublishTab.astro +1980 -2564
  58. package/apps/storefront/src/components/admin/AdminSettingsTab.astro +2 -2
  59. package/apps/storefront/src/components/admin/AdminSubscriptionsTab.astro +1 -3
  60. package/apps/storefront/src/components/admin/orders/OrdersWorkspace.astro +5 -5
  61. package/apps/storefront/src/components/blog/BlogPaywall.astro +87 -0
  62. package/apps/storefront/src/components/blog/PostAccessBadge.astro +43 -0
  63. package/apps/storefront/src/components/blog/PostGrid.astro +57 -0
  64. package/apps/storefront/src/components/blog/ReactionBar.astro +214 -0
  65. package/apps/storefront/src/components/chrome/NavDropdown.astro +12 -0
  66. package/apps/storefront/src/components/chrome/SiteFooter.astro +7 -2
  67. package/apps/storefront/src/components/chrome/SiteHeader.astro +46 -10
  68. package/apps/storefront/src/components/compliance/AdultSignatureNotice.astro +1 -1
  69. package/apps/storefront/src/components/compliance/ComplianceNotice.astro +1 -2
  70. package/apps/storefront/src/components/compliance/ExciseTaxNotice.astro +1 -2
  71. package/apps/storefront/src/components/compliance/PactActNotice.astro +1 -1
  72. package/apps/storefront/src/components/compliance/Prop65Warning.astro +1 -2
  73. package/apps/storefront/src/components/compliance/PurchaseLimitNotice.astro +2 -3
  74. package/apps/storefront/src/components/compliance/ShippingRestrictionNotice.astro +2 -2
  75. package/apps/storefront/src/components/compliance/StateEligibilityNotice.astro +2 -3
  76. package/apps/storefront/src/components/content/TrustStrip.astro +4 -4
  77. package/apps/storefront/src/components/islands/MobileNav.tsx +26 -1
  78. package/apps/storefront/src/components/islands/VariantSelector.tsx +27 -2
  79. package/apps/storefront/src/components/islands/useCheckoutHandoffCorrelation.ts +75 -0
  80. package/apps/storefront/src/components/membership/IllustrativeLabel.astro +1 -2
  81. package/apps/storefront/src/components/membership/TierCards.astro +2 -2
  82. package/apps/storefront/src/components/membership/TierComparisonTable.astro +2 -2
  83. package/apps/storefront/src/components/subscription/SavingsExplainer.astro +2 -2
  84. package/apps/storefront/src/config/adminTenantLookup.ts +35 -0
  85. package/apps/storefront/src/config/devTenantSeed.ts +9 -9
  86. package/apps/storefront/src/config/resolver.ts +4 -4
  87. package/apps/storefront/src/layouts/Layout.astro +146 -21
  88. package/apps/storefront/src/lib/activity/alerts.ts +17 -19
  89. package/apps/storefront/src/lib/activity/candidateSubmitLease.ts +87 -0
  90. package/apps/storefront/src/lib/activity/changeActorAttribution.ts +89 -9
  91. package/apps/storefront/src/lib/activity/deployVersion.ts +20 -27
  92. package/apps/storefront/src/lib/activity/ingest.ts +8 -8
  93. package/apps/storefront/src/lib/activity/ingestAuth.ts +1 -1
  94. package/apps/storefront/src/lib/activity/killSwitch.ts +6 -6
  95. package/apps/storefront/src/lib/activity/query.ts +9 -9
  96. package/apps/storefront/src/lib/activity/recordActivity.ts +11 -15
  97. package/apps/storefront/src/lib/activity/store.ts +4 -6
  98. package/apps/storefront/src/lib/activity/uiActor.ts +12 -12
  99. package/apps/storefront/src/lib/activity/workerCommit.ts +6 -6
  100. package/apps/storefront/src/lib/admin/adminShell.ts +292 -0
  101. package/apps/storefront/src/lib/admin/ai/approvalMode.ts +2 -3
  102. package/apps/storefront/src/lib/admin/ai/audit.ts +3 -5
  103. package/apps/storefront/src/lib/admin/checkoutStyleInput.ts +7 -7
  104. package/apps/storefront/src/lib/admin/checkoutStyleTarget.ts +3 -3
  105. package/apps/storefront/src/lib/admin/envelope.ts +1 -2
  106. package/apps/storefront/src/lib/admin/orderClient.ts +3 -5
  107. package/apps/storefront/src/lib/admin/services/orders.ts +17 -19
  108. package/apps/storefront/src/lib/admin/viewmodels/aiWorkflows.ts +4 -6
  109. package/apps/storefront/src/lib/admin/viewmodels/settings.ts +1 -1
  110. package/apps/storefront/src/lib/apps/adminService.ts +14 -4
  111. package/apps/storefront/src/lib/apps/adminSession.ts +54 -45
  112. package/apps/storefront/src/lib/apps/apiAuth.ts +2 -2
  113. package/apps/storefront/src/lib/apps/apiRoute.ts +2 -2
  114. package/apps/storefront/src/lib/apps/appVersionStore.ts +281 -0
  115. package/apps/storefront/src/lib/apps/catalogMapper.ts +1 -1
  116. package/apps/storefront/src/lib/apps/consentConfigStore.ts +228 -0
  117. package/apps/storefront/src/lib/apps/credentials.ts +2 -2
  118. package/apps/storefront/src/lib/apps/gatewayKeys.ts +4 -4
  119. package/apps/storefront/src/lib/apps/gtmMigrationInstall.ts +447 -0
  120. package/apps/storefront/src/lib/apps/gtmMigrationReport.ts +367 -0
  121. package/apps/storefront/src/lib/apps/gtmMigrationTab.ts +315 -0
  122. package/apps/storefront/src/lib/apps/healthAggregate.ts +5 -5
  123. package/apps/storefront/src/lib/apps/integrationLifecycle.ts +614 -0
  124. package/apps/storefront/src/lib/apps/integrationLifecycleController.ts +125 -0
  125. package/apps/storefront/src/lib/apps/integrationReadModel.ts +563 -0
  126. package/apps/storefront/src/lib/apps/integrationsTab.ts +547 -0
  127. package/apps/storefront/src/lib/apps/integrationsView.ts +106 -0
  128. package/apps/storefront/src/lib/apps/managedAnalyticsService.ts +599 -0
  129. package/apps/storefront/src/lib/apps/orders/attributionService.ts +2 -2
  130. package/apps/storefront/src/lib/apps/orders/customerHash.ts +1 -1
  131. package/apps/storefront/src/lib/apps/orders/foxyOrderClient.ts +12 -12
  132. package/apps/storefront/src/lib/apps/orders/idempotency.ts +7 -7
  133. package/apps/storefront/src/lib/apps/orders/orderConversionD1.ts +150 -0
  134. package/apps/storefront/src/lib/apps/orders/orderForwardReceiver.ts +9 -1
  135. package/apps/storefront/src/lib/apps/orders/orderMapper.ts +2 -2
  136. package/apps/storefront/src/lib/apps/orders/ordersStore.ts +7 -7
  137. package/apps/storefront/src/lib/apps/orders/verifiedProviderMeasurement.ts +117 -0
  138. package/apps/storefront/src/lib/apps/registryService.ts +270 -16
  139. package/apps/storefront/src/lib/apps/scopes.ts +2 -2
  140. package/apps/storefront/src/lib/apps/tenantIntegrationMaterialization.ts +170 -0
  141. package/apps/storefront/src/lib/apps/tokenIssuer.ts +4 -4
  142. package/apps/storefront/src/lib/apps/tokenVerifier.ts +6 -6
  143. package/apps/storefront/src/lib/apps/v84CleanCloneReplayContext.ts +16 -0
  144. package/apps/storefront/src/lib/apps/v84CloneLifecycleCacheEvidence.ts +105 -0
  145. package/apps/storefront/src/lib/apps/v84CloneLifecycleEvidence.ts +177 -0
  146. package/apps/storefront/src/lib/apps/v84CloneLifecycleMaterialization.ts +251 -0
  147. package/apps/storefront/src/lib/apps/v84CloneLifecycleSemantics.ts +241 -0
  148. package/apps/storefront/src/lib/apps/v84CloneMigrationEvidence.ts +211 -0
  149. package/apps/storefront/src/lib/apps/v84CloneNativeInstallEvidence.ts +409 -0
  150. package/apps/storefront/src/lib/apps/v84NonportableCodeCoaching.ts +368 -0
  151. package/apps/storefront/src/lib/apps/v84NonportableRouteContract.ts +188 -0
  152. package/apps/storefront/src/lib/apps/v84NonportableRouteDogfood.ts +291 -0
  153. package/apps/storefront/src/lib/apps/widgets/eligibility.ts +2 -2
  154. package/apps/storefront/src/lib/apps/widgets/frameProps.ts +3 -3
  155. package/apps/storefront/src/lib/apps/widgets/launchToken.ts +4 -4
  156. package/apps/storefront/src/lib/apps/widgets/placements.ts +2 -2
  157. package/apps/storefront/src/lib/apps/widgets/renderSlot.ts +1 -1
  158. package/apps/storefront/src/lib/apps/ws1ManagedAnalyticsClient.ts +95 -0
  159. package/apps/storefront/src/lib/auth/adminApiGuard.ts +66 -0
  160. package/apps/storefront/src/lib/auth/adminEntry.ts +11 -11
  161. package/apps/storefront/src/lib/auth/adminLanding.ts +88 -0
  162. package/apps/storefront/src/lib/auth/identityToken.ts +6 -14
  163. package/apps/storefront/src/lib/auth/loginGate.ts +75 -13
  164. package/apps/storefront/src/lib/auth/mcpClientAssertion.ts +2 -4
  165. package/apps/storefront/src/lib/auth/operatorSession.ts +113 -0
  166. package/apps/storefront/src/lib/auth/session.ts +7 -8
  167. package/apps/storefront/src/lib/auth/totAccessClient.ts +8 -18
  168. package/apps/storefront/src/lib/basePath.ts +9 -2
  169. package/apps/storefront/src/lib/blog/access.ts +29 -0
  170. package/apps/storefront/src/lib/blog/collection.ts +400 -0
  171. package/apps/storefront/src/lib/blog/markdown.ts +174 -0
  172. package/apps/storefront/src/lib/blog/provider.ts +62 -3
  173. package/apps/storefront/src/lib/blog/reactions.ts +87 -0
  174. package/apps/storefront/src/lib/blog/rss.ts +92 -0
  175. package/apps/storefront/src/lib/blog/teaser.ts +83 -0
  176. package/apps/storefront/src/lib/blog/types.ts +34 -0
  177. package/apps/storefront/src/lib/blog/viewCounts.ts +243 -0
  178. package/apps/storefront/src/lib/chrome/examples/tokenoftrust.chrome-assignments.example.json +6 -0
  179. package/apps/storefront/src/lib/chrome/examples/tokenoftrust.chrome.example.json +79 -0
  180. package/apps/storefront/src/lib/chrome/model.ts +48 -253
  181. package/apps/storefront/src/lib/chrome/navCurrent.ts +29 -0
  182. package/apps/storefront/src/lib/chrome/parseConfig.ts +18 -32
  183. package/apps/storefront/src/lib/chrome/variant.ts +39 -0
  184. package/apps/storefront/src/lib/commerce/checkoutHandoffCorrelation.ts +105 -0
  185. package/apps/storefront/src/lib/compliance/tamper-sentinel-boot.ts +152 -0
  186. package/apps/storefront/src/lib/compliance/tamper-sentinel.ts +327 -0
  187. package/apps/storefront/src/lib/content/index.ts +5 -5
  188. package/apps/storefront/src/lib/content-edit/applyDiff.ts +1 -1
  189. package/apps/storefront/src/lib/content-edit/route.ts +1 -1
  190. package/apps/storefront/src/lib/d1/catalog.ts +14 -2
  191. package/apps/storefront/src/lib/d1/schema-apps.ts +372 -17
  192. package/apps/storefront/src/lib/dev/activityIngestToken.ts +2 -4
  193. package/apps/storefront/src/lib/dev/activityStore.ts +3 -5
  194. package/apps/storefront/src/lib/dev/apiBase.ts +1 -4
  195. package/apps/storefront/src/lib/dev/cockpit/ask.ts +49 -0
  196. package/apps/storefront/src/lib/dev/cockpit/clickToSource.ts +71 -0
  197. package/apps/storefront/src/lib/dev/cockpit/copyCommand.ts +227 -0
  198. package/apps/storefront/src/lib/dev/cockpit/files.ts +249 -0
  199. package/apps/storefront/src/lib/dev/cockpit/hostedActivity.ts +500 -0
  200. package/apps/storefront/src/lib/dev/cockpit/infoPopover.ts +12 -0
  201. package/apps/storefront/src/lib/dev/cockpit/mcpCopy.ts +34 -0
  202. package/apps/storefront/src/lib/dev/cockpit/monitor.ts +107 -0
  203. package/apps/storefront/src/lib/dev/cockpit/stepper.ts +116 -0
  204. package/apps/storefront/src/lib/dev/cockpit/themeToggle.ts +23 -0
  205. package/apps/storefront/src/lib/dev/cockpitStore.ts +1 -9
  206. package/apps/storefront/src/lib/dev/devDraft.ts +1 -1
  207. package/apps/storefront/src/lib/dev/previewStatus.ts +9 -21
  208. package/apps/storefront/src/lib/dev/rendezvousBroker.ts +9 -24
  209. package/apps/storefront/src/lib/dev/runtimeStore.ts +1 -1
  210. package/apps/storefront/src/lib/edgeCache.ts +34 -5
  211. package/apps/storefront/src/lib/email/candidateConflictEmail.ts +80 -0
  212. package/apps/storefront/src/lib/http/fetchTransport.ts +63 -0
  213. package/apps/storefront/src/lib/i18n.ts +25 -0
  214. package/apps/storefront/src/lib/integration/browserEnvironment.ts +137 -0
  215. package/apps/storefront/src/lib/integration/managedInstallDeclarations.ts +72 -0
  216. package/apps/storefront/src/lib/integration/nonceStamp.ts +49 -0
  217. package/apps/storefront/src/lib/integration/tenantDeclarations.ts +116 -0
  218. package/apps/storefront/src/lib/jsonld.ts +118 -0
  219. package/apps/storefront/src/lib/membership/eligibility.ts +1 -1
  220. package/apps/storefront/src/lib/membership/model.ts +1 -2
  221. package/apps/storefront/src/lib/monitoring/manifest.ts +11 -11
  222. package/apps/storefront/src/lib/newsletter/confirmationEmail.ts +30 -0
  223. package/apps/storefront/src/lib/newsletter/consent.ts +23 -0
  224. package/apps/storefront/src/lib/newsletter/digest.ts +117 -0
  225. package/apps/storefront/src/lib/newsletter/resendClient.ts +79 -0
  226. package/apps/storefront/src/lib/newsletter/send.ts +265 -0
  227. package/apps/storefront/src/lib/newsletter/subscribers.ts +156 -0
  228. package/apps/storefront/src/lib/previewReload.ts +57 -1
  229. package/apps/storefront/src/lib/publish/adminPublishTab.ts +4625 -0
  230. package/apps/storefront/src/lib/publish/apex-readiness.ts +41 -18
  231. package/apps/storefront/src/lib/publish/buildStream.ts +269 -0
  232. package/apps/storefront/src/lib/publish/collapsePersistence.ts +72 -0
  233. package/apps/storefront/src/lib/publish/dispatchHealth.ts +5 -7
  234. package/apps/storefront/src/lib/publish/domainState.ts +22 -13
  235. package/apps/storefront/src/lib/publish/lifecycleState.ts +369 -0
  236. package/apps/storefront/src/lib/publish/liveReleaseSummary.ts +29 -0
  237. package/apps/storefront/src/lib/publish/mergeDoctorOnFailure.ts +78 -0
  238. package/apps/storefront/src/lib/publish/mergeHealthBanner.ts +62 -0
  239. package/apps/storefront/src/lib/publish/mergeRowFindings.ts +124 -0
  240. package/apps/storefront/src/lib/publish/mergeSupportEscalation.ts +75 -0
  241. package/apps/storefront/src/lib/publish/panelPolling.ts +78 -0
  242. package/apps/storefront/src/lib/publish/publish-guard.ts +88 -0
  243. package/apps/storefront/src/lib/publish/publishFormat.ts +165 -0
  244. package/apps/storefront/src/lib/publish/publishHero.ts +177 -0
  245. package/apps/storefront/src/lib/publish/reviewRelease/changeState.ts +66 -0
  246. package/apps/storefront/src/lib/publish/reviewRelease/copy.ts +141 -0
  247. package/apps/storefront/src/lib/publish/reviewRelease/index.ts +41 -0
  248. package/apps/storefront/src/lib/publish/reviewRelease/permissions.ts +47 -0
  249. package/apps/storefront/src/lib/publish/reviewRelease/releaseState.ts +42 -0
  250. package/apps/storefront/src/lib/publish/reviewRelease/types.ts +59 -0
  251. package/apps/storefront/src/lib/publish/reviewRelease/viewModel.ts +440 -0
  252. package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/actions.ts +161 -0
  253. package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/controller.ts +325 -0
  254. package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/render.ts +241 -0
  255. package/apps/storefront/src/lib/publish/shipWorkspace.ts +121 -51
  256. package/apps/storefront/src/lib/publish/sseRoute.ts +119 -0
  257. package/apps/storefront/src/lib/publish/stageBundleUpload.ts +215 -0
  258. package/apps/storefront/src/lib/publish/streamLogConsole.ts +142 -0
  259. package/apps/storefront/src/lib/publish/versionNumber.ts +52 -0
  260. package/apps/storefront/src/lib/rate/kvWindow.ts +53 -0
  261. package/apps/storefront/src/lib/rawChrome.ts +125 -47
  262. package/apps/storefront/src/lib/rawMarketingHtml.ts +74 -3
  263. package/apps/storefront/src/lib/search/index.ts +2 -2
  264. package/apps/storefront/src/lib/seo/alternates.ts +42 -0
  265. package/apps/storefront/src/lib/seo/meta.ts +65 -0
  266. package/apps/storefront/src/lib/social/golive.ts +212 -0
  267. package/apps/storefront/src/lib/social/notify.ts +32 -0
  268. package/apps/storefront/src/lib/social/tokenStore.ts +171 -0
  269. package/apps/storefront/src/lib/storyblok/content-model.ts +7 -33
  270. package/apps/storefront/src/lib/storyblok/provider.ts +168 -60
  271. package/apps/storefront/src/lib/subscription/model.ts +4 -4
  272. package/apps/storefront/src/lib/the-build/provider.ts +32 -0
  273. package/apps/storefront/src/lib/the-build/readingTime.ts +35 -0
  274. package/apps/storefront/src/lib/the-build/toc.ts +95 -0
  275. package/apps/storefront/src/lib/tot/ToTClient.ts +1 -1
  276. package/apps/storefront/src/lib/tot/d1Client.ts +2 -2
  277. package/apps/storefront/src/lib/tot/totClientInterface.ts +3 -4
  278. package/apps/storefront/src/lib/webhooks/deliveryStore.ts +16 -17
  279. package/apps/storefront/src/middleware/index.ts +385 -52
  280. package/apps/storefront/src/pages/[...slug].astro +9 -4
  281. package/apps/storefront/src/pages/admin/review-release.astro +265 -0
  282. package/apps/storefront/src/pages/admin/select.astro +96 -0
  283. package/apps/storefront/src/pages/admin.astro +25 -1313
  284. package/apps/storefront/src/pages/api/activity.ts +8 -8
  285. package/apps/storefront/src/pages/api/admin/activity-alerts.ts +5 -20
  286. package/apps/storefront/src/pages/api/admin/orders/[id].ts +7 -2
  287. package/apps/storefront/src/pages/api/admin/orders.ts +8 -2
  288. package/apps/storefront/src/pages/api/apps/admin/gtm-migration-install.ts +174 -0
  289. package/apps/storefront/src/pages/api/apps/admin/gtm-migration.ts +96 -0
  290. package/apps/storefront/src/pages/api/apps/admin/integration-lifecycle.ts +118 -0
  291. package/apps/storefront/src/pages/api/apps/admin/integrations.ts +89 -0
  292. package/apps/storefront/src/pages/api/apps/admin/platform-adapters.ts +85 -0
  293. package/apps/storefront/src/pages/api/apps/internal/order-forward.ts +74 -2
  294. package/apps/storefront/src/pages/api/blog/[collection]/[slug]/react.ts +104 -0
  295. package/apps/storefront/src/pages/api/commerce/checkout-handoff.ts +77 -0
  296. package/apps/storefront/src/pages/api/compliance/tamper.ts +88 -0
  297. package/apps/storefront/src/pages/api/integrations/v1/[operation].ts +108 -0
  298. package/apps/storefront/src/pages/api/newsletter/[collection]/subscribe.ts +146 -0
  299. package/apps/storefront/src/pages/api/newsletter/confirm.ts +75 -0
  300. package/apps/storefront/src/pages/api/newsletter/unsubscribe.ts +90 -0
  301. package/apps/storefront/src/pages/api/publish/stage-bundle.ts +70 -0
  302. package/apps/storefront/src/pages/api/rum/vitals.ts +20 -2
  303. package/apps/storefront/src/pages/blog/[slug].astro +99 -19
  304. package/apps/storefront/src/pages/blog/author/[author].astro +140 -0
  305. package/apps/storefront/src/pages/blog/category/[category].astro +67 -0
  306. package/apps/storefront/src/pages/blog/index.astro +4 -2
  307. package/apps/storefront/src/pages/blog/tag/[tag].astro +65 -0
  308. package/apps/storefront/src/pages/cockpit.astro +77 -1353
  309. package/apps/storefront/src/pages/dashboard/[appDomain]/team.astro +15 -11
  310. package/apps/storefront/src/pages/index.astro +10 -5
  311. package/apps/storefront/src/pages/llms.txt.ts +1 -1
  312. package/apps/storefront/src/pages/products/[handle].astro +7 -6
  313. package/apps/storefront/src/pages/search.astro +1 -1
  314. package/apps/storefront/src/pages/sitemap.xml.ts +21 -1
  315. package/apps/storefront/src/pages/style-guide/[tenant]/[theme].astro +31 -27
  316. package/apps/storefront/src/pages/style-guide/[tenant]/chrome/[theme].astro +1 -1
  317. package/apps/storefront/src/pages/tenants/[id]/[...path].ts +38 -2
  318. package/apps/storefront/src/pages/the-build/[slug].astro +129 -0
  319. package/apps/storefront/src/pages/the-build/index.astro +146 -0
  320. package/apps/storefront/src/pages/the-build/rss.xml.ts +33 -0
  321. package/apps/storefront/src/styles/admin.css +1106 -0
  322. package/apps/storefront/tsconfig.json +6 -1
  323. package/package.json +1 -1
  324. package/packages/public-runtime/package.json +3 -1
  325. package/packages/public-runtime/schemas/managed-analytics/v1/adapter-definition.schema.json +427 -0
  326. package/packages/public-runtime/schemas/managed-analytics/v1/create-integration-install-request.schema.json +161 -0
  327. package/packages/public-runtime/schemas/managed-analytics/v1/create-migration-draft-request.schema.json +157 -0
  328. package/packages/public-runtime/schemas/managed-analytics/v1/delete-integration-install-request.schema.json +84 -0
  329. package/packages/public-runtime/schemas/managed-analytics/v1/delete-migration-draft-request.schema.json +84 -0
  330. package/packages/public-runtime/schemas/managed-analytics/v1/error-envelope.schema.json +180 -0
  331. package/packages/public-runtime/schemas/managed-analytics/v1/get-adapter-definition-request.schema.json +52 -0
  332. package/packages/public-runtime/schemas/managed-analytics/v1/get-integration-install-request.schema.json +52 -0
  333. package/packages/public-runtime/schemas/managed-analytics/v1/get-integration-revision-request.schema.json +79 -0
  334. package/packages/public-runtime/schemas/managed-analytics/v1/get-migration-draft-request.schema.json +52 -0
  335. package/packages/public-runtime/schemas/managed-analytics/v1/integration-install.schema.json +167 -0
  336. package/packages/public-runtime/schemas/managed-analytics/v1/integration-revision.schema.json +208 -0
  337. package/packages/public-runtime/schemas/managed-analytics/v1/list-adapter-definitions-request.schema.json +53 -0
  338. package/packages/public-runtime/schemas/managed-analytics/v1/list-integration-installs-request.schema.json +53 -0
  339. package/packages/public-runtime/schemas/managed-analytics/v1/list-integration-revisions-request.schema.json +82 -0
  340. package/packages/public-runtime/schemas/managed-analytics/v1/migration-draft.schema.json +218 -0
  341. package/packages/public-runtime/schemas/managed-analytics/v1/mutation-request.schema.json +52 -0
  342. package/packages/public-runtime/schemas/managed-analytics/v1/mutation-success-envelope.schema.json +49 -0
  343. package/packages/public-runtime/schemas/managed-analytics/v1/read-request.schema.json +20 -0
  344. package/packages/public-runtime/schemas/managed-analytics/v1/read-success-envelope.schema.json +45 -0
  345. package/packages/public-runtime/schemas/managed-analytics/v1/revise-integration-install-request.schema.json +156 -0
  346. package/packages/public-runtime/schemas/managed-analytics/v1/set-integration-install-status-request.schema.json +92 -0
  347. package/packages/public-runtime/schemas/managed-analytics/v1/update-migration-draft-request.schema.json +184 -0
  348. package/packages/public-runtime/scripts/generate-managed-analytics-api-v1-schemas.mjs +13 -0
  349. package/packages/public-runtime/src/activity/catalog.ts +89 -33
  350. package/packages/public-runtime/src/activity/event.ts +6 -6
  351. package/packages/public-runtime/src/activity/index.ts +2 -2
  352. package/packages/public-runtime/src/activity/redaction.ts +4 -4
  353. package/packages/public-runtime/src/candidate-index.ts +42 -8
  354. package/packages/public-runtime/src/catalog-d1.ts +1 -1
  355. package/packages/public-runtime/src/checkout-orders.ts +2 -2
  356. package/packages/public-runtime/src/checkout-style-publish.ts +2 -2
  357. package/packages/public-runtime/src/checkout-style.ts +7 -7
  358. package/packages/public-runtime/src/checkout.ts +3 -3
  359. package/packages/public-runtime/src/chrome.ts +777 -0
  360. package/packages/public-runtime/src/compliance-obligations.ts +310 -0
  361. package/packages/public-runtime/src/csp.ts +99 -0
  362. package/packages/public-runtime/src/customization-preview.ts +25 -2
  363. package/packages/public-runtime/src/customization-runtime.ts +156 -3
  364. package/packages/public-runtime/src/customization-versioning.ts +10 -0
  365. package/packages/public-runtime/src/destination-webhook/contract.ts +353 -0
  366. package/packages/public-runtime/src/embed-catalog.d.mts +9 -0
  367. package/packages/public-runtime/src/embed-catalog.mjs +40 -0
  368. package/packages/public-runtime/src/evidence.ts +288 -0
  369. package/packages/public-runtime/src/gtm-migration/bounds.ts +138 -0
  370. package/packages/public-runtime/src/gtm-migration/disposition-rules.ts +361 -0
  371. package/packages/public-runtime/src/gtm-migration/dispositions.ts +181 -0
  372. package/packages/public-runtime/src/gtm-migration/draft-generator.ts +400 -0
  373. package/packages/public-runtime/src/gtm-migration/graph.ts +468 -0
  374. package/packages/public-runtime/src/gtm-migration/index.ts +95 -0
  375. package/packages/public-runtime/src/gtm-migration/parse.ts +410 -0
  376. package/packages/public-runtime/src/gtm-migration/references.ts +266 -0
  377. package/packages/public-runtime/src/gtm-migration/types.ts +86 -0
  378. package/packages/public-runtime/src/index.ts +17 -1
  379. package/packages/public-runtime/src/integration/assurance-decision.ts +259 -0
  380. package/packages/public-runtime/src/integration/assurance.ts +228 -0
  381. package/packages/public-runtime/src/integration/candidate-evidence.ts +377 -0
  382. package/packages/public-runtime/src/integration/commerce-broker.ts +497 -0
  383. package/packages/public-runtime/src/integration/consent-broker.ts +337 -0
  384. package/packages/public-runtime/src/integration/consent-cmp-demand.ts +115 -0
  385. package/packages/public-runtime/src/integration/consent-config.ts +260 -0
  386. package/packages/public-runtime/src/integration/consent-preview.ts +125 -0
  387. package/packages/public-runtime/src/integration/correlation-token.ts +444 -0
  388. package/packages/public-runtime/src/integration/csp-compiler.ts +267 -0
  389. package/packages/public-runtime/src/integration/csp.ts +105 -0
  390. package/packages/public-runtime/src/integration/digest.ts +43 -0
  391. package/packages/public-runtime/src/integration/environment.ts +228 -0
  392. package/packages/public-runtime/src/integration/events-catalog.ts +186 -0
  393. package/packages/public-runtime/src/integration/events.ts +701 -0
  394. package/packages/public-runtime/src/integration/g2-action-boundary.ts +106 -0
  395. package/packages/public-runtime/src/integration/index.ts +90 -0
  396. package/packages/public-runtime/src/integration/interim-bridge.ts +138 -0
  397. package/packages/public-runtime/src/integration/lifecycle-boot.ts +317 -0
  398. package/packages/public-runtime/src/integration/lifecycle-runtime.ts +393 -0
  399. package/packages/public-runtime/src/integration/lifecycle.ts +94 -0
  400. package/packages/public-runtime/src/integration/managed-analytics-api-v1-safety.d.mts +2 -0
  401. package/packages/public-runtime/src/integration/managed-analytics-api-v1-safety.mjs +10 -0
  402. package/packages/public-runtime/src/integration/managed-analytics-api-v1.schemas.ts +382 -0
  403. package/packages/public-runtime/src/integration/managed-analytics-api-v1.ts +684 -0
  404. package/packages/public-runtime/src/integration/managed-analytics-bridge.ts +383 -0
  405. package/packages/public-runtime/src/integration/managed-analytics-value-safety.ts +14 -0
  406. package/packages/public-runtime/src/integration/managed-analytics.ts +277 -0
  407. package/packages/public-runtime/src/integration/manifest.ts +470 -0
  408. package/packages/public-runtime/src/integration/native-amplitude.ts +362 -0
  409. package/packages/public-runtime/src/integration/native-ga4.ts +352 -0
  410. package/packages/public-runtime/src/integration/observability.ts +451 -0
  411. package/packages/public-runtime/src/integration/order-conversion.ts +0 -0
  412. package/packages/public-runtime/src/integration/phases.ts +182 -0
  413. package/packages/public-runtime/src/integration/plan.ts +112 -0
  414. package/packages/public-runtime/src/integration/platform-adapter-runtime.ts +146 -0
  415. package/packages/public-runtime/src/integration/platform-adapters.ts +671 -0
  416. package/packages/public-runtime/src/integration/promotion-gate.ts +451 -0
  417. package/packages/public-runtime/src/integration/provider-checkout-extension.ts +425 -0
  418. package/packages/public-runtime/src/integration/receipt-measurement.ts +370 -0
  419. package/packages/public-runtime/src/integration/regulated-parent-cert.ts +311 -0
  420. package/packages/public-runtime/src/integration/render-phases.ts +267 -0
  421. package/packages/public-runtime/src/integration/resolve.ts +465 -0
  422. package/packages/public-runtime/src/integration/result.ts +239 -0
  423. package/packages/public-runtime/src/integration/secrets.ts +92 -0
  424. package/packages/public-runtime/src/integration/tamper-evidence.ts +205 -0
  425. package/packages/public-runtime/src/integration/tamper-recovery.ts +127 -0
  426. package/packages/public-runtime/src/integration/version.ts +92 -0
  427. package/packages/public-runtime/src/integration-capabilities.ts +520 -0
  428. package/packages/public-runtime/src/membership.ts +2 -2
  429. package/packages/public-runtime/src/raw-html-policy.ts +2 -4
  430. package/packages/public-runtime/src/regulated-commerce/broker/consent-dedupe.ts +144 -0
  431. package/packages/public-runtime/src/regulated-commerce/correlation/contract.ts +177 -0
  432. package/packages/public-runtime/src/regulated-commerce/diagnostics/local-dispatch.ts +24 -0
  433. package/packages/public-runtime/src/regulated-commerce/diagnostics/read-model.ts +69 -0
  434. package/packages/public-runtime/src/regulated-commerce/dispatch/core.ts +134 -0
  435. package/packages/public-runtime/src/regulated-commerce/events/contract.ts +113 -0
  436. package/packages/public-runtime/src/regulated-commerce/ledger/core.ts +81 -0
  437. package/packages/public-runtime/src/regulated-commerce/mappings/ga4-ads.ts +87 -0
  438. package/packages/public-runtime/src/regulated-commerce/provider-order/bridge.ts +52 -0
  439. package/packages/public-runtime/src/regulated-commerce/purchase-truth/contract.ts +252 -0
  440. package/packages/public-runtime/src/regulated-commerce/sources/accepted-browser-operation.ts +67 -0
  441. package/packages/public-runtime/src/regulated-commerce/testing/fake-destination.ts +93 -0
  442. package/packages/public-runtime/src/static-bundle.ts +357 -0
  443. package/packages/public-runtime/src/tenant-assets.ts +143 -4
  444. package/packages/public-runtime/src/tenant.ts +81 -17
  445. package/packages/public-runtime/tests/fixtures/integration/browser-environment.example.json +8 -0
  446. package/packages/public-runtime/tests/fixtures/integration/commerce-event.example.json +44 -0
  447. package/packages/public-runtime/tests/fixtures/integration/commerce-order-event.example.json +44 -0
  448. package/packages/public-runtime/tests/fixtures/integration/compliance-assurance-record.example.json +50 -0
  449. package/packages/public-runtime/tests/fixtures/integration/integration-manifest-v2.example.json +120 -0
  450. package/packages/public-runtime/tests/fixtures/integration/managed-analytics-v1/fake-adapter-catalog.json +35 -0
  451. package/packages/public-runtime/tests/fixtures/integration/tenant-action-registry.example.json +11 -0
  452. package/packages/public-runtime/tests/fixtures/integration/tenant-local-example/README.md +22 -0
  453. package/packages/public-runtime/tests/fixtures/integration/tenant-local-example/entry.js +30 -0
  454. package/packages/public-runtime/tests/fixtures/integration/tenant-local-example/manifest.json +75 -0
  455. package/packages/public-runtime/tests/fixtures/integration/tenant-local-example/public-config.json +3 -0
  456. package/packages/public-runtime/tests/fixtures/regulated-commerce/fake-destinations.ts +38 -0
  457. package/packages/public-runtime/tests/gtm-migration/fixtures/gtm-sample-container-v84.provenance.json +29 -0
  458. package/packages/public-runtime/tests/gtm-migration/fixtures/gtm-sample-container-v84.redacted.json +3397 -0
  459. package/scripts/build/copy-tenant-assets.mjs +14 -4
  460. package/scripts/dev/ai-edit.mjs +1 -1
  461. package/scripts/dev/checkout-watch.mjs +2 -2
  462. package/scripts/dev/file-browser.mjs +4 -6
  463. package/scripts/dev/file-writer.mjs +3 -3
  464. package/scripts/dev/git-status.mjs +2 -2
  465. package/scripts/dev/integration-guardrails.mjs +498 -0
  466. package/scripts/dev/locate-handler.mjs +3 -3
  467. package/scripts/dev/port-check.mjs +3 -3
  468. package/scripts/dev/publish.mjs +5 -9
  469. package/scripts/dev/safe-path.mjs +2 -2
  470. package/scripts/dev/shot.mjs +1 -1
  471. package/scripts/dev/tenant-source-root.mjs +1 -1
  472. package/scripts/dev/unified-diff.mjs +8 -3
  473. package/scripts/tot-dev.mjs +8 -11
  474. package/apps/storefront/src/lib/dev/vcBinding.ts +0 -80
@@ -0,0 +1,292 @@
1
+ /**
2
+ * Admin console shell client logic — hash-router tab switching, the floating
3
+ * Ask envelope, tenant-picker navigation, and roving-tabindex keyboard nav for
4
+ * the tablists. Imported from a processed `<script>` in admin.astro (ADR 0013):
5
+ * type-checked, bundled, tree-shaken, and its bundle hash is in the enforced
6
+ * CSP. The Ask envelope is built with the shared, unit-tested
7
+ * `buildAskEnvelope` (ai/askEnvelope) instead of a hand-copied inline mirror.
8
+ *
9
+ * There is no chat backend yet — the Ask envelope is emitted for dev inspection
10
+ * only (window.__toTAdminAsk + a "tot:admin-ask" CustomEvent), never sent over
11
+ * the network.
12
+ */
13
+ import { buildAskEnvelope, type AskEnvelope } from "./ai/askEnvelope";
14
+
15
+ const TAB_IDS = [
16
+ "orders",
17
+ "products",
18
+ "subscriptions",
19
+ "customers",
20
+ "fulfillment",
21
+ "reporting",
22
+ "ai-workflows",
23
+ "blog",
24
+ "publish",
25
+ "integrations",
26
+ "settings",
27
+ ] as const;
28
+
29
+ const ASK_CONTEXTS: Record<string, string> = {
30
+ orders: "Orders",
31
+ products: "Products",
32
+ subscriptions: "Subscriptions",
33
+ customers: "Customers",
34
+ fulfillment: "Fulfillment",
35
+ reporting: "Reporting",
36
+ "ai-workflows": "AI Workflows",
37
+ blog: "Blog",
38
+ publish: "Publish",
39
+ integrations: "Integrations",
40
+ settings: "Settings",
41
+ };
42
+
43
+ declare global {
44
+ interface Window {
45
+ __toTAdminAsk?: AskEnvelope;
46
+ }
47
+ }
48
+
49
+ export function initAdminShell(): void {
50
+ const tabSet = new Set<string>(TAB_IDS);
51
+ const tabHashPattern = new RegExp(`^#(${TAB_IDS.join("|")})$`);
52
+ const canViewInternalGuide =
53
+ document.documentElement.dataset.internalAdminGuide === "true";
54
+ const defaultTab = canViewInternalGuide ? "orders" : "settings";
55
+
56
+ const buildAskEnvelopeForTab = (id: string): AskEnvelope => {
57
+ const root = document.documentElement.dataset;
58
+ const isStaff = root.adminIsStaff === "true";
59
+ const panel = document.getElementById(id);
60
+ const selectedRecordId =
61
+ panel?.querySelector<HTMLElement>("[data-admin-selected-id]")?.dataset
62
+ .adminSelectedId || null;
63
+
64
+ return buildAskEnvelope({
65
+ tenant: {
66
+ adminAppTenant: root.adminAppTenant ?? "",
67
+ targetTenant: root.adminTargetTenant ?? "",
68
+ operator: root.adminOperator || null,
69
+ },
70
+ isStaff,
71
+ activeTab: id,
72
+ selectedRecordId,
73
+ });
74
+ };
75
+
76
+ const setAskContext = (id: string): void => {
77
+ const label = ASK_CONTEXTS[id] ?? "Storefront";
78
+ const askButton = document.querySelector<HTMLElement>("[data-admin-ask]");
79
+ const askContext = document.querySelector<HTMLElement>(
80
+ "[data-admin-ask-context]",
81
+ );
82
+
83
+ if (askContext) askContext.textContent = label;
84
+ if (askButton) {
85
+ askButton.setAttribute("aria-label", `Ask about ${label}`);
86
+ askButton.setAttribute("title", `Ask about ${label}`);
87
+ askButton.dataset.askScope = id;
88
+ }
89
+
90
+ window.__toTAdminAsk = buildAskEnvelopeForTab(id);
91
+ };
92
+
93
+ const panelIdFromHash = (): string | null => {
94
+ const rawHash = window.location.hash.slice(1);
95
+ // The tab id is the part before any "?" query suffix (#publish?pr=42);
96
+ // the raw hash is still used for internal-guide anchor resolution.
97
+ const hash = rawHash.split("?")[0] ?? "";
98
+ if (!rawHash) return defaultTab;
99
+ if (tabSet.has(hash)) return hash;
100
+ if (!canViewInternalGuide) return defaultTab;
101
+
102
+ const target = rawHash ? document.getElementById(rawHash) : null;
103
+ const panel = target?.closest<HTMLElement>("[data-admin-panel]");
104
+ if (panel?.id && tabSet.has(panel.id)) return panel.id;
105
+
106
+ return null;
107
+ };
108
+
109
+ const setActiveTab = (id: string): void => {
110
+ if (!tabSet.has(id)) return;
111
+
112
+ document.documentElement.dataset.adminMode = "work-area";
113
+ document.documentElement.dataset.adminTab = id;
114
+ setAskContext(id);
115
+
116
+ document.querySelectorAll<HTMLElement>("[data-admin-panel]").forEach((panel) => {
117
+ const active = panel.id === id;
118
+ panel.hidden = !active;
119
+ panel.setAttribute("aria-hidden", active ? "false" : "true");
120
+ });
121
+
122
+ document
123
+ .querySelectorAll<HTMLAnchorElement>("[data-admin-tab-link]")
124
+ .forEach((link) => {
125
+ const active = link.hash === `#${id}`;
126
+ link.classList.toggle("active", active);
127
+
128
+ if (link.getAttribute("role") === "tab") {
129
+ link.setAttribute("aria-selected", active ? "true" : "false");
130
+ link.tabIndex = active ? 0 : -1;
131
+ }
132
+ });
133
+ };
134
+
135
+ const setGuideMode = (): void => {
136
+ if (!canViewInternalGuide) {
137
+ setActiveTab(defaultTab);
138
+ return;
139
+ }
140
+
141
+ document.documentElement.dataset.adminMode = "guide";
142
+ setAskContext(defaultTab);
143
+
144
+ document.querySelectorAll<HTMLElement>("[data-admin-panel]").forEach((panel) => {
145
+ panel.hidden = true;
146
+ panel.setAttribute("aria-hidden", "true");
147
+ });
148
+
149
+ document
150
+ .querySelectorAll<HTMLAnchorElement>("[data-admin-tab-link]")
151
+ .forEach((link) => {
152
+ link.classList.remove("active");
153
+
154
+ if (link.getAttribute("role") === "tab") {
155
+ link.setAttribute("aria-selected", "false");
156
+ link.tabIndex = 0;
157
+ }
158
+ });
159
+ };
160
+
161
+ const scrollWorkspaceToTop = (): void => {
162
+ const scroller = document.querySelector<HTMLElement>(".main");
163
+ const reset = (): void => {
164
+ if (scroller) {
165
+ scroller.scrollTo({ top: 0, left: 0 });
166
+ return;
167
+ }
168
+
169
+ window.scrollTo({ top: 0, left: 0 });
170
+ };
171
+
172
+ reset();
173
+ requestAnimationFrame(reset);
174
+ setTimeout(reset, 0);
175
+ };
176
+
177
+ const scrollToHashTarget = (panelId: string): void => {
178
+ const hash = window.location.hash.slice(1);
179
+ const target = hash ? document.getElementById(hash) : null;
180
+
181
+ if (!target || tabSet.has(hash) || target.id === panelId) {
182
+ scrollWorkspaceToTop();
183
+ return;
184
+ }
185
+
186
+ target?.scrollIntoView({ block: "start" });
187
+ };
188
+
189
+ const activateFromHash = ({ scroll = false }: { scroll?: boolean } = {}): void => {
190
+ const panelId = panelIdFromHash();
191
+
192
+ if (panelId) {
193
+ setActiveTab(panelId);
194
+ // Strip any query suffix before deciding whether the hash names a
195
+ // real tab — a valid deep link like #publish?pr=42 must not be
196
+ // normalized away to #settings for merchant viewers.
197
+ const hashTab = window.location.hash.slice(1).split("?")[0] ?? "";
198
+ if (!canViewInternalGuide && !tabSet.has(hashTab)) {
199
+ history.replaceState(null, "", "#settings");
200
+ }
201
+ if (scroll) requestAnimationFrame(() => scrollToHashTarget(panelId));
202
+ return;
203
+ }
204
+
205
+ setGuideMode();
206
+ if (scroll) {
207
+ const hash = window.location.hash.slice(1);
208
+ requestAnimationFrame(() =>
209
+ document.getElementById(hash)?.scrollIntoView({ block: "start" }),
210
+ );
211
+ }
212
+ };
213
+
214
+ document
215
+ .querySelector<HTMLSelectElement>("[data-admin-tenant-picker-select]")
216
+ ?.addEventListener("change", (event) => {
217
+ const params = new URLSearchParams(window.location.search);
218
+ params.set("asTenant", (event.target as HTMLSelectElement).value);
219
+ window.location.assign(
220
+ `${window.location.pathname}?${params}${window.location.hash}`,
221
+ );
222
+ });
223
+
224
+ // Emit the Ask envelope on open. No chat backend yet — dev-inspectable
225
+ // only via window.__toTAdminAsk (already kept current by setAskContext)
226
+ // and this "tot:admin-ask" CustomEvent.
227
+ document.querySelector("[data-admin-ask]")?.addEventListener("click", () => {
228
+ const activeTab = document.documentElement.dataset.adminTab ?? defaultTab;
229
+ const envelope = buildAskEnvelopeForTab(activeTab);
230
+ window.__toTAdminAsk = envelope;
231
+ document.dispatchEvent(new CustomEvent("tot:admin-ask", { detail: envelope }));
232
+ if (
233
+ window.location.hostname === "localhost" ||
234
+ window.location.hostname === "127.0.0.1"
235
+ ) {
236
+ console.debug("[admin:ask]", envelope);
237
+ }
238
+ });
239
+
240
+ document.addEventListener("click", (event) => {
241
+ const target =
242
+ event.target instanceof Element
243
+ ? event.target
244
+ : (event.target as Node | null)?.parentElement ?? null;
245
+ const link = target?.closest<HTMLAnchorElement>("a[href^='#']");
246
+ if (!link || !tabHashPattern.test(link.hash)) return;
247
+
248
+ event.preventDefault();
249
+ const id = link.hash.slice(1);
250
+ setActiveTab(id);
251
+ history.pushState(null, "", link.hash);
252
+ scrollWorkspaceToTop();
253
+ });
254
+
255
+ document.addEventListener("keydown", (event) => {
256
+ const target = event.target instanceof Element ? event.target : null;
257
+ const currentTab = target?.closest<HTMLElement>(
258
+ "[role='tab'][data-admin-tab-link]",
259
+ );
260
+ if (!currentTab) return;
261
+
262
+ // Filter to visible tabs only: the mobile tab bar and the internal
263
+ // Admin Tab Map can both be present in the DOM at once (one hidden
264
+ // via CSS depending on viewport/viewer), and this selector matches
265
+ // role="tab" elements in either — without this filter, arrow/home/
266
+ // end navigation could walk into a display:none tablist whose
267
+ // .focus() is a silent no-op.
268
+ const tabs = Array.from(
269
+ document.querySelectorAll<HTMLElement>("[role='tab'][data-admin-tab-link]"),
270
+ ).filter((el) => el.offsetParent !== null);
271
+ const currentIndex = tabs.indexOf(currentTab);
272
+ let nextIndex = currentIndex;
273
+
274
+ if (event.key === "ArrowRight") nextIndex = (currentIndex + 1) % tabs.length;
275
+ if (event.key === "ArrowLeft")
276
+ nextIndex = (currentIndex - 1 + tabs.length) % tabs.length;
277
+ if (event.key === "Home") nextIndex = 0;
278
+ if (event.key === "End") nextIndex = tabs.length - 1;
279
+
280
+ if (nextIndex === currentIndex) return;
281
+
282
+ const nextTab = tabs[nextIndex];
283
+ if (!nextTab) return;
284
+
285
+ event.preventDefault();
286
+ nextTab.focus();
287
+ nextTab.click();
288
+ });
289
+
290
+ window.addEventListener("hashchange", () => activateFromHash({ scroll: true }));
291
+ activateFromHash({ scroll: Boolean(window.location.hash) });
292
+ }
@@ -1,7 +1,6 @@
1
1
  /**
2
- * Canonical approval state machine (baseline §Settings / §AI Workflows,
3
- * ai-evidence-substrate item d). `settings.ts` and `aiWorkflows.ts` previously
4
- * declared their own copies of this union; both now import it from here.
2
+ * Canonical approval state machine. `settings.ts` and `aiWorkflows.ts` import
3
+ * this union from here.
5
4
  */
6
5
  export type ApprovalMode = "draft_only" | "approval_required" | "guarded_automation";
7
6
 
@@ -1,9 +1,7 @@
1
1
  /**
2
- * Canonical audit event model (baseline "Audit logs must record both the
3
- * operator and the target tenant"; ai-evidence-substrate item e). Every
4
- * mutation-shaped or AI-suggested action in the admin console should record
5
- * one of these, keyed by `targetTenant` — never `adminAppTenant`, per
6
- * decision `tenant-envelope-contract`.
2
+ * Canonical audit event model records both the operator and the target
3
+ * tenant. Every mutation-shaped or AI-suggested action in the admin console
4
+ * should record one of these, keyed by `targetTenant` never `adminAppTenant`.
7
5
  */
8
6
  export interface AuditEvent {
9
7
  /** The signed-in operator's email, or a system actor id for automation-triggered events. */
@@ -1,23 +1,23 @@
1
1
  /**
2
2
  * Validate + sanitize merchant-submitted checkout styling into a safe, complete
3
- * `CheckoutStyle` before it is published to the versioned spine (U12 save path).
3
+ * `CheckoutStyle` before it is published to the versioned spine (the save path).
4
4
  *
5
5
  * The submitted body is a partial (`DeepPartial<CheckoutStyle>`): a merchant may
6
6
  * set one field without restating the rest, so this merges any valid override
7
- * over `DEFAULT_CHECKOUT_STYLE` (reusing U10's `mergeCheckoutStyle`) and returns a
8
- * complete descriptor. It is the WRITE-side guard; the go-live GateReport (U13)
7
+ * over `DEFAULT_CHECKOUT_STYLE` (reusing `mergeCheckoutStyle`) and returns a
8
+ * complete descriptor. It is the WRITE-side guard; the GateReport
9
9
  * still does the deeper compliance/contrast/perf pass on promote.
10
10
  *
11
11
  * Two hard constraints enforced here:
12
12
  * - **ASCII-safe.** Hosted checkout cache pass is not Unicode-safe — a non-ASCII
13
- * byte in a value that U11 renders into the pushed CSS can blank the checkout.
13
+ * byte in a value rendered into the pushed CSS can blank the checkout.
14
14
  * Every provided string leaf must be printable ASCII.
15
- * - **CSS-token hygiene.** These values are interpolated into generated CSS
16
- * (U11), so we reject the characters that could break out of a declaration
15
+ * - **CSS-token hygiene.** These values are interpolated into generated CSS,
16
+ * so we reject the characters that could break out of a declaration
17
17
  * (`;` `{` `}` `<` `>` and newlines). Defense-in-depth, not the full gate.
18
18
  *
19
19
  * Pure + dependency-free (no I/O, no Astro): unit-testable in isolation and safe
20
- * to reuse from the gate (U13) or the CSS renderer (U11) if promoted to
20
+ * to reuse from the gate or the CSS renderer if promoted to
21
21
  * public-runtime later.
22
22
  */
23
23
  import {
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Decide which tenant a checkout-style save may write to (U12b — staff
3
- * cross-tenant save).
2
+ * Decide which tenant a checkout-style save may write to — staff cross-tenant
3
+ * save.
4
4
  *
5
5
  * The base save gate (`resolveOwnerSession`) resolves the operator's OWN tenant
6
- * (the routed appDomain). U12 always wrote there. But a ToT-staff operator can
6
+ * (the routed appDomain). But a ToT-staff operator can
7
7
  * "operate as" another tenant via the admin picker (`?asTenant=`), and their
8
8
  * save must land on THAT tenant's artifact — provided they're actually
9
9
  * authorized for it. This resolver makes that decision, and it deliberately
@@ -4,7 +4,6 @@
4
4
  * staff-override authorization (`resolveAdminTenantMode`) that admin.astro
5
5
  * actually runs. This module re-exports that type so every mock service under
6
6
  * `lib/admin/**` can keep importing it from a stable relative path
7
- * (`../../envelope`) without declaring a second, competing interface (decision
8
- * `envelope-type-duplication-follow-up`).
7
+ * (`../../envelope`) without declaring a second, competing interface.
9
8
  */
10
9
  export type { AdminTenantEnvelope } from "@/lib/adminTenantEnvelope";
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Server-side client for the checkout order READ API (card 8585 / U2).
2
+ * Server-side client for the checkout order READ API.
3
3
  *
4
4
  * Calls `GET /commerce/orders[/:orderId]` with the tenant's per-tenant bearer key
5
5
  * (the ToT `partnerApi.apiKey`, held as a Worker secret — NEVER shipped to the
@@ -8,8 +8,7 @@
8
8
  *
9
9
  * The fetch runs on the Cloudflare Worker (server), so the call is same-origin →
10
10
  * cross-service server-to-server; it is NOT browser-originated and therefore not
11
- * CSP-governed — the U2 CSP connect-src entry is intentionally skipped (board
12
- * decision `u2-csp-server-side-fetch`).
11
+ * CSP-governed — the CSP connect-src entry is intentionally skipped.
13
12
  *
14
13
  * `fetchImpl` is injectable so the client is unit-testable offline.
15
14
  */
@@ -68,8 +67,7 @@ export interface CheckoutOrderClientConfig {
68
67
  /**
69
68
  * Resolve the checkout order API base URL for an environment (contract §2).
70
69
  * qa/test use the non-prod proxy; live uses prod. Kept private so it does not
71
- * collide with U11b's exported checkout theme base URL before the units fold;
72
- * the integrator can dedup into one shared export.
70
+ * collide with the exported checkout theme base URL.
73
71
  */
74
72
  export function orderApiBaseUrl(env: CustomizationEnv): string {
75
73
  return env === "live"
@@ -1,22 +1,20 @@
1
1
  /**
2
- * REAL orders view model (card 8585 / U3) replaces the deterministic mock as
3
- * the Orders tab's data source. Fetches the tenant's checkout orders via U2's
4
- * order client and maps the frozen DTO (`@tot/public-runtime` checkout-orders)
5
- * into the EXISTING `OrdersViewModel` shape, so `OrdersWorkspace.astro` renders
6
- * unchanged. Read-only (scope-locks) — no write paths.
2
+ * REAL orders view model the Orders tab's data source. Fetches the tenant's
3
+ * checkout orders via the order client and maps the frozen DTO
4
+ * (`@tot/public-runtime` checkout-orders) into the `OrdersViewModel` shape that
5
+ * `OrdersWorkspace.astro` renders. Read-only (scope-locks) no write paths.
7
6
  *
8
7
  * The mapping is a pure function (`mapOrdersToViewModel`) for testability; the
9
8
  * orchestration (`getOrdersViewModel`) lists orders, eagerly fetches each order's
10
9
  * detail (OrdersWorkspace renders `detailsById[row.id]` for every row), and maps.
11
- * On ANY upstream failure it returns a valid EMPTY view model so the tab renders
12
- * (rich loading/empty/error UX is U5). NOTE: the live "real qa data" path is
13
- * gated on ToT-core exposing `GET /api/exciseTax/orders` (see U1/U2 notes); until
14
- * then this yields the empty model on qa.
10
+ * On ANY upstream failure it returns a valid EMPTY view model so the tab renders.
11
+ * The live "real qa data" path is gated on ToT-core exposing
12
+ * `GET /api/exciseTax/orders`; until that exists this yields the empty model on qa.
15
13
  *
16
14
  * Identity/age fields (riskLevel, readiness "identity_and_age", evidence) are
17
- * derived provisionally from commerce facts here; U4 (the tot20 verification
18
- * join) fills them authoritatively via the DTO's null `verification` /
19
- * `verificationDetail` slots — no shape change needed.
15
+ * derived provisionally from commerce facts here; the tot20 verification join
16
+ * fills them authoritatively via the DTO's null `verification` /
17
+ * `verificationDetail` slots.
20
18
  */
21
19
  import type {
22
20
  CheckoutOrderDetail,
@@ -45,7 +43,7 @@ function deriveNextStep(fulfillment: OrderShipState, blocker: string | null): st
45
43
  return "Create label";
46
44
  }
47
45
 
48
- /** Provisional risk until U4 fills `verification`. Prefer a real riskLevel when present. */
46
+ /** Provisional risk until the verification join fills `verification`. Prefer a real riskLevel when present. */
49
47
  function deriveRisk(
50
48
  verification: CheckoutOrderVerification | null,
51
49
  blocker: string | null,
@@ -75,7 +73,7 @@ export function mapSummaryToRow(s: CheckoutOrderSummary): OrderRow {
75
73
  };
76
74
  }
77
75
 
78
- /** Commerce-derived readiness checks (U4 enriches the identity dimension). */
76
+ /** Commerce-derived readiness checks (the verification join enriches the identity dimension). */
79
77
  function deriveReadinessChecks(d: CheckoutOrderDetail): OrderReadinessCheck[] {
80
78
  const ageHold = d.blocker === "Age verification hold";
81
79
  return [
@@ -118,7 +116,7 @@ function deriveReadinessChecks(d: CheckoutOrderDetail): OrderReadinessCheck[] {
118
116
  ];
119
117
  }
120
118
 
121
- /** Base commerce evidence events (U4 replaces with the real verification timeline). */
119
+ /** Base commerce evidence events (the verification join replaces with the real verification timeline). */
122
120
  function deriveEvidenceTimeline(d: CheckoutOrderDetail): OrderEvidenceEvent[] {
123
121
  const events: OrderEvidenceEvent[] = [
124
122
  { title: "Order imported", detail: "Storefront order became available in the admin queue.", at: d.placedAt },
@@ -226,7 +224,7 @@ export interface GetOrdersViewModelOptions {
226
224
  * the Orders tab always renders.
227
225
  */
228
226
  /**
229
- * Load outcome for the Orders tab (U5) — lets the UI pick the right state:
227
+ * Load outcome for the Orders tab — lets the UI pick the right state:
230
228
  * `loaded` (rows), `empty` (fetch OK, 0 orders), `error` (upstream failed), and
231
229
  * `not_configured` (produced by the caller when no bearer/client is available —
232
230
  * the service itself never returns it). `page` carries the pagination cursor.
@@ -240,7 +238,7 @@ export interface OrdersLoadResult {
240
238
  }
241
239
 
242
240
  /**
243
- * Parse server-backed list filters from a request's query string (U5). `queue`
241
+ * Parse server-backed list filters from a request's query string. `queue`
244
242
  * of `"all"` (or absent) means no server filter. Non-numeric `limit` is ignored.
245
243
  * `payment`/search are NOT here — they are client-side refinements (the DTO list
246
244
  * API has no payment filter, per contract §9).
@@ -263,7 +261,7 @@ export function parseOrderFilters(params: URLSearchParams): CheckoutOrderListFil
263
261
  }
264
262
 
265
263
  /**
266
- * Fetch + map the orders view model AND report the load outcome (U5). Lists,
264
+ * Fetch + map the orders view model AND report the load outcome. Lists,
267
265
  * eagerly fetches per-order detail, maps. Distinguishes empty from error so the
268
266
  * tab can degrade gracefully. Never throws.
269
267
  */
@@ -292,7 +290,7 @@ export async function getOrdersViewModelResult(
292
290
  }
293
291
  }
294
292
 
295
- /** Back-compat convenience: just the view model (see getOrdersViewModelResult). */
293
+ /** Convenience wrapper: just the view model (see getOrdersViewModelResult). */
296
294
  export async function getOrdersViewModel(
297
295
  opts: GetOrdersViewModelOptions,
298
296
  ): Promise<OrdersViewModel> {
@@ -1,10 +1,8 @@
1
1
  /**
2
- * AI Workflows view model (baseline §AI Workflows) — the 8 named recurring
3
- * jobs as a control-plane record. No execution: this unit only defines the
4
- * read-oriented record shape (ai-workflows-scaffold/operational build the tab
5
- * + execution on top of it). `ApprovalMode`/`AuditEvent`/`AiRecommendation`
6
- * now come from the ai-evidence-substrate (`lib/admin/ai`), which formalizes
7
- * the approval/evidence models this view model originally stubbed.
2
+ * AI Workflows view model — the 8 named recurring jobs as a control-plane
3
+ * record. No execution: this defines only the read-oriented record shape; the
4
+ * tab + execution build on top of it. `ApprovalMode`/`AuditEvent`/`AiRecommendation`
5
+ * come from `lib/admin/ai`, which formalizes the approval/evidence models.
8
6
  */
9
7
 
10
8
  import type { ApprovalMode } from "../ai/approvalMode";
@@ -54,7 +54,7 @@ export interface SettingsViewModel {
54
54
  auditTrail: SettingsAuditEvent[];
55
55
  /**
56
56
  * The target tenant's current checkout styling — the editable descriptor the
57
- * "Checkout styling" section (U12) renders in its editor and saves back through
57
+ * "Checkout styling" section renders in its editor and saves back through
58
58
  * the versioned publish spine (`POST /api/admin/checkout-style` →
59
59
  * `publishToTest` on `tenants/<id>/checkout-style.json`). Always a complete
60
60
  * `CheckoutStyle` (the resolved default merged with any published override), so
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Composition root + shared helpers for the `/api/apps/admin/*` routes
3
- * (PrivateApps epic, D2 Chunk C) — builds an `AppRegistryService` over the
2
+ * Composition root + shared helpers for the `/api/apps/admin/*` routes
3
+ * builds an `AppRegistryService` over the
4
4
  * `STOREFRONT_APPS_DB` `Queryable` binding and a `D1CredentialStore`, the same
5
- * construction `api/apps/oauth/token.ts` (Chunk B) uses, and mirrors
5
+ * construction `api/apps/oauth/token.ts` uses, and mirrors
6
6
  * `../grants/route.ts`'s `getService()` + no-store `json()` + 503-when-
7
7
  * unconfigured pattern. Kept out of the pure service module so that stays
8
8
  * transport-free and unit-testable against a fake `Queryable`.
@@ -18,6 +18,7 @@ import { DEFAULT_APP_GATEWAY_KID, APP_GATEWAY_KID_ENV } from "./gatewayKeys.js";
18
18
  import { fromD1 } from "../d1/catalog.js";
19
19
  import { readD1, readEnv } from "../env.js";
20
20
  import { MANAGE_ROLES, type AdminAuthResult } from "./adminSession.js";
21
+ import { ManagedAnalyticsApiV1Facade } from "./managedAnalyticsService.js";
21
22
 
22
23
  /**
23
24
  * No-store JSON response — install/rotate bodies carry a one-time client
@@ -44,6 +45,13 @@ export async function getRegistryService(): Promise<AppRegistryService | Respons
44
45
  return new AppRegistryService(db, credentials);
45
46
  }
46
47
 
48
+ /** Build the managed-analytics v1 service over the same tenant control-plane D1. */
49
+ export async function getManagedAnalyticsService(): Promise<ManagedAnalyticsApiV1Facade | Response> {
50
+ const d1 = await readD1("STOREFRONT_APPS_DB");
51
+ if (!d1) return json({ error: "app registry not configured" }, 503);
52
+ return new ManagedAnalyticsApiV1Facade(fromD1(d1));
53
+ }
54
+
47
55
  /** HTTP status per `RegistryError` code — the one shared fail-closed mapping. */
48
56
  const STATUS_BY_REGISTRY_CODE: Record<RegistryErrorCode, number> = {
49
57
  scope_denied: 400,
@@ -52,6 +60,8 @@ const STATUS_BY_REGISTRY_CODE: Record<RegistryErrorCode, number> = {
52
60
  invalid_state: 409,
53
61
  invalid_webhook_endpoint: 400,
54
62
  invalid_widget_placement: 400,
63
+ unknown_version: 404,
64
+ invalid_version_facets: 400,
55
65
  };
56
66
 
57
67
  /** Map a `RegistryError` to its HTTP status. Never echoes internals — code + message only. */
@@ -72,7 +82,7 @@ export function parseInstallId(body: unknown): string | null {
72
82
  * Resolve `installId` and verify it belongs to `tenantId` — every mutating
73
83
  * admin route (update/suspend/resume/uninstall/rotate) MUST call this BEFORE
74
84
  * invoking a service method, since those methods take a bare `installId` with
75
- * no tenant check of their own (Chunk A assumption #1). A foreign-tenant
85
+ * no tenant check of their own. A foreign-tenant
76
86
  * `installId` is reported IDENTICALLY to a truly-missing one — 404, same
77
87
  * body shape as `RegistryError("not_found")` — so there is no cross-tenant
78
88
  * existence oracle.